Index: Source/bindings/templates/constructors.cpp |
diff --git a/Source/bindings/templates/constructors.cpp b/Source/bindings/templates/constructors.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3bac1163ef797e764432465861e6a2fde2eb17b8 |
--- /dev/null |
+++ b/Source/bindings/templates/constructors.cpp |
@@ -0,0 +1,189 @@ |
+{% from 'macros.cpp' import deprecation_notification, feature_observation, parameters_check with context %} |
+ |
+{##############################################################################} |
+{% macro make_constructors() %} |
+{% if has_named_constructor %} |
+{% elif has_constructor %} |
+{% for constructor in constructors %} |
+{{normal_constructor(constructor)}} |
+{% endfor %} |
+{% elif is_constructor_template_of_event %} |
+{{constructor_template_of_event()}} |
+{% elif is_constructor_template_of_typed_array %} |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro normal_constructor(constructor) %} |
+{# FIXME: check name #} |
+static void constructor{{constructor.overloaded_index_string}}(const v8::FunctionCallbackInfo<v8::Value>& args) |
+{ |
+{% if constructor.overloaded_index == 0 and constructor.mandatory_parameters %} |
+ if (args.Length() < {{constructor.mandatory_parameters}}) { |
+ throwNotEnoughArgumentsError(args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+{% if constructor_raises_exception %} |
+ ExceptionState es(args.GetIsolate()); |
+{% endif %} |
+{{parameters_check(constructor)}} |
+{% if constructor_call_with == 'ScriptExecutionContext' %} |
+ ScriptExecutionContext* context = getScriptExecutionContext(); |
+{% endif %} |
+ RefPtr<{{cpp_class_name}}> impl = {{cpp_class_name}}::create({{constructor.argument_string}}); |
+ v8::Handle<v8::Object> wrapper = args.Holder(); |
+{% if constructor_raises_exception %} |
+ if (es.throwIfNeeded()) |
+ return; |
+{% endif %} |
+ |
+ V8DOMWrapper::associateObjectWithWrapper<{{v8_class_name}}>(impl.release(), &{{v8_class_name}}::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent); |
+ args.GetReturnValue().Set(wrapper); |
+} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro constructor_template_of_event() %} |
+{# FIXME: check name #} |
+static void constructor(const v8::FunctionCallbackInfo<v8::Value>& args) |
+{ |
+ if (args.Length() < 1) { |
+ throwNotEnoughArgumentsError(args.GetIsolate()); |
+ return; |
+ } |
+ |
+ V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, args[0]); |
+{% for attribute in attributes %} |
+{% if attribute.type == 'any' %} |
+ v8::Local<v8::Value> {{attribute.name}}; |
+{% endif %} |
+{% endfor %} |
+ {{cpp_class_name}}Init eventInit; |
+ if (args.Length() >= 2) { |
+ V8TRYCATCH_VOID(Dictionary, options, Dictionary(args[1], args.GetIsolate())); |
+ if (!fill{{cpp_class_name}}Init(eventInit, options)) |
+ return; |
+{% for attribute in attributes %} |
+{% if attribute.type == 'any' %} |
+ options.get("{{attribute.name}}", {{attribute.name}}); |
+ if (!{{attribute.name}}.IsEmpty()) |
+ args.Holder()->SetHiddenValue(V8HiddenPropertyName::{{attribute.name}}(), {{attribute.name}}); |
+{% endif %} |
+{% endfor %} |
+ } |
+ |
+ RefPtr<{{cpp_class_name}}> event = {{cpp_class_name}}::create(type, eventInit); |
+{% if number_of_any_attributes %} |
+{# If we're in an isolated world, create a SerializedScriptValue and store it in the event for |
+ # later cloning if the property is accessed from another world. |
+ # The main world case is handled lazily (in Custom code). #} |
+ if (isolatedWorldForIsolate(args.GetIsolate())) { |
+{% for attribute in attributes %} |
+{% if attribute.type == 'any' %} |
+ if (!{{attribute.name}}.IsEmpty()) |
+ event->{{attribute.setter}}(SerializedScriptValue::createAndSwallowExceptions({{attribute.name}}, args.GetIsolate())); |
+{% endif %} |
+{% endfor %} |
+ } |
+ |
+{% endif %} |
+ v8::Handle<v8::Object> wrapper = args.Holder(); |
+ V8DOMWrapper::associateObjectWithWrapper<{{v8_class_name}}>(event.release(), &{{v8_class_name}}::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent); |
+ v8SetReturnValue(args, wrapper); |
+}{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro more_constructor_stuff() %} |
+{# FIXME: check name #} |
+{% if has_named_constructor %} |
+{## working #} |
+WrapperTypeInfo {{v8_class_name}}Constructor::info = { {{v8_class_name}}Constructor::GetTemplate, {{v8_class_name}}::derefObject, {{to_active_dom_object}}, {{to_event_target}}, 0, {{v8_class_name}}::installPerContextPrototypeProperties, 0, WrapperTypeObjectPrototype }; |
+ |
+static void {{v8_class_name}}ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
+{ |
+{{feature_observation(measure_as) -}} |
+{{deprecation_notification(deprecate_as)}} if (!args.IsConstructCall()) { |
+ throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); |
+ return; |
+ } |
+ |
+ if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) { |
+ args.GetReturnValue().Set(args.Holder()); |
+ return; |
+ } |
+ |
+ Document* document = currentDocument(); |
+ |
+ // Make sure the document is added to the DOM Node map. Otherwise, the {{cpp_class_name}} instance |
+ // may end up being the only node in the map and get garbage-collected prematurely. |
+ toV8(document, args.Holder(), args.GetIsolate()); |
+ |
+{{parameters_check(named_constructor)}} |
+{% if constructor_raises_exception %} |
+ ExceptionCode ec = 0; |
+{% endif %} |
+ RefPtr<{{cpp_class_name}}> impl = {{cpp_class_name}}::createForJSConstructor({{named_constructor.argument_string}}); |
+ v8::Handle<v8::Object> wrapper = args.Holder(); |
+{% if constructor_raises_exception %} |
+ if (ec) { |
+ setDOMException(ec, args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+ |
+ V8DOMWrapper::associateObjectWithWrapper<{{v8_class_name}}>(impl.release(), &{{v8_class_name}}Constructor::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent); |
+ args.GetReturnValue().Set(wrapper); |
+} |
+ |
+v8::Handle<v8::FunctionTemplate> {{v8_class_name}}Constructor::GetTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType) |
+{ |
+ // This is only for getting a unique pointer which we can pass to privateTemplate. |
+ static const char* privateTemplateUniqueKey = "{{v8_class_name}}Constructor::GetTemplatePrivateTemplate"; |
+ V8PerIsolateData* data = V8PerIsolateData::from(isolate); |
+ v8::Handle<v8::FunctionTemplate> result = data->privateTemplateIfExists(currentWorldType, &privateTemplateUniqueKey); |
+ if (!result.IsEmpty()) |
+ return result; |
+ |
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate"); |
+ v8::HandleScope scope(isolate); |
+ result = v8::FunctionTemplate::New({{v8_class_name}}ConstructorCallback); |
+ |
+ v8::Local<v8::ObjectTemplate> instance = result->InstanceTemplate(); |
+ instance->SetInternalFieldCount({{v8_class_name}}::internalFieldCount); |
+ result->SetClassName(v8::String::NewSymbol("{{cpp_class_name}}")); |
+ result->Inherit({{v8_class_name}}::GetTemplate(isolate, currentWorldType)); |
+ data->setPrivateTemplate(currentWorldType, &privateTemplateUniqueKey, result); |
+ |
+ return scope.Close(result); |
+} |
+ |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro constructor_callback() %} |
+void {{v8_class_name}}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
+{ |
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "DOMConstructor");{{feature_observation(measure_as)}}{{deprecation_notification(deprecate_as)}} |
+ if (!args.IsConstructCall()) { |
+ throwTypeError("DOM object constructor cannot be called as a function.", args.GetIsolate()); |
+ return; |
+ } |
+ |
+ if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) { |
+ args.GetReturnValue().Set(args.Holder()); |
+ return; |
+ } |
+ |
+{% if has_custom_constructor %} |
+ {{v8_class_name}}::constructorCustom(args); |
+{% else %} |
+ {{cpp_class_name}}V8Internal::constructor(args); |
+{% endif %} |
+} |
+{% endmacro %} |