Chromium Code Reviews| Index: third_party/WebKit/Source/bindings/core/v8/V8Binding.h |
| diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h |
| index 3d5ea9e20f91f19ec507c2cf2548f142e2cfce26..cde8cb190c646b03dbca071c81ca8bdd4043e600 100644 |
| --- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h |
| +++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h |
| @@ -728,6 +728,61 @@ VectorType toImplArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int |
| return result; |
| } |
| +// Gets an iterator from an Object. |
| +v8::MaybeLocal<v8::Object> getIterator(v8::Local<v8::Object>, v8::Isolate*, ExceptionState&); |
|
haraken
2016/09/08 09:32:08
I don't have any strong opinion but might prefer r
bashi
2016/09/09 00:54:22
I think using MaybeLocal has two advantages:
1. Ca
|
| + |
| +// Converts a V8 value to an array (an IDL sequence) as per the WebIDL |
| +// specification: http://heycam.github.io/webidl/#es-sequence |
| +template <typename VectorType> |
| +VectorType toImplSequence(v8::Local<v8::Value> value, v8::Isolate* isolate, ExceptionState& exceptionState) |
|
Yuki
2016/09/08 08:32:21
Could you make v8::Isolate* the first argument?
bashi
2016/09/09 00:54:23
Done. Having said that it's inconsistent with othe
|
| +{ |
| + typedef typename VectorType::ValueType ValueType; |
|
Yuki
2016/09/08 08:32:21
I guess
using VectorType::ValueType;
does the
bashi
2016/09/09 00:54:22
Done.
|
| + |
| + if (!value->IsObject() || value->IsRegExp()) { |
| + exceptionState.throwTypeError("The provided value cannot be converted to a sequence."); |
| + return VectorType(); |
| + } |
| + |
| + v8::Local<v8::Object> iterator; |
| + if (!getIterator(value.As<v8::Object>(), isolate, exceptionState).ToLocal(&iterator)) |
| + return VectorType(); |
| + |
| + v8::Local<v8::String> nextKey = v8String(isolate, "next"); |
| + v8::Local<v8::String> valueKey = v8String(isolate, "value"); |
| + v8::Local<v8::String> doneKey = v8String(isolate, "done"); |
| + v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| + VectorType result; |
| + while (true) { |
| + v8::Local<v8::Value> next; |
| + if (!iterator->Get(context, nextKey).ToLocal(&next)) |
| + return VectorType(); |
| + if (!next->IsObject() || !next.As<v8::Object>()->IsCallable()) { |
| + exceptionState.throwTypeError("The next property should be callable."); |
|
Yuki
2016/09/08 08:32:21
I think
"Iterator.next should be callable."
is e
bashi
2016/09/09 00:54:23
Done.
|
| + return VectorType(); |
| + } |
| + v8::Local<v8::Value> nextResult; |
| + if (!next.As<v8::Object>()->CallAsFunction(context, iterator, 0, nullptr).ToLocal(&nextResult)) |
| + return VectorType(); |
|
haraken
2016/09/08 09:32:08
Don't we need to throw an exception?
bashi
2016/09/09 00:54:23
No, as described in another reply.
|
| + if (!nextResult->IsObject()) { |
| + exceptionState.throwTypeError("Iterator.next() does not return an object."); |
|
Yuki
2016/09/08 08:32:21
s/does/did/
bashi
2016/09/09 00:54:23
Done.
|
| + return VectorType(); |
| + } |
| + v8::Local<v8::Object> resultObject = nextResult.As<v8::Object>(); |
| + v8::Local<v8::Value> element; |
| + v8::Local<v8::Value> done; |
| + if (!resultObject->Get(context, valueKey).ToLocal(&element) |
| + || !resultObject->Get(context, doneKey).ToLocal(&done)) |
| + return VectorType(); |
|
haraken
2016/09/08 09:32:08
Ditto.
|
| + v8::Local<v8::Boolean> doneBoolean; |
| + if (!done->ToBoolean(context).ToLocal(&doneBoolean)) |
| + return VectorType(); |
|
haraken
2016/09/08 09:32:08
Ditto.
|
| + result.uncheckedAppend(NativeValueTraits<ValueType>::nativeValue(isolate, element, exceptionState)); |
| + if (doneBoolean->Value()) |
| + break; |
| + } |
| + return result; |
| +} |
| + |
| // Validates that the passed object is a sequence type per WebIDL spec |
| // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence |
| inline bool toV8Sequence(v8::Local<v8::Value> value, uint32_t& length, v8::Isolate* isolate, ExceptionState& exceptionState) |