···11import { test, testDeep, summary } from './helpers.js';
22+import { inspect } from 'node:util';
2334console.log('Async Iterator Tests\n');
45···1718test('async generator function constructor name', AsyncGeneratorFunction.name, 'AsyncGeneratorFunction');
1819test('async generator function prototype chain', Object.getPrototypeOf(protoShapeAsyncGen), AsyncGeneratorFunction.prototype);
1920test('async generator function prototype tag', AsyncGeneratorFunction.prototype[Symbol.toStringTag], 'AsyncGeneratorFunction');
2121+test('async generator function inspect tag', inspect(protoShapeAsyncGen), '[AsyncGeneratorFunction: protoShapeAsyncGen]');
2022test('async generator function prototype prototype', AsyncGeneratorFunction.prototype.prototype, sharedAsyncGeneratorProto);
2123test(
2224 'new async generator function throws',
+47
examples/spec/completion.js
···11+import { test, testDeep, testThrows, summary } from './helpers.js';
22+33+console.log('Completion Value Tests\n');
44+55+test('empty blocks produce undefined', eval('{}{}{};'), undefined);
66+test('label inside block completion', eval("{foo: 'bar'}{};"), 'bar');
77+test('block before labelled completion', eval("{}{foo: 'bar'};"), 'bar');
88+test('last non-empty block completion', eval("{a: 'b'}{c: 'd'}{};"), 'd');
99+1010+test('nested label passes expression completion', eval('a: b: c: 1;'), 1);
1111+test('nested label passes comma expression completion', eval('a: b: c: (1, 2, 3);'), 3);
1212+1313+test('statement-position braces parse as block label', eval('{ a: 1 }'), 1);
1414+test('multiple labels in block preserve last completion', eval('{ a: 1; b: 2 }'), 2);
1515+testDeep('parenthesized braces parse as object literal', eval('({ a: 1, b: 2 })'), { a: 1, b: 2 });
1616+testThrows('comma cannot separate labelled statements', () => eval('{ a: 1, b: 2 }'));
1717+1818+test('declaration empty completion preserves previous value', eval("'a'; var x = 5;"), 'a');
1919+test('if true carries body completion', eval("if (true) 'a';"), 'a');
2020+test('if false has empty completion', eval("if (false) 'a';"), undefined);
2121+test('if false overwrites previous expression with undefined', eval("'a'; if (false) 'b';"), undefined);
2222+test('if true empty body overwrites previous expression with undefined', eval("'a'; if (true) ;"), undefined);
2323+test('for loop completion is last body value', eval('for (let i=0;i<3;i++) i;'), 2);
2424+test('while false overwrites previous expression with undefined', eval("'a'; while (false) 'b';"), undefined);
2525+test('for false overwrites previous expression with undefined', eval("'a'; for (;false;) 'b';"), undefined);
2626+test('for empty body overwrites previous expression with undefined', eval("'a'; for (let i=0;i<1;i++);"), undefined);
2727+test('do while empty body overwrites previous expression with undefined', eval("'a'; do ; while(false);"), undefined);
2828+test('with empty body overwrites previous expression with undefined', eval("'a'; with ({}) ;"), undefined);
2929+3030+test('empty finally preserves try completion', eval("try { 'a' } finally { }"), 'a');
3131+test('non-empty finally overrides try completion', eval("try { 'a' } finally { 'b' }"), 'b');
3232+test('empty try finally overwrites previous expression with undefined', eval("'a'; try { } finally { }"), undefined);
3333+3434+test('break label preserves previous non-empty completion', eval("outer: { 'before'; break outer; 'after'; }"), 'before');
3535+test('nested block completion flows outward', eval("outer: { { 'inner'; } ; }"), 'inner');
3636+test('empty block after expression preserves value', eval("'a'; { var x; }"), 'a');
3737+3838+test('switch fallthrough preserves last non-empty case value', eval("switch (1) { case 0: 'zero'; case 1: 'one'; case 2: ; }"), 'one');
3939+test('switch with no matching case is empty', eval("switch (9) { case 0: 'zero'; }"), undefined);
4040+test('switch with no matching case overwrites previous expression with undefined', eval("'a'; switch (9) { case 0: 'zero'; }"), undefined);
4141+test('switch default fallthrough can be overwritten', eval("switch (2) { case 1: 'one'; default: 'default'; case 2: 'two'; }"), 'two');
4242+4343+test('function block body ignores completion value', eval("(function(){ 'block'; })()"), undefined);
4444+test('arrow block body ignores completion value', eval("(()=>{ 'block'; })()"), undefined);
4545+test('arrow expression body returns expression value', eval("(()=> 'expr')()"), 'expr');
4646+4747+summary();
+7
examples/spec/generators.js
···11import { test, testDeep, summary } from './helpers.js';
22+import { inspect } from 'node:util';
2334console.log('Generator Tests\n');
45···262263const ownGeneratorProto = Object.getPrototypeOf(protoShapeGen);
263264const sharedGeneratorProto = Object.getPrototypeOf(ownGeneratorProto);
264265const iteratorProto = Object.getPrototypeOf(sharedGeneratorProto);
266266+const GeneratorFunction = protoShapeFn.constructor;
267267+test('generator function constructor name', GeneratorFunction.name, 'GeneratorFunction');
268268+test('generator function prototype chain', Object.getPrototypeOf(protoShapeFn), GeneratorFunction.prototype);
269269+test('generator function prototype tag', GeneratorFunction.prototype[Symbol.toStringTag], 'GeneratorFunction');
270270+test('generator function toStringTag', Object.prototype.toString.call(protoShapeFn), '[object GeneratorFunction]');
271271+test('generator function inspect tag', inspect(protoShapeFn), '[GeneratorFunction: protoShapeFn]');
265272test('generator instance uses function prototype', ownGeneratorProto, protoShapeFn.prototype);
266273test('generator shared prototype has next', sharedGeneratorProto.hasOwnProperty('next'), true);
267274test('generator Symbol.iterator inherited from iterator prototype', iteratorProto.hasOwnProperty(Symbol.iterator), true);
+1
include/silver/compiler.h
···119119 bool is_tla;
120120 int try_depth;
121121 int with_depth;
122122+ int completion_local;
122123 int strict_args_local;
123124 int new_target_local;
124125 int super_local;