Bug 38920 - V8 overload support ported to JSC
Summary: V8 overload support ported to JSC
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: 528+ (Nightly build)
Hardware: Other OS X 10.5
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks: 40443
  Show dependency treegraph
 
Reported: 2010-05-11 11:26 PDT by Yaar Schnitman
Modified: 2010-06-10 14:04 PDT (History)
5 users (show)

See Also:


Attachments
Patch (17.44 KB, patch)
2010-05-11 12:14 PDT, Yaar Schnitman
no flags Details | Formatted Diff | Diff
Patch (17.44 KB, patch)
2010-05-12 12:00 PDT, Yaar Schnitman
no flags Details | Formatted Diff | Diff
Patch (16.27 KB, patch)
2010-05-13 09:30 PDT, Yaar Schnitman
no flags Details | Formatted Diff | Diff
Patch (16.25 KB, patch)
2010-05-13 09:37 PDT, Yaar Schnitman
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yaar Schnitman 2010-05-11 11:26:23 PDT
V8 overload support ported to JSC
Comment 1 Yaar Schnitman 2010-05-11 12:14:38 PDT
Created attachment 55732 [details]
Patch
Comment 2 Yaar Schnitman 2010-05-11 12:16:15 PDT
Comment on attachment 55732 [details]
Patch

Please cq+ if ok.
Comment 3 Yaar Schnitman 2010-05-12 12:00:00 PDT
Created attachment 55882 [details]
Patch
Comment 4 Adam Barth 2010-05-12 14:31:38 PDT
Comment on attachment 55882 [details]
Patch

WebCore/bindings/scripts/CodeGenerator.pm:378
 +          $function->{overloadIndex} = @{$nameToFunctionsMap{$name}};
This perl is slightly mysterious to me.

This looks reasonable.  It's a bit of a hack to skip the functions when the overload index is greater than one, but I think that's ok for now.
Comment 5 Sam Weinig 2010-05-12 18:37:19 PDT
Comment on attachment 55882 [details]
Patch

