Skip to content
Permalink
Browse files
Support [Custom] for static functions
https://bugs.webkit.org/show_bug.cgi?id=80573

Reviewed by Kentaro Hara.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader): If the function is static, add static qualifier to cpp function.
(GenerateImplementation): Reorganize the function to split out based on the static
attribute, instead of checking for it at every line we output.
    If the function is static and not custom, the listed code should be the code in
the rest of the function that did not have the static check. If it is custom, then
we check the number of arguments, and then call the static impl function directly.
    If the function is not static, all of the "unless ($function->isStatic)" checks
are removed since it is not necessary.

* bindings/scripts/test/TestObj.idl: Added new test case.

* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore):
(WebCore::jsTestObjConstructorFunctionClassMethod2):
* bindings/scripts/test/JS/JSTestObj.h:
(JSTestObj):
(WebCore):
* bindings/scripts/test/ObjC/DOMTestObj.h:
* bindings/scripts/test/ObjC/DOMTestObj.mm:
(-[DOMTestObj classMethod2]):
* bindings/scripts/test/V8/V8TestObj.cpp:
(WebCore::ConfigureV8TestObjTemplate):
* bindings/scripts/test/V8/V8TestObj.h:
(V8TestObj):

Canonical link: https://commits.webkit.org/97830@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@110232 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
qanat committed Mar 9, 2012
1 parent b831c67 commit 510a21a171990a28c15af05d2d037a6fb00413d7
@@ -1,3 +1,36 @@
2012-03-07 Jon Lee <jonlee@apple.com>

Support [Custom] for static functions
https://bugs.webkit.org/show_bug.cgi?id=80573

Reviewed by Kentaro Hara.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader): If the function is static, add static qualifier to cpp function.
(GenerateImplementation): Reorganize the function to split out based on the static
attribute, instead of checking for it at every line we output.
If the function is static and not custom, the listed code should be the code in
the rest of the function that did not have the static check. If it is custom, then
we check the number of arguments, and then call the static impl function directly.
If the function is not static, all of the "unless ($function->isStatic)" checks
are removed since it is not necessary.

* bindings/scripts/test/TestObj.idl: Added new test case.

* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore):
(WebCore::jsTestObjConstructorFunctionClassMethod2):
* bindings/scripts/test/JS/JSTestObj.h:
(JSTestObj):
(WebCore):
* bindings/scripts/test/ObjC/DOMTestObj.h:
* bindings/scripts/test/ObjC/DOMTestObj.mm:
(-[DOMTestObj classMethod2]):
* bindings/scripts/test/V8/V8TestObj.cpp:
(WebCore::ConfigureV8TestObjTemplate):
* bindings/scripts/test/V8/V8TestObj.h:
(V8TestObj):

2012-03-08 Mark Pilgrim <pilgrim@chromium.org>

Collapse ENABLE(BLOB)|ENABLE(FILE_SYSTEM) to just ENABLE(BLOB)
@@ -891,7 +891,7 @@ sub GenerateHeader
my $conditionalString = GenerateConditionalString($function->signature);
push(@headerContent, "#if ${conditionalString}\n") if $conditionalString;
my $functionImplementationName = $function->signature->extendedAttributes->{"ImplementedAs"} || $codeGenerator->WK_lcfirst($function->signature->name);
push(@headerContent, " JSC::JSValue " . $functionImplementationName . "(JSC::ExecState*);\n");
push(@headerContent, " " . ($function->isStatic ? "static " : "") . "JSC::JSValue " . $functionImplementationName . "(JSC::ExecState*);\n");
push(@headerContent, "#endif\n") if $conditionalString;
}
}
@@ -2077,63 +2077,79 @@ sub GenerateImplementation

$implIncludes{"<runtime/Error.h>"} = 1;

if ($interfaceName eq "DOMWindow") {
push(@implContent, " $className* castedThis = toJSDOMWindow(exec->hostThisValue().toThisObject(exec));\n");
push(@implContent, " if (!castedThis)\n");
push(@implContent, " return throwVMTypeError(exec);\n");
} elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) {
push(@implContent, " $className* castedThis = to${className}(exec->hostThisValue().toThisObject(exec));\n");
push(@implContent, " if (!castedThis)\n");
push(@implContent, " return throwVMTypeError(exec);\n");
} elsif (!$function->isStatic) {
push(@implContent, " JSValue thisValue = exec->hostThisValue();\n");
push(@implContent, " if (!thisValue.inherits(&${className}::s_info))\n");
push(@implContent, " return throwVMTypeError(exec);\n");
push(@implContent, " $className* castedThis = static_cast<$className*>(asObject(thisValue));\n");
}

push(@implContent, " ASSERT_GC_OBJECT_INHERITS(castedThis, &${className}::s_info);\n") unless ($function->isStatic);
if ($function->isStatic) {
if ($isCustom) {
GenerateArgumentsCountCheck(\@implContent, $function, $dataNode);
push(@implContent, " return JSValue::encode(${className}::" . $functionImplementationName . "(exec));\n");
} else {
GenerateArgumentsCountCheck(\@implContent, $function, $dataNode);

if ($dataNode->extendedAttributes->{"CheckSecurity"} and
!$function->signature->extendedAttributes->{"DoNotCheckSecurity"} and
!$function->isStatic) {
push(@implContent, " if (!castedThis->allowsAccessFrom(exec))\n");
push(@implContent, " return JSValue::encode(jsUndefined());\n");
}
if (@{$function->raisesExceptions}) {
push(@implContent, " ExceptionCode ec = 0;\n");
}

if ($isCustom) {
push(@implContent, " return JSValue::encode(castedThis->" . $functionImplementationName . "(exec));\n") unless ($function->isStatic);
my $numParameters = @{$function->parameters};
my ($functionString, $dummy) = GenerateParametersCheck(\@implContent, $function, $dataNode, $numParameters, $implClassName, $functionImplementationName, $svgPropertyType, $svgPropertyOrListPropertyType, $svgListPropertyType);
GenerateImplementationFunctionCall($function, $functionString, " ", $svgPropertyType, $implClassName);
}
} else {
push(@implContent, " $implType* impl = static_cast<$implType*>(castedThis->impl());\n") unless ($function->isStatic);
if ($svgPropertyType and !$function->isStatic) {
push(@implContent, " if (impl->role() == AnimValRole) {\n");
push(@implContent, " setDOMException(exec, NO_MODIFICATION_ALLOWED_ERR);\n");
push(@implContent, " return JSValue::encode(jsUndefined());\n");
push(@implContent, " }\n");
push(@implContent, " $svgPropertyType& podImpl = impl->propertyReference();\n");
$implIncludes{"ExceptionCode.h"} = 1;
if ($interfaceName eq "DOMWindow") {
push(@implContent, " $className* castedThis = toJSDOMWindow(exec->hostThisValue().toThisObject(exec));\n");
push(@implContent, " if (!castedThis)\n");
push(@implContent, " return throwVMTypeError(exec);\n");
} elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) {
push(@implContent, " $className* castedThis = to${className}(exec->hostThisValue().toThisObject(exec));\n");
push(@implContent, " if (!castedThis)\n");
push(@implContent, " return throwVMTypeError(exec);\n");
} else {
push(@implContent, " JSValue thisValue = exec->hostThisValue();\n");
push(@implContent, " if (!thisValue.inherits(&${className}::s_info))\n");
push(@implContent, " return throwVMTypeError(exec);\n");
push(@implContent, " $className* castedThis = static_cast<$className*>(asObject(thisValue));\n");
}

GenerateArgumentsCountCheck(\@implContent, $function, $dataNode);
push(@implContent, " ASSERT_GC_OBJECT_INHERITS(castedThis, &${className}::s_info);\n");

if (@{$function->raisesExceptions}) {
push(@implContent, " ExceptionCode ec = 0;\n");
}

if ($function->signature->extendedAttributes->{"CheckSecurityForNode"} and !$function->isStatic) {
push(@implContent, " if (!shouldAllowAccessToNode(exec, impl->" . $function->signature->name . "(" . (@{$function->raisesExceptions} ? "ec" : "") .")))\n");
if ($dataNode->extendedAttributes->{"CheckSecurity"} and
!$function->signature->extendedAttributes->{"DoNotCheckSecurity"}) {
push(@implContent, " if (!castedThis->allowsAccessFrom(exec))\n");
push(@implContent, " return JSValue::encode(jsUndefined());\n");
$implIncludes{"JSDOMBinding.h"} = 1;
}

if ($function->signature->name eq "addEventListener") {
push(@implContent, GenerateEventListenerCall($className, "add"));
} elsif ($function->signature->name eq "removeEventListener") {
push(@implContent, GenerateEventListenerCall($className, "remove"));
if ($isCustom) {
push(@implContent, " return JSValue::encode(castedThis->" . $functionImplementationName . "(exec));\n");
} else {
my $numParameters = @{$function->parameters};
my ($functionString, $dummy) = GenerateParametersCheck(\@implContent, $function, $dataNode, $numParameters, $implClassName, $functionImplementationName, $svgPropertyType, $svgPropertyOrListPropertyType, $svgListPropertyType);
GenerateImplementationFunctionCall($function, $functionString, " ", $svgPropertyType, $implClassName);
push(@implContent, " $implType* impl = static_cast<$implType*>(castedThis->impl());\n");
if ($svgPropertyType) {
push(@implContent, " if (impl->role() == AnimValRole) {\n");
push(@implContent, " setDOMException(exec, NO_MODIFICATION_ALLOWED_ERR);\n");
push(@implContent, " return JSValue::encode(jsUndefined());\n");
push(@implContent, " }\n");
push(@implContent, " $svgPropertyType& podImpl = impl->propertyReference();\n");
$implIncludes{"ExceptionCode.h"} = 1;
}

GenerateArgumentsCountCheck(\@implContent, $function, $dataNode);

if (@{$function->raisesExceptions}) {
push(@implContent, " ExceptionCode ec = 0;\n");
}

if ($function->signature->extendedAttributes->{"CheckSecurityForNode"}) {
push(@implContent, " if (!shouldAllowAccessToNode(exec, impl->" . $function->signature->name . "(" . (@{$function->raisesExceptions} ? "ec" : "") .")))\n");
push(@implContent, " return JSValue::encode(jsUndefined());\n");
$implIncludes{"JSDOMBinding.h"} = 1;
}

if ($function->signature->name eq "addEventListener") {
push(@implContent, GenerateEventListenerCall($className, "add"));
} elsif ($function->signature->name eq "removeEventListener") {
push(@implContent, GenerateEventListenerCall($className, "remove"));
} else {
my $numParameters = @{$function->parameters};
my ($functionString, $dummy) = GenerateParametersCheck(\@implContent, $function, $dataNode, $numParameters, $implClassName, $functionImplementationName, $svgPropertyType, $svgPropertyOrListPropertyType, $svgListPropertyType);
GenerateImplementationFunctionCall($function, $functionString, " ", $svgPropertyType, $implClassName);
}
}
}

@@ -163,6 +163,7 @@ static const HashTableValue JSTestObjConstructorTableValues[] =
{ "CONST_JAVASCRIPT", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCONST_JAVASCRIPT), (intptr_t)0, NoIntrinsic },
{ "classMethod", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestObjConstructorFunctionClassMethod), (intptr_t)0, NoIntrinsic },
{ "classMethodWithOptional", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestObjConstructorFunctionClassMethodWithOptional), (intptr_t)1, NoIntrinsic },
{ "classMethod2", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestObjConstructorFunctionClassMethod2), (intptr_t)1, NoIntrinsic },
#if ENABLE(Condition1)
{ "overloadedMethod1", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestObjConstructorFunctionOverloadedMethod1), (intptr_t)1, NoIntrinsic },
#endif
@@ -2082,6 +2083,13 @@ EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionClassMethodWithOptional
return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionClassMethod2(ExecState* exec)
{
if (exec->argumentCount() < 1)
return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
return JSValue::encode(JSTestObj::classMethod2(exec));
}

#if ENABLE(Condition1)
static EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionOverloadedMethod11(ExecState* exec)
{
@@ -65,6 +65,7 @@ class JSTestObj : public JSDOMWrapper {
// Custom functions
JSC::JSValue customMethod(JSC::ExecState*);
JSC::JSValue customMethodWithArgs(JSC::ExecState*);
static JSC::JSValue classMethod2(JSC::ExecState*);
TestObj* impl() const { return m_impl; }
void releaseImpl() { m_impl->deref(); m_impl = 0; }

@@ -196,6 +197,7 @@ JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionConditionalMethod3(J
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionClassMethod(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionClassMethodWithOptional(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionClassMethod2(JSC::ExecState*);
#if ENABLE(Condition1)
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionOverloadedMethod1(JSC::ExecState*);
#endif
@@ -206,6 +206,7 @@ enum {
#endif
- (void)classMethod;
- (int)classMethodWithOptional:(int)arg;
- (void)classMethod2:(int)arg;
#if ENABLE(Condition1)
- (void)overloadedMethod1:(int)arg;
#endif
@@ -932,6 +932,12 @@ - (int)classMethodWithOptional:(int)arg
return IMPL->classMethodWithOptional(arg);
}

- (void)classMethod2:(int)arg
{
WebCore::JSMainThreadNullState state;
IMPL->classMethod2(arg);
}


#if ENABLE(Condition1)
- (void)overloadedMethod1:(int)arg
@@ -172,9 +172,9 @@ module test {
// Class methods within JavaScript (like what's used for IDBKeyRange).
static void classMethod();
static long classMethodWithOptional(in [Optional] long arg);
[Custom] static void classMethod2(in long arg);

// Static method with conditional on overloaded methods

[Conditional=Condition1] static void overloadedMethod1(in long arg);
[Conditional=Condition1] static void overloadedMethod1(in DOMString type);

@@ -2011,6 +2011,7 @@ static v8::Persistent<v8::FunctionTemplate> ConfigureV8TestObjTemplate(v8::Persi
proto->Set(v8::String::New("methodThatRequiresAllArgsAndThrows"), v8::FunctionTemplate::New(TestObjInternal::methodThatRequiresAllArgsAndThrowsCallback, v8::Handle<v8::Value>(), methodThatRequiresAllArgsAndThrowsSignature));
desc->Set(v8::String::New("classMethod"), v8::FunctionTemplate::New(TestObjInternal::classMethodCallback, v8::Handle<v8::Value>(), v8::Local<v8::Signature>()));
desc->Set(v8::String::New("classMethodWithOptional"), v8::FunctionTemplate::New(TestObjInternal::classMethodWithOptionalCallback, v8::Handle<v8::Value>(), v8::Local<v8::Signature>()));
desc->Set(v8::String::New("classMethod2"), v8::FunctionTemplate::New(V8TestObj::classMethod2Callback, v8::Handle<v8::Value>(), v8::Local<v8::Signature>()));
#if ENABLE(Condition1)
desc->Set(v8::String::New("overloadedMethod1"), v8::FunctionTemplate::New(TestObjInternal::overloadedMethod1Callback, v8::Handle<v8::Value>(), v8::Local<v8::Signature>()));
#endif // ENABLE(Condition1)
@@ -45,6 +45,7 @@ class V8TestObj {
static WrapperTypeInfo info;
static v8::Handle<v8::Value> customMethodCallback(const v8::Arguments&);
static v8::Handle<v8::Value> customMethodWithArgsCallback(const v8::Arguments&);
static v8::Handle<v8::Value> classMethod2Callback(const v8::Arguments&);
static v8::Handle<v8::Value> constructorCallback(const v8::Arguments&);
static v8::Handle<v8::Value> customAttrAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo&);
static void customAttrAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value>, const v8::AccessorInfo&);

0 comments on commit 510a21a

Please sign in to comment.