Expose %IteratorPrototype% as an intrinsic in the public API.

The WebIDL spec expects iterator objects from interfaces that declare pair
iterators to ultimately inherit from %IteratorPrototype%. Expose the
intrinsic object in the public API so we can use it in Blink's bindings
code.

BUG=chromium:689576
R=caitp@igalia.com,jkummerow@chromium.org,jochen@chromium.org

Review-Url: https://codereview.chromium.org/2784543004
Cr-Commit-Position: refs/heads/master@{#44472}
This commit is contained in:
raphael.kubo.da.costa 2017-04-07 01:33:57 -07:00 committed by Commit bot
parent 1329d15e99
commit 5ec1cddcdd
2 changed files with 74 additions and 1 deletions

View File

@ -4755,7 +4755,8 @@ class V8_EXPORT External : public Value {
F(ArrayProto_entries, array_entries_iterator) \
F(ArrayProto_forEach, array_for_each_iterator) \
F(ArrayProto_keys, array_keys_iterator) \
F(ArrayProto_values, array_values_iterator)
F(ArrayProto_values, array_values_iterator) \
F(IteratorPrototype, initial_iterator_prototype)
enum Intrinsic {
#define V8_DECL_INTRINSIC(name, iname) k##name,

View File

@ -25901,6 +25901,78 @@ TEST(AccessCheckedToStringTag) {
CHECK_EQ(0, strcmp(*result_denied, "[object Object]"));
}
TEST(TemplateIteratorPrototypeIntrinsics) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
// Object templates.
{
Local<ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate);
object_template->SetIntrinsicDataProperty(v8_str("iter_proto"),
v8::kIteratorPrototype);
Local<Object> object =
object_template->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("obj"), object).FromJust());
ExpectTrue("obj.iter_proto === [][Symbol.iterator]().__proto__.__proto__");
}
// Setting %IteratorProto% on the function object's prototype template.
{
Local<FunctionTemplate> func_template = v8::FunctionTemplate::New(isolate);
func_template->PrototypeTemplate()->SetIntrinsicDataProperty(
v8_str("iter_proto"), v8::kIteratorPrototype);
Local<Function> func1 =
func_template->GetFunction(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("func1"), func1).FromJust());
Local<Function> func2 =
func_template->GetFunction(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("func2"), func2).FromJust());
ExpectTrue(
"func1.prototype.iter_proto === "
"[][Symbol.iterator]().__proto__.__proto__");
ExpectTrue(
"func2.prototype.iter_proto === "
"[][Symbol.iterator]().__proto__.__proto__");
ExpectTrue("func1.prototype.iter_proto === func2.prototype.iter_proto");
Local<Object> instance1 = func1->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()
->Set(env.local(), v8_str("instance1"), instance1)
.FromJust());
ExpectFalse("instance1.hasOwnProperty('iter_proto')");
ExpectTrue("'iter_proto' in instance1.__proto__");
ExpectTrue(
"instance1.iter_proto === [][Symbol.iterator]().__proto__.__proto__");
}
// Put %IteratorProto% in a function object's inheritance chain.
{
Local<FunctionTemplate> parent_template =
v8::FunctionTemplate::New(isolate);
parent_template->RemovePrototype(); // Remove so there is no name clash.
parent_template->SetIntrinsicDataProperty(v8_str("prototype"),
v8::kIteratorPrototype);
Local<FunctionTemplate> func_template = v8::FunctionTemplate::New(isolate);
func_template->Inherit(parent_template);
Local<Function> func =
func_template->GetFunction(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust());
ExpectTrue(
"func.prototype.__proto__ === "
"[][Symbol.iterator]().__proto__.__proto__");
Local<Object> func_instance =
func->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()
->Set(env.local(), v8_str("instance"), func_instance)
.FromJust());
ExpectTrue(
"instance.__proto__.__proto__ === "
"[][Symbol.iterator]().__proto__.__proto__");
ExpectTrue("instance.__proto__.__proto__.__proto__ === Object.prototype");
}
}
TEST(ObjectTemplateArrayProtoIntrinsics) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);