Improve coverage for reference type in various contexts

Missing coverage encountered while implementing
<https://github.com/tc39/ecma262/pull/3307> in SpiderMonkey.

Ensure environment lookups are performed in the correct order:
- keyed-destructuring-property-reference-target-evaluation-order-with-bindings.js

Ensure `delete super[elem]` steps are correctly performed:
- delete/super-property-topropertykey.js
- delete/super-property-uninitialized-this.js

Ensure ToPropertyKey for computed property names in object literals
correctly performed:
- object/computed-property-name-topropertykey-before-value-evaluation.js

Ensure `GetSuperBase` is executed before `ToPropertKey`:
- super/prop-expr-getsuperbase-before-topropertykey-*

Ensure `GetThisBinding` is executed first:
- super/prop-expr-uninitialized-this-*
This commit is contained in:
André Bargull 2024-09-02 17:05:27 +02:00 committed by Ms2ger
parent de3a117f02
commit 18ae34d8f2
13 changed files with 669 additions and 0 deletions

View File

@ -0,0 +1,88 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization
description: >
Ensure correct evaluation order for binding lookups when destructuring target is var-binding.
info: |
14.3.3.1 Runtime Semantics: PropertyBindingInitialization
BindingProperty : PropertyName : BindingElement
1. Let P be ? Evaluation of PropertyName.
2. Perform ? KeyedBindingInitialization of BindingElement with arguments value, environment, and P.
...
14.3.3.3 Runtime Semantics: KeyedBindingInitialization
SingleNameBinding : BindingIdentifier Initializer_opt
1. Let bindingId be the StringValue of BindingIdentifier.
2. Let lhs be ? ResolveBinding(bindingId, environment).
3. Let v be ? GetV(value, propertyName).
4. If Initializer is present and v is undefined, then
...
b. Else,
i. Let defaultValue be ? Evaluation of Initializer.
ii. Set v to ? GetValue(defaultValue).
...
6. Return ? InitializeReferencedBinding(lhs, v).
9.4.2 ResolveBinding ( name [ , env ] )
...
4. Return ? GetIdentifierReference(env, name, strict).
9.1.2.1 GetIdentifierReference ( env, name, strict )
...
2. Let exists be ? env.HasBinding(name).
...
includes: [compareArray.js]
features: [Proxy]
flags: [noStrict]
---*/
var log = [];
var sourceKey = {
toString: () => {
log.push("sourceKey");
return "p";
}
};
var source = {
get p() {
log.push("get source");
return undefined;
}
};
var env = new Proxy({}, {
has(t, pk) {
log.push("binding::" + pk);
return false;
}
});
var defaultValue = 0;
var varTarget;
with (env) {
var {
[sourceKey]: varTarget = defaultValue
} = source;
}
assert.compareArray(log, [
"binding::source",
"binding::sourceKey",
"sourceKey",
"binding::varTarget",
"get source",
"binding::defaultValue",
]);

View File

@ -0,0 +1,90 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-runtime-semantics-propertydestructuringassignmentevaluation
description: >
Ensure correct evaluation order for binding lookups when destructuring target is var-binding.
info: |
13.15.5.3 Runtime Semantics: PropertyDestructuringAssignmentEvaluation
AssignmentProperty : PropertyName : AssignmentElement
1. Let name be ? Evaluation of PropertyName.
2. Perform ? KeyedDestructuringAssignmentEvaluation of AssignmentElement with arguments value and name.
...
13.15.5.6 Runtime Semantics: KeyedDestructuringAssignmentEvaluation
AssignmentElement : DestructuringAssignmentTarget Initializer_opt
1. If DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral, then
a. Let lRef be ? Evaluation of DestructuringAssignmentTarget.
2. Let v be ? GetV(value, propertyName).
3. If Initializer is present and v is undefined, then
...
b. Else,
i. Let defaultValue be ? Evaluation of Initializer.
ii. Let rhsValue be ? GetValue(defaultValue).
...
6. Return ? PutValue(lRef, rhsValue).
includes: [compareArray.js]
features: [Proxy]
flags: [noStrict]
---*/
var log = [];
var targetKey = {
toString: () => {
log.push("targetKey");
return "q";
}
};
var sourceKey = {
toString: () => {
log.push("sourceKey");
return "p";
}
};
var source = {
get p() {
log.push("get source");
return undefined;
}
};
var target = {
set q(v) {
log.push("set target");
},
};
var env = new Proxy({}, {
has(t, pk) {
log.push("binding::" + pk);
}
});
var defaultValue = 0;
with (env) {
({
[sourceKey]: target[targetKey] = defaultValue
} = source);
}
assert.compareArray(log, [
"binding::source",
"binding::sourceKey",
"sourceKey",
"binding::target",
"binding::targetKey",
"get source",
"binding::defaultValue",
"targetKey",
"set target",
]);

View File

@ -0,0 +1,32 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-delete-operator-runtime-semantics-evaluation
description: >
ToPropertyKey not performed when deleting a super reference.
info: |
13.5.1.2 Runtime Semantics: Evaluation
UnaryExpression : delete UnaryExpression
1. Let ref be ? Evaluation of UnaryExpression.
...
4. If IsPropertyReference(ref) is true, then
...
b. If IsSuperReference(ref) is true, throw a ReferenceError exception.
---*/
var key = {
toString() {
throw new Test262Error("ToPropertyKey performed");
}
};
var obj = {
m() {
delete super[key];
}
};
assert.throws(ReferenceError, () => obj.m());

View File

@ -0,0 +1,43 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-delete-operator-runtime-semantics-evaluation
description: >
Element expression in delete super not evaluated when this is uninitialized.
info: |
13.5.1.2 Runtime Semantics: Evaluation
UnaryExpression : delete UnaryExpression
1. Let ref be ? Evaluation of UnaryExpression.
...
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
...
9.1.1.3.4 GetThisBinding ( )
...
2. If envRec.[[ThisBindingStatus]] is uninitialized, throw a ReferenceError exception.
...
---*/
class Base {
constructor() {
throw new Test262Error("base constructor called");
}
}
class Derived extends Base {
constructor() {
delete super[(super(), 0)];
}
}
assert.throws(ReferenceError, () => new Derived);

View File

@ -0,0 +1,44 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-runtime-semantics-propertydefinitionevaluation
description: >
ToPropertyKey is performed before evaluating the value expression.
info: |
13.2.5.5 Runtime Semantics: PropertyDefinitionEvaluation
PropertyDefinition : PropertyName : AssignmentExpression
1. Let propKey be ? Evaluation of PropertyName.
...
6. Else,
a. Let exprValueRef be ? Evaluation of AssignmentExpression.
b. Let propValue be ? GetValue(exprValueRef).
...
9. Perform ! CreateDataPropertyOrThrow(object, propKey, propValue).
...
13.2.5.4 Runtime Semantics: Evaluation
ComputedPropertyName : [ AssignmentExpression ]
1. Let exprValue be ? Evaluation of AssignmentExpression.
2. Let propName be ? GetValue(exprValue).
3. Return ? ToPropertyKey(propName).
---*/
var value = "bad";
var key = {
toString() {
value = "ok";
return "p";
}
};
var obj = {
[key]: value
};
assert.sameValue(obj.p, "ok");

View File

@ -0,0 +1,60 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
GetSuperBase is performed before ToPropertyKey in GetValue.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
4. Let propertyNameValue be ? GetValue(propertyNameReference).
...
7. Return ? MakeSuperPropertyReference(actualThis, propertyNameValue, strict).
13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )
1. Let env be GetThisEnvironment().
...
3. Let baseValue be ? env.GetSuperBase().
...
6.2.5.5 GetValue ( V )
...
3. If IsPropertyReference(V) is true, then
...
c. If V.[[ReferencedName]] is not a property key, then
i. Set V.[[ReferencedName]] to ? ToPropertyKey(V.[[ReferencedName]]).
d. Return ? baseObj.[[Get]](V.[[ReferencedName]], GetThisValue(V)).
...
---*/
var proto = {
p: "ok",
};
var proto2 = {
p: "bad",
};
var obj = {
__proto__: proto,
m() {
return super[key];
}
};
var key = {
toString() {
Object.setPrototypeOf(obj, proto2);
return "p";
}
};
assert.sameValue(obj.m(), "ok");

View File

@ -0,0 +1,60 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
GetSuperBase is performed before ToPropertyKey in PutValue with compound assignment.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
4. Let propertyNameValue be ? GetValue(propertyNameReference).
...
7. Return ? MakeSuperPropertyReference(actualThis, propertyNameValue, strict).
13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )
1. Let env be GetThisEnvironment().
...
3. Let baseValue be ? env.GetSuperBase().
...
6.2.5.6 PutValue ( V, W )
3. If IsPropertyReference(V) is true, then
...
c. If V.[[ReferencedName]] is not a property key, then
i. Set V.[[ReferencedName]] to ? ToPropertyKey(V.[[ReferencedName]]).
d. Let succeeded be ? baseObj.[[Set]](V.[[ReferencedName]], W, GetThisValue(V)).
...
...
---*/
var proto = {
p: 1,
};
var proto2 = {
p: -1,
};
var obj = {
__proto__: proto,
m() {
return super[key] += 1;
}
};
var key = {
toString() {
Object.setPrototypeOf(obj, proto2);
return "p";
}
};
assert.sameValue(obj.m(), 2);

View File

@ -0,0 +1,60 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
GetSuperBase is performed before ToPropertyKey in PutValue with increment operator.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
4. Let propertyNameValue be ? GetValue(propertyNameReference).
...
7. Return ? MakeSuperPropertyReference(actualThis, propertyNameValue, strict).
13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )
1. Let env be GetThisEnvironment().
...
3. Let baseValue be ? env.GetSuperBase().
...
6.2.5.6 PutValue ( V, W )
3. If IsPropertyReference(V) is true, then
...
c. If V.[[ReferencedName]] is not a property key, then
i. Set V.[[ReferencedName]] to ? ToPropertyKey(V.[[ReferencedName]]).
d. Let succeeded be ? baseObj.[[Set]](V.[[ReferencedName]], W, GetThisValue(V)).
...
...
---*/
var proto = {
p: 1,
};
var proto2 = {
p: -1,
};
var obj = {
__proto__: proto,
m() {
return ++super[key];
}
};
var key = {
toString() {
Object.setPrototypeOf(obj, proto2);
return "p";
}
};
assert.sameValue(obj.m(), 2);

View File

@ -0,0 +1,68 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
GetSuperBase is performed before ToPropertyKey in PutValue.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
4. Let propertyNameValue be ? GetValue(propertyNameReference).
...
7. Return ? MakeSuperPropertyReference(actualThis, propertyNameValue, strict).
13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )
1. Let env be GetThisEnvironment().
...
3. Let baseValue be ? env.GetSuperBase().
...
6.2.5.6 PutValue ( V, W )
3. If IsPropertyReference(V) is true, then
...
c. If V.[[ReferencedName]] is not a property key, then
i. Set V.[[ReferencedName]] to ? ToPropertyKey(V.[[ReferencedName]]).
d. Let succeeded be ? baseObj.[[Set]](V.[[ReferencedName]], W, GetThisValue(V)).
...
...
---*/
var result;
var proto = {
set p(v) {
result = "ok";
},
};
var proto2 = {
set p(v) {
result = "bad";
},
};
var obj = {
__proto__: proto,
m() {
super[key] = 10;
}
};
var key = {
toString() {
Object.setPrototypeOf(obj, proto2);
return "p";
}
};
obj.m();
assert.sameValue(result, "ok");

View File

@ -0,0 +1,31 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
Expression not evaluated when this binding is uninitialized in GetValue context.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
...
---*/
class Base {
constructor() {
throw new Test262Error("base constructor");
}
}
class Derived extends Base {
constructor() {
return super[super()];
}
}
assert.throws(ReferenceError, () => new Derived);

View File

@ -0,0 +1,31 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
Expression not evaluated when this binding is uninitialized in PutValue context with compound assignment.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
...
---*/
class Base {
constructor() {
throw new Test262Error("base constructor");
}
}
class Derived extends Base {
constructor() {
super[super()] += 0;
}
}
assert.throws(ReferenceError, () => new Derived);

View File

@ -0,0 +1,31 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
Expression not evaluated when this binding is uninitialized in PutValue context with increment operator.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
...
---*/
class Base {
constructor() {
throw new Test262Error("base constructor");
}
}
class Derived extends Base {
constructor() {
super[super()]++;
}
}
assert.throws(ReferenceError, () => new Derived);

View File

@ -0,0 +1,31 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-super-keyword-runtime-semantics-evaluation
description: >
Expression not evaluated when this binding is uninitialized in PutValue context.
info: |
13.3.7.1 Runtime Semantics: Evaluation
SuperProperty : super [ Expression ]
...
2. Let actualThis be ? env.GetThisBinding().
3. Let propertyNameReference be ? Evaluation of Expression.
...
---*/
class Base {
constructor() {
throw new Test262Error("base constructor");
}
}
class Derived extends Base {
constructor() {
super[super()] = 0;
}
}
assert.throws(ReferenceError, () => new Derived);