2023-08-27 18:21:25 +00:00
|
|
|
define("values/function", () => {
|
|
|
|
var Function = env.global.Function = function() {
|
|
|
|
throw 'Using the constructor Function() is forbidden.';
|
|
|
|
} as unknown as FunctionConstructor;
|
|
|
|
|
2023-09-04 11:30:57 +00:00
|
|
|
env.setProto('function', Function.prototype);
|
|
|
|
setConstr(Function.prototype, Function);
|
2023-08-27 18:21:25 +00:00
|
|
|
|
2023-09-04 11:30:57 +00:00
|
|
|
setProps(Function.prototype, {
|
2023-08-27 18:21:25 +00:00
|
|
|
apply(thisArg, args) {
|
|
|
|
if (typeof args !== 'object') throw 'Expected arguments to be an array-like object.';
|
|
|
|
var len = args.length - 0;
|
|
|
|
let newArgs: any[];
|
2023-09-04 11:30:57 +00:00
|
|
|
if (internals.isArray(args)) newArgs = args;
|
2023-08-27 18:21:25 +00:00
|
|
|
else {
|
|
|
|
newArgs = [];
|
|
|
|
|
|
|
|
while (len >= 0) {
|
|
|
|
len--;
|
|
|
|
newArgs[len] = args[len];
|
|
|
|
}
|
2023-08-25 20:48:40 +00:00
|
|
|
}
|
2023-08-05 15:37:18 +00:00
|
|
|
|
2023-09-04 11:30:57 +00:00
|
|
|
return internals.apply(this, thisArg, newArgs);
|
2023-08-27 18:21:25 +00:00
|
|
|
},
|
|
|
|
call(thisArg, ...args) {
|
|
|
|
return this.apply(thisArg, args);
|
|
|
|
},
|
|
|
|
bind(thisArg, ...args) {
|
2023-09-04 11:30:57 +00:00
|
|
|
const func = this;
|
|
|
|
const res = function() {
|
|
|
|
const resArgs = [];
|
2023-08-05 15:37:18 +00:00
|
|
|
|
2023-09-04 11:30:57 +00:00
|
|
|
for (let i = 0; i < args.length; i++) {
|
2023-08-27 18:21:25 +00:00
|
|
|
resArgs[i] = args[i];
|
|
|
|
}
|
2023-09-04 11:30:57 +00:00
|
|
|
for (let i = 0; i < arguments.length; i++) {
|
2023-08-27 18:21:25 +00:00
|
|
|
resArgs[i + args.length] = arguments[i];
|
|
|
|
}
|
2023-08-05 15:37:18 +00:00
|
|
|
|
2023-08-27 18:21:25 +00:00
|
|
|
return func.apply(thisArg, resArgs);
|
|
|
|
};
|
|
|
|
res.name = "<bound> " + func.name;
|
|
|
|
return res;
|
|
|
|
},
|
|
|
|
toString() {
|
|
|
|
return 'function (...) { ... }';
|
|
|
|
},
|
|
|
|
});
|
2023-09-04 11:30:57 +00:00
|
|
|
setProps(Function, {
|
2023-08-27 18:21:25 +00:00
|
|
|
async(func) {
|
|
|
|
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
|
|
|
|
|
|
|
|
return function (this: any) {
|
|
|
|
const args = arguments;
|
|
|
|
|
|
|
|
return new Promise((res, rej) => {
|
2023-09-04 11:30:57 +00:00
|
|
|
const gen = internals.apply(internals.generator(func as any), this, args as any);
|
2023-08-27 18:21:25 +00:00
|
|
|
|
|
|
|
(function next(type: 'none' | 'err' | 'ret', val?: any) {
|
|
|
|
try {
|
|
|
|
let result;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case 'err': result = gen.throw(val); break;
|
|
|
|
case 'ret': result = gen.next(val); break;
|
|
|
|
case 'none': result = gen.next(); break;
|
|
|
|
}
|
|
|
|
if (result.done) res(result.value);
|
|
|
|
else Promise.resolve(result.value).then(
|
|
|
|
v => next('ret', v),
|
|
|
|
v => next('err', v)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
rej(e);
|
|
|
|
}
|
|
|
|
})('none');
|
|
|
|
});
|
|
|
|
};
|
|
|
|
},
|
|
|
|
asyncGenerator(func) {
|
|
|
|
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
|
|
|
|
|
2023-09-04 11:30:57 +00:00
|
|
|
return function(this: any, ...args: any[]) {
|
|
|
|
const gen = internals.apply(internals.generator((_yield) => func(
|
2023-08-27 18:21:25 +00:00
|
|
|
val => _yield(['await', val]) as any,
|
|
|
|
val => _yield(['yield', val])
|
2023-09-04 11:30:57 +00:00
|
|
|
)), this, args) as Generator<['await' | 'yield', any]>;
|
2023-08-27 18:21:25 +00:00
|
|
|
|
|
|
|
const next = (resolve: Function, reject: Function, type: 'none' | 'val' | 'ret' | 'err', val?: any) => {
|
|
|
|
let res;
|
2023-08-25 20:48:57 +00:00
|
|
|
|
2023-08-27 18:21:25 +00:00
|
|
|
try {
|
2023-08-25 20:48:57 +00:00
|
|
|
switch (type) {
|
2023-08-27 18:21:25 +00:00
|
|
|
case 'val': res = gen.next(val); break;
|
|
|
|
case 'ret': res = gen.return(val); break;
|
|
|
|
case 'err': res = gen.throw(val); break;
|
|
|
|
default: res = gen.next(); break;
|
2023-08-25 20:48:57 +00:00
|
|
|
}
|
2023-08-25 21:41:28 +00:00
|
|
|
}
|
2023-08-27 18:21:25 +00:00
|
|
|
catch (e) { return reject(e); }
|
|
|
|
|
|
|
|
if (res.done) return { done: true, res: <any>res };
|
|
|
|
else if (res.value[0] === 'await') Promise.resolve(res.value[1]).then(
|
|
|
|
v => next(resolve, reject, 'val', v),
|
|
|
|
v => next(resolve, reject, 'err', v),
|
|
|
|
)
|
|
|
|
else resolve({ done: false, value: res.value[1] });
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
next() {
|
|
|
|
const args = arguments;
|
|
|
|
if (arguments.length === 0) return new Promise((res, rej) => next(res, rej, 'none'));
|
|
|
|
else return new Promise((res, rej) => next(res, rej, 'val', args[0]));
|
|
|
|
},
|
|
|
|
return: (value) => new Promise((res, rej) => next(res, rej, 'ret', value)),
|
|
|
|
throw: (value) => new Promise((res, rej) => next(res, rej, 'err', value)),
|
2023-09-09 14:32:46 +00:00
|
|
|
[env.global.Symbol.asyncIterator]() { return this; }
|
2023-08-25 21:41:28 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-27 18:21:25 +00:00
|
|
|
},
|
|
|
|
generator(func) {
|
|
|
|
if (typeof func !== 'function') throw new TypeError('Expected func to be function.');
|
2023-09-04 11:30:57 +00:00
|
|
|
const gen = internals.generator(func);
|
|
|
|
return function(this: any, ...args: any[]) {
|
|
|
|
const it = internals.apply(gen, this, args);
|
2023-08-27 18:21:25 +00:00
|
|
|
|
|
|
|
return {
|
2023-09-04 11:30:57 +00:00
|
|
|
next: (...args) => internals.apply(it.next, it, args),
|
|
|
|
return: (val) => internals.apply(it.next, it, [val]),
|
|
|
|
throw: (val) => internals.apply(it.next, it, [val]),
|
2023-09-09 14:32:46 +00:00
|
|
|
[env.global.Symbol.iterator]() { return this; }
|
2023-08-27 18:21:25 +00:00
|
|
|
}
|
2023-08-25 21:44:28 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-27 18:21:25 +00:00
|
|
|
})
|
2023-09-04 11:30:57 +00:00
|
|
|
internals.markSpecial(Function);
|
2023-08-27 18:21:25 +00:00
|
|
|
});
|