UNPKG

prepack

Version:

Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.

203 lines (148 loc) 8.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = _default; var _singletons = require("../../singletons.js"); var _index = require("../../values/index.js"); var _call = require("../../methods/call.js"); var _get = require("../../methods/get.js"); var _is = require("../../methods/is.js"); var _has = require("../../methods/has.js"); var _abstract = require("../../methods/abstract.js"); var _invariant = _interopRequireDefault(require("../../invariant.js")); var _descriptors = require("../../descriptors.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ /* strict-local */ function _default(realm, obj) { // ECMA262 19.2.3 obj.$Call = (thisArgument, argsList) => { return realm.intrinsics.undefined; }; // ECMA262 19.2.3 obj.defineNativeProperty("length", realm.intrinsics.zero, { writable: false }); // ECMA262 19.2.3 obj.defineNativeProperty("name", realm.intrinsics.emptyString, { writable: false }); // ECMA262 19.2.3.3 obj.defineNativeMethod("call", 1, (func, [thisArg, ...argList]) => { // 1. If IsCallable(func) is false, throw a TypeError exception. if ((0, _is.IsCallable)(realm, func) === false) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "not callable"); } // 2. Let argList be a new empty List. // 3. If this method was called with more than one argument, then in left to right order, // starting with the second argument, append each argument as the last element of argList. argList; // TODO #1008 4. Perform PrepareForTailCall(). // 5. Return ? Call(func, thisArg, argList). return (0, _call.Call)(realm, func, thisArg, argList); }); function conditionalFunctionApply(func, thisArg, condValue, consequentVal, alternateVal) { return realm.evaluateWithAbstractConditional(condValue, () => { return realm.evaluateForEffects(() => functionApply(func, thisArg, consequentVal), null, "conditionalFunctionApply consequent"); }, () => { return realm.evaluateForEffects(() => functionApply(func, thisArg, alternateVal), null, "conditionalFunctionApply alternate"); }); } function functionApply(func, thisArg, argArray) { // 1. If IsCallable(func) is false, throw a TypeError exception. if ((0, _is.IsCallable)(realm, func) === false) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "not callable"); } // 2. If argArray is null or undefined, then if ((0, _has.HasSomeCompatibleType)(argArray, _index.NullValue, _index.UndefinedValue)) { // TODO #1008 a. Perform PrepareForTailCall(). // b. Return ? Call(func, thisArg). return (0, _call.Call)(realm, func, thisArg); } if (argArray instanceof _index.AbstractValue) { if (argArray.kind === "conditional") { let [condValue, consequentVal, alternateVal] = argArray.args; (0, _invariant.default)(condValue instanceof _index.AbstractValue); return conditionalFunctionApply(func, thisArg, condValue, consequentVal, alternateVal); } else if (argArray.kind === "||") { let [leftValue, rightValue] = argArray.args; (0, _invariant.default)(leftValue instanceof _index.AbstractValue); return conditionalFunctionApply(func, thisArg, leftValue, leftValue, rightValue); } else if (argArray.kind === "&&") { let [leftValue, rightValue] = argArray.args; (0, _invariant.default)(leftValue instanceof _index.AbstractValue); return conditionalFunctionApply(func, thisArg, leftValue, rightValue, leftValue); } } // 3. Let argList be ? CreateListFromArrayLike(argArray). let argList = _singletons.Create.CreateListFromArrayLike(realm, argArray); // TODO #1008 4. Perform PrepareForTailCall(). // 5. Return ? Call(func, thisArg, argList). return (0, _call.Call)(realm, func, thisArg, argList); } // ECMA262 19.2.3.1 obj.defineNativeMethod("apply", 2, (func, [thisArg, argArray]) => functionApply(func, thisArg, argArray)); // ECMA262 19.2.3.2 obj.defineNativeMethod("bind", 1, (context, [thisArg, ...args]) => { // 1. Let Target be the realm value. let Target = context; // 2. If IsCallable(Target) is false, throw a TypeError exception. if ((0, _is.IsCallable)(realm, Target) === false) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } (0, _invariant.default)(Target instanceof _index.ObjectValue); // 3. Let args be a new (possibly empty) List consisting of all of the argument values provided after thisArg in order. args; // 4. Let F be ? BoundFunctionCreate(Target, thisArg, args). let F = _singletons.Functions.BoundFunctionCreate(realm, Target, thisArg, args); // 5. Let targetHasLength be ? HasOwnProperty(Target, "length"). let targetHasLength = (0, _has.HasOwnProperty)(realm, Target, new _index.StringValue(realm, "length")); let L; // 6. If targetHasLength is true, then if (targetHasLength === true) { // a. Let targetLen be ? Get(Target, "length"). let targetLen = (0, _get.Get)(realm, Target, new _index.StringValue(realm, "length")); // b. If Type(targetLen) is not Number, let L be 0. if (!targetLen.mightBeNumber()) { L = 0; } else { // c. Else, targetLen = targetLen.throwIfNotConcreteNumber(); // i. Let targetLen be ToInteger(targetLen). targetLen = _singletons.To.ToInteger(realm, targetLen); // ii. Let L be the larger of 0 and the result of targetLen minus the number of elements of args. L = Math.max(0, targetLen - args.length); } } else { // 7. Else let L be 0. L = 0; } // 8. Perform ! DefinePropertyOrThrow(F, "length", PropertyDescriptor {[[Value]]: L, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}). _singletons.Properties.DefinePropertyOrThrow(realm, F, "length", new _descriptors.PropertyDescriptor({ value: new _index.NumberValue(realm, L), writable: false, enumerable: false, configurable: true })); // 9. Let targetName be ? Get(Target, "name"). let targetName = (0, _get.Get)(realm, Target, new _index.StringValue(realm, "name")); // 10. If Type(targetName) is not String, let targetName be the empty string. if (!(targetName instanceof _index.StringValue)) targetName = realm.intrinsics.emptyString; // 11. Perform SetFunctionName(F, targetName, "bound"). _singletons.Functions.SetFunctionName(realm, F, targetName, "bound"); // 12. Return F. return F; }); // ECMA262 19.2.3.6 obj.defineNativeMethod(realm.intrinsics.SymbolHasInstance, 1, (context, [V]) => { // 1. Let F be the this value. let F = context; // 2. Return ? OrdinaryHasInstance(F, V). return new _index.BooleanValue(realm, (0, _abstract.OrdinaryHasInstance)(realm, F, V)); }, { writable: false, configurable: false }); // ECMA262 19.2.3.5 obj.defineNativeMethod("toString", 0, _context => { let context = _context.throwIfNotConcrete(); if (context instanceof _index.NativeFunctionValue) { let name = context.name; if (name instanceof _index.AbstractValue) { return new _index.StringValue(realm, `function () {[native code]}`); } else { (0, _invariant.default)(typeof name === "string"); return new _index.StringValue(realm, `function ${name}() { [native code] }`); } } else if (context instanceof _index.FunctionValue) { // TODO #1009: provide function source code return new _index.StringValue(realm, "function () { }"); } else { // 3. Throw a TypeError exception. throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, new _index.StringValue(realm, "Function.prototype.toString is not generic")); } }); } //# sourceMappingURL=FunctionPrototype.js.map