UNPKG

prepack

Version:

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

266 lines (189 loc) 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = _default; var _errors = require("../errors.js"); var _index = require("../domains/index.js"); var _index2 = require("../values/index.js"); var _environment = require("../environment.js"); var _invariant = _interopRequireDefault(require("../invariant.js")); var _index3 = require("../methods/index.js"); var _singletons = require("../singletons.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 */ //import { SimpleNormalCompletion } from "../completions.js"; function isInstance(proto, Constructor) { return proto instanceof Constructor || proto === Constructor.prototype; } function evaluateDeleteOperation(expr, realm) { // ECMA262 12.5.3.2 // 1. Let ref be the result of evaluating UnaryExpression. let ref = expr; // 2. ReturnIfAbrupt(ref). // 3. If Type(ref) is not Reference, return true. if (!(ref instanceof _environment.Reference)) return realm.intrinsics.true; // 4. If IsUnresolvableReference(ref) is true, then if (_singletons.Environment.IsUnresolvableReference(realm, ref)) { // a. Assert: IsStrictReference(ref) is false. (0, _invariant.default)(!_singletons.Environment.IsStrictReference(realm, ref), "did not expect a strict reference"); // b. Return true. return realm.intrinsics.true; } // 5. If IsPropertyReference(ref) is true, then if (_singletons.Environment.IsPropertyReference(realm, ref)) { // a. If IsSuperReference(ref) is true, throw a ReferenceError exception. if (_singletons.Environment.IsSuperReference(realm, ref)) { throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError); } // b. Let baseObj be ! ToObject(GetBase(ref)). let base = _singletons.Environment.GetBase(realm, ref); // Constructing the reference checks that base is coercible to an object hence (0, _invariant.default)(base instanceof _index2.ConcreteValue || base instanceof _index2.AbstractObjectValue); let baseObj = _singletons.To.ToObject(realm, base); // c. Let deleteStatus be ? baseObj.[[Delete]](GetReferencedName(ref)). let deleteStatus = baseObj.$Delete(_singletons.Environment.GetReferencedName(realm, ref)); // d. If deleteStatus is false and IsStrictReference(ref) is true, throw a TypeError exception. if (!deleteStatus && _singletons.Environment.IsStrictReference(realm, ref)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } // e. Return deleteStatus. return new _index2.BooleanValue(realm, deleteStatus); } // 6. Else ref is a Reference to an Environment Record binding, // a. Let bindings be GetBase(ref). let bindings = _singletons.Environment.GetBase(realm, ref); (0, _invariant.default)(bindings instanceof _environment.EnvironmentRecord); // b. Return ? bindings.DeleteBinding(GetReferencedName(ref)). let referencedName = _singletons.Environment.GetReferencedName(realm, ref); (0, _invariant.default)(typeof referencedName === "string"); return new _index2.BooleanValue(realm, bindings.DeleteBinding(referencedName)); } function tryToEvaluateOperationOrLeaveAsAbstract(ast, expr, func, strictCode, realm) { let effects; try { effects = realm.evaluateForEffects(() => func(ast, expr, strictCode, realm), undefined, "tryToEvaluateOperationOrLeaveAsAbstract"); } catch (error) { if (error instanceof _errors.FatalError) { return realm.evaluateWithPossibleThrowCompletion(() => { let value = _singletons.Environment.GetValue(realm, expr); // if the value is abstract, then create a unary op for it, // otherwise we rethrow the error as we don't handle it at this // point in time if (value instanceof _index2.AbstractValue) { return _index2.AbstractValue.createFromUnaryOp(realm, ast.operator, value); } throw error; }, _index.TypesDomain.topVal, _index.ValuesDomain.topVal); } else { throw error; } } realm.applyEffects(effects); return realm.returnOrThrowCompletion(effects.result); } function evaluateOperation(ast, expr, strictCode, realm) { function reportError(value) { if (value.getType() === _index2.SymbolValue) { // Symbols never implicitly coerce to primitives. throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } let error = new _errors.CompilerDiagnostic("might be a symbol or an object with an unknown valueOf or toString or Symbol.toPrimitive method", ast.argument.loc, "PP0008", "RecoverableError"); if (realm.handleError(error) === "Fail") throw new _errors.FatalError(); } if (ast.operator === "+") { // ECMA262 12.5.6.1 // 1. Let expr be the result of evaluating UnaryExpression. expr; // 2. Return ? ToNumber(? GetValue(expr)). let value = _singletons.Environment.GetValue(realm, expr); if (value instanceof _index2.AbstractValue) { if (!_singletons.To.IsToNumberPure(realm, value)) reportError(value); return _index2.AbstractValue.createFromUnaryOp(realm, "+", value); } (0, _invariant.default)(value instanceof _index2.ConcreteValue); return _index2.IntegralValue.createFromNumberValue(realm, _singletons.To.ToNumber(realm, value)); } else if (ast.operator === "-") { // ECMA262 12.5.7.1 // 1. Let expr be the result of evaluating UnaryExpression. expr; // 2. Let oldValue be ? ToNumber(? GetValue(expr)). let value = _singletons.Environment.GetValue(realm, expr); if (value instanceof _index2.AbstractValue) { if (!_singletons.To.IsToNumberPure(realm, value)) reportError(value); return _index2.AbstractValue.createFromUnaryOp(realm, "-", value); } (0, _invariant.default)(value instanceof _index2.ConcreteValue); let oldValue = _singletons.To.ToNumber(realm, value); // 3. If oldValue is NaN, return NaN. if (isNaN(oldValue)) { return realm.intrinsics.NaN; } // 4. Return the result of negating oldValue; that is, compute a Number with the same magnitude but opposite sign. return _index2.IntegralValue.createFromNumberValue(realm, -oldValue); } else if (ast.operator === "~") { // ECMA262 12.5.8 // 1. Let expr be the result of evaluating UnaryExpression. expr; // 2. Let oldValue be ? ToInt32(? GetValue(expr)). let value = _singletons.Environment.GetValue(realm, expr); if (value instanceof _index2.AbstractValue) { if (!_singletons.To.IsToNumberPure(realm, value)) reportError(value); return _index2.AbstractValue.createFromUnaryOp(realm, "~", value); } (0, _invariant.default)(value instanceof _index2.ConcreteValue); let oldValue = _singletons.To.ToInt32(realm, value); // 3. Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer. return _index2.IntegralValue.createFromNumberValue(realm, ~oldValue); } else if (ast.operator === "!") { // ECMA262 12.6.9 // 1. Let expr be the result of evaluating UnaryExpression. expr; // 2. Let oldValue be ToBoolean(? GetValue(expr)). let value = _singletons.Environment.GetConditionValue(realm, expr); if (value instanceof _index2.AbstractValue) return _index2.AbstractValue.createFromUnaryOp(realm, "!", value); (0, _invariant.default)(value instanceof _index2.ConcreteValue); let oldValue = _singletons.To.ToBoolean(realm, value); // 3. If oldValue is true, return false. if (oldValue === true) return realm.intrinsics.false; // 4. Return true. return realm.intrinsics.true; } else if (ast.operator === "void") { // 1. Let expr be the result of evaluating UnaryExpression. expr; // 2. Perform ? GetValue(expr). _singletons.Environment.GetValue(realm, expr); // 3. Return undefined. return realm.intrinsics.undefined; } else { (0, _invariant.default)(ast.operator === "typeof"); // ECMA262 12.6.5 // 1. Let val be the result of evaluating UnaryExpression. let val = expr; // 2. If Type(val) is Reference, then if (val instanceof _environment.Reference) { // a. If IsUnresolvableReference(val) is true, return "undefined". if (_singletons.Environment.IsUnresolvableReference(realm, val)) { return new _index2.StringValue(realm, "undefined"); } } // 3. Let val be ? GetValue(val). val = _singletons.Environment.GetValue(realm, val); // 4. Return a String according to Table 35. let proto = val.getType().prototype; if (isInstance(proto, _index2.UndefinedValue)) { return new _index2.StringValue(realm, "undefined"); } else if (isInstance(proto, _index2.NullValue)) { return new _index2.StringValue(realm, "object"); } else if (isInstance(proto, _index2.StringValue)) { return new _index2.StringValue(realm, "string"); } else if (isInstance(proto, _index2.BooleanValue)) { return new _index2.StringValue(realm, "boolean"); } else if (isInstance(proto, _index2.NumberValue)) { return new _index2.StringValue(realm, "number"); } else if (isInstance(proto, _index2.SymbolValue)) { return new _index2.StringValue(realm, "symbol"); } else if (isInstance(proto, _index2.ObjectValue)) { if ((0, _index3.IsCallable)(realm, val)) { return new _index2.StringValue(realm, "function"); } return new _index2.StringValue(realm, "object"); } else { (0, _invariant.default)(val instanceof _index2.AbstractValue); return _index2.AbstractValue.createFromUnaryOp(realm, "typeof", val); } } } function _default(ast, strictCode, env, realm) { let expr = env.evaluate(ast.argument, strictCode); if (ast.operator === "delete") { return evaluateDeleteOperation(expr, realm); } if (realm.isInPureScope()) { return tryToEvaluateOperationOrLeaveAsAbstract(ast, expr, evaluateOperation, strictCode, realm); } else { return evaluateOperation(ast, expr, strictCode, realm); } } //# sourceMappingURL=UnaryExpression.js.map