"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"); } }; }(); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** * 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. */ exports.default = function (realm, processArgv) { if (!realm.useAbstractInterpretation) { (0, _invariant2.default)(false, "Realm is not enabled for Abstract Interpretation"); } // TODO: This causes a dependency on the native `process` which doesn't // exist in all environments such as the webpack version. // Constant bindings // TODO: Implement icu module so that we can let hasIntl be true. var configOverride = _extends({}, process.binding("config"), { hasIntl: false }); // By the time we run the host has already deleted natives.config so we have // to restore it. var nativeOverride = _extends({}, process.binding("natives"), { config: reverseConfigJSON(process.config) }); var config = (0, _utils.createDeepIntrinsic)(realm, configOverride, 'process.binding("config")'); var constants = (0, _utils.createDeepIntrinsic)(realm, process.binding("constants"), 'process.binding("constants")'); var natives = (0, _utils.createDeepIntrinsic)(realm, nativeOverride, 'process.binding("natives")'); // Built-in native bindings var contextify = (0, _contextify2.default)(realm); var fs = (0, _fs2.default)(realm); var fsEvent = initializeFSEvent(realm); var url = initializeURL(realm); var timerWrap = initializeTimerWrap(realm); var ttyWrap = initializeTTYWrap(realm); var signalWrap = initializeSignalWrap(realm); var streamWrap = initializeStreamWrap(realm); var caresWrap = createAbstractValue(realm, _index.ObjectValue, 'process.binding("cares_wrap")'); var tcpWrap = createAbstractValue(realm, _index.ObjectValue, 'process.binding("tcp_wrap")'); tcpWrap.makeSimple(); var pipeWrap = createAbstractValue(realm, _index.ObjectValue, 'process.binding("pipe_wrap")'); pipeWrap.makeSimple(); var uv = createAbstractValue(realm, _index.ObjectValue, 'process.binding("uv")'); var buffer = (0, _buffer2.default)(realm); var util = initializeUtil(realm); var os = createAbstractValue(realm, _index.ObjectValue, 'process.binding("os")'); os.makeSimple(); // List of loaded native modules var moduleLoadList = createIntrinsicArrayValue(realm, "process.moduleLoadList"); // The process object var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process"); obj.defineNativeMethod("binding", 1, function (context, args) { var arg0 = args.length < 1 ? realm.intrinsics.undefined : args[0]; var module = _singletons.To.ToString(realm, arg0); // TODO: Add the module to the moduleLoadList but don't track that // as a side-effect. switch (module) { // Constants case "config": return config; case "constants": return constants; case "natives": return natives; // Built-in bindings case "contextify": return contextify; case "fs": return fs; case "fs_event_wrap": return fsEvent; case "url": return url; case "uv": return uv; case "buffer": return buffer; case "util": return util; case "os": return os; case "timer_wrap": return timerWrap; case "tty_wrap": return ttyWrap; case "cares_wrap": return caresWrap; case "tcp_wrap": return tcpWrap; case "pipe_wrap": return pipeWrap; case "stream_wrap": return streamWrap; case "signal_wrap": return signalWrap; default: throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "No such module: " + module); } }); (0, _utils.copyProperty)(realm, process, obj, "moduleLoadList", moduleLoadList); // Constants on the process var constantNames = ["version", "versions", "_promiseRejectEvent", "arch", "platform", "release", "features", "_needImmediateCallback"]; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = constantNames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var name = _step.value; var value = (0, _utils.createDeepIntrinsic)(realm, process[name], "process." + name); (0, _utils.copyProperty)(realm, process, obj, name, value); } // process._events is a mutable object with null prototype. } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var _events = new _index.ObjectValue(realm, realm.intrinsics.null, "process._events"); (0, _utils.copyProperty)(realm, process, obj, "_events", _events); // TODO: When abstract numbers in string templates is implemented, turn this // back into an abstract value. // let pid = createAbstractValue(realm, NumberValue, "process.pid"); var pid = new _index.NumberValue(realm, 0, "process.pid"); (0, _utils.copyProperty)(realm, process, obj, "pid", pid); var debugPort = createAbstractValue(realm, _index.NumberValue, "process.debugPort"); (0, _utils.copyProperty)(realm, process, obj, "debugPort", debugPort); var title = createAbstractValue(realm, _index.StringValue, "process.title"); (0, _utils.copyProperty)(realm, process, obj, "title", title); // process.execArgv should probably be passed as an argument to the compile // step rather than letting arbitrary options be passed to the program. // For now I'll just hard code it as empty array. // TODO: Allow execArgv to be passed as a compiler option. var execArgv = createIntrinsicArrayValue(realm, "process.execArgv"); (0, _utils.copyProperty)(realm, process, obj, "execArgv", execArgv); var cwd = new _index.NativeFunctionValue(realm, "process.cwd", "cwd", 0, function (context, args) { return new _index.StringValue(realm, process.cwd(), "process.cwd()"); }); (0, _utils.copyProperty)(realm, process, obj, "cwd", cwd); // These properties all depend on options being defined in "execArgv" but // since we hard coded it, none of this will be added. // "_eval" : string // "_print_eval" : boolean // "_syntax_check_only" : boolean // "_forceRepl" : boolean // "noDeprecation" : boolean // "noProcessWarnings" : boolean // "traceProcessWarnings" : boolean // "throwDeprecation" : boolean // "_noBrowserGlobals" : boolean // "profProcess" : boolean // "traceDeprecation" : boolean // "_debugWaitConnect" : boolean // "_preload_modules" gets looped over so it needs to be known but typically // we don't need to do this so we can just leave it not defined. // Side-effectful Methods var methodNames = ["_startProfilerIdleNotifier", "_stopProfilerIdleNotifier", "_getActiveRequests", "_getActiveHandles", "reallyExit", "abort", "chdir", "umask", // Start Posix only "getuid", "geteuid", "setuid", "seteuid", "setgid", "setegid", "getgid", "getegid", "getgroups", "setgroups", "initgroups", // End Posix only "_kill", "_debugProcess", "_debugPause", "_debugEnd", "hrtime", "cpuUsage", "dlopen", "uptime", "memoryUsage", "_linkedBinding", "_setupNextTick", "_setupPromises", "_setupDomainUse"]; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = methodNames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _name = _step2.value; var abstractMethod = createAbstractValue(realm, _index.FunctionValue, "process." + _name); (0, _utils.copyProperty)(realm, process, obj, _name, abstractMethod); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } var argv0 = new _index.StringValue(realm, process.argv0, "process.argv0"); _singletons.Properties.DefinePropertyOrThrow(realm, obj, "argv0", { value: argv0, writable: false, configurable: true, enumerable: true }); var argv = createAbstractValue(realm, _index.ObjectValue, "process.argv"); _singletons.Properties.DefinePropertyOrThrow(realm, argv, "0", { value: argv0, writable: true, configurable: true, enumerable: true }); _singletons.Properties.DefinePropertyOrThrow(realm, argv, "1", { value: new _index.StringValue(realm, processArgv[1]), writable: true, configurable: true, enumerable: true }); _singletons.Properties.DefinePropertyOrThrow(realm, argv, "indexOf", { value: new _index.NativeFunctionValue(realm, "process.argv.indexOf", "indexOf", 0, function (context, args) { return realm.intrinsics.false; }), writable: true, configurable: true, enumerable: true }); argv.makeSimple(); (0, _utils.copyProperty)(realm, process, obj, "argv", argv); var execPath = new _index.StringValue(realm, process.execPath, "process.execPath"); (0, _utils.copyProperty)(realm, process, obj, "execPath", execPath); var env = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.env"); // TODO: This abstract value doesn't work with a conditional for some reason. _singletons.Properties.DefinePropertyOrThrow(realm, env, "NODE_NO_WARNINGS", { value: new _index.StringValue(realm, "0", "process.env.NODE_NO_WARNINGS"), writable: true, configurable: true, enumerable: true }); // Uncomment this to debug the module resolution system. // DefinePropertyOrThrow(realm, env, "NODE_DEBUG", { // value: new StringValue( // realm, "module", "process.env.NODE_DEBUG" // ), // writable: true, // configurable: true, // enumerable: true, // }); env.makeSimple(); (0, _utils.copyProperty)(realm, process, obj, "env", env); // This method just gets passed a value from the initialization code and // then deletes itself. // TODO: The generated code needs to either always invoke this (make it // abstract) or, if we assume it has been done, it doesn't need to delete it. obj.defineNativeMethod("_setupProcessObject", 1, function (self, _ref) { var _ref2 = _slicedToArray(_ref, 1), pushValueToArray = _ref2[0]; _singletons.Properties.OrdinaryDelete(realm, obj, "_setupProcessObject"); return realm.intrinsics.undefined; }); // This method injects a generic global promise reject callback. In real // environment we'd want to call this at rejections but we can safely skip it. obj.defineNativeMethod("_setupPromises", 1, function (self, _ref3) { var _ref4 = _slicedToArray(_ref3, 1), promiseRejectCallback = _ref4[0]; _singletons.Properties.OrdinaryDelete(realm, obj, "_setupPromises"); return realm.intrinsics.undefined; }); // TODO: Support Promises. Set up a micro task runner and invoke the // tickCallback as needed. obj.defineNativeMethod("_setupNextTick", 1, function (self, _ref5) { var _ref6 = _slicedToArray(_ref5, 2), tickCallback = _ref6[0], runMicrotasks = _ref6[1]; _singletons.Properties.OrdinaryDelete(realm, obj, "_setupNextTick"); var runMicrotasksCallback = new _index.NativeFunctionValue(realm, "(function() { throw new Error('TODO runMicrotasks not reachable') })", "runMicrotasks", 0, function (context, args) { // TODO: Implement Promises and micro tasks. return realm.intrinsics.undefined; }); _singletons.Properties.OrdinaryDefineOwnProperty(realm, runMicrotasks, "runMicrotasks", { value: runMicrotasksCallback, writable: true, enumerable: true, configurable: true }); var tickInfo = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "(function() { throw new Error('TODO tickInfo is not reachable in the host environment') })"); _singletons.Properties.OrdinaryDefineOwnProperty(realm, tickInfo, "0", { value: realm.intrinsics.zero, writable: true, enumerable: true, configurable: true }); _singletons.Properties.OrdinaryDefineOwnProperty(realm, tickInfo, "1", { value: realm.intrinsics.zero, writable: true, enumerable: true, configurable: true }); return tickInfo; }); return obj; }; var _invariant = require("../../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _index = require("../../values/index.js"); var _index2 = require("../../methods/index.js"); var _index3 = require("../../domains/index.js"); var _singletons = require("../../singletons.js"); var _builder = require("../../utils/builder.js"); var _builder2 = _interopRequireDefault(_builder); var _buffer = require("./buffer.js"); var _buffer2 = _interopRequireDefault(_buffer); var _contextify = require("./contextify.js"); var _contextify2 = _interopRequireDefault(_contextify); var _fs = require("./fs.js"); var _fs2 = _interopRequireDefault(_fs); var _utils = require("./utils.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function initializeTimerWrap(realm) { var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('timer_wrap')"); var constructor = new _index.NativeFunctionValue(realm, "process.binding('timer_wrap').Timer", "Timer", 0, function (context, args) { return realm.intrinsics.undefined; }); _singletons.Properties.OrdinaryDefineOwnProperty(realm, obj, "Timer", { value: constructor, writable: true, enumerable: true, configurable: true }); // TODO: Implement the rest of this protocol as needed. return obj; } function initializeTTYWrap(realm) { var nativeTTYWrap = process.binding("tty_wrap"); // let nativeTTY = nativeTTYWrap.TTY; var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('tty_wrap')"); var constructor = new _index.NativeFunctionValue(realm, "process.binding('tty_wrap').TTY", "TTY", 0, function (context, args, argCount, NewTarget) { (0, _invariant2.default)(args[0] instanceof _index.ConcreteValue); var fd = _singletons.To.ToInteger(realm, args[0]); (0, _invariant2.default)(args[1] instanceof _index.ConcreteValue); var value = _singletons.To.ToBoolean(realm, args[1]); (0, _invariant2.default)(NewTarget, "TTY must be called as a constructor."); var proto = (0, _index2.Get)(realm, NewTarget, new _index.StringValue(realm, "prototype")); if (!(proto instanceof _index.ObjectValue)) { proto = TTYPrototype; } // TODO: Store nativeTTY in an internal slot so that it can be used if this // object gets passed to another native call. return new _index.ObjectValue(realm, proto, "new (process.binding('tty_wrap').TTY)(" + fd + ", " + value.toString() + ")"); }); _singletons.Properties.OrdinaryDefineOwnProperty(realm, obj, "TTY", { value: constructor, writable: true, enumerable: true, configurable: true }); var TTYPrototype = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('tty_wrap').TTY.prototype"); TTYPrototype.defineNativeMethod("setBlocking", 0, function (context, args) { return realm.intrinsics.undefined; }); TTYPrototype.defineNativeMethod("getWindowSize", 0, function (context, args) { return realm.intrinsics.undefined; }); TTYPrototype.defineNativeMethod("writeUtf8String", 0, function (context, args) { // TODO: Store this as a side-effect. When we do that, we need the first arg // to be passed along to that side-effect. // let req = args[0]; var content = args[1]; (0, _invariant2.default)(content instanceof _index.StringValue); return realm.intrinsics.undefined; }); _singletons.Properties.DefinePropertyOrThrow(realm, constructor, "prototype", { value: TTYPrototype, writable: true, enumerable: false, configurable: false }); obj.defineNativeMethod("guessHandleType", 0, function (context, args) { var fd = _singletons.To.ToInteger(realm, args[0]); return new _index.StringValue(realm, nativeTTYWrap.guessHandleType(fd)); // TODO: Make this abstract so that changing the pipe at runtime is // possible. Currently this causes an introspection error. // let types = new TypesDomain(StringValue); // let values = new ValuesDomain(new Set([ // new StringValue(realm, "TCP"), // new StringValue(realm, "TTY"), // new StringValue(realm, "UDP"), // new StringValue(realm, "FILE"), // new StringValue(realm, "PIPE"), // new StringValue(realm, "UNKNOWN") // ])); // let buildNode = buildExpressionTemplate( // `(process.binding('tty_wrap').guessHandleType(${fd}))` // )(this.realm.preludeGenerator); // return realm.createAbstract(types, values, [], buildNode, undefined, `(process.binding('tty_wrap').guessHandleType(${fd}))`); }); obj.defineNativeMethod("isTTY", 0, function (context, args) { var fd = _singletons.To.ToInteger(realm, args[0]); var isTTYtemplateSrc = "(process.binding('tty_wrap').isTTY(" + fd + "))"; var isTTYtemplate = (0, _builder2.default)(isTTYtemplateSrc); var val = _index.AbstractValue.createFromTemplate(realm, isTTYtemplate, _index.BooleanValue, [], isTTYtemplateSrc); val.intrinsicName = isTTYtemplateSrc; return val; }); // TODO: Implement the rest of this protocol. return obj; } function initializeSignalWrap(realm) { // TODO: Implement more of this protocol. When doing so, we'll likely need to // forward it to the native implementation. // let nativeSignalWrap = process.binding("signal_wrap"); var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('signal_wrap')"); var constructor = new _index.NativeFunctionValue(realm, "process.binding('signal_wrap').Signal", "Signal", 0, function (context, args) { return realm.intrinsics.undefined; }); _singletons.Properties.OrdinaryDefineOwnProperty(realm, obj, "Signal", { value: constructor, writable: true, enumerable: true, configurable: true }); var SignalPrototype = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('signal_wrap').Signal.prototype"); SignalPrototype.defineNativeMethod("unref", 0, function (context, args) { // TODO: Track the side-effect of this. return realm.intrinsics.undefined; }); SignalPrototype.defineNativeMethod("start", 0, function (context, args) { // TODO: Track the side-effect of this. return realm.intrinsics.undefined; }); SignalPrototype.defineNativeMethod("close", 0, function (context, args) { // TODO: Track the side-effect of this. return realm.intrinsics.undefined; }); _singletons.Properties.DefinePropertyOrThrow(realm, constructor, "prototype", { value: SignalPrototype, writable: true, enumerable: false, configurable: false }); // TODO return obj; } function initializeStreamWrap(realm) { // let nativeStreamWrap = process.binding("stream_wrap"); var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('stream_wrap')"); var constructor = new _index.NativeFunctionValue(realm, "process.binding('stream_wrap').WriteWrap", "WriteWrap", 0, function (context, args) { return realm.intrinsics.undefined; }); _singletons.Properties.OrdinaryDefineOwnProperty(realm, obj, "WriteWrap", { value: constructor, writable: true, enumerable: true, configurable: true }); var WriteWrapPrototype = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('stream_wrap').WriteWrap.prototype"); WriteWrapPrototype.defineNativeMethod("unref", 0, function (context, args) { // TODO: Track the side-effect of this. return realm.intrinsics.undefined; }); _singletons.Properties.DefinePropertyOrThrow(realm, constructor, "prototype", { value: WriteWrapPrototype, writable: true, enumerable: false, configurable: false }); var ShutdownWrap = createAbstractValue(realm, _index.FunctionValue, "process.binding('stream_wrap').ShutdownWrap"); _singletons.Properties.DefinePropertyOrThrow(realm, obj, "ShutdownWrap", { value: ShutdownWrap, writable: true, configurable: true, enumerable: true }); // TODO return obj; } function initializeFSEvent(realm) { var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, "process.binding('fs_event_wrap')"); var FSEvent = createAbstractValue(realm, _index.FunctionValue, "process.binding('fs_event_wrap').FSEvent"); _singletons.Properties.DefinePropertyOrThrow(realm, obj, "FSEvent", { value: FSEvent, writable: true, configurable: true, enumerable: true }); // TODO return obj; } function initializeURL(realm) { var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype); // TODO return obj; } function initializeUtil(realm) { var obj = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, 'process.binding("util")'); obj.defineNativeMethod("isUint8Array", 0, function (context, args) { var arr = args[0]; if (arr instanceof _index.ObjectValue && arr.$TypedArrayName === "Uint8Array") { return realm.intrinsics.true; } return realm.intrinsics.false; }); (0, _utils.copyProperty)(realm, process.binding("util"), obj, "pushValToArrayMax", new _index.NumberValue(realm, process.binding("util").pushValToArrayMax, 'process.binding("util").pushValToArrayMax')); // TODO return obj; } function createAbstractValue(realm, type, intrinsicName) { var template = (0, _builder2.default)(intrinsicName); var val = _index.AbstractValue.createFromTemplate(realm, template, _index.ObjectValue, [], intrinsicName); val.values = new _index3.ValuesDomain(new Set([new _index.ObjectValue(realm)])); val.intrinsicName = intrinsicName; return val; } function createIntrinsicArrayValue(realm, intrinsicName) { // Like ArrayCreate but accepts an intrinsic name. var obj = new _index.ArrayValue(realm, intrinsicName); obj.setExtensible(true); _singletons.Properties.OrdinaryDefineOwnProperty(realm, obj, "length", { value: realm.intrinsics.zero, writable: true, enumerable: false, configurable: false }); return obj; } function reverseConfigJSON(config) { // Hack to restore the gyp config format var json = JSON.stringify(process.config).replace(/"/g, "'"); return "\n" + json; } //# sourceMappingURL=process.js.map