mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 14:46:37 +03:00
Create tasks for TODOs
Summary: Updated todo comments with task numbers. Not included in this list: 1) node related todos: Sebastian should do that 2) serializer related todos: Nikolai should do that 3) partial evaluator todos: I should do that, but it will take some time. Closes https://github.com/facebook/prepack/pull/1024 Differential Revision: D5950510 Pulled By: hermanventer fbshipit-source-id: 131601c18115d5bf8c1a4e1f6a87e45619acc0ba
This commit is contained in:
parent
310c594f87
commit
336236d85b
@ -991,16 +991,8 @@ function runTest(
|
||||
// succeeded
|
||||
return new TestResult(true, strict);
|
||||
} catch (err) {
|
||||
switch (err.message) {
|
||||
case "TODO: Patterns aren't supported yet":
|
||||
case "TODO: AwaitExpression":
|
||||
case "TODO: YieldExpression":
|
||||
return null;
|
||||
default:
|
||||
if (err.value && err.value.$Prototype && err.value.$Prototype.intrinsicName === "SyntaxError.prototype") {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
if (err.value && err.value.$Prototype && err.value.$Prototype.intrinsicName === "SyntaxError.prototype") {
|
||||
return null;
|
||||
}
|
||||
|
||||
let stack = err.stack;
|
||||
|
@ -42,7 +42,7 @@ export default class TypesDomain {
|
||||
|
||||
// return the type of the result in the case where there is no exception
|
||||
static binaryOp(op: BabelBinaryOperator, left: TypesDomain, right: TypesDomain): TypesDomain {
|
||||
//todo: goto top only if op === "+"
|
||||
//todo #999: goto top only if op === "+"
|
||||
let lType = left._type;
|
||||
let rType = right._type;
|
||||
if (lType === undefined || rType === undefined) return TypesDomain.topVal;
|
||||
|
@ -80,7 +80,7 @@ export default class ValuesDomain {
|
||||
let rightElements = right._elements;
|
||||
// Return top if left and/or right are top or if the size of the value set would get to be quite large.
|
||||
// Note: the larger the set of values, the less we know and therefore the less we get value from computing
|
||||
// all of these values. TODO: probably the upper bound can be quite a bit smaller.
|
||||
// all of these values. TODO #1000: probably the upper bound can be quite a bit smaller.
|
||||
if (!leftElements || !rightElements || leftElements.size > 100 || rightElements.size > 100)
|
||||
return ValuesDomain.topVal;
|
||||
let resultSet = new Set();
|
||||
@ -265,7 +265,7 @@ export default class ValuesDomain {
|
||||
let rightElements = right._elements;
|
||||
// Return top if left and/or right are top or if the size of the value set would get to be quite large.
|
||||
// Note: the larger the set of values, the less we know and therefore the less we get value from computing
|
||||
// all of these values. TODO: probably the upper bound can be quite a bit smaller.
|
||||
// all of these values. TODO #1000: probably the upper bound can be quite a bit smaller.
|
||||
if (!leftElements || !rightElements || leftElements.size > 100 || rightElements.size > 100)
|
||||
return ValuesDomain.topVal;
|
||||
let resultSet = new Set();
|
||||
|
@ -947,7 +947,7 @@ export class GlobalEnvironmentRecord extends EnvironmentRecord {
|
||||
// 7. Perform ? DefinePropertyOrThrow(globalObject, N, desc).
|
||||
DefinePropertyOrThrow(this.realm, globalObject, N, desc);
|
||||
|
||||
// TODO? 8. Record that the binding for N in ObjRec has been initialized.
|
||||
// 8. Record that the binding for N in ObjRec has been initialized.
|
||||
|
||||
// 9. Perform ? Set(globalObject, N, V, false).
|
||||
Set(this.realm, globalObject, N, V, false);
|
||||
@ -965,36 +965,6 @@ export class GlobalEnvironmentRecord extends EnvironmentRecord {
|
||||
}
|
||||
}
|
||||
|
||||
// ECMA262 8.1.1.5
|
||||
export class ModuleEnvironmentRecord extends DeclarativeEnvironmentRecord {
|
||||
// ECMA262 8.1.1.3.1
|
||||
BindThisValue(
|
||||
V: NullValue | ObjectValue | AbstractObjectValue | UndefinedValue
|
||||
): NullValue | ObjectValue | AbstractObjectValue | UndefinedValue {
|
||||
throw new FatalError("TODO: implement modules");
|
||||
}
|
||||
|
||||
// ECMA262 8.1.1.3.2
|
||||
HasThisBinding(): boolean {
|
||||
throw new FatalError("TODO: implement modules");
|
||||
}
|
||||
|
||||
// ECMA262 8.1.1.3.3
|
||||
HasSuperBinding(): boolean {
|
||||
throw new FatalError("TODO: implement modules");
|
||||
}
|
||||
|
||||
// ECMA262 8.1.1.3.4
|
||||
GetThisBinding(): NullValue | ObjectValue | AbstractObjectValue | UndefinedValue {
|
||||
throw new FatalError("TODO: implement modules");
|
||||
}
|
||||
|
||||
// ECMA262 8.1.1.3.5
|
||||
GetSuperBase(): NullValue | ObjectValue | UndefinedValue {
|
||||
throw new FatalError("TODO: implement modules");
|
||||
}
|
||||
}
|
||||
|
||||
// ECMA262 8.1
|
||||
export class LexicalEnvironment {
|
||||
constructor(realm: Realm) {
|
||||
|
@ -21,5 +21,5 @@ export default function(
|
||||
env: LexicalEnvironment,
|
||||
realm: Realm
|
||||
): Value {
|
||||
throw new FatalError("TODO: AwaitExpression");
|
||||
throw new FatalError("TODO #712: AwaitExpression");
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ export function computeBinary(
|
||||
(!lval.mightNotBeObject() && (rval instanceof NullValue || rval instanceof UndefinedValue)) ||
|
||||
((lval instanceof NullValue || lval instanceof UndefinedValue) && !rval.mightNotBeObject())
|
||||
) {
|
||||
//TODO: We can only get here if lval or rval is known to be an object. In general, we require that such values
|
||||
//TODO #1001: We can only get here if lval or rval is known to be an object. In general, we require that such values
|
||||
//can never be null or undefined, so the next line makes no sense. It is in fact a short term hack to deal
|
||||
//with the need for some intrinsic objects to be optionally null or undefined. It is still an open question
|
||||
//how best to model such objects. When that question is resolved, the next line should go away.
|
||||
|
@ -154,7 +154,7 @@ function EvaluateCall(
|
||||
} else if (func.kind === "conditional") {
|
||||
return callBothFunctionsAndJoinTheirEffects(func.args, ast, strictCode, env, realm);
|
||||
} else {
|
||||
// Assume that it is a safe function. TODO: really?
|
||||
// Assume that it is a safe function. TODO #705: really?
|
||||
}
|
||||
return generateRuntimeCall();
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ function letAndConst(
|
||||
): Value {
|
||||
for (let declar of ast.declarations) {
|
||||
if (declar.id.type !== "Identifier") {
|
||||
throw new FatalError("TODO: Patterns aren't supported yet");
|
||||
throw new FatalError("TODO #415: Patterns aren't supported yet");
|
||||
}
|
||||
|
||||
let Initializer = declar.init;
|
||||
|
@ -21,5 +21,5 @@ export default function(
|
||||
env: LexicalEnvironment,
|
||||
realm: Realm
|
||||
): Value {
|
||||
throw new FatalError("TODO: YieldExpression");
|
||||
throw new FatalError("TODO: #712 YieldExpression");
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ export default function(realm: Realm): void {
|
||||
let callback = args[0].throwIfNotConcrete();
|
||||
if (!(callback instanceof FunctionValue))
|
||||
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "callback arguments must be function");
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO: implement global.setTimeout");
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO #1003: implement global.setTimeout");
|
||||
invariant(realm.generator !== undefined);
|
||||
let generator = realm.generator;
|
||||
return generator.emitCallAndCaptureResult(
|
||||
@ -71,7 +71,7 @@ export default function(realm: Realm): void {
|
||||
|
||||
global.$DefineOwnProperty("clearTimeout", {
|
||||
value: new NativeFunctionValue(realm, "global.clearTimeout", "", 2, (context, args) => {
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO: implement global.clearTimeout");
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO #1003: implement global.clearTimeout");
|
||||
invariant(realm.generator !== undefined);
|
||||
let generator = realm.generator;
|
||||
generator.emitCall(() => generator.preludeGenerator.memoizeReference("global.clearTimeout"), args);
|
||||
@ -84,7 +84,7 @@ export default function(realm: Realm): void {
|
||||
|
||||
global.$DefineOwnProperty("setInterval", {
|
||||
value: new NativeFunctionValue(realm, "global.setInterval", "", 2, (context, args) => {
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO: implement global.setInterval");
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO #1003: implement global.setInterval");
|
||||
let callback = args[0].throwIfNotConcrete();
|
||||
if (!(callback instanceof FunctionValue))
|
||||
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "callback arguments must be function");
|
||||
@ -104,7 +104,7 @@ export default function(realm: Realm): void {
|
||||
|
||||
global.$DefineOwnProperty("clearInterval", {
|
||||
value: new NativeFunctionValue(realm, "global.clearInterval", "", 2, (context, args) => {
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO: implement global.clearInterval");
|
||||
if (!realm.useAbstractInterpretation) throw new FatalError("TODO #1003: implement global.clearInterval");
|
||||
invariant(realm.generator !== undefined);
|
||||
let generator = realm.generator;
|
||||
generator.emitCall(() => generator.preludeGenerator.memoizeReference("global.clearInterval"), args);
|
||||
|
@ -1319,10 +1319,6 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO exotic objects
|
||||
// If obj is an exotic object (including Proxy exotic objects) whose behaviour for [[Get]], [[Set]], [[Delete]], and [[GetOwnProperty]]
|
||||
// is not the ordinary object implementation of these internal methods.
|
||||
|
||||
// Any integer index property of obj whose name is a nonnegative integer less than len
|
||||
for (let j = 0; j < len; j++) {
|
||||
//is a data property whose [[writable]] attribute is false.
|
||||
@ -1333,9 +1329,6 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO If comparefn is undefined and the application of ToString to any value passed as an argument to SortCompare modifies obj or any object on obj's prototype chain.
|
||||
// TODO If comparefn is undefined and all applications of ToString, to any specific value passed as an argument to SortCompare, do not produce the same result.
|
||||
|
||||
// The SortCompare abstract operation is called with two arguments x and y. It also has access to the comparefn
|
||||
// argument passed to the current invocation of the sort method. The following steps are taken:
|
||||
|
||||
|
@ -36,7 +36,7 @@ export default function(realm: Realm): NativeFunctionValue {
|
||||
if (realm.strictlyMonotonicDateNow && lastNow >= newNow) {
|
||||
if (!offsetGenerator) offsetGenerator = seedrandom(0);
|
||||
// certain behaviors in the test262 test suite can only be (reliably) triggered if Date.now() is strictly monotonically increasing
|
||||
// TODO: Set the strictlyMonotonicDateNow option on the realm in the test262 test runner, fix the issues that will come up in the tests, and remove this TODO.
|
||||
// TODO #1004: Set the strictlyMonotonicDateNow option on the realm in the test262 test runner, fix the issues that will come up in the tests, and remove this comment.
|
||||
newNow = lastNow + 1 + Math.floor(offsetGenerator() * 500);
|
||||
}
|
||||
lastNow = newNow;
|
||||
|
@ -678,7 +678,7 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
|
||||
// ECMA262 20.3.4.35
|
||||
obj.defineNativeMethod("toDateString", 0, context => {
|
||||
throw new FatalError("TODO: implement Date.prototype.toDateString");
|
||||
throw new FatalError("TODO #1005: implement Date.prototype.toDateString");
|
||||
});
|
||||
|
||||
// ECMA262 20.3.4.36
|
||||
@ -710,17 +710,17 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
|
||||
// ECMA262 20.3.4.38
|
||||
obj.defineNativeMethod("toLocaleDateString", 0, context => {
|
||||
throw new FatalError("TODO: implement Date.prototype.toLocaleDateString");
|
||||
throw new FatalError("TODO #1005: implement Date.prototype.toLocaleDateString");
|
||||
});
|
||||
|
||||
// ECMA262 20.3.4.39
|
||||
obj.defineNativeMethod("toLocaleString", 0, context => {
|
||||
throw new FatalError("TODO: implement Date.prototype.toLocaleString");
|
||||
throw new FatalError("TODO #1005: implement Date.prototype.toLocaleString");
|
||||
});
|
||||
|
||||
// ECMA262 20.3.4.40
|
||||
obj.defineNativeMethod("toLocaleTimeString", 0, context => {
|
||||
throw new FatalError("TODO: implement Date.prototype.toLocaleTimeString");
|
||||
throw new FatalError("TODO #1005: implement Date.prototype.toLocaleTimeString");
|
||||
});
|
||||
|
||||
// ECMA262 20.3.4.41
|
||||
@ -745,12 +745,12 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
|
||||
// ECMA262 20.3.4.42
|
||||
obj.defineNativeMethod("toTimeString", 0, context => {
|
||||
throw new FatalError("TODO: implement Date.prototype.toTimeString");
|
||||
throw new FatalError("TODO #1005: implement Date.prototype.toTimeString");
|
||||
});
|
||||
|
||||
// ECMA262 20.3.4.43
|
||||
obj.defineNativeMethod("toUTCString", 0, context => {
|
||||
throw new FatalError("TODO: implement Date.prototype.toUTCString");
|
||||
throw new FatalError("TODO #1005: implement Date.prototype.toUTCString");
|
||||
});
|
||||
|
||||
// ECMA262 20.3.4.44
|
||||
|
@ -56,7 +56,7 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
// starting with the second argument, append each argument as the last element of argList.
|
||||
argList;
|
||||
|
||||
// TODO 4. Perform PrepareForTailCall().
|
||||
// TODO #1008 4. Perform PrepareForTailCall().
|
||||
|
||||
// 5. Return ? Call(func, thisArg, argList).
|
||||
return Call(realm, func, thisArg, argList);
|
||||
@ -71,7 +71,7 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
|
||||
// 2. If argArray is null or undefined, then
|
||||
if (HasSomeCompatibleType(argArray, NullValue, UndefinedValue)) {
|
||||
// TODO a. Perform PrepareForTailCall().
|
||||
// TODO #1008 a. Perform PrepareForTailCall().
|
||||
|
||||
// b. Return ? Call(func, thisArg).
|
||||
return Call(realm, func, thisArg);
|
||||
@ -80,7 +80,7 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
// 3. Let argList be ? CreateListFromArrayLike(argArray).
|
||||
let argList = CreateListFromArrayLike(realm, argArray);
|
||||
|
||||
// TODO 4. Perform PrepareForTailCall().
|
||||
// TODO #1008 4. Perform PrepareForTailCall().
|
||||
|
||||
// 5. Return ? Call(func, thisArg, argList).
|
||||
return Call(realm, func, thisArg, argList);
|
||||
@ -177,7 +177,8 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
return new StringValue(realm, `function ${name}() { [native code] }`);
|
||||
}
|
||||
} else if (context instanceof FunctionValue) {
|
||||
return new StringValue(realm, "function () { TODO: provide function source code }");
|
||||
// TODO #1009: provide function source code
|
||||
return new StringValue(realm, "function () { }");
|
||||
} else {
|
||||
// 3. Throw a TypeError exception.
|
||||
throw realm.createErrorThrowCompletion(
|
||||
|
@ -334,7 +334,7 @@ function InternalJSONClone(realm: Realm, val: Value): Value {
|
||||
obVal.values = new ValuesDomain(new Set([InternalCloneObject(realm, val.getTemplate())]));
|
||||
return obVal;
|
||||
}
|
||||
// TODO: NaN and Infinity must be mapped to null.
|
||||
// TODO #1010: NaN and Infinity must be mapped to null.
|
||||
return val;
|
||||
}
|
||||
if (
|
||||
@ -358,7 +358,7 @@ function InternalJSONClone(realm: Realm, val: Value): Value {
|
||||
let P = ToString(realm, new NumberValue(realm, I));
|
||||
let newElement = Get(realm, val, P);
|
||||
if (!(newElement instanceof UndefinedValue)) {
|
||||
// TODO: An abstract value that ultimately yields undefined should still be skipped
|
||||
// TODO #1011: An abstract value that ultimately yields undefined should still be skipped
|
||||
CreateDataProperty(realm, clonedObj, P, InternalJSONClone(realm, newElement));
|
||||
}
|
||||
I += 1;
|
||||
@ -376,7 +376,7 @@ function InternalJSONClone(realm: Realm, val: Value): Value {
|
||||
invariant(P instanceof StringValue);
|
||||
let newElement = Get(realm, val, P);
|
||||
if (!(newElement instanceof UndefinedValue)) {
|
||||
// TODO: An abstract value that ultimately yields undefined should still be skipped
|
||||
// TODO #1011: An abstract value that ultimately yields undefined should still be skipped
|
||||
CreateDataProperty(realm, clonedObj, P, InternalJSONClone(realm, newElement));
|
||||
}
|
||||
}
|
||||
@ -500,7 +500,7 @@ export default function(realm: Realm): ObjectValue {
|
||||
// 9. Let wrapper be ObjectCreate(%ObjectPrototype%).
|
||||
let wrapper = ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
|
||||
|
||||
// TODO: Make result abstract if any nested element is an abstract value.
|
||||
// TODO #1012: Make result abstract if any nested element is an abstract value.
|
||||
if (value instanceof AbstractValue || (value instanceof ObjectValue && value.isPartialObject())) {
|
||||
// Return abstract result. This enables cloning via JSON.parse(JSON.stringify(...)).
|
||||
let clonedValue = InternalJSONClone(realm, value);
|
||||
|
@ -94,7 +94,7 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
|
||||
obj.$DefineOwnProperty("__proto__", {
|
||||
// B.2.2.1.1
|
||||
get: new NativeFunctionValue(realm, "TODO", "get __proto__", 0, context => {
|
||||
get: new NativeFunctionValue(realm, undefined, "get __proto__", 0, context => {
|
||||
// 1. Let O be ? ToObject(this value).
|
||||
let O = ToObject(realm, context.throwIfNotConcrete());
|
||||
|
||||
@ -103,7 +103,7 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
}),
|
||||
|
||||
// B.2.2.1.2
|
||||
set: new NativeFunctionValue(realm, "TODO", "set __proto__", 1, (context, [proto]) => {
|
||||
set: new NativeFunctionValue(realm, undefined, "set __proto__", 1, (context, [proto]) => {
|
||||
// 1. Let O be ? RequireObjectCoercible(this value).
|
||||
let O = RequireObjectCoercible(realm, context);
|
||||
|
||||
|
@ -36,7 +36,7 @@ export default function(realm: Realm): ObjectValue {
|
||||
// 2. Let args be ? CreateListFromArrayLike(argumentsList).
|
||||
let args = CreateListFromArrayLike(realm, argumentsList);
|
||||
|
||||
// TODO 3. Perform PrepareForTailCall().
|
||||
// TODO #1008 3. Perform PrepareForTailCall().
|
||||
|
||||
// 4. Return ? Call(target, thisArgument, args).
|
||||
return Call(realm, target, thisArgument, args);
|
||||
|
@ -205,7 +205,7 @@ export default function(realm: Realm, obj: ObjectValue): void {
|
||||
|
||||
// ECMA262 23.2.3.9 get Set.prototype.size
|
||||
obj.$DefineOwnProperty("size", {
|
||||
get: new NativeFunctionValue(realm, "TODO", "get size", 0, context => {
|
||||
get: new NativeFunctionValue(realm, undefined, "get size", 0, context => {
|
||||
// 1. Let S be the this value.
|
||||
let S = context.throwIfNotConcrete();
|
||||
|
||||
|
@ -804,7 +804,7 @@ export default function(realm: Realm, obj: ObjectValue): ObjectValue {
|
||||
if (realm.isCompatibleWith(realm.MOBILE_JSC_VERSION)) {
|
||||
locales = undefined;
|
||||
} else {
|
||||
// TODO filter locales for only serialisable values
|
||||
// TODO #1013 filter locales for only serialisable values
|
||||
if (locales) locales = locales.serialize();
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,6 @@ export default function(realm: Realm): void {
|
||||
// that is computed by invoking function(arg0, arg1, ...) in the residual program and
|
||||
// where typeNameOrTemplate either either 'string', 'boolean', 'number', 'object', or an actual object defining known properties.
|
||||
// The function must not have side effects, and it must not access any state (besides the supplied arguments).
|
||||
// TODO: In some distant future, Prepack should be able to figure out automatically what computations need to remain part of the residual program.
|
||||
global.$DefineOwnProperty("__residual", {
|
||||
value: deriveNativeFunctionValue(false),
|
||||
writable: true,
|
||||
@ -188,7 +187,7 @@ export default function(realm: Realm): void {
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
// TODO: Remove this property. It's just here as some existing internal test cases assume that the __annotate property is exists and is readable.
|
||||
// TODO #1023: Remove this property. It's just here as some existing internal test cases assume that the __annotate property is exists and is readable.
|
||||
global.$DefineOwnProperty("__annotate", {
|
||||
value: realm.intrinsics.undefined,
|
||||
writable: true,
|
||||
|
@ -472,7 +472,7 @@ export function PrepareForTailCall(realm: Realm) {
|
||||
// top of the stack becomes the running execution context.
|
||||
realm.popContext(leafContext);
|
||||
|
||||
// TODO 4. Assert: leafContext has no further use. It will never be activated as the running execution context.
|
||||
// TODO #1008 4. Assert: leafContext has no further use. It will never be activated as the running execution context.
|
||||
}
|
||||
|
||||
// ECMA262 7.3.12
|
||||
|
@ -619,7 +619,7 @@ export function ObjectCreate(
|
||||
let obj = new ObjectValue(realm);
|
||||
Object.assign(obj, internalSlotsList);
|
||||
|
||||
// TODO 3. Set obj's essential internal methods to the default ordinary object definitions specified in 9.1.
|
||||
// 3. Set obj's essential internal methods to the default ordinary object definitions specified in 9.1.
|
||||
|
||||
// 4. Set the [[Prototype]] internal slot of obj to proto.
|
||||
obj.$Prototype = proto;
|
||||
|
@ -154,7 +154,7 @@ export function WeekDay(realm: Realm, t: number): number {
|
||||
|
||||
// ECMA262 20.3.1.7
|
||||
export function DaylightSavingTA(realm: Realm, t: number): number {
|
||||
// TODO: Implement DaylightSavingTA
|
||||
// TODO #1014: Implement DaylightSavingTA
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ export function IsArray(realm: Realm, argument: Value): boolean {
|
||||
|
||||
// ECMA262 14.6.1
|
||||
export function IsInTailPosition(realm: Realm, node: BabelNodeCallExpression): boolean {
|
||||
// TODO: implement tail calls
|
||||
// TODO #1008: implement tail calls
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -540,7 +540,7 @@ export function joinDescriptors(
|
||||
getAbstractValue: (void | Value, void | Value) => Value
|
||||
): void | Descriptor {
|
||||
function clone_with_abstract_value(d: Descriptor) {
|
||||
if (!IsDataDescriptor(realm, d)) throw new FatalError("TODO: join computed properties");
|
||||
if (!IsDataDescriptor(realm, d)) throw new FatalError("TODO #1015: join computed properties");
|
||||
let dc = cloneDescriptor(d);
|
||||
invariant(dc !== undefined);
|
||||
dc.value = getAbstractValue(d.value, realm.intrinsics.empty);
|
||||
@ -561,6 +561,7 @@ export function joinDescriptors(
|
||||
if (enumerable !== undefined) d3.enumerable = enumerable;
|
||||
let configurable = joinBooleans(d1.configurable, d2.configurable);
|
||||
if (configurable !== undefined) d3.configurable = configurable;
|
||||
//TODO #1015: do not join the values if one the descriptors is a getter/setters
|
||||
if (IsDataDescriptor(realm, d1) || IsDataDescriptor(realm, d2))
|
||||
d3.value = joinValues(realm, d1.value, d2.value, getAbstractValue);
|
||||
if (d1.hasOwnProperty("get") || d2.hasOwnProperty("get"))
|
||||
|
@ -176,7 +176,7 @@ function parentPermitsChildPropertyCreation(realm: Realm, O: ObjectValue, P: Pro
|
||||
if (!ownDesc || ownDescValue.mightHaveBeenDeleted()) {
|
||||
// O might not object, so first ask its parent
|
||||
let parent = O.$GetPrototypeOf();
|
||||
parent.throwIfNotConcrete(); //TODO: deal with abstract parents
|
||||
parent.throwIfNotConcrete(); //TODO #1016: deal with abstract parents
|
||||
if (!(parent instanceof NullValue)) {
|
||||
if (!parentPermitsChildPropertyCreation(realm, parent, P)) return false;
|
||||
}
|
||||
@ -189,7 +189,7 @@ function parentPermitsChildPropertyCreation(realm: Realm, O: ObjectValue, P: Pro
|
||||
// O might have a property P and so might object
|
||||
if (IsDataDescriptor(realm, ownDesc)) {
|
||||
if (ownDesc.writable) {
|
||||
// The grand parent does not object so it is OK parent does not have P
|
||||
// The grand parent does not object so it is OK that parent does not have P
|
||||
// If parent does have P, it is also OK because it is a writable data property
|
||||
return true;
|
||||
}
|
||||
@ -216,7 +216,7 @@ export function OrdinarySet(realm: Realm, O: ObjectValue, P: PropertyKeyValue, V
|
||||
if (!ownDesc || ownDescValue.mightHaveBeenDeleted()) {
|
||||
// a. Let parent be ? O.[[GetPrototypeOf]]().
|
||||
let parent = O.$GetPrototypeOf();
|
||||
parent.throwIfNotConcrete(); //TODO: deal with abstract parents
|
||||
parent.throwIfNotConcrete(); //TODO #1016: deal with abstract parents
|
||||
|
||||
// b. If parent is not null, then
|
||||
if (!(parent instanceof NullValue)) {
|
||||
@ -1113,7 +1113,7 @@ export function OrdinarySetPrototypeOf(realm: Realm, O: ObjectValue, V: ObjectVa
|
||||
return false;
|
||||
} else {
|
||||
// c. Else,
|
||||
// TODO i. If the [[GetPrototypeOf]] internal method of p is not the ordinary object internal method defined in 9.1.1, let done be true.
|
||||
// TODO #1017 i. If the [[GetPrototypeOf]] internal method of p is not the ordinary object internal method defined in 9.1.1, let done be true.
|
||||
|
||||
// ii. Else, let p be the value of p's [[Prototype]] internal slot.
|
||||
p = p.$Prototype;
|
||||
|
@ -268,8 +268,8 @@ export function RegExpBuiltinExec(realm: Realm, R: ObjectValue, S: string): Obje
|
||||
|
||||
// 14. If fullUnicode is true, then
|
||||
if (fullUnicode) {
|
||||
// TODO a. e is an index into the Input character list, derived from S, matched by matcher. Let eUTF be the smallest index into S that corresponds to the character at element e of Input. If e is greater than or equal to the length of Input, then eUTF is the number of code units in S.
|
||||
// TODO b. Let e be eUTF.
|
||||
// TODO #1018 a. e is an index into the Input character list, derived from S, matched by matcher. Let eUTF be the smallest index into S that corresponds to the character at element e of Input. If e is greater than or equal to the length of Input, then eUTF is the number of code units in S.
|
||||
// b. Let e be eUTF.
|
||||
}
|
||||
|
||||
// 15. If global is true or sticky is true, then
|
||||
@ -315,8 +315,8 @@ export function RegExpBuiltinExec(realm: Realm, R: ObjectValue, S: string): Obje
|
||||
capturedValue = realm.intrinsics.undefined;
|
||||
} else if (fullUnicode) {
|
||||
// c. Else if fullUnicode is true, then
|
||||
// TODO: i. Assert: captureI is a List of code points.
|
||||
// TODO: ii. Let capturedValue be a string whose code units are the UTF16Encoding of the code points of captureI.
|
||||
// TODO #1018: i. Assert: captureI is a List of code points.
|
||||
// ii. Let capturedValue be a string whose code units are the UTF16Encoding of the code points of captureI.
|
||||
capturedValue = realm.intrinsics.undefined;
|
||||
} else {
|
||||
// d. Else, fullUnicode is false,
|
||||
|
@ -21,8 +21,6 @@ import v8 from "v8";
|
||||
// Prepack helper
|
||||
declare var __residual: any;
|
||||
|
||||
// Currently we need to explictly pass the captured variables we want to access.
|
||||
// TODO: In a future version of this can be automatic.
|
||||
function run(
|
||||
Object,
|
||||
Array,
|
||||
|
@ -90,7 +90,6 @@ export function prepackFile(
|
||||
|
||||
export function prepackFileSync(filenames: Array<string>, options: PrepackOptions = defaultOptions) {
|
||||
if (options.compatibility === "node-cli") {
|
||||
// TODO: support multiple file prepack in node-cli mode.
|
||||
if (filenames.length !== 1) {
|
||||
console.error(`Does not support multiple file prepack in node-cli mode.`);
|
||||
process.exit(1);
|
||||
@ -100,8 +99,6 @@ export function prepackFileSync(filenames: Array<string>, options: PrepackOption
|
||||
const sourceFiles = filenames.map(filename => {
|
||||
let code = fs.readFileSync(filename, "utf8");
|
||||
let sourceMap = "";
|
||||
// Use the single input source map file for each source file.
|
||||
// TODO: support separate source map file for each source file.
|
||||
let sourceMapFilename = options.inputSourceMapFilename || filename + ".map";
|
||||
try {
|
||||
sourceMap = fs.readFileSync(sourceMapFilename, "utf8");
|
||||
|
@ -113,9 +113,6 @@ export function prepackFromAst(
|
||||
let filename = options.filename || (ast.loc && ast.loc.source) || "unknown";
|
||||
let sources = [{ filePath: filename, fileContents: code }];
|
||||
|
||||
// TODO: Expose an option to wire an already parsed ast all the way through
|
||||
// to the execution environment. For now, we just reparse.
|
||||
|
||||
let realm = construct_realm(getRealmOptions(options));
|
||||
initializeGlobals(realm);
|
||||
let serializer = new Serializer(realm, getSerializerOptions(options));
|
||||
|
@ -113,11 +113,11 @@ export class ExecutionContext {
|
||||
}
|
||||
|
||||
suspend(): void {
|
||||
// TODO: suspend
|
||||
// TODO #712: suspend
|
||||
}
|
||||
|
||||
resume(): Value {
|
||||
// TODO: resume
|
||||
// TODO #712: resume
|
||||
return this.realm.intrinsics.undefined;
|
||||
}
|
||||
}
|
||||
@ -722,7 +722,7 @@ export class Realm {
|
||||
}
|
||||
|
||||
reportIntrospectionError(message?: void | string | StringValue) {
|
||||
if (message === undefined) message = "TODO";
|
||||
if (message === undefined) message = "";
|
||||
if (typeof message === "string") message = new StringValue(this, message);
|
||||
invariant(message instanceof StringValue);
|
||||
this.nextContextLocation = this.currentLocation;
|
||||
@ -732,7 +732,7 @@ export class Realm {
|
||||
|
||||
createErrorThrowCompletion(type: NativeFunctionValue, message?: void | string | StringValue): ThrowCompletion {
|
||||
invariant(type !== this.intrinsics.__IntrospectionError);
|
||||
if (message === undefined) message = "TODO";
|
||||
if (message === undefined) message = "";
|
||||
if (typeof message === "string") message = new StringValue(this, message);
|
||||
invariant(message instanceof StringValue);
|
||||
this.nextContextLocation = this.currentLocation;
|
||||
|
@ -275,4 +275,4 @@ export type ObjectKind =
|
||||
| "WeakMap"
|
||||
| "WeakSet"
|
||||
| TypedArrayKind;
|
||||
// TODO #26: Promises. All kinds of iterators. Generators.
|
||||
// TODO #26 #712: Promises. All kinds of iterators. Generators.
|
||||
|
@ -95,7 +95,7 @@ export class Generator {
|
||||
}
|
||||
|
||||
if (canBeIdentifier) {
|
||||
// TODO: revert this when Unicode identifiers are supported by all targetted JavaScript engines
|
||||
// TODO #1020: revert this when Unicode identifiers are supported by all targetted JavaScript engines
|
||||
let keyIsAscii = /^[\u0000-\u007f]*$/.test(key);
|
||||
if (t.isValidIdentifier(key) && keyIsAscii) return t.identifier(key);
|
||||
}
|
||||
|
@ -43,6 +43,6 @@ export default function convert(realm: Realm, val: any): Value {
|
||||
|
||||
return obj;
|
||||
} else {
|
||||
throw new FatalError("TODO: need to convert value of type " + typeof val);
|
||||
throw new FatalError("need to convert value of type " + typeof val);
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ function negate(realm: Realm, value: Value): Value {
|
||||
if (value instanceof ConcreteValue) return ValuesDomain.computeUnary(realm, "!", value);
|
||||
invariant(value instanceof AbstractValue);
|
||||
if (value.kind === "!") return makeBoolean(realm, value.args[0]);
|
||||
// todo: remove this check once intrinsic objects can be properly nullable
|
||||
// todo #1001: remove this check once intrinsic objects can be properly nullable
|
||||
if (!(value instanceof AbstractObjectValue) || !value.isIntrinsic()) {
|
||||
if (!value.mightNotBeTrue()) return realm.intrinsics.false;
|
||||
if (!value.mightNotBeFalse()) return realm.intrinsics.true;
|
||||
|
@ -324,7 +324,7 @@ export default class AbstractObjectValue extends AbstractValue {
|
||||
|
||||
$GetPartial(P: AbstractValue | PropertyKeyValue, Receiver: Value): Value {
|
||||
if (!(P instanceof AbstractValue)) return this.$Get(P, Receiver);
|
||||
invariant(this === Receiver, "TODO");
|
||||
invariant(this === Receiver, "TODO #1021");
|
||||
if (this.values.isTop()) {
|
||||
AbstractValue.reportIntrospectionError(this);
|
||||
throw new FatalError();
|
||||
@ -354,7 +354,7 @@ export default class AbstractObjectValue extends AbstractValue {
|
||||
// ECMA262 9.1.9
|
||||
$Set(P: PropertyKeyValue, V: Value, Receiver: Value): boolean {
|
||||
if (P instanceof StringValue) P = P.value;
|
||||
invariant(this === Receiver, "TODO");
|
||||
invariant(this === Receiver, "TODO #1021");
|
||||
if (this.values.isTop()) {
|
||||
AbstractValue.reportIntrospectionError(this, P);
|
||||
throw new FatalError();
|
||||
@ -393,7 +393,7 @@ export default class AbstractObjectValue extends AbstractValue {
|
||||
|
||||
$SetPartial(P: AbstractValue | PropertyKeyValue, V: Value, Receiver: Value): boolean {
|
||||
if (!(P instanceof AbstractValue)) return this.$Set(P, V, Receiver);
|
||||
invariant(this === Receiver, "TODO");
|
||||
invariant(this === Receiver, "TODO #1021");
|
||||
if (this.values.isTop()) {
|
||||
AbstractValue.reportIntrospectionError(this);
|
||||
throw new FatalError();
|
||||
|
@ -294,6 +294,14 @@ export default class AbstractValue extends Value {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Simplify an already constructed abstract value in the light of the path conditions that apply in the
|
||||
// context where is this value is now being used.
|
||||
// TODO #1019: this logic largely duplicates the functionality in simplifyAbstractValue.
|
||||
// To fix this, two thing have to happen:
|
||||
// 1. Avoid injecting simplifier.js into the big Flow dependency cycle that includes AbstractValue. This can probably
|
||||
// be done by storing simplifyAbstractValue in the realm.
|
||||
// 2. Make simplifyAbstractValue path sensitive by checking for each condition if the current path conditions
|
||||
// imply them and then simplifying appropriately.
|
||||
refineWithPathCondition(): Value {
|
||||
function pathImplies(condition: AbstractValue): boolean {
|
||||
let path = condition.$Realm.pathConditions;
|
||||
|
@ -312,7 +312,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
if (this.$WeakMapData !== undefined) return "WeakMap";
|
||||
if (this.$WeakSetData !== undefined) return "WeakSet";
|
||||
if (this.$TypedArrayName !== undefined) return this.$TypedArrayName;
|
||||
// TODO #26: Promises. All kinds of iterators. Generators.
|
||||
// TODO #26 #712: Promises. All kinds of iterators. Generators.
|
||||
return "Object";
|
||||
}
|
||||
|
||||
@ -501,7 +501,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
if (!(P instanceof AbstractValue)) return this.$Get(P, Receiver);
|
||||
// We assume that simple objects have no getter/setter properties.
|
||||
if (this !== Receiver || !this.isSimpleObject() || P.mightNotBeString()) {
|
||||
AbstractValue.reportIntrospectionError(P, "TODO");
|
||||
AbstractValue.reportIntrospectionError(P, "TODO: #1021");
|
||||
throw new FatalError();
|
||||
}
|
||||
// If all else fails, use this expression
|
||||
@ -584,7 +584,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
// We assume that simple objects have no getter/setter properties and
|
||||
// that all properties are writable.
|
||||
if (this !== Receiver || !this.isSimpleObject() || P.mightNotBeString()) {
|
||||
AbstractValue.reportIntrospectionError(P, "TODO");
|
||||
AbstractValue.reportIntrospectionError(P, "TODO #1021");
|
||||
throw new FatalError();
|
||||
}
|
||||
|
||||
@ -645,7 +645,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
// ECMA262 9.1.10
|
||||
$Delete(P: PropertyKeyValue): boolean {
|
||||
if (this.unknownProperty !== undefined) {
|
||||
// TODO: generate a delete from the object
|
||||
// TODO #946: generate a delete from the object
|
||||
AbstractValue.reportIntrospectionError(this, P);
|
||||
throw new FatalError();
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ export default class ProxyValue extends ObjectValue {
|
||||
constructor(realm: Realm) {
|
||||
super(realm);
|
||||
|
||||
// $FlowFixMe TODO: exotics should not have $Realm
|
||||
// $FlowFixMe TODO #1022: exotics should not have $Realm
|
||||
this.$Realm = undefined;
|
||||
this.realm = realm;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user