Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: third_party/WebKit/Source/bindings/templates/interface.cpp.tmpl

Issue 2647643002: Fix V8 bindings for named constructors to set prototype object correctly (Closed)
Patch Set: Fixed failing test Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 {% extends 'interface_base.cpp.tmpl' %} 1 {% extends 'interface_base.cpp.tmpl' %}
2 2
3 {% set has_prepare_prototype_and_interface_object = 3 {% set has_prepare_prototype_and_interface_object =
4 unscopables or has_conditional_attributes_on_prototype or 4 unscopables or has_conditional_attributes_on_prototype or
5 methods | conditionally_exposed(is_partial) %} 5 methods | conditionally_exposed(is_partial) %}
6 {% set prepare_prototype_and_interface_object_func = 6 {% set prepare_prototype_and_interface_object_func =
7 '%s::preparePrototypeAndInterfaceObject' % v8_class 7 '%s::preparePrototypeAndInterfaceObject' % v8_class
8 if has_prepare_prototype_and_interface_object 8 if has_prepare_prototype_and_interface_object
9 else 'nullptr' %} 9 else 'nullptr' %}
10 10
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 } 515 }
516 516
517 {% endif %} 517 {% endif %}
518 {% endblock %} 518 {% endblock %}
519 519
520 520
521 {##############################################################################} 521 {##############################################################################}
522 {% block named_constructor %} 522 {% block named_constructor %}
523 {% from 'methods.cpp.tmpl' import generate_constructor with context %} 523 {% from 'methods.cpp.tmpl' import generate_constructor with context %}
524 {% if named_constructor %} 524 {% if named_constructor %}
525 {% set parent_wrapper_type_info = '&V8%s::wrapperTypeInfo' % parent_interface
526 if parent_interface else '0' %}
525 {% set active_scriptwrappable_inheritance = 527 {% set active_scriptwrappable_inheritance =
526 'InheritFromActiveScriptWrappable' 528 'InheritFromActiveScriptWrappable'
527 if active_scriptwrappable else 529 if active_scriptwrappable else
528 'NotInheritFromActiveScriptWrappable' %} 530 'NotInheritFromActiveScriptWrappable' %}
529 // Suppress warning: global constructors, because struct WrapperTypeInfo is triv ial 531 // Suppress warning: global constructors, because struct WrapperTypeInfo is triv ial
530 // and does not depend on another global objects. 532 // and does not depend on another global objects.
531 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG) 533 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
532 #pragma clang diagnostic push 534 #pragma clang diagnostic push
533 #pragma clang diagnostic ignored "-Wglobal-constructors" 535 #pragma clang diagnostic ignored "-Wglobal-constructors"
534 #endif 536 #endif
535 const WrapperTypeInfo {{v8_class}}Constructor::wrapperTypeInfo = { gin::kEmbedde rBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::trace, {{v8_class}}: :traceWrappers, 0, {{prepare_prototype_and_interface_object_func}}, "{{interface _name}}", 0, WrapperTypeInfo::WrapperTypeObjectPrototype, WrapperTypeInfo::{{wra pper_class_id}}, WrapperTypeInfo::{{active_scriptwrappable_inheritance}}, Wrappe rTypeInfo::{{event_target_inheritance}}, WrapperTypeInfo::{{lifetime}} }; 537 const WrapperTypeInfo {{v8_class}}Constructor::wrapperTypeInfo = { gin::kEmbedde rBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::trace, {{v8_class}}: :traceWrappers, 0, {{prepare_prototype_and_interface_object_func}}, "{{interface _name}}", {{parent_wrapper_type_info}}, WrapperTypeInfo::WrapperTypeObjectProtot ype, WrapperTypeInfo::{{wrapper_class_id}}, WrapperTypeInfo::{{active_scriptwrap pable_inheritance}}, WrapperTypeInfo::{{event_target_inheritance}}, WrapperTypeI nfo::{{lifetime}} };
536 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG) 538 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
537 #pragma clang diagnostic pop 539 #pragma clang diagnostic pop
538 #endif 540 #endif
539 541
540 {{generate_constructor(named_constructor)}} 542 {{generate_constructor(named_constructor)}}
541 v8::Local<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolate * isolate, const DOMWrapperWorld& world) { 543 v8::Local<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolate * isolate, const DOMWrapperWorld& world) {
542 static int domTemplateKey; // This address is used for a key to look up the do m template. 544 static int domTemplateKey; // This address is used for a key to look up the do m template.
543 V8PerIsolateData* data = V8PerIsolateData::from(isolate); 545 V8PerIsolateData* data = V8PerIsolateData::from(isolate);
544 v8::Local<v8::FunctionTemplate> result = data->findInterfaceTemplate(world, &d omTemplateKey); 546 v8::Local<v8::FunctionTemplate> result = data->findInterfaceTemplate(world, &d omTemplateKey);
545 if (!result.IsEmpty()) 547 if (!result.IsEmpty())
546 return result; 548 return result;
547 549
548 result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback); 550 result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback);
549 v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate(); 551 v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
550 instanceTemplate->SetInternalFieldCount({{v8_class}}::internalFieldCount); 552 instanceTemplate->SetInternalFieldCount({{v8_class}}::internalFieldCount);
551 result->SetClassName(v8AtomicString(isolate, "{{cpp_class}}")); 553 result->SetClassName(v8AtomicString(isolate, "{{named_constructor.name}}"));
552 result->Inherit({{v8_class}}::domTemplate(isolate, world)); 554 result->Inherit({{v8_class}}::domTemplate(isolate, world));
553 data->setInterfaceTemplate(world, &domTemplateKey, result); 555 data->setInterfaceTemplate(world, &domTemplateKey, result);
554 return result; 556 return result;
555 } 557 }
556 558
559 void {{v8_class}}Constructor::NamedConstructorAttributeGetter(
560 v8::Local<v8::Name> propertyName,
561 const v8::PropertyCallbackInfo<v8::Value>& info) {
562 v8::Local<v8::Value> data = info.Data();
Yuki 2017/01/20 05:54:42 You no longer use |data|.
sashab 2017/01/25 02:34:51 Done
563 DCHECK(data->IsExternal());
564 V8PerContextData* perContextData =
565 V8PerContextData::from(info.Holder()->CreationContext());
566 if (!perContextData)
567 return;
568
569 v8::Local<v8::Function> namedConstructor = perContextData->constructorForType( &{{v8_class}}Constructor::wrapperTypeInfo);
570 v8::Local<v8::Function> interface = perContextData->constructorForType(&{{v8_c lass}}::wrapperTypeInfo);
haraken 2017/01/20 08:07:04 Move this code into the if clause at line 576.
sashab 2017/01/25 02:34:51 Oh yup nice, thx done.
571
572 // Set the prototype of named constructors to the regular constructor.
573 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
haraken 2017/01/20 08:07:04 You're using info.Holder()->CreationContext() at l
Yuki 2017/01/20 15:20:30 Both are correct. The interface obejct and protot
sashab 2017/01/25 02:34:51 Renamed to |currentContext| and only used info.Hol
574 auto privateProperty = V8PrivateProperty::getNamedConstructorInitialized(info. GetIsolate());
575 v8::Local<v8::Value> privateValue = privateProperty.get(context, namedConstruc tor);
576 if (privateValue.IsEmpty()) {
577 // Only Window exposes named constructors, so that will always be the interf ace name.
578 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::GetterConte xt, "Window", "{{named_constructor.name}}");
579 v8::MaybeLocal<v8::Value> interfacePrototype = interface->Get(context, v8Ato micString(info.GetIsolate(), "prototype"));
haraken 2017/01/20 08:07:04 Can you avoid using a MaybeLocal handle? Local<
sashab 2017/01/25 02:34:51 Nice! Done.
580 if (interfacePrototype.IsEmpty()) {
581 exceptionState.throwTypeError("Could not get prototype for {{v8_class}}.") ;
582 return;
583 }
584
585 v8::Maybe<bool> setResult = namedConstructor->Set(context, v8AtomicString(in fo.GetIsolate(), "prototype"), interfacePrototype.ToLocalChecked());
haraken 2017/01/20 08:07:04 Ditto. Avoid using Maybe. You can use To.
sashab 2017/01/25 02:34:51 Done. Changed to: if (namedConstructor->Set(curre
586 if (setResult.IsNothing() || setResult.ToChecked() != true) {
587 exceptionState.throwTypeError("Could not set prototype for {{named_constru ctor.name}}.");
588 return;
589 }
590
591 privateProperty.set(context, namedConstructor, v8::True(info.GetIsolate()));
592 }
593
594 v8SetReturnValue(info, namedConstructor);
595 }
596
557 {% endif %} 597 {% endif %}
558 {% endblock %} 598 {% endblock %}
559 599
560 {##############################################################################} 600 {##############################################################################}
561 {% block overloaded_constructor %} 601 {% block overloaded_constructor %}
562 {% if constructor_overloads %} 602 {% if constructor_overloads %}
563 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info) { 603 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info) {
564 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ConstructionC ontext, "{{interface_name}}"); 604 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ConstructionC ontext, "{{interface_name}}");
565 {# 2. Initialize argcount to be min(maxarg, n). #} 605 {# 2. Initialize argcount to be min(maxarg, n). #}
566 switch (std::min({{constructor_overloads.maxarg}}, info.Length())) { 606 switch (std::min({{constructor_overloads.maxarg}}, info.Length())) {
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 } 996 }
957 997
958 {% for method in methods if method.overloads and method.overloads.has_partial_ov erloads %} 998 {% for method in methods if method.overloads and method.overloads.has_partial_ov erloads %}
959 void {{v8_class}}::register{{method.name | blink_capitalize}}MethodForPartialInt erface(void (*method)(const v8::FunctionCallbackInfo<v8::Value>&)) { 999 void {{v8_class}}::register{{method.name | blink_capitalize}}MethodForPartialInt erface(void (*method)(const v8::FunctionCallbackInfo<v8::Value>&)) {
960 {{cpp_class}}V8Internal::{{method.name}}MethodForPartialInterface = method; 1000 {{cpp_class}}V8Internal::{{method.name}}MethodForPartialInterface = method;
961 } 1001 }
962 1002
963 {% endfor %} 1003 {% endfor %}
964 {% endif %} 1004 {% endif %}
965 {% endblock %} 1005 {% endblock %}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698