Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upMake Async-from-Sync iterator object inaccessible to ECMAScript code #1172
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
anba
Apr 12, 2018
Contributor
Any idea for a fix?
CreateAsyncFromSyncIterator, step 3 could be changed to:
- Let nextMethod be %AsyncFromSyncIteratorPrototype_next%.
- Return the Record {[[Iterator]]: asyncIterator, [[NextMethod]]: nextMethod, [[Done]]: false}.
where %AsyncFromSyncIteratorPrototype_next% is a new intrinsic for 25.1.4.2.1 %AsyncFromSyncIteratorPrototype%.next.
Or alternatively add %AsyncFromSyncIteratorPrototype%[@@asyncIterator] with the same steps as 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( ).
CreateAsyncFromSyncIterator, step 3 could be changed to:
where Or alternatively add |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
littledan
Apr 12, 2018
Member
It sounds like the first option would be what browsers currently implement. Is that your understanding?
|
It sounds like the first option would be what browsers currently implement. Is that your understanding? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
anba
Apr 12, 2018
Contributor
Both options result in the same behaviour, except the first one is easier to reason about.
|
Both options result in the same behaviour, except the first one is easier to reason about. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
caitp
Apr 12, 2018
Contributor
In particular, v8's implementation doesn't include tc39/proposal-async-iteration@201c814, so there's no subsequent GetIterator(asyncIterator, async) after the Async-from-Sync Iterator is created.
The actual behaviour:
method = obj[Symbol.asyncIterator]->undefined- If
methodisundefined/nullsyncIterator = obj[Symbol.iterator]()->[object Array Iterator]asyncIterator = %_CreateAsyncFromSyncIterator(syncIterator)->[object Async-from-Sync Iterator]
next = asyncIterator.next->%AsyncFromSyncIteratorPrototype.next%
But the way the spec is written, we should be loading @@asyncIterator after %_CreateAsyncFromSyncIterator(syncIterator), which would potentially call an accessor and expose the Async-from-Sync Iterator receiver to it.
AFAIU we don't want to expose the Async-from-Sync Iterator directly, so it only makes sense to avoid recursing into the GetIterator algorithm. Also, the GetIterator in step 3 is potentially recursive/non-terminating behaviour, so we also probably don't want that.
+1 to @anba's suggestion which doesn't include a GetIterator at the end of CreateAsyncFromSyncIterator, because it's easier to reason about if we don't jump back and forth between those 2 algorithms, imho
|
In particular, v8's implementation doesn't include tc39/proposal-async-iteration@201c814, so there's no subsequent The actual behaviour:
But the way the spec is written, we should be loading AFAIU we don't want to expose the Async-from-Sync Iterator directly, so it only makes sense to avoid recursing into the GetIterator algorithm. Also, the GetIterator in step 3 is potentially recursive/non-terminating behaviour, so we also probably don't want that. +1 to @anba's suggestion which doesn't include a |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Thanks for digging out the commit which introduced this behaviour! |
anba commentedApr 12, 2018
25.1.4.1 CreateAsyncFromSyncIterator should not expose the Async-from-Sync iterator object to ECMAScript code.
Let's take this example:
14.4.13 Runtime Semantics: Evaluation for
YieldExpression : yield * AssignmentExpression.with
generatorKind = async.7.4.1 GetIterator ( obj [ , hint [ , method ] ] )
25.1.4.1 CreateAsyncFromSyncIterator
where
asyncIteratoris an Async-from-Sync iterator object. Its prototype is%AsyncFromSyncIteratorPrototype%and the prototype of%AsyncFromSyncIteratorPrototype%is%AsyncIteratorPrototype%.%AsyncIteratorPrototype%is accessible from ECMAScript code, which means it's possible to redefine%AsyncIteratorPrototype%[@@asyncIterator]:That in turn means the GetIterator call in CreateAsyncFromSyncIterator can be used to get access to the Async-from-Sync iterator object. And I don't think we don't want to that to happen.
Note: All engines implementing async generators assume Async-from-Sync iterator object are never directly accessible to ECMAScript code, so the above code won't print "HI" to the console.