> Index: WebCore/bindings/scripts/test/JS/JSTestObj.cpp
> ===================================================================
> --- WebCore/bindings/scripts/test/JS/JSTestObj.cpp	(revision 59097)
> +++ WebCore/bindings/scripts/test/JS/JSTestObj.cpp	(working copy)
> @@ -133,7 +133,7 @@ bool JSTestObjConstructor::getOwnPropert
>  #define THUNK_GENERATOR(generator)
>  #endif
>  
> -static const HashTableValue JSTestObjPrototypeTableValues[26] =
> +static const HashTableValue JSTestObjPrototypeTableValues[27] =
>  {
>      { "voidMethod", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionVoidMethod), (intptr_t)0 THUNK_GENERATOR(0) },
>      { "voidMethodWithArgs", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionVoidMethodWithArgs), (intptr_t)3 THUNK_GENERATOR(0) },
> @@ -160,6 +160,7 @@ static const HashTableValue JSTestObjPro
>      { "methodWithOptionalArg", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalArg), (intptr_t)1 THUNK_GENERATOR(0) },
>      { "methodWithNonOptionalArgAndOptionalArg", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithNonOptionalArgAndOptionalArg), (intptr_t)2 THUNK_GENERATOR(0) },
>      { "methodWithNonOptionalArgAndTwoOptionalArgs", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithNonOptionalArgAndTwoOptionalArgs), (intptr_t)3 THUNK_GENERATOR(0) },
> +    { "overloadedMethod", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionOverloadedMethod), (intptr_t)2 THUNK_GENERATOR(0) },
>      { 0, 0, 0, 0 THUNK_GENERATOR(0) }
>  };
>  
> @@ -801,6 +802,80 @@ JSValue JSC_HOST_CALL jsTestObjPrototype
>      return jsUndefined();
>  }
>  
> +JSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod1(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
> +{
> +    UNUSED_PARAM(args);
> +    if (!thisValue.inherits(&JSTestObj::s_info))
> +        return throwError(exec, TypeError);
> +    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
> +    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
> +    TestObj* objArg = toTestObj(args.at(0));
> +    const String& strArg = ustringToString(args.at(1).toString(exec));
> +
> +    imp->overloadedMethod(objArg, strArg);
> +    return jsUndefined();
> +}
> +
> +JSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod2(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
> +{
> +    UNUSED_PARAM(args);
> +    if (!thisValue.inherits(&JSTestObj::s_info))
> +        return throwError(exec, TypeError);
> +    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
> +    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
> +    TestObj* objArg = toTestObj(args.at(0));
> +
> +    int argsCount = args.size();
> +    if (argsCount < 2) {
> +        imp->overloadedMethod(objArg);
> +        return jsUndefined();
> +    }
> +
> +    int intArg = args.at(1).toInt32(exec);
> +
> +    imp->overloadedMethod(objArg, intArg);
> +    return jsUndefined();
> +}
> +
> +JSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod3(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
> +{
> +    UNUSED_PARAM(args);
> +    if (!thisValue.inherits(&JSTestObj::s_info))
> +        return throwError(exec, TypeError);
> +    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
> +    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
> +    const String& strArg = ustringToString(args.at(0).toString(exec));
> +
> +    imp->overloadedMethod(strArg);
> +    return jsUndefined();
> +}
> +
> +JSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod4(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
> +{
> +    UNUSED_PARAM(args);
> +    if (!thisValue.inherits(&JSTestObj::s_info))
> +        return throwError(exec, TypeError);
> +    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
> +    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
> +    int intArg = args.at(0).toInt32(exec);
> +
> +    imp->overloadedMethod(intArg);
> +    return jsUndefined();
> +}
> +
> +JSValue JSC_HOST_CALL testObjPrototypeFunctionOverloadedMethod(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
> +{
> +    if ((args.size() == 2 && (args.at(0).isNull() || asObject(args.at(0))->inherits(JSTestObj::s_info) && (args.at(1).isNull() || args.at(1).isUndefined() || args.at(1).isString() || args.at(1).isObject())))
> +        return testObjPrototypeFunctionOverloadedMethod1Callback(args);
> +    if ((args.size() == 1 && (args.at(0).isNull() || asObject(args.at(0))->inherits(JSTestObj::s_info)) || (args.size() == 2 && (args.at(0).isNull() || asObject(args.at(0))->inherits(JSTestObj::s_info)))
> +        return testObjPrototypeFunctionOverloadedMethod2Callback(args);
> +    if ((args.size() == 1 && (args.at(0).isNull() || args.at(0).isUndefined() || args.at(0).isString() || args.at(0).isObject())))
> +        return testObjPrototypeFunctionOverloadedMethod3Callback(args);
> +    if (args.size() == 1)
> +        return testObjPrototypeFunctionOverloadedMethod4Callback(args);
> +    return throwError(exec, TypeError);
> +}
> +
>  JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, TestObj* object)
>  {


It is possible I am reading this wrong, but where are the implementations of testObjPrototypeFunctionOverloadedMethod1Callback and friends.  Are they supposed to be called jsTestObjPrototypeFunctionOverloadedMethod1 and friends. Are they supposed to take more parameters?  Can we optimize the if statement in this function so it does not do the same work multiple times (calling things like inherits)?
Comment 6 Yaar Schnitman 2010-05-12 18:55:43 PDT
(In reply to comment #5)
> It is possible I am reading this wrong, but where are the implementations of testObjPrototypeFunctionOverloadedMethod1Callback and friends.  
Nice catch. This slipped in from V8. I'll fix that. I would have probably caught that once I turned on some of the overloads in the IDLs.

> Can we optimize the if statement in this function so it does not do the same work multiple times (calling things like inherits)?
This can probably be done, but its very hard and with significant added complexity to the generator. In real use cases (WebGL, Canvas and XHR overloads), the primary determinant is the length of the args vector, and therefore only a small portion of the if statements are actually passed through. Also, in these overrides, the overhead of override selection is dwarfed by what these overrides usually do (e.g. copy large arrays). Therefore such an optimization won't have a big impact.
Comment 7 Sam Weinig 2010-05-12 19:05:11 PDT
Comment on attachment 55882 [details]
Patch

r-ing now that I know it is wrong.  I will look at making it a bit smarter in the future I guess.
Comment 8 Yaar Schnitman 2010-05-13 09:30:14 PDT
Created attachment 55988 [details]
Patch
Comment 9 Yaar Schnitman 2010-05-13 09:37:18 PDT
Created attachment 55989 [details]
Patch
Comment 10 Yaar Schnitman 2010-05-13 09:43:42 PDT
Comment on attachment 55989 [details]
Patch

Fixed method names. Please cq+ if ok.
Comment 11 Adam Barth 2010-05-14 11:44:26 PDT
Comment on attachment 55989 [details]
Patch

Thanks!
Comment 12 Yaar Schnitman 2010-05-14 12:16:19 PDT
Thank you too!
Comment 13 WebKit Commit Bot 2010-05-15 03:15:03 PDT
Comment on attachment 55989 [details]
Patch

Clearing flags on attachment: 55989

Committed r59533: <http://trac.webkit.org/changeset/59533>
Comment 14 WebKit Commit Bot 2010-05-15 03:15:10 PDT
All reviewed patches have been landed.  Closing bug.
Comment 15 WebKit Review Bot 2010-05-15 04:09:44 PDT
http://trac.webkit.org/changeset/59533 might have broken GTK Linux 32-bit Release
The following changes are on the blame list:
http://trac.webkit.org/changeset/59530
http://trac.webkit.org/changeset/59531
http://trac.webkit.org/changeset/59532
http://trac.webkit.org/changeset/59533