Modify $262.uncallableAndIsHTMLDDA() to $262.IsHTMLDDA (#1305)

Modify $262.uncallableAndIsHTMLDDA() to an optional $262.IsHTMLDDA (whose use must be guarded by a feature of the same name), and narrowly/correctly prescribe its requirements consistent with `document.all`'s behavior in HTML.
This commit is contained in:
Jeff Walden 2017-10-19 12:03:21 -07:00 committed by Leo Balter
parent 893013a658
commit c05138b44c
5 changed files with 39 additions and 36 deletions

View File

@ -64,16 +64,16 @@ properties of the global scope prior to test execution.
6. Return Completion(status).
- **`global`** - a reference to the global object on which `$262` was initially defined
- **`uncallableAndIsHTMLDDA`** - a function that returns an object *`obj`* for
which [Call](https://tc39.github.io/ecma262/#sec-call)(*`obj`*, *any value*, «»)
throws a `TypeError`. (The value of [IsCallable]()(*`obj`*) is unspecified:
a callable *`obj`* that throws a `TypeError` or an uncallable *`obj`* works
equally well.) In hosts supporting the
[IsHTMLDDA](https://tc39.github.io/ecma262/#sec-IsHTMLDDA-internal-slot)
internal slot, *`obj`* must also have such a slot. (These highly specific
behaviors are entirely motivated by the very few tests that use this. Read
them for an explanation.) Tests that use this function should be marked as
using the `uncallableAndIsHTMLDDA` feature.
- **`IsHTMLDDA`** - (present only in implementations that can provide it) an
object that 1) has an [[IsHTMLDDA]] internal slot, and 2) when called with
no arguments or with the single argument `""` returns `null`. Use this
property to test that ECMAScript algorithms aren't mis-implemented to treat
`document.all` as being `undefined` or of type Undefined (instead of
Object). (The peculiar second requirement permits testing algorithms when
they also call `document.all` with such arguments, so that testing for
correct behavior requires knowing how the call behaves. This is rarely
necessary.) Tests using this function must be tagged with the `IsHTMLDDA`
feature so that only hosts supporting this property will run them.
- **`agent`** - an ordinary object with the following properties:
- **`start`** - a function that takes a script source string and runs
the script in a concurrent agent. Will block until that agent is

View File

@ -124,4 +124,4 @@ WeakSet
# language features, exposed through global-environment functions on the $262
# object, go here.
uncallableAndIsHTMLDDA
IsHTMLDDA

View File

@ -2,18 +2,19 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: sec-generator-function-definitions-runtime-semantics-evaluation
esid: sec-generator-function-definitions-runtime-semantics-evaluation
description: >
If <iterator>.return is an object emulating `undefined` (e.g. `document.all`
in browsers), it shouldn't be treated as if it were actually `undefined` by
the yield* operator.
features: [generators, uncallableAndIsHTMLDDA]
features: [generators, IsHTMLDDA]
---*/
var IsHTMLDDA = $262.IsHTMLDDA;
var iter = {
[Symbol.iterator]() { return this; },
next() { return {}; },
return: $262.uncallableAndIsHTMLDDA(),
return: IsHTMLDDA,
};
var outer = (function*() { yield* iter; })();
@ -21,11 +22,10 @@ var outer = (function*() { yield* iter; })();
outer.next();
assert.throws(TypeError, function() {
// This code is expected to throw a TypeError because `iter.return` throws a
// TypeError when invoked with `iter` as `this` and no arguments provided.
// It's irrelevant that in hosts that support the [[IsHTMLDDA]] internal slot,
// this object has that slot: `<iterator>.return` behavior is skipped only if
// that property is exactly the value `undefined`, not a value loosely equal
// to it.
outer.return();
// `IsHTMLDDA` is called here with `iter` as `this` and `emptyString` as the
// sole argument, and it's specified to return `null` under these conditions.
// As `iter`'s iteration isn't ending because of a throw, the iteration
// protocol will then throw a `TypeError` because `null` isn't an object.
var emptyString = "";
outer.return(emptyString);
});

View File

@ -7,19 +7,23 @@ description: >
`GetIterator(obj, ~async~)` must attempt to call `obj[@@asyncIterator]` when
that value is an object with an [[IsHTMLDDA]] internal slot, not act as if
the value were `undefined`.
features: [async-iteration, uncallableAndIsHTMLDDA]
features: [async-iteration, IsHTMLDDA]
flags: [async]
---*/
async function f() {
var fakeIter = {
[Symbol.asyncIterator]: $262.uncallableAndIsHTMLDDA(),
var IsHTMLDDA = $262.IsHTMLDDA;
var iter = {
[Symbol.asyncIterator]: IsHTMLDDA,
get [Symbol.iterator]() {
throw new Test262Error("shouldn't touch Symbol.iterator");
},
};
for await (var x of fakeIter)
// `IsHTMLDDA` is called here with `iter` as `this` and no arguments, and it's
// expected to return `null` under these conditions. Then the iteration
// protocol throws a `TypeError` because `null` isn't an object.
for await (var x of iter)
return "for-await-of body shouldn't be reached";
return "should have failed earlier";
@ -28,7 +32,8 @@ async function f() {
f().then($DONE,
function (e) {
assert.sameValue(e.constructor, TypeError,
"expected TypeError from calling " +
"uncallableAndIsHTMLDDA() value: " + e);
"expected TypeError because " +
"`iter[Symbol.asyncIterator]() returned a " +
"non-object: " + e);
})
.then($DONE, $DONE);

View File

@ -2,26 +2,24 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: sec-iteratorclose
esid: sec-iteratorclose
description: >
If <iterator>.return is an object emulating `undefined` (e.g. `document.all`
in browsers), it shouldn't be treated as if it were actually `undefined`.
features: [generators, uncallableAndIsHTMLDDA]
features: [generators, IsHTMLDDA]
---*/
var IsHTMLDDA = $262.IsHTMLDDA;
var iter = {
[Symbol.iterator]() { return this; },
next() { return {}; },
return: $262.uncallableAndIsHTMLDDA(),
return: IsHTMLDDA,
};
assert.throws(TypeError, function() {
// This code is expected to throw a TypeError because `iter.return` throws a
// TypeError when invoked with `iter` as `this` and no arguments provided.
// It's irrelevant that in hosts that support the [[IsHTMLDDA]] internal slot,
// this object has that slot: `<iterator>.return` behavior is skipped only if
// that property is exactly the value `undefined`, not a value loosely equal
// to it.
// `IsHTMLDDA` is called here with `iter` as `this` and no arguments, and it's
// specified to return `null` under these conditions. Then the iteration
// protocol throws a `TypeError` because `null` isn't an object.
for (var x of iter)
break;
});