Abrupt completion cases (#2321)

* Added abrupt completition into PrivateFieldSet and PrivateFieldGet

* Adding abrupt completition for computed property evaluation

* Added case to cover abrupt completition on field initializer

* Fixing typo for 'complition' word

* Fixing typo into setter and getter description

* Fixing broken test abrupt-completition-on-field-initializer.js

* Fixing NITs

* Fixing typo of completion
This commit is contained in:
Caio Lima 2019-09-05 17:15:05 -03:00 committed by Leo Balter
parent d6d37f2f43
commit d65b9b35be
4 changed files with 175 additions and 0 deletions

View File

@ -0,0 +1,53 @@
// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: If an initializer returns an abrupt completion, other initializers should not execute
esid: sec-ecmascript-function-objects-construct-argumentslist-newtarget
info: |
[[Construct]] ( argumentsList, newTarget)
...
8. If kind is "base", then
a. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
b. Let result be InitializeInstanceFields(thisArgument, F).
c. If result is an abrupt completion, then
i. Remove calleeContext from execution context stack and restore callerContext as the running execution context.
ii. Return Completion(result).
...
ClassTail : ClassHeritage { ClassBody }
...
34. For each item fieldRecord in order from staticFields,
a. Perform ? DefineField(F, field).
...
features: [class-fields-public, class-static-fields-public, class]
---*/
function abruptCompletion() {
throw new Test262Error();
}
let neverExecuted = false;
function sideEffect() {
neverExecuted = true;
}
class C {
a = abruptCompletion();
b = sideEffect();
}
assert.throws(Test262Error, function() {
let c = new C();
}, 'field initializer should end with abrupt completion');
assert.sameValue(neverExecuted, false);
assert.throws(Test262Error, function() {
class D {
static a = abruptCompletion();
static b = sideEffect();
}
}, 'static field initializer should end with abrupt completion');
assert.sameValue(neverExecuted, false);

View File

@ -0,0 +1,43 @@
// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: PrivateFieldGet should return with abrupt completion
esid: runtime-semantics-class-definition-evaluation
info: |
ClassTail : ClassHeritage { ClassBody }
...
28. For each ClassElement e in order from elements,
a. If IsStatic of e is false, then
i. Let field be the result of performing ClassElementEvaluation for e with arguments proto and false.
b. Else,
i. Let field be the result of performing PropertyDefinitionEvaluation for mClassElementEvaluation for e with arguments F and false.
c. If field is an abrupt completion, then
i. Set the running execution context's LexicalEnvironment to lex.
ii. Set the running execution context's PrivateEnvironment to outerPrivateEnvironment.
iii. Return Completion(field).
...
features: [class-fields-public, class-static-fields-public, class]
---*/
function abruptCompletion() {
throw new Test262Error();
}
let neverExecuted = false;
assert.throws(Test262Error, function() {
class C {
[abruptCompletion()];
[neverExecuted = true];
}
}, 'computed property should have abrupt completion');
assert.sameValue(neverExecuted, false);
assert.throws(Test262Error, function() {
class C {
static [abruptCompletion()];
[neverExecuted = true];
}
}, 'static computed property should have abrupt completion');
assert.sameValue(neverExecuted, false);

View File

@ -0,0 +1,39 @@
// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: PrivateFieldGet should return an abrupt completion
esid: sec-privatefieldget
info: |
PrivateFieldGet (P, O)
1. Assert: P is a Private Name.
2. If O is not an object, throw a TypeError exception.
3. If P.[[Kind]] is "field",
a. Let entry be PrivateFieldFind(P, O).
b. If entry is empty, throw a TypeError exception.
c. Return entry.[[PrivateFieldValue]].
4. Perform ? PrivateBrandCheck(O, P).
5. If P.[[Kind]] is "method",
a. Return P.[[Value]].
6. Else,
a. Assert: P.[[Kind]] is "accessor".
b. If P does not have a [[Get]] field, throw a TypeError exception.
c. Let getter be P.[[Get]].
d. Return ? Call(getter, O).
features: [class-methods-private, class]
---*/
class C {
get #m() {
throw new Test262Error();
}
access() {
this.#m;
}
}
let c = new C();
assert.throws(Test262Error, function() {
c.access();
}, 'private getter should have abrupt completion');

View File

@ -0,0 +1,40 @@
// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: PrivateFieldSet should return an abrupt completion
esid: sec-privatefieldset
info: |
PrivateFieldSet (P, O, value)
1. Assert: P is a Private Name.
2. If O is not an object, throw a TypeError exception.
3. If P.[[Kind]] is "field",
a. Let entry be PrivateFieldFind(P, O).
b. If entry is empty, throw a TypeError exception.
c. Set entry.[[PrivateFieldValue]] to value.
d. Return.
4. If P.[[Kind]] is "method", throw a TypeError exception.
5. Else,
a. Assert: P.[[Kind]] is "accessor".
b. If O.[[PrivateFieldBrands]] does not contain P.[[Brand]], throw a TypeError exception.
c. If P does not have a [[Set]] field, throw a TypeError exception.
d. Let setter be P.[[Set]].
e. Perform ? Call(setter, O, value).
f. Return.
features: [class-methods-private, class]
---*/
class C {
set #m(_) {
throw new Test262Error();
}
access() {
this.#m = 'Test262';
}
}
let c = new C();
assert.throws(Test262Error, function() {
c.access();
}, 'private setter should have abrupt completion');