• Raphael Kubo da Costa's avatar
    bindings: Do not access @@iterator twice when converting union to sequence · 9dfff6a5
    Raphael Kubo da Costa authored
    A rough approximation of https://heycam.github.io/webidl/#es-union when
    trying to convert an ES value to an IDL sequence or frozen array is:
    1. Call the GetMethod abstract ES operation to retrieve the @@iterator
       property.
    2. If it is not undefined, invoke
       https://heycam.github.io/webidl/#create-sequence-from-iterable with the
       ES value and the method obtained above.
    
    So far, we were implementing it roughly like this:
    1. Call the GetMethod abstract ES operation to retrieve the @@iterator
       property.
    2. Invoke https://heycam.github.io/webidl/#es-sequence with the ES value,
       which disregards the method obtained in step 1 and goes through the whole
       process of calling GetMethod again and using that to create a sequence
       from an interable.
    
    This is obviously not compliant with the spec, and the multiple calls to the
    GetMethod abstract operation are user-visible, as can be seen in the test
    case attached to the bug 1024388.
    
    Properly fixing this requires changes to a few different classes and
    functions:
    * Make HasCallableIteratorSymbol(), which is called by the overload
      resolution algorithm implementation, be a small wrapper around
      GetEsIteratorMethod(). While HasCallableIteratorSymbol() precedes
      GetEsIteratorMethod(), the latter's implementation is more spec-compliant.
    * Add a move constructor to ScriptIterator, as well as a static method that
      can create a ScriptIterator out of an ES value by invoking
      GetEsIteratorMethod() and GetEsIteratorWithMethod() underneath.
    * Make NativeValueTraits<IDLSequence<T>>::ConvertSequenceSlow() take a
      ScriptIterator rather than a v8::Local<v8::Object>, which allows us to
      delegate getting an iterator out of an iterable object to the static
      ScriptIterator method mentioned above. This also helps reduce the size of
      the generated per-type NativeValueTraits<IDLSequence<T>> template code.
    * Analogously, invoke ScriptIterator::FromIterable() in the union conversion
      code, and invoke a new NativeValueTraits<IDLSequence<T>>::NativeValue()
      overload that takes a ScriptIterator, so that we do not access the
      @@iterator property multiple times in the union conversion code.
    
    Bug: 1024388
    Change-Id: I47e6c0ca881e6e77f883ee78b5e1611138cdcc4a
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1917169
    Commit-Queue: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
    Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#716960}
    9dfff6a5
init-message-event-expected.txt 597 Bytes