Index: Source/bindings/templates/macros.cpp |
diff --git a/Source/bindings/templates/macros.cpp b/Source/bindings/templates/macros.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ed57afa35b2ace4189e3a25a09a3790a925a853f |
--- /dev/null |
+++ b/Source/bindings/templates/macros.cpp |
@@ -0,0 +1,298 @@ |
+{% macro parameters_check(function) %} |
+{% for parameter in function.parameters %}{#### see GenerateParametersCheck #} |
+{# |
+// { {parameter.name} } |
+// { {parameter.is_callback_interface} } |
+#} |
+{% if parameter.early_call %} |
+ if (args.Length() <= {{parameter.index}}) { |
+ {{function_call(parameter.early_call_statement_parameter) | trim | indent}} |
+{# FIXME: whitespace error in V8Entry.cpp, fix Perl CG to remove this line #} |
+ } |
+{% endif %} |
+{# TODO if ($parameter->isOptional && !$parameter->extendedAttributes->{"Default"} && $nativeType ne "Dictionary" && !IsCallbackInterface($parameter->type)) { #} |
+{# TODO if ($parameter->isOptional and $default eq "NullString") { #} |
+{% if parameter.is_callback_interface %}{###########################} |
+{% if parameter.is_optional %} |
+ RefPtr<{{parameter.type}}> {{parameter.name}}; |
+ if (args.Length() > {{parameter.index}} && !args[{{parameter.index}}]->IsNull() && !args[{{parameter.index}}]->IsUndefined()) { |
+ if (!args[{{parameter.index}}]->IsFunction()) { |
+ throwTypeError(args.GetIsolate()); |
+ return; |
+ } |
+ {{parameter.name}} = V8{{parameter.type}}::create(args[{{parameter.index}}], getScriptExecutionContext()); |
+ } |
+{% else %} |
+ if (args.Length() <= {{parameter.index}} || !args[{{parameter.index}}]->IsFunction()) { |
+ throwTypeError(args.GetIsolate()); |
+ return; |
+ } |
+ RefPtr<{{parameter.type}}> {{parameter.name}} = V8{{parameter.type}}::create(args[{{parameter.index}}], getScriptExecutionContext()); |
+{% endif %} |
+{% elif parameter.clamp %}{###########################} |
+ {{parameter.type}} {{parameter.name}}NativeValue = 0; |
+ V8TRYCATCH_VOID(double, $nativeValue, args[{{parameter.index}}]->NumberValue()); |
+ if (!std::isnan({{parameter.name}}NativeValue)) |
+ {{parameter.name}}NativeValue = clampTo<{{parameter.type}}>({{parameter.name}}NativeValue); |
+{% elif parameter.type == "SerializedScriptValue" %}{###########################} |
+ bool {{parameter.name}}DidThrow = false; |
+ {{parameter.naive_type}} {{parameter.name}} = SerializedScriptValue::create(args[{{parameter.index}}], 0, 0, {{parameter.name}}DidThrow, args.GetIsolate()); |
+ if ({{parameter.name}}DidThrow) |
+ return; |
+{% elif parameter.is_variadic %}{###########################} |
+{% if parameter.is_wrapper_type %} |
+ Vector<{{parameter.native_type}}> {{parameter.name}}; |
+ for (int i = {{parameter.index}}; i < args.Length(); ++i) { |
+ if (!V8{{parameter.type}}::HasInstance(args[i], args.GetIsolate(), worldType(args.GetIsolate()))) { |
+ throwTypeError(args.GetIsolate()); |
+ return; |
+ } |
+ {{parameter.name}}.append(V8{{parameter.type}}::toNative(v8::Handle<v8::Object>::Cast(args[i]))); |
+ } |
+{% else %} |
+ V8TRYCATCH_VOID(Vector<{{parameter.native_element_type}}>, {{parameter.name}}, toNativeArguments<{{parameter.native_element_type}}>(args, {{parameter.index}})); |
+{% endif %} |
+{% elif parameter.is_string %}{###########################} |
+ {{parameter.convert_to_v8_string_resource}} |
+{% if parameter.is_enum_type %} |
+ String string = {{parameter.name}}; |
+ if (!({{parameter.enum_validation_expression}})) { |
+ throwTypeError(args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+{% else %}{###########################} |
+{# |
+ If the "StrictTypeChecking" extended attribute is present, and the argument's type is an |
+ interface type, then if the incoming value does not implement that interface, a TypeError |
+ is thrown rather than silently passing NULL to the C++ code. |
+ Per the Web IDL and ECMAScript specifications, incoming values can always be converted |
+ to both strings and numbers, so do not throw TypeError if the argument is of these |
+ types. |
+#} |
+{# TODO #} |
+{% if parameter.strict_type_checking and parameter.is_wrapper_type %} |
+ if (args.Length() > {{parameter.index}} && !isUndefinedOrNull(arg[{{parameter.index}}]) && !V8{{parameter.type}}::HasInstance(arg[{{parameter.index}}], args.GetIsolate(), worldType(args.GetIsolate()))) { |
+ throwTypeError(args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+{################# JS to native #} |
+ {{parameter.js_to_native_statement}} |
+{% if parameter.native_type == "Dictionary" %} |
+ if (!{{parameter.name}}.isUndefinedOrNull() && !{{parameter.name}}.isObject()) { |
+ throwTypeError("Not an object.", args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+{% endif %} |
+{% if parameter.is_index %} |
+ if (UNLIKELY({{parameter.name}} < 0)) { |
+ setDOMException(IndexSizeError, args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+{% endfor %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro function_call(function_call) %} |
+{{call_with_statements(function_call.call_with) -}} |
+{% for parameter in function_call.parameters %} |
+{% if parameter.svg_tear_off_and_not_list %} |
+ if (!{{parameter.name}}) { |
+ setDOMException(WebCore::TypeMismatchError, args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+{% endfor %} |
+{% if function_call.statement %} |
+ {{function_call.statement | indent}} |
+{% endif %} |
+{% if function_call.raises_exception %} |
+ if (es.throwIfNeeded()) |
+ return; |
+{% endif %} |
+{% if function_call.extended_attribute_contains_script_state %} |
+ if (state.hadException()) { |
+ v8::Local<v8::Value> exception = state.exception(); |
+ state.clearException(); |
+ throwError(exception); |
+ return; |
+ } |
+{% endif %} |
+{% if function_call.svg_tear_off_and_not_list %} |
+{% if function_call.is_dom_node_type %} |
+ v8SetReturnValue(args, toV8Fast{{function_call.for_main_world_suffix}}(WTF::getPtr({{function_call.svg_native_type}}::create({{function_call.native_value_expression}})), args, imp)); |
+{% else %} |
+ v8SetReturnValue(args, toV8{{function_call.for_main_world_suffix}}(WTF::getPtr({{function_call.svg_native_type}}::create({{function_call.native_value_expression}})), args.Holder(), args.GetIsolate())); |
+{% endif %} |
+ return; |
+{% else %} |
+{% if function_call.return_js_value_statement %} |
+ {{function_call.return_js_value_statement | indent}} |
+{% else %} |
+ |
+{% endif %} |
+ return; |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro feature_observation(measure_as) %} |
+{% if measure_as %} |
+ UseCounter::count(activeDOMWindow(), UseCounter::{{measure_as}}); |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro deprecation_notification(deprecate_as) %} |
+{% if deprecate_as %} |
+ UseCounter::countDeprecation(activeDOMWindow(), UseCounter::{{deprecate_as}}); |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro call_with_statements(call_with) %} |
+{% if call_with %} |
+{% if call_with.script_state %} |
+ ScriptState* currentState = ScriptState::current(); |
+ if (!currentState) |
+ return{{script_state_return_value}}; |
+ ScriptState& state = *currentState; |
+{% endif %} |
+{% if call_with.script_execution_context %} |
+ ScriptExecutionContext* scriptContext = getScriptExecutionContext(); |
+{%- endif %} |
+{% if call_with.function and call_with.script_arguments %} |
+ |
+ RefPtr<ScriptArguments> scriptArguments(createScriptArguments(args, {{call_with.number_of_function_parameters}})); |
+{% endif %} |
+{% endif %} |
+{%- endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro activity_logging(access_type, property_name) %} |
+{% if access_type == "Method" %} |
+ V8PerContextData* contextData = V8PerContextData::from(args.GetIsolate()->GetCurrentContext()); |
+ if (contextData && contextData->activityLogger()) { |
+ Vector<v8::Handle<v8::Value> > loggerArgs = toVectorOfArguments(args); |
+ contextData->activityLogger()->log("{{interface_name}}.{{property_name}}", args.Length(), loggerArgs.data(), "{{access_type}}"); |
+ } |
+{% endif %} |
+{% if access_type == "Setter" %} |
+ V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext()); |
+ if (contextData && contextData->activityLogger()) { |
+ v8::Handle<v8::Value> loggerArg[] = { value }; |
+ contextData->activityLogger()->log("{{interface_name}}.{{property_name}}", 1, &loggerArg[0], "{{access_type}}"); |
+ } |
+{% endif %} |
+{% if access_type == "Getter" %} |
+ V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext()); |
+ if (contextData && contextData->activityLogger()) |
+ contextData->activityLogger()->log("{{interface_name}}.{{property_name}}", 0, 0, "{{access_type}}"); |
+{% endif %} |
+{%- endmacro %} |
+ |
+ |
+{##############################################################################} |
+{# user: replaceable attr setter, normal attr setter, normal attr setter callback, function #} |
+{% macro custom_element_invocation(custom_element_invocation_scope) %} |
+{% if custom_element_invocation_scope %} |
+ CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro method(function, for_main_world_suffix) %} |
+{% if function.conditional_string %} |
+#if {{function.conditional_string}} |
+{% endif %} |
+static void {{function.name}}Method{{for_main_world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& args) |
+{ |
+{% if function.mandatory_parameters %} |
+ if (args.Length() < {{function.mandatory_parameters}}) { |
+ throwNotEnoughArgumentsError(args.GetIsolate()); |
+ return; |
+ } |
+{% endif %} |
+{###################### Get imp #} |
+{% if not function.is_static %} |
+ {{cpp_class_name}}* imp = {{v8_class_name}}::toNative(args.Holder()); |
+{% endif %} |
+{{custom_element_invocation(function.custom_element_invocation_scope) -}} |
+{% if function.raises_exception %} |
+ ExceptionState es(args.GetIsolate()); |
+{% endif %} |
+{% if function.check_security_for_node %} |
+ if (!BindingSecurity::shouldAllowAccessToNode(imp->{{function.cpp_name}}(es))) { |
+ v8SetReturnValueNull(args); |
+ return; |
+ } |
+{% endif %} |
+{{parameters_check(function) -}} |
+{{function_call(function.function_call_parameter[for_main_world_suffix]) -}} |
+} |
+ |
+{% if function.conditional_string %} |
+#endif // {{function.conditional_string}} |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro method_callback(function, for_main_world_suffix) %} |
+{% if function.name %} |
+{% if function.conditional_string %} |
+#if {{function.conditional_string}} |
+{% endif %} |
+static void {{function.name}}MethodCallback{{function.for_main_world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& args) |
+{ |
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMMethod"); |
+{{feature_observation(function.measure_as) -}} |
+{{deprecation_notification(function.deprecate_as) -}} |
+{% if for_main_world_suffix in function.activity_logging %} |
+{{activity_logging("Method", function.name)}} |
+{% endif %} |
+{% if function.is_custom %} |
+ {{v8_class_name}}::{{function.name}}MethodCustom(args); |
+{% else %} |
+ {{cpp_class_name}}V8Internal::{{function.name}}Method{{function.for_main_world_suffix}}(args); |
+{% endif %} |
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution"); |
+} |
+ |
+{% if function.conditional_string %} |
+#endif // {{function.conditional_string}} |
+{% endif %} |
+{% endif %} |
+{% endmacro %} |
+ |
+ |
+{##############################################################################} |
+{% macro if_else_statement(type, variable_name, condition_and_statements) %} |
+{% if condition_and_statements | length == 1 %} |
+ {{type}} {{variable_name}} = {{condition_and_statements[0]["statement"]}} |
+{% else %} |
+ {{type}} {{variable_name}}; |
+{% for condition_and_statement in condition_and_statements %} |
+{% if loop.first %} |
+ if{% elif loop.last %} |
+ |
+ else{% else %} |
+ |
+ else if{% endif %} |
+{% if condition_and_statement["condition"] %} ({{condition_and_statement["condition"]}}) |
+{% else %} |
+ |
+{% endif %} |
+ {{variable_name}} = {{condition_and_statement["statement"]}} |
+{%- endfor %} |
+{% endif %} |
+{% endmacro %} |