"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); exports.default = function (realm) { var intrinsicName = 'process.binding("contextify")'; var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, intrinsicName); // Contextify function runInDebugContextImpl(code) { // TODO: Make this an abstract result. throw realm.createErrorThrowCompletion(realm.intrinsics.Error, "The V8 debugger is not available from within Prepack."); } function makeContextImpl() { // TODO: Allow sub-realms to be created and restored. throw realm.createErrorThrowCompletion(realm.intrinsics.Error, "makeContext is not yet implemented in Prepack."); } function isContextImpl() { // TODO: We don't have a way to create contexts so this is always false. return realm.intrinsics.false; } // ContextifyScript var ContextifyScriptInternal = function ContextifyScriptInternal(ast) { _classCallCheck(this, ContextifyScriptInternal); this.ast = ast; }; function ContextifyScriptConstructor(context, args, argLength, newTarget) { if (!newTarget) { throw realm.createErrorThrowCompletion(realm.intrinsics.Error, "Must call vm.Script as a constructor."); } var proto = (0, _index2.Get)(realm, newTarget, "prototype"); if (!(proto instanceof _index.ObjectValue)) { realm = (0, _index2.GetFunctionRealm)(realm, newTarget); proto = ContextifyScriptPrototype; } (0, _invariant2.default)(args[0] instanceof _index.ConcreteValue); var code = _singletons.To.ToString(realm, args[0]); var options = args[1]; var filename = getFilenameArg(options); var lineOffset = getLineOffsetArg(options); var columnOffset = getColumnOffsetArg(options); var displayErrors = getDisplayErrorsArg(options); var cachedDataBuf = getCachedData(options); var produceCachedData = getProduceCachedData(options); var resolvedOptions = { filename: filename, lineOffset: lineOffset, columnOffset: columnOffset, displayErrors: displayErrors, cachedDataBuf: undefined, // Not serializable. produceCachedData: produceCachedData }; var intrinsicConstructor = "new (" + intrinsicName + ").ContextifyScript(" + JSON.stringify(code) + ", " + JSON.stringify(resolvedOptions) + ")"; var self = new _index.ObjectValue(realm, proto, intrinsicConstructor); if (cachedDataBuf.length) { _singletons.Properties.Set(realm, obj, "cachedDataRejected", realm.intrinsics.true, true); } if (produceCachedData) { _singletons.Properties.Set(realm, obj, "cachedDataProduced", realm.intrinsics.false, true); } var ast = void 0; try { // TODO: Somehow pass columnOffset to Babylon. ast = (0, _parse2.default)(realm, transform(code, filename), filename, "script", 1 + lineOffset); } catch (e) { if (displayErrors && e instanceof _completions.ThrowCompletion) { decorateErrorStack(e); } throw e; } // TODO: Pick up source map files and automatically fix up source locations. self.$InternalSlot = new ContextifyScriptInternal(ast); return self; } var runInDebugContext = new _index.NativeFunctionValue(realm, intrinsicName + ".runInDebugContext", "runInDebugContext", 0, runInDebugContextImpl); _singletons.Properties.Set(realm, obj, "runInDebugContext", runInDebugContext, true); var makeContext = new _index.NativeFunctionValue(realm, intrinsicName + ".makeContext", "makeContext", 0, makeContextImpl); _singletons.Properties.Set(realm, obj, "makeContext", makeContext, true); var isContext = new _index.NativeFunctionValue(realm, intrinsicName + ".isContext", "isContext", 0, isContextImpl); _singletons.Properties.Set(realm, obj, "isContext", isContext, true); var ContextifyScript = new _index.NativeFunctionValue(realm, intrinsicName + ".ContextifyScript", "ContextifyScript", 0, ContextifyScriptConstructor, true); _singletons.Properties.Set(realm, obj, "ContextifyScript", ContextifyScript, true); // ContextifyScript.prototype function runInThisContext(self, args) { var timeout = getTimeoutArg(args[0]); var displayErrors = getDisplayErrorsArg(args[0]); var breakOnSigint = getBreakOnSigintArg(args[0]); return evalMachine(self, timeout, displayErrors, breakOnSigint); } function runInContext(self, _ref) { var _ref2 = _slicedToArray(_ref, 2), sandbox = _ref2[0], options = _ref2[1]; throw realm.createErrorThrowCompletion(realm.intrinsics.Error, "Cannot run in arbitrary contexts within Prepack yet."); } function decorateErrorStack(completion) { var error = completion.value; if (!(error instanceof _index.ObjectValue)) { return; } var errorData = error.$ErrorData; if (!errorData) { return; } var errorLocation = errorData.locationData; if (!errorLocation || errorLocation.stackDecorated) { return; } var stack = (0, _index2.Get)(realm, error, "stack"); if (!(stack instanceof _index.StringValue)) { return; } var lines = errorLocation.sourceCode.split(/\r?\n/); var line = lines[errorLocation.loc.line - 1] || ""; var arrow = " ".repeat(errorLocation.loc.column) + "^"; var decoratedStack = errorLocation.filename + ":" + errorLocation.loc.line + "\n" + line + "\n" + arrow + "\n" + stack.value; _singletons.Properties.Set(realm, error, "stack", new _index.StringValue(realm, decoratedStack), false); errorLocation.stackDecorated = true; } function getBreakOnSigintArg(options) { if (options instanceof _index.UndefinedValue || options instanceof _index.StringValue) { return false; } if (!(options instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "options must be an object"); } var value = (0, _index2.Get)(realm, options, "breakOnSigint"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); return value instanceof _index.BooleanValue && value.value; } function getTimeoutArg(options) { if (options instanceof _index.UndefinedValue || options instanceof _index.StringValue) { return -1; } if (!(options instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "options must be an object"); } var value = (0, _index2.Get)(realm, options, "timeout"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); if (value instanceof _index.UndefinedValue) { return -1; } var timeout = _singletons.To.ToInteger(realm, value); if (timeout <= 0) { throw realm.createErrorThrowCompletion(realm.intrinsics.RangeError, "timeout must be a positive number"); } return timeout; } function getDisplayErrorsArg(options) { if (options instanceof _index.UndefinedValue || options instanceof _index.StringValue) { return true; } if (!(options instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "options must be an object"); } var value = (0, _index2.Get)(realm, options, "displayErrors"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); if (value instanceof _index.UndefinedValue) { return true; } return _singletons.To.ToBoolean(realm, value); } function getFilenameArg(options) { var defaultFilename = "evalmachine."; if (options instanceof _index.UndefinedValue) { return defaultFilename; } if (options instanceof _index.StringValue) { return options.value; } if (!(options instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "options must be an object"); } var value = (0, _index2.Get)(realm, options, "filename"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); if (value instanceof _index.UndefinedValue) { return defaultFilename; } return _singletons.To.ToString(realm, value); } function getCachedData(options) { if (!(options instanceof _index.ObjectValue)) { return new Uint8Array(0); } var value = (0, _index2.Get)(realm, options, "cachedData"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); if (value instanceof _index.UndefinedValue) { return new Uint8Array(0); } if (!value.$ViewedArrayBuffer || !(value.$ViewedArrayBuffer.$ArrayBufferData instanceof Uint8Array)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "options.cachedData must be a Buffer instance"); } return value.$ViewedArrayBuffer.$ArrayBufferData; } function getProduceCachedData(options) { if (!(options instanceof _index.ObjectValue)) { return false; } var value = (0, _index2.Get)(realm, options, "produceCachedData"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); return value instanceof _index.BooleanValue && value.value; } function getLineOffsetArg(options) { var defaultLineOffset = 0; if (!(options instanceof _index.ObjectValue)) { return defaultLineOffset; } var value = (0, _index2.Get)(realm, options, "lineOffset"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); return value instanceof _index.UndefinedValue ? defaultLineOffset : _singletons.To.ToInteger(realm, value); } function getColumnOffsetArg(options) { var defaultColumnOffset = 0; if (!(options instanceof _index.ObjectValue)) { return defaultColumnOffset; } var value = (0, _index2.Get)(realm, options, "columnOffset"); (0, _invariant2.default)(value instanceof _index.ConcreteValue); return value instanceof _index.UndefinedValue ? defaultColumnOffset : _singletons.To.ToInteger(realm, value); } function evalMachine(self, timeout, displayErrors, breakOnSigint) { if (!(self instanceof _index.ObjectValue) || !(self.$InternalSlot instanceof ContextifyScriptInternal)) { throw realm.createErrorThrowCompletion(realm.intrinsics.Error, "Script methods can only be called on script instances."); } var script = self.$InternalSlot; var environment = realm.$GlobalEnv; var previousContext = realm.getRunningContext(); previousContext.suspend(); var context = realm.createExecutionContext(); context.lexicalEnvironment = environment; context.variableEnvironment = environment; context.realm = realm; realm.pushContext(context); var result = void 0; try { result = environment.evaluateCompletion(script.ast, false); } finally { context.suspend(); realm.popContext(context); (0, _invariant2.default)(context.lexicalEnvironment === realm.$GlobalEnv); realm.onDestroyScope(context.lexicalEnvironment); } (0, _invariant2.default)(realm.getRunningContext() === previousContext); previousContext.resume(); if (result instanceof _index.EmptyValue) { return realm.intrinsics.undefined; } else if (result instanceof _index.Value) { return result; } else { (0, _invariant2.default)(result instanceof _completions.AbruptCompletion); if (displayErrors) { decorateErrorStack(result); } throw result; } } var ContextifyScriptPrototype = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, intrinsicName + ".ContextifyScript.prototype"); ContextifyScriptPrototype.defineNativeMethod("runInContext", 2, runInContext); ContextifyScriptPrototype.defineNativeMethod("runInThisContext", 1, runInThisContext); _singletons.Properties.DefinePropertyOrThrow(realm, ContextifyScript, "prototype", { value: ContextifyScriptPrototype, writable: true, enumerable: false, configurable: false }); _singletons.Properties.DefinePropertyOrThrow(realm, ContextifyScriptPrototype, "constructor", { value: ContextifyScript, writable: true, enumerable: false, configurable: true }); return obj; }; var _invariant = require("../../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _realm = require("../../realm.js"); var _completions = require("../../completions.js"); var _index = require("../../values/index.js"); var _index2 = require("../../methods/index.js"); var _singletons = require("../../singletons.js"); var _parse = require("../../utils/parse.js"); var _parse2 = _interopRequireDefault(_parse); var _babelCore = require("babel-core"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * 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. */ // TODO: This creates a strong dependency on babel and its transforms even // outside of devDependencies which is unfortunate. Get rid of this once classes // and destructuring is fully implemented. // Hook for transpiling function transform(code, filename) { var patchedCode = code.replace( // Work around the fact that Babel classes can't extend natives. /class FastBuffer extends Uint8Array {\s+constructor\(arg1, arg2, arg3\) {\s+super\(arg1, arg2, arg3\);\s+}\s+}/g, "function FastBuffer(arg1, arg2, arg3) {\n" + " var self = new Uint8Array(arg1, arg2, arg3);\n" + " Object.setPrototypeOf(self, FastBuffer.prototype);\n" + " return self;\n" + "}; Object.setPrototypeOf(FastBuffer, Uint8Array); Object.setPrototypeOf(FastBuffer.prototype, Uint8Array.prototype);"); var transformedCode = (0, _babelCore.transform)(patchedCode, { plugins: [ // Prepack doesn't support classes or destructuring yet. "transform-es2015-classes", "transform-es2015-destructuring", "transform-es2015-parameters"], retainLines: true }); return transformedCode.code; } //# sourceMappingURL=contextify.js.map