From 49170831670bb0aee31302a7f930564123690bd1 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 13 Dec 2022 23:52:18 -0800 Subject: [PATCH] [New] `ES2015`+ (CompletionRecord, NormalCompletion), `ES2018`+ (ThrowCompletion): add new AOs --- .gitattributes | 17 +++++++++ 2015/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2015/NormalCompletion.js | 9 +++++ 2016/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2016/NormalCompletion.js | 9 +++++ 2017/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2017/NormalCompletion.js | 9 +++++ 2018/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2018/NormalCompletion.js | 9 +++++ 2018/ThrowCompletion.js | 9 +++++ 2019/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2019/NormalCompletion.js | 9 +++++ 2019/ThrowCompletion.js | 9 +++++ 2020/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2020/NormalCompletion.js | 9 +++++ 2020/ThrowCompletion.js | 9 +++++ 2021/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2021/NormalCompletion.js | 9 +++++ 2021/ThrowCompletion.js | 9 +++++ 2022/CompletionRecord.js | 53 ++++++++++++++++++++++++++++ 2022/NormalCompletion.js | 9 +++++ 2022/ThrowCompletion.js | 9 +++++ es2015.js | 2 ++ es2016.js | 2 ++ es2017.js | 2 ++ es2018.js | 3 ++ es2019.js | 3 ++ es2020.js | 3 ++ es2021.js | 3 ++ es2022.js | 3 ++ operations/2015.js | 3 ++ operations/2016.js | 3 ++ operations/2017.js | 3 ++ operations/2018.js | 3 ++ operations/2019.js | 3 ++ operations/2020.js | 3 ++ operations/2021.js | 3 ++ operations/2022.js | 3 ++ operations/getOps.js | 6 ++++ test/diffOps.js | 6 ++-- test/es2015.js | 1 - test/es2016.js | 1 - test/es2017.js | 1 - test/es2018.js | 2 -- test/es2019.js | 2 -- test/es2020.js | 2 -- test/es2021.js | 2 -- test/es2022.js | 2 -- test/tests.js | 76 +++++++++++++++++++++++++++++++++++++++- 49 files changed, 688 insertions(+), 16 deletions(-) create mode 100644 2015/CompletionRecord.js create mode 100644 2015/NormalCompletion.js create mode 100644 2016/CompletionRecord.js create mode 100644 2016/NormalCompletion.js create mode 100644 2017/CompletionRecord.js create mode 100644 2017/NormalCompletion.js create mode 100644 2018/CompletionRecord.js create mode 100644 2018/NormalCompletion.js create mode 100644 2018/ThrowCompletion.js create mode 100644 2019/CompletionRecord.js create mode 100644 2019/NormalCompletion.js create mode 100644 2019/ThrowCompletion.js create mode 100644 2020/CompletionRecord.js create mode 100644 2020/NormalCompletion.js create mode 100644 2020/ThrowCompletion.js create mode 100644 2021/CompletionRecord.js create mode 100644 2021/NormalCompletion.js create mode 100644 2021/ThrowCompletion.js create mode 100644 2022/CompletionRecord.js create mode 100644 2022/NormalCompletion.js create mode 100644 2022/ThrowCompletion.js diff --git a/.gitattributes b/.gitattributes index 85208bf4..d19efd66 100644 --- a/.gitattributes +++ b/.gitattributes @@ -100,6 +100,7 @@ /2016/MakeTime.js spackled linguist-generated=true /2016/MinFromTime.js spackled linguist-generated=true /2016/MonthFromTime.js spackled linguist-generated=true +/2016/NormalCompletion.js spackled linguist-generated=true /2016/ObjectCreate.js spackled linguist-generated=true /2016/ObjectDefineProperties.js spackled linguist-generated=true /2016/OrdinaryCreateFromConstructor.js spackled linguist-generated=true @@ -165,6 +166,7 @@ /2017/CanonicalNumericIndexString.js spackled linguist-generated=true /2017/CharacterRange.js spackled linguist-generated=true /2017/CompletePropertyDescriptor.js spackled linguist-generated=true +/2017/CompletionRecord.js spackled linguist-generated=true /2017/CreateDataProperty.js spackled linguist-generated=true /2017/CreateDataPropertyOrThrow.js spackled linguist-generated=true /2017/CreateHTML.js spackled linguist-generated=true @@ -216,6 +218,7 @@ /2017/MakeTime.js spackled linguist-generated=true /2017/MinFromTime.js spackled linguist-generated=true /2017/MonthFromTime.js spackled linguist-generated=true +/2017/NormalCompletion.js spackled linguist-generated=true /2017/ObjectCreate.js spackled linguist-generated=true /2017/ObjectDefineProperties.js spackled linguist-generated=true /2017/OrdinaryCreateFromConstructor.js spackled linguist-generated=true @@ -285,6 +288,7 @@ /2018/CanonicalNumericIndexString.js spackled linguist-generated=true /2018/CharacterRange.js spackled linguist-generated=true /2018/CompletePropertyDescriptor.js spackled linguist-generated=true +/2018/CompletionRecord.js spackled linguist-generated=true /2018/CreateDataProperty.js spackled linguist-generated=true /2018/CreateDataPropertyOrThrow.js spackled linguist-generated=true /2018/CreateHTML.js spackled linguist-generated=true @@ -336,6 +340,7 @@ /2018/MakeTime.js spackled linguist-generated=true /2018/MinFromTime.js spackled linguist-generated=true /2018/MonthFromTime.js spackled linguist-generated=true +/2018/NormalCompletion.js spackled linguist-generated=true /2018/ObjectCreate.js spackled linguist-generated=true /2018/ObjectDefineProperties.js spackled linguist-generated=true /2018/OrdinaryCreateFromConstructor.js spackled linguist-generated=true @@ -408,6 +413,7 @@ /2019/CanonicalNumericIndexString.js spackled linguist-generated=true /2019/CharacterRange.js spackled linguist-generated=true /2019/CompletePropertyDescriptor.js spackled linguist-generated=true +/2019/CompletionRecord.js spackled linguist-generated=true /2019/CopyDataProperties.js spackled linguist-generated=true /2019/CreateDataProperty.js spackled linguist-generated=true /2019/CreateDataPropertyOrThrow.js spackled linguist-generated=true @@ -464,6 +470,7 @@ /2019/MakeTime.js spackled linguist-generated=true /2019/MinFromTime.js spackled linguist-generated=true /2019/MonthFromTime.js spackled linguist-generated=true +/2019/NormalCompletion.js spackled linguist-generated=true /2019/NumberToString.js spackled linguist-generated=true /2019/ObjectCreate.js spackled linguist-generated=true /2019/ObjectDefineProperties.js spackled linguist-generated=true @@ -494,6 +501,7 @@ /2019/StringGetOwnProperty.js spackled linguist-generated=true /2019/SymbolDescriptiveString.js spackled linguist-generated=true /2019/TestIntegrityLevel.js spackled linguist-generated=true +/2019/ThrowCompletion.js spackled linguist-generated=true /2019/TimeClip.js spackled linguist-generated=true /2019/TimeFromYear.js spackled linguist-generated=true /2019/TimeString.js spackled linguist-generated=true @@ -539,6 +547,7 @@ /2020/CanonicalNumericIndexString.js spackled linguist-generated=true /2020/CharacterRange.js spackled linguist-generated=true /2020/CompletePropertyDescriptor.js spackled linguist-generated=true +/2020/CompletionRecord.js spackled linguist-generated=true /2020/CreateDataProperty.js spackled linguist-generated=true /2020/CreateDataPropertyOrThrow.js spackled linguist-generated=true /2020/CreateHTML.js spackled linguist-generated=true @@ -591,6 +600,7 @@ /2020/MakeTime.js spackled linguist-generated=true /2020/MinFromTime.js spackled linguist-generated=true /2020/MonthFromTime.js spackled linguist-generated=true +/2020/NormalCompletion.js spackled linguist-generated=true /2020/ObjectDefineProperties.js spackled linguist-generated=true /2020/OrdinaryDefineOwnProperty.js spackled linguist-generated=true /2020/OrdinaryGetOwnProperty.js spackled linguist-generated=true @@ -616,6 +626,7 @@ /2020/StringGetOwnProperty.js spackled linguist-generated=true /2020/SymbolDescriptiveString.js spackled linguist-generated=true /2020/TestIntegrityLevel.js spackled linguist-generated=true +/2020/ThrowCompletion.js spackled linguist-generated=true /2020/TimeClip.js spackled linguist-generated=true /2020/TimeFromYear.js spackled linguist-generated=true /2020/TimeString.js spackled linguist-generated=true @@ -680,6 +691,7 @@ /2021/CanonicalNumericIndexString.js spackled linguist-generated=true /2021/CharacterRange.js spackled linguist-generated=true /2021/CompletePropertyDescriptor.js spackled linguist-generated=true +/2021/CompletionRecord.js spackled linguist-generated=true /2021/CreateAsyncFromSyncIterator.js spackled linguist-generated=true /2021/CreateDataProperty.js spackled linguist-generated=true /2021/CreateDataPropertyOrThrow.js spackled linguist-generated=true @@ -738,6 +750,7 @@ /2021/MakeDate.js spackled linguist-generated=true /2021/MinFromTime.js spackled linguist-generated=true /2021/MonthFromTime.js spackled linguist-generated=true +/2021/NormalCompletion.js spackled linguist-generated=true /2021/Number/bitwiseAND.js spackled linguist-generated=true /2021/Number/bitwiseNOT.js spackled linguist-generated=true /2021/Number/bitwiseOR.js spackled linguist-generated=true @@ -781,6 +794,7 @@ /2021/StringToBigInt.js spackled linguist-generated=true /2021/SymbolDescriptiveString.js spackled linguist-generated=true /2021/TestIntegrityLevel.js spackled linguist-generated=true +/2021/ThrowCompletion.js spackled linguist-generated=true /2021/TimeClip.js spackled linguist-generated=true /2021/TimeFromYear.js spackled linguist-generated=true /2021/TimeString.js spackled linguist-generated=true @@ -860,6 +874,7 @@ /2022/CodePointAt.js spackled linguist-generated=true /2022/CodePointsToString.js spackled linguist-generated=true /2022/CompletePropertyDescriptor.js spackled linguist-generated=true +/2022/CompletionRecord.js spackled linguist-generated=true /2022/CopyDataProperties.js spackled linguist-generated=true /2022/CreateAsyncFromSyncIterator.js spackled linguist-generated=true /2022/CreateDataProperty.js spackled linguist-generated=true @@ -923,6 +938,7 @@ /2022/MakeTime.js spackled linguist-generated=true /2022/MinFromTime.js spackled linguist-generated=true /2022/MonthFromTime.js spackled linguist-generated=true +/2022/NormalCompletion.js spackled linguist-generated=true /2022/Number/add.js spackled linguist-generated=true /2022/Number/bitwiseAND.js spackled linguist-generated=true /2022/Number/bitwiseNOT.js spackled linguist-generated=true @@ -977,6 +993,7 @@ /2022/StringToCodePoints.js spackled linguist-generated=true /2022/SymbolDescriptiveString.js spackled linguist-generated=true /2022/TestIntegrityLevel.js spackled linguist-generated=true +/2022/ThrowCompletion.js spackled linguist-generated=true /2022/TimeClip.js spackled linguist-generated=true /2022/TimeFromYear.js spackled linguist-generated=true /2022/TimeString.js spackled linguist-generated=true diff --git a/2015/CompletionRecord.js b/2015/CompletionRecord.js new file mode 100644 index 00000000..c0ad487c --- /dev/null +++ b/2015/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/6.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[type]]', type); + SLOT.set(this, '[[value]]', value); + // [[target]] slot? +}; + +CompletionRecord.prototype.type = function type() { + return SLOT.get(this, '[[type]]'); +}; + +CompletionRecord.prototype.value = function value() { + return SLOT.get(this, '[[value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[type]]'); + var value = SLOT.get(this, '[[value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2015/NormalCompletion.js b/2015/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2015/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2016/CompletionRecord.js b/2016/CompletionRecord.js new file mode 100644 index 00000000..370a5677 --- /dev/null +++ b/2016/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[Type]]', type); + SLOT.set(this, '[[Value]]', value); + // [[Target]] slot? +}; + +CompletionRecord.prototype.type = function Type() { + return SLOT.get(this, '[[Type]]'); +}; + +CompletionRecord.prototype.value = function Value() { + return SLOT.get(this, '[[Value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[Type]]'); + var value = SLOT.get(this, '[[Value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[Type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[Value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2016/NormalCompletion.js b/2016/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2016/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2017/CompletionRecord.js b/2017/CompletionRecord.js new file mode 100644 index 00000000..370a5677 --- /dev/null +++ b/2017/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[Type]]', type); + SLOT.set(this, '[[Value]]', value); + // [[Target]] slot? +}; + +CompletionRecord.prototype.type = function Type() { + return SLOT.get(this, '[[Type]]'); +}; + +CompletionRecord.prototype.value = function Value() { + return SLOT.get(this, '[[Value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[Type]]'); + var value = SLOT.get(this, '[[Value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[Type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[Value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2017/NormalCompletion.js b/2017/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2017/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2018/CompletionRecord.js b/2018/CompletionRecord.js new file mode 100644 index 00000000..370a5677 --- /dev/null +++ b/2018/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[Type]]', type); + SLOT.set(this, '[[Value]]', value); + // [[Target]] slot? +}; + +CompletionRecord.prototype.type = function Type() { + return SLOT.get(this, '[[Type]]'); +}; + +CompletionRecord.prototype.value = function Value() { + return SLOT.get(this, '[[Value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[Type]]'); + var value = SLOT.get(this, '[[Value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[Type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[Value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2018/NormalCompletion.js b/2018/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2018/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2018/ThrowCompletion.js b/2018/ThrowCompletion.js new file mode 100644 index 00000000..b7d388a3 --- /dev/null +++ b/2018/ThrowCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/9.0/#sec-throwcompletion + +module.exports = function ThrowCompletion(argument) { + return new CompletionRecord('throw', argument); +}; diff --git a/2019/CompletionRecord.js b/2019/CompletionRecord.js new file mode 100644 index 00000000..370a5677 --- /dev/null +++ b/2019/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[Type]]', type); + SLOT.set(this, '[[Value]]', value); + // [[Target]] slot? +}; + +CompletionRecord.prototype.type = function Type() { + return SLOT.get(this, '[[Type]]'); +}; + +CompletionRecord.prototype.value = function Value() { + return SLOT.get(this, '[[Value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[Type]]'); + var value = SLOT.get(this, '[[Value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[Type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[Value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2019/NormalCompletion.js b/2019/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2019/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2019/ThrowCompletion.js b/2019/ThrowCompletion.js new file mode 100644 index 00000000..b7d388a3 --- /dev/null +++ b/2019/ThrowCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/9.0/#sec-throwcompletion + +module.exports = function ThrowCompletion(argument) { + return new CompletionRecord('throw', argument); +}; diff --git a/2020/CompletionRecord.js b/2020/CompletionRecord.js new file mode 100644 index 00000000..370a5677 --- /dev/null +++ b/2020/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[Type]]', type); + SLOT.set(this, '[[Value]]', value); + // [[Target]] slot? +}; + +CompletionRecord.prototype.type = function Type() { + return SLOT.get(this, '[[Type]]'); +}; + +CompletionRecord.prototype.value = function Value() { + return SLOT.get(this, '[[Value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[Type]]'); + var value = SLOT.get(this, '[[Value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[Type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[Value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2020/NormalCompletion.js b/2020/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2020/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2020/ThrowCompletion.js b/2020/ThrowCompletion.js new file mode 100644 index 00000000..b7d388a3 --- /dev/null +++ b/2020/ThrowCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/9.0/#sec-throwcompletion + +module.exports = function ThrowCompletion(argument) { + return new CompletionRecord('throw', argument); +}; diff --git a/2021/CompletionRecord.js b/2021/CompletionRecord.js new file mode 100644 index 00000000..370a5677 --- /dev/null +++ b/2021/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[Type]]', type); + SLOT.set(this, '[[Value]]', value); + // [[Target]] slot? +}; + +CompletionRecord.prototype.type = function Type() { + return SLOT.get(this, '[[Type]]'); +}; + +CompletionRecord.prototype.value = function Value() { + return SLOT.get(this, '[[Value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[Type]]'); + var value = SLOT.get(this, '[[Value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[Type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[Value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2021/NormalCompletion.js b/2021/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2021/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2021/ThrowCompletion.js b/2021/ThrowCompletion.js new file mode 100644 index 00000000..b7d388a3 --- /dev/null +++ b/2021/ThrowCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/9.0/#sec-throwcompletion + +module.exports = function ThrowCompletion(argument) { + return new CompletionRecord('throw', argument); +}; diff --git a/2022/CompletionRecord.js b/2022/CompletionRecord.js new file mode 100644 index 00000000..370a5677 --- /dev/null +++ b/2022/CompletionRecord.js @@ -0,0 +1,53 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $SyntaxError = GetIntrinsic('%SyntaxError%'); + +var SLOT = require('internal-slot'); + +// https://262.ecma-international.org/7.0/#sec-completion-record-specification-type + +var CompletionRecord = function CompletionRecord(type, value) { + if (!(this instanceof CompletionRecord)) { + return new CompletionRecord(type, value); + } + if (type !== 'normal' && type !== 'break' && type !== 'continue' && type !== 'return' && type !== 'throw') { + throw new $SyntaxError('Assertion failed: `type` must be one of "normal", "break", "continue", "return", or "throw"'); + } + SLOT.set(this, '[[Type]]', type); + SLOT.set(this, '[[Value]]', value); + // [[Target]] slot? +}; + +CompletionRecord.prototype.type = function Type() { + return SLOT.get(this, '[[Type]]'); +}; + +CompletionRecord.prototype.value = function Value() { + return SLOT.get(this, '[[Value]]'); +}; + +CompletionRecord.prototype['?'] = function ReturnIfAbrupt() { + var type = SLOT.get(this, '[[Type]]'); + var value = SLOT.get(this, '[[Value]]'); + + if (type === 'normal') { + return value; + } + if (type === 'throw') { + throw value; + } + throw new $SyntaxError('Completion Record is not of type "normal" or "throw": other types not supported'); +}; + +CompletionRecord.prototype['!'] = function assert() { + var type = SLOT.get(this, '[[Type]]'); + + if (type !== 'normal') { + throw new $SyntaxError('Assertion failed: Completion Record is not of type "normal"'); + } + return SLOT.get(this, '[[Value]]'); +}; + +module.exports = CompletionRecord; diff --git a/2022/NormalCompletion.js b/2022/NormalCompletion.js new file mode 100644 index 00000000..1e429dd6 --- /dev/null +++ b/2022/NormalCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/6.0/#sec-normalcompletion + +module.exports = function NormalCompletion(value) { + return new CompletionRecord('normal', value); +}; diff --git a/2022/ThrowCompletion.js b/2022/ThrowCompletion.js new file mode 100644 index 00000000..b7d388a3 --- /dev/null +++ b/2022/ThrowCompletion.js @@ -0,0 +1,9 @@ +'use strict'; + +var CompletionRecord = require('./CompletionRecord'); + +// https://262.ecma-international.org/9.0/#sec-throwcompletion + +module.exports = function ThrowCompletion(argument) { + return new CompletionRecord('throw', argument); +}; diff --git a/es2015.js b/es2015.js index 09bf4a6f..77e51e41 100644 --- a/es2015.js +++ b/es2015.js @@ -15,6 +15,7 @@ var ES2015 = { CanonicalNumericIndexString: require('./2015/CanonicalNumericIndexString'), CharacterRange: require('./2015/CharacterRange'), CompletePropertyDescriptor: require('./2015/CompletePropertyDescriptor'), + CompletionRecord: require('./2015/CompletionRecord'), CreateDataProperty: require('./2015/CreateDataProperty'), CreateDataPropertyOrThrow: require('./2015/CreateDataPropertyOrThrow'), CreateHTML: require('./2015/CreateHTML'), @@ -70,6 +71,7 @@ var ES2015 = { modulo: require('./2015/modulo'), MonthFromTime: require('./2015/MonthFromTime'), msFromTime: require('./2015/msFromTime'), + NormalCompletion: require('./2015/NormalCompletion'), ObjectCreate: require('./2015/ObjectCreate'), ObjectDefineProperties: require('./2015/ObjectDefineProperties'), OrdinaryCreateFromConstructor: require('./2015/OrdinaryCreateFromConstructor'), diff --git a/es2016.js b/es2016.js index 951aa8f8..5f87f5c2 100644 --- a/es2016.js +++ b/es2016.js @@ -15,6 +15,7 @@ var ES2016 = { CanonicalNumericIndexString: require('./2016/CanonicalNumericIndexString'), CharacterRange: require('./2016/CharacterRange'), CompletePropertyDescriptor: require('./2016/CompletePropertyDescriptor'), + CompletionRecord: require('./2016/CompletionRecord'), CreateDataProperty: require('./2016/CreateDataProperty'), CreateDataPropertyOrThrow: require('./2016/CreateDataPropertyOrThrow'), CreateHTML: require('./2016/CreateHTML'), @@ -71,6 +72,7 @@ var ES2016 = { modulo: require('./2016/modulo'), MonthFromTime: require('./2016/MonthFromTime'), msFromTime: require('./2016/msFromTime'), + NormalCompletion: require('./2016/NormalCompletion'), ObjectCreate: require('./2016/ObjectCreate'), ObjectDefineProperties: require('./2016/ObjectDefineProperties'), OrdinaryCreateFromConstructor: require('./2016/OrdinaryCreateFromConstructor'), diff --git a/es2017.js b/es2017.js index 30988c87..bddf417d 100644 --- a/es2017.js +++ b/es2017.js @@ -15,6 +15,7 @@ var ES2017 = { CanonicalNumericIndexString: require('./2017/CanonicalNumericIndexString'), CharacterRange: require('./2017/CharacterRange'), CompletePropertyDescriptor: require('./2017/CompletePropertyDescriptor'), + CompletionRecord: require('./2017/CompletionRecord'), CreateDataProperty: require('./2017/CreateDataProperty'), CreateDataPropertyOrThrow: require('./2017/CreateDataPropertyOrThrow'), CreateHTML: require('./2017/CreateHTML'), @@ -72,6 +73,7 @@ var ES2017 = { modulo: require('./2017/modulo'), MonthFromTime: require('./2017/MonthFromTime'), msFromTime: require('./2017/msFromTime'), + NormalCompletion: require('./2017/NormalCompletion'), ObjectCreate: require('./2017/ObjectCreate'), ObjectDefineProperties: require('./2017/ObjectDefineProperties'), OrdinaryCreateFromConstructor: require('./2017/OrdinaryCreateFromConstructor'), diff --git a/es2018.js b/es2018.js index 8ac67fa8..48f0f256 100644 --- a/es2018.js +++ b/es2018.js @@ -15,6 +15,7 @@ var ES2018 = { CanonicalNumericIndexString: require('./2018/CanonicalNumericIndexString'), CharacterRange: require('./2018/CharacterRange'), CompletePropertyDescriptor: require('./2018/CompletePropertyDescriptor'), + CompletionRecord: require('./2018/CompletionRecord'), CopyDataProperties: require('./2018/CopyDataProperties'), CreateAsyncFromSyncIterator: require('./2018/CreateAsyncFromSyncIterator'), CreateDataProperty: require('./2018/CreateDataProperty'), @@ -75,6 +76,7 @@ var ES2018 = { modulo: require('./2018/modulo'), MonthFromTime: require('./2018/MonthFromTime'), msFromTime: require('./2018/msFromTime'), + NormalCompletion: require('./2018/NormalCompletion'), NumberToString: require('./2018/NumberToString'), ObjectCreate: require('./2018/ObjectCreate'), ObjectDefineProperties: require('./2018/ObjectDefineProperties'), @@ -110,6 +112,7 @@ var ES2018 = { thisStringValue: require('./2018/thisStringValue'), thisSymbolValue: require('./2018/thisSymbolValue'), thisTimeValue: require('./2018/thisTimeValue'), + ThrowCompletion: require('./2018/ThrowCompletion'), TimeClip: require('./2018/TimeClip'), TimeFromYear: require('./2018/TimeFromYear'), TimeString: require('./2018/TimeString'), diff --git a/es2019.js b/es2019.js index c7fb20ae..a9b94b01 100644 --- a/es2019.js +++ b/es2019.js @@ -17,6 +17,7 @@ var ES2019 = { CanonicalNumericIndexString: require('./2019/CanonicalNumericIndexString'), CharacterRange: require('./2019/CharacterRange'), CompletePropertyDescriptor: require('./2019/CompletePropertyDescriptor'), + CompletionRecord: require('./2019/CompletionRecord'), CopyDataProperties: require('./2019/CopyDataProperties'), CreateAsyncFromSyncIterator: require('./2019/CreateAsyncFromSyncIterator'), CreateDataProperty: require('./2019/CreateDataProperty'), @@ -78,6 +79,7 @@ var ES2019 = { modulo: require('./2019/modulo'), MonthFromTime: require('./2019/MonthFromTime'), msFromTime: require('./2019/msFromTime'), + NormalCompletion: require('./2019/NormalCompletion'), NumberToString: require('./2019/NumberToString'), ObjectCreate: require('./2019/ObjectCreate'), ObjectDefineProperties: require('./2019/ObjectDefineProperties'), @@ -113,6 +115,7 @@ var ES2019 = { thisStringValue: require('./2019/thisStringValue'), thisSymbolValue: require('./2019/thisSymbolValue'), thisTimeValue: require('./2019/thisTimeValue'), + ThrowCompletion: require('./2019/ThrowCompletion'), TimeClip: require('./2019/TimeClip'), TimeFromYear: require('./2019/TimeFromYear'), TimeString: require('./2019/TimeString'), diff --git a/es2020.js b/es2020.js index aa681c1f..7c90ac3d 100644 --- a/es2020.js +++ b/es2020.js @@ -23,6 +23,7 @@ var ES2020 = { CharacterRange: require('./2020/CharacterRange'), CodePointAt: require('./2020/CodePointAt'), CompletePropertyDescriptor: require('./2020/CompletePropertyDescriptor'), + CompletionRecord: require('./2020/CompletionRecord'), CopyDataProperties: require('./2020/CopyDataProperties'), CreateAsyncFromSyncIterator: require('./2020/CreateAsyncFromSyncIterator'), CreateDataProperty: require('./2020/CreateDataProperty'), @@ -91,6 +92,7 @@ var ES2020 = { modulo: require('./2020/modulo'), MonthFromTime: require('./2020/MonthFromTime'), msFromTime: require('./2020/msFromTime'), + NormalCompletion: require('./2020/NormalCompletion'), Number: require('./2020/Number'), NumberBitwiseOp: require('./2020/NumberBitwiseOp'), NumberToBigInt: require('./2020/NumberToBigInt'), @@ -131,6 +133,7 @@ var ES2020 = { thisStringValue: require('./2020/thisStringValue'), thisSymbolValue: require('./2020/thisSymbolValue'), thisTimeValue: require('./2020/thisTimeValue'), + ThrowCompletion: require('./2020/ThrowCompletion'), TimeClip: require('./2020/TimeClip'), TimeFromYear: require('./2020/TimeFromYear'), TimeString: require('./2020/TimeString'), diff --git a/es2021.js b/es2021.js index 85f9cab0..dc937259 100644 --- a/es2021.js +++ b/es2021.js @@ -30,6 +30,7 @@ var ES2021 = { CodePointAt: require('./2021/CodePointAt'), CodePointsToString: require('./2021/CodePointsToString'), CompletePropertyDescriptor: require('./2021/CompletePropertyDescriptor'), + CompletionRecord: require('./2021/CompletionRecord'), CopyDataProperties: require('./2021/CopyDataProperties'), CreateAsyncFromSyncIterator: require('./2021/CreateAsyncFromSyncIterator'), CreateDataProperty: require('./2021/CreateDataProperty'), @@ -98,6 +99,7 @@ var ES2021 = { modulo: require('./2021/modulo'), MonthFromTime: require('./2021/MonthFromTime'), msFromTime: require('./2021/msFromTime'), + NormalCompletion: require('./2021/NormalCompletion'), Number: require('./2021/Number'), NumberBitwiseOp: require('./2021/NumberBitwiseOp'), NumberToBigInt: require('./2021/NumberToBigInt'), @@ -141,6 +143,7 @@ var ES2021 = { thisStringValue: require('./2021/thisStringValue'), thisSymbolValue: require('./2021/thisSymbolValue'), thisTimeValue: require('./2021/thisTimeValue'), + ThrowCompletion: require('./2021/ThrowCompletion'), TimeClip: require('./2021/TimeClip'), TimeFromYear: require('./2021/TimeFromYear'), TimeString: require('./2021/TimeString'), diff --git a/es2022.js b/es2022.js index ce1bdb38..70780bc7 100644 --- a/es2022.js +++ b/es2022.js @@ -27,6 +27,7 @@ var ES2022 = { CodePointAt: require('./2022/CodePointAt'), CodePointsToString: require('./2022/CodePointsToString'), CompletePropertyDescriptor: require('./2022/CompletePropertyDescriptor'), + CompletionRecord: require('./2022/CompletionRecord'), CopyDataProperties: require('./2022/CopyDataProperties'), CreateAsyncFromSyncIterator: require('./2022/CreateAsyncFromSyncIterator'), CreateDataProperty: require('./2022/CreateDataProperty'), @@ -105,6 +106,7 @@ var ES2022 = { modulo: require('./2022/modulo'), MonthFromTime: require('./2022/MonthFromTime'), msFromTime: require('./2022/msFromTime'), + NormalCompletion: require('./2022/NormalCompletion'), Number: require('./2022/Number'), NumberBitwiseOp: require('./2022/NumberBitwiseOp'), NumberToBigInt: require('./2022/NumberToBigInt'), @@ -150,6 +152,7 @@ var ES2022 = { thisStringValue: require('./2022/thisStringValue'), thisSymbolValue: require('./2022/thisSymbolValue'), thisTimeValue: require('./2022/thisTimeValue'), + ThrowCompletion: require('./2022/ThrowCompletion'), TimeClip: require('./2022/TimeClip'), TimeFromYear: require('./2022/TimeFromYear'), TimeString: require('./2022/TimeString'), diff --git a/operations/2015.js b/operations/2015.js index c6f6c225..54044f8f 100644 --- a/operations/2015.js +++ b/operations/2015.js @@ -60,6 +60,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/6.0/#sec-implicit-completion-values' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/6.0/#sec-completion-record-specification-type' + }, Construct: { url: 'https://262.ecma-international.org/6.0/#sec-construct' }, diff --git a/operations/2016.js b/operations/2016.js index 98e6f959..66e6d4af 100644 --- a/operations/2016.js +++ b/operations/2016.js @@ -69,6 +69,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/7.0/#sec-completion-record-specification-type' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/7.0/#sec-completion-record-specification-type' + }, Construct: { url: 'https://262.ecma-international.org/7.0/#sec-construct' }, diff --git a/operations/2017.js b/operations/2017.js index 0ceeb5d7..5fa6e6ae 100644 --- a/operations/2017.js +++ b/operations/2017.js @@ -99,6 +99,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/8.0/#sec-completion-record-specification-type' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/8.0/#sec-completion-record-specification-type' + }, ComposeWriteEventBytes: { url: 'https://262.ecma-international.org/8.0/#sec-composewriteeventbytes' }, diff --git a/operations/2018.js b/operations/2018.js index c722323e..251a4092 100644 --- a/operations/2018.js +++ b/operations/2018.js @@ -127,6 +127,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/9.0/#sec-completion-record-specification-type' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/9.0/#sec-completion-record-specification-type' + }, ComposeWriteEventBytes: { url: 'https://262.ecma-international.org/9.0/#sec-composewriteeventbytes' }, diff --git a/operations/2019.js b/operations/2019.js index b1e64119..d19150c8 100644 --- a/operations/2019.js +++ b/operations/2019.js @@ -133,6 +133,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/10.0/#sec-completion-record-specification-type' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/10.0/#sec-completion-record-specification-type' + }, ComposeWriteEventBytes: { url: 'https://262.ecma-international.org/10.0/#sec-composewriteeventbytes' }, diff --git a/operations/2020.js b/operations/2020.js index 3f0f27ae..1e448539 100644 --- a/operations/2020.js +++ b/operations/2020.js @@ -199,6 +199,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/11.0/#sec-completion-record-specification-type' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/11.0/#sec-completion-record-specification-type' + }, ComposeWriteEventBytes: { url: 'https://262.ecma-international.org/11.0/#sec-composewriteeventbytes' }, diff --git a/operations/2021.js b/operations/2021.js index 86e04fa5..54d02094 100644 --- a/operations/2021.js +++ b/operations/2021.js @@ -223,6 +223,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/12.0/#sec-completion-record-specification-type' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/12.0/#sec-completion-record-specification-type' + }, ComposeWriteEventBytes: { url: 'https://262.ecma-international.org/12.0/#sec-composewriteeventbytes' }, diff --git a/operations/2022.js b/operations/2022.js index 55042e20..d1b88ebb 100644 --- a/operations/2022.js +++ b/operations/2022.js @@ -232,6 +232,9 @@ module.exports = { Completion: { url: 'https://262.ecma-international.org/13.0/#sec-completion-ao' }, + CompletionRecord: { + url: 'https://262.ecma-international.org/13.0/#sec-completion-record-specification-type' + }, ComposeWriteEventBytes: { url: 'https://262.ecma-international.org/13.0/#sec-composewriteeventbytes' }, diff --git a/operations/getOps.js b/operations/getOps.js index 7f069f92..84cb566c 100755 --- a/operations/getOps.js +++ b/operations/getOps.js @@ -109,6 +109,12 @@ async function getOps(year) { throw `Missing URLs: ${missings}`; } + entries.push([ + 'CompletionRecord', year < 2015 + ? 'https://262.ecma-international.org/5.1/#sec-8.9' + : `https://262.ecma-international.org/${edition}.0/#sec-completion-record-specification-type`, + ]); + if (year === 2015) { entries.push( ['abs', 'https://262.ecma-international.org/6.0/#sec-algorithm-conventions'], diff --git a/test/diffOps.js b/test/diffOps.js index a85369ae..5a7c92d6 100644 --- a/test/diffOps.js +++ b/test/diffOps.js @@ -5,7 +5,7 @@ var forEach = require('for-each'); var indexOf = require('array.prototype.indexof'); var has = require('has'); -module.exports = function diffOperations(actual, expected, expectedMissing) { +module.exports = function diffOperations(actual, expected, expectedMissing, expectedExtra) { var actualKeys = keys(actual); var expectedKeys = keys(expected); @@ -19,7 +19,9 @@ module.exports = function diffOperations(actual, expected, expectedMissing) { forEach(keys(actual[op]), function (nestedOp) { var fullNestedOp = op + '::' + nestedOp; if (!(fullNestedOp in expected)) { - extra.push(fullNestedOp); + if (indexOf(expectedExtra, fullNestedOp) === -1) { + extra.push(fullNestedOp); + } } else if (indexOf(expectedMissing, fullNestedOp) !== -1) { extra.push(fullNestedOp); } diff --git a/test/es2015.js b/test/es2015.js index 343fc46e..c45b289f 100644 --- a/test/es2015.js +++ b/test/es2015.js @@ -101,7 +101,6 @@ var expectedMissing = [ 'NewModuleEnvironment', 'NewObjectEnvironment', 'NewPromiseCapability', - 'NormalCompletion', // completion records 'OrdinaryCallBindThis', 'OrdinaryCallEvaluateBody', 'ParseModule', diff --git a/test/es2016.js b/test/es2016.js index 8d97b6c8..ca319113 100644 --- a/test/es2016.js +++ b/test/es2016.js @@ -105,7 +105,6 @@ var expectedMissing = [ 'NewObjectEnvironment', 'NewPromiseCapability', 'NextJob', - 'NormalCompletion', // completion records 'OrdinaryCallBindThis', 'OrdinaryCallEvaluateBody', 'OrdinaryDelete', diff --git a/test/es2017.js b/test/es2017.js index b59939b2..28d8469e 100644 --- a/test/es2017.js +++ b/test/es2017.js @@ -131,7 +131,6 @@ var expectedMissing = [ 'NewModuleEnvironment', 'NewObjectEnvironment', 'NewPromiseCapability', - 'NormalCompletion', // completion records 'NumberToRawBytes', 'OrdinaryCallBindThis', 'OrdinaryCallEvaluateBody', diff --git a/test/es2018.js b/test/es2018.js index 17a19664..16959128 100644 --- a/test/es2018.js +++ b/test/es2018.js @@ -145,7 +145,6 @@ var expectedMissing = [ 'NewModuleEnvironment', 'NewObjectEnvironment', 'NewPromiseCapability', - 'NormalCompletion', // completion records 'NumberToRawBytes', 'OrdinaryCallBindThis', 'OrdinaryCallEvaluateBody', @@ -196,7 +195,6 @@ var expectedMissing = [ 'SortCompare', // mystery access to `comparefn` arg 'Suspend', 'synchronizes-with', - 'ThrowCompletion', 'TimeZoneString', // depends on LocalTZA 'TopLevelModuleEvaluationJob', 'TriggerPromiseReactions', diff --git a/test/es2019.js b/test/es2019.js index bbc37b39..57ef6873 100644 --- a/test/es2019.js +++ b/test/es2019.js @@ -145,7 +145,6 @@ var expectedMissing = [ 'NewModuleEnvironment', 'NewObjectEnvironment', 'NewPromiseCapability', - 'NormalCompletion', // completion records 'NotifyWaiter', 'NumberToRawBytes', 'OrdinaryCallBindThis', @@ -198,7 +197,6 @@ var expectedMissing = [ 'Suspend', 'SynchronizeEventSet', 'synchronizes-with', - 'ThrowCompletion', 'TimeZoneString', // depends on LocalTZA 'TopLevelModuleEvaluationJob', 'TriggerPromiseReactions', diff --git a/test/es2020.js b/test/es2020.js index 919adf90..393df3de 100644 --- a/test/es2020.js +++ b/test/es2020.js @@ -148,7 +148,6 @@ var expectedMissing = [ 'NewPromiseCapability', 'NewPromiseReactionJob', 'NewPromiseResolveThenableJob', - 'NormalCompletion', // completion records 'NotifyWaiter', 'NumericToRawBytes', 'OrdinaryCallBindThis', @@ -199,7 +198,6 @@ var expectedMissing = [ 'SortCompare', // mystery access to `comparefn` arg 'Suspend', 'synchronizes-with', - 'ThrowCompletion', 'TimeZoneString', // depends on LocalTZA 'TriggerPromiseReactions', 'TypedArrayCreate', diff --git a/test/es2021.js b/test/es2021.js index ca03eefa..e3a1d6f7 100644 --- a/test/es2021.js +++ b/test/es2021.js @@ -151,7 +151,6 @@ var expectedMissing = [ 'NewPromiseCapability', 'NewPromiseReactionJob', 'NewPromiseResolveThenableJob', - 'NormalCompletion', // completion records 'NotifyWaiter', 'NumericToRawBytes', 'OrdinaryCallBindThis', @@ -207,7 +206,6 @@ var expectedMissing = [ 'SortCompare', // mystery access to `comparefn` arg 'SuspendAgent', 'synchronizes-with', - 'ThrowCompletion', 'TimeZoneString', // depends on LocalTZA 'TriggerPromiseReactions', 'TypedArrayCreate', diff --git a/test/es2022.js b/test/es2022.js index 4e6afef3..5d261278 100644 --- a/test/es2022.js +++ b/test/es2022.js @@ -146,7 +146,6 @@ var expectedMissing = [ 'NewPromiseCapability', 'NewPromiseReactionJob', 'NewPromiseResolveThenableJob', - 'NormalCompletion', 'NotifyWaiter', 'NumericToRawBytes', 'OrdinaryCallBindThis', @@ -201,7 +200,6 @@ var expectedMissing = [ 'SharedDataBlockEventSet', 'SuspendAgent', 'synchronizes-with', - 'ThrowCompletion', 'TimeZoneString', 'TriggerPromiseReactions', 'TypedArrayCreate', diff --git a/test/tests.js b/test/tests.js index 9e41f478..9e534189 100644 --- a/test/tests.js +++ b/test/tests.js @@ -344,7 +344,7 @@ var es5 = function ES5(ES, ops, expectedMissing, skips) { var test = makeTest(ES, skips); test('has expected operations', function (t) { - var diff = diffOps(ES, ops, expectedMissing); + var diff = diffOps(ES, ops, expectedMissing, []); t.deepEqual(diff.extra, [], 'no extra ops'); @@ -1761,6 +1761,38 @@ var es2015 = function ES2015(ES, ops, expectedMissing, skips) { t.end(); }); + test('CompletionRecord', function (t) { + t['throws']( + function () { return new ES.CompletionRecord('invalid'); }, + SyntaxError, + 'invalid Completion Record type throws' + ); + + forEach(['break', 'continue', 'return'], function (unsupportedType) { + var completion = ES.CompletionRecord(unsupportedType); + t['throws']( + function () { completion['?'](); }, + SyntaxError, + 'type ' + unsupportedType + ' is not supported' + ); + }); + + forEach(['break', 'continue', 'return', 'throw'], function (nonNormalType) { + var completion = ES.CompletionRecord(nonNormalType); + t['throws']( + function () { completion['!'](); }, + SyntaxError, + 'assertion failed: type ' + nonNormalType + ' is not "normal"' + ); + }); + + var sentinel = {}; + var completion = ES.CompletionRecord('normal', sentinel); + t.equal(completion['!'](), sentinel, '! returns the value of a normal completion'); + + t.end(); + }); + test('CreateDataProperty', function (t) { forEach(v.primitives, function (primitive) { t['throws']( @@ -3084,6 +3116,20 @@ var es2015 = function ES2015(ES, ops, expectedMissing, skips) { t.end(); }); + test('NormalCompletion', function (t) { + var sentinel = {}; + var completion = ES.NormalCompletion(sentinel); + + t.ok(completion instanceof ES.CompletionRecord, 'produces an instance of CompletionRecord'); + + t.equal(SLOT.get(completion, '[[type]]'), 'normal', 'completion type is "normal"'); + t.equal(completion.type(), 'normal', 'completion type is "normal" (via property)'); + t.equal(SLOT.get(completion, '[[value]]'), sentinel, 'completion value is the argument provided'); + t.equal(completion.value(), sentinel, 'completion value is the argument provided (via property)'); + + t.end(); + }); + test('ObjectCreate', function (t) { forEach(v.nonNullPrimitives, function (value) { t['throws']( @@ -4636,6 +4682,7 @@ var es2015 = function ES2015(ES, ops, expectedMissing, skips) { var es2016 = function ES2016(ES, ops, expectedMissing, skips) { es2015(ES, ops, expectedMissing, assign(assign({}, skips), { + NormalCompletion: true, StringGetIndexProperty: true })); var test = makeTest(ES, skips); @@ -4678,6 +4725,20 @@ var es2016 = function ES2016(ES, ops, expectedMissing, skips) { t.end(); }); + test('NormalCompletion', function (t) { + var sentinel = {}; + var completion = ES.NormalCompletion(sentinel); + + t.ok(completion instanceof ES.CompletionRecord, 'produces an instance of CompletionRecord'); + + t.equal(SLOT.get(completion, '[[Type]]'), 'normal', 'completion type is "normal"'); + t.equal(completion.type(), 'normal', 'completion type is "normal" (via method)'); + t.equal(SLOT.get(completion, '[[Value]]'), sentinel, 'completion value is the argument provided'); + t.equal(completion.value(), sentinel, 'completion value is the argument provided (via method)'); + + t.end(); + }); + test('OrdinaryGetPrototypeOf', function (t) { t.test('values', { skip: !$getProto }, function (st) { st.equal(ES.OrdinaryGetPrototypeOf([]), Array.prototype, 'array [[Prototype]] is Array.prototype'); @@ -5654,6 +5715,19 @@ var es2018 = function ES2018(ES, ops, expectedMissing, skips) { t.end(); }); + test('ThrowCompletion', function (t) { + var sentinel = {}; + var completion = ES.ThrowCompletion(sentinel); + + t.ok(completion instanceof ES.CompletionRecord, 'produces an instance of CompletionRecord'); + t.equal(SLOT.get(completion, '[[Type]]'), 'throw', 'completion type is "throw"'); + t.equal(completion.type(), 'throw', 'completion type is "throw" (via property)'); + t.equal(SLOT.get(completion, '[[Value]]'), sentinel, 'completion value is the argument provided'); + t.equal(completion.value(), sentinel, 'completion value is the argument provided (via property)'); + + t.end(); + }); + test('TimeString', function (t) { forEach(v.nonNumbers.concat(NaN), function (nonNumberOrNaN) { t['throws'](