184 lines
12 KiB
JavaScript
184 lines
12 KiB
JavaScript
"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"); } }; }(); /**
|
|
* 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.
|
|
*/
|
|
|
|
// ECMA262 2.2.5.3
|
|
|
|
|
|
exports.default = function (ast, strictCode, env, realm) {
|
|
// 1. Let array be ArrayCreate(0).
|
|
var array = _singletons.Create.ArrayCreate(realm, 0);
|
|
|
|
// 2. Let len be the result of performing ArrayAccumulation for ElementList with arguments array and 0.
|
|
var elements = ast.elements || [];
|
|
var partial_elements = [];
|
|
var io = [];
|
|
var len = elements.length;
|
|
var nextIndex = 0;
|
|
for (var i = 0; i < len; i++) {
|
|
var elem = elements[i];
|
|
if (!elem) {
|
|
nextIndex++;
|
|
continue;
|
|
}
|
|
|
|
var elemValue = void 0,
|
|
elemAst = void 0,
|
|
elemIO = void 0;
|
|
if (elem.type === "SpreadElement") {
|
|
;
|
|
|
|
var _env$partiallyEvaluat = env.partiallyEvaluateCompletionDeref(elem.argument, strictCode);
|
|
|
|
var _env$partiallyEvaluat2 = _slicedToArray(_env$partiallyEvaluat, 3);
|
|
|
|
elemValue = _env$partiallyEvaluat2[0];
|
|
elemAst = _env$partiallyEvaluat2[1];
|
|
elemIO = _env$partiallyEvaluat2[2];
|
|
} else {
|
|
;
|
|
|
|
var _env$partiallyEvaluat3 = env.partiallyEvaluateCompletionDeref(elem, strictCode);
|
|
|
|
var _env$partiallyEvaluat4 = _slicedToArray(_env$partiallyEvaluat3, 3);
|
|
|
|
elemValue = _env$partiallyEvaluat4[0];
|
|
elemAst = _env$partiallyEvaluat4[1];
|
|
elemIO = _env$partiallyEvaluat4[2];
|
|
}io.concat(elemIO);
|
|
if (elemValue instanceof _completions.AbruptCompletion) {
|
|
return [elemValue, ast, io]; //todo: log an error message
|
|
} else if (elemValue instanceof _completions.PossiblyNormalCompletion) {
|
|
// TODO: there was a conditional abrupt completion while evaluating elem, so join states somehow
|
|
_index2.AbstractValue.reportIntrospectionError(elemValue.value);
|
|
throw new _errors.FatalError();
|
|
}
|
|
(0, _invariant2.default)(elemValue instanceof _index2.Value);
|
|
partial_elements[nextIndex] = elemAst;
|
|
|
|
// ECMA262 12.2.5.2
|
|
if (elem.type === "SpreadElement") {
|
|
var spreadObj = elemValue;
|
|
partial_elements[nextIndex] = t.spreadElement(elemAst);
|
|
|
|
// update the abstract state with the contents of spreadObj, if known
|
|
if (spreadObj instanceof _index2.ObjectValue && !spreadObj.isPartialObject()) {
|
|
// 3. Let iterator be ? GetIterator(spreadObj).
|
|
var iterator = (0, _index.GetIterator)(realm, spreadObj);
|
|
|
|
// 4. Repeat
|
|
while (true) {
|
|
// a. Let next be ? IteratorStep(iterator).
|
|
var next = (0, _index.IteratorStep)(realm, iterator);
|
|
|
|
// b. If next is false, return nextIndex.
|
|
if (next === false) break;
|
|
|
|
// c. Let nextValue be ? IteratorValue(next).
|
|
var nextValue = (0, _index.IteratorValue)(realm, next);
|
|
|
|
// d. Let status be CreateDataProperty(array, ToString(ToUint32(nextIndex)), nextValue).
|
|
var status = _singletons.Create.CreateDataProperty(realm, array, new _index2.StringValue(realm, nextIndex + ""), nextValue);
|
|
|
|
// e. Assert: status is true.
|
|
(0, _invariant2.default)(status === true);
|
|
|
|
// f. Let nextIndex be nextIndex + 1.
|
|
nextIndex++;
|
|
}
|
|
} else {
|
|
// Update the abstract state to reflect our lack of complete knowledge
|
|
// of all of the properties of the result of evaluating elem.
|
|
array.makePartial();
|
|
|
|
// terminate the loop if all elements have been processed
|
|
if (i === len - 1) break;
|
|
|
|
// If there are elements that come after this spread element, we need
|
|
// to take their effects into account for the abstract state that results
|
|
// from the array expression.
|
|
|
|
// First check if the runtime spread operation cannot fail
|
|
if (spreadObj instanceof _index2.AbstractValue && spreadObj.getType() === "Array") {
|
|
var method = (0, _index.GetMethod)(realm, spreadObj, realm.intrinsics.SymbolIterator);
|
|
if (method === realm.intrinsics.ArrayProto_values) continue;
|
|
}
|
|
|
|
// At this point we have to be pessimistic and assume that iterating spreadObj may
|
|
// throw an exception, in which case we can't assume that the remaining element
|
|
// expressions will be evaluated at runtime. As a consequence their effects
|
|
// have be provisional.
|
|
// TODO: join states somehow
|
|
_index2.AbstractValue.reportIntrospectionError(spreadObj);
|
|
throw new _errors.FatalError();
|
|
}
|
|
} else if (array.isPartialObject()) {
|
|
// Dealing with an array element that follows on a spread object that
|
|
// could not be iterated at compile time, so the index that this element
|
|
// will have at runtime is not known at this point.
|
|
|
|
var abstractIndex = _index2.AbstractValue.createFromType(realm, _index2.NumberValue);
|
|
array.$SetPartial(abstractIndex, elemValue, array);
|
|
} else {
|
|
// Redundant steps.
|
|
// 1. Let postIndex be the result of performing ArrayAccumulation for ElementList with arguments array and nextIndex.
|
|
// 2. ReturnIfAbrupt(postIndex).
|
|
// 3. Let padding be the ElisionWidth of Elision; if Elision is not present, use the numeric value zero.
|
|
|
|
// 4. Let initResult be the result of evaluating AssignmentExpression.
|
|
// 5. Let initValue be ? GetValue(initResult).
|
|
var initValue = elemValue;
|
|
|
|
// 6. Let created be CreateDataProperty(array, ToString(ToUint32(postIndex+padding)), initValue).
|
|
var created = _singletons.Create.CreateDataProperty(realm, array, new _index2.StringValue(realm, nextIndex++ + ""), initValue);
|
|
|
|
// 7. Assert: created is true.
|
|
(0, _invariant2.default)(created === true, "expected data property creation");
|
|
}
|
|
}
|
|
|
|
// Not necessary since we propagate completions with exceptions.
|
|
// 3. ReturnIfAbrupt(len).
|
|
|
|
// 4. Perform Set(array, "length", ToUint32(len), false).
|
|
_singletons.Properties.Set(realm, array, "length", new _index2.NumberValue(realm, nextIndex), false);
|
|
|
|
// 5. NOTE: The above Set cannot fail because of the nature of the object returned by ArrayCreate.
|
|
|
|
// 6. Return array.
|
|
return [array, t.arrayExpression(partial_elements), io];
|
|
};
|
|
|
|
var _completions = require("../completions.js");
|
|
|
|
var _errors = require("../errors.js");
|
|
|
|
var _index = require("../methods/index.js");
|
|
|
|
var _index2 = require("../values/index.js");
|
|
|
|
var _singletons = require("../singletons.js");
|
|
|
|
var _invariant = require("../invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
var _babelTypes = require("babel-types");
|
|
|
|
var t = _interopRequireWildcard(_babelTypes);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
//# sourceMappingURL=ArrayExpression.js.map
|