Changeset 207328 in webkit


Ignore:
Timestamp:
Oct 13, 2016 11:58:28 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

Binding generated code for private operations should assert for casted-this checks
https://bugs.webkit.org/show_bug.cgi?id=163326

Patch by Youenn Fablet <youenn@apple.com> on 2016-10-13
Reviewed by Darin Adler.

Covered by existing tests.

Private operations are not exposed to user scripts and are only called by built-in scripts or other WebKit-controlled code.
The call sites already ensure that the caller is of the right type so there is no need to do that work twice.

Introducing a casted-this-error Assert mode for casted-this checks, which may be reused for other binding generated code.
Updated binding generator to use that mode for private operations.

  • bindings/js/JSDOMBinding.h:

(WebCore::BindingCaller::callPromiseOperation):
(WebCore::BindingCaller::callOperation):

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateImplementation):

  • bindings/scripts/test/JS/JSTestGlobalObject.cpp:

(WebCore::jsTestGlobalObjectInstanceFunctionTestPrivateFunction):

  • bindings/scripts/test/JS/JSTestObj.cpp:

(WebCore::jsTestObjPrototypeFunctionPrivateMethod):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r207325 r207328  
     12016-10-13  Youenn Fablet  <youenn@apple.com>
     2
     3        Binding generated code for private operations should assert for casted-this checks
     4        https://bugs.webkit.org/show_bug.cgi?id=163326
     5
     6        Reviewed by Darin Adler.
     7
     8        Covered by existing tests.
     9
     10        Private operations are not exposed to user scripts and are only called by built-in scripts or other WebKit-controlled code.
     11        The call sites already ensure that the caller is of the right type so there is no need to do that work twice.
     12
     13        Introducing a casted-this-error Assert mode for casted-this checks, which may be reused for other binding generated code.
     14        Updated binding generator to use that mode for private operations.
     15
     16        * bindings/js/JSDOMBinding.h:
     17        (WebCore::BindingCaller::callPromiseOperation):
     18        (WebCore::BindingCaller::callOperation):
     19        * bindings/scripts/CodeGeneratorJS.pm:
     20        (GenerateImplementation):
     21        * bindings/scripts/test/JS/JSTestGlobalObject.cpp:
     22        (WebCore::jsTestGlobalObjectInstanceFunctionTestPrivateFunction):
     23        * bindings/scripts/test/JS/JSTestObj.cpp:
     24        (WebCore::jsTestObjPrototypeFunctionPrivateMethod):
     25
    1262016-10-13  Carlos Garcia Campos  <cgarcia@igalia.com>
    227
  • trunk/Source/WebCore/bindings/js/JSDOMBinding.h

    r207193 r207328  
    332332
    333333
    334 enum class CastedThisErrorBehavior { Throw, ReturnEarly, RejectPromise };
     334enum class CastedThisErrorBehavior { Throw, ReturnEarly, RejectPromise, Assert };
    335335
    336336template<typename JSClass>
     
    344344    static JSClass* castForOperation(JSC::ExecState&);
    345345
    346     template<PromiseOperationCallerFunction operationCaller>
     346    template<PromiseOperationCallerFunction operationCaller, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::RejectPromise>
    347347    static JSC::EncodedJSValue callPromiseOperation(JSC::ExecState* state, Ref<DeferredPromise>&& promise, const char* operationName)
    348348    {
     
    350350        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
    351351        auto* thisObject = castForOperation(*state);
    352         if (UNLIKELY(!thisObject)) {
     352        if (shouldThrow != CastedThisErrorBehavior::Assert && UNLIKELY(!thisObject)) {
    353353            ASSERT(JSClass::info());
    354354            return rejectPromiseWithThisTypeError(promise.get(), JSClass::info()->className, operationName);
    355355        }
     356        ASSERT(thisObject);
    356357        ASSERT_GC_OBJECT_INHERITS(thisObject, JSClass::info());
    357358        // FIXME: We should refactor the binding generated code to use references for state and thisObject.
     
    365366        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
    366367        auto* thisObject = castForOperation(*state);
    367         if (UNLIKELY(!thisObject)) {
     368        if (shouldThrow != CastedThisErrorBehavior::Assert && UNLIKELY(!thisObject)) {
    368369            ASSERT(JSClass::info());
    369370            if (shouldThrow == CastedThisErrorBehavior::Throw)
     
    372373            return rejectPromiseWithThisTypeError(*state, JSClass::info()->className, operationName);
    373374        }
     375        ASSERT(thisObject);
    374376        ASSERT_GC_OBJECT_INHERITS(thisObject, JSClass::info());
    375377        // FIXME: We should refactor the binding generated code to use references for state and thisObject.
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r207324 r207328  
    36783678                my $methodName = $function->signature->name;
    36793679                if (IsReturningPromise($function) && !$isCustom) {
    3680                     push(@implContent, "    return BindingCaller<$className>::callPromiseOperation<${functionName}Caller>(state, WTFMove(promise), \"${methodName}\");\n");
     3680                    my $templateParameters = "${functionName}Caller";
     3681                    $templateParameters .= ", CastedThisErrorBehavior::Assert" if ($function->signature->extendedAttributes->{PrivateIdentifier} and not $function->signature->extendedAttributes->{PublicIdentifier});
     3682                    push(@implContent, "    return BindingCaller<$className>::callPromiseOperation<${templateParameters}>(state, WTFMove(promise), \"${methodName}\");\n");
    36813683                    push(@implContent, "}\n");
    36823684                    push(@implContent, "\n");
     
    36853687                    my $classParameterType = $className eq "JSEventTarget" ? "JSEventTargetWrapper*" : "${className}*";
    36863688                    my $templateParameters = "${functionName}Caller";
    3687                     # FIXME: We need this specific handling for custom promise-returning functions.
    3688                     # It would be better to have the casted-this code calling the promise-specific code.
    3689                     $templateParameters .= ", CastedThisErrorBehavior::RejectPromise" if IsReturningPromise($function);
     3689                    if ($function->signature->extendedAttributes->{PrivateIdentifier} and not $function->signature->extendedAttributes->{PublicIdentifier}) {
     3690                        $templateParameters .= ", CastedThisErrorBehavior::Assert";
     3691                    } elsif (IsReturningPromise($function)) {
     3692                        # FIXME: We need this specific handling for custom promise-returning functions.
     3693                        # It would be better to have the casted-this code calling the promise-specific code.
     3694                        $templateParameters .= ", CastedThisErrorBehavior::RejectPromise" if IsReturningPromise($function);
     3695                    }
    36903696
    36913697                    push(@implContent, "    return BindingCaller<$className>::callOperation<${templateParameters}>(state, \"${methodName}\");\n");
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp

    r207193 r207328  
    459459EncodedJSValue JSC_HOST_CALL jsTestGlobalObjectInstanceFunctionTestPrivateFunction(ExecState* state)
    460460{
    461     return BindingCaller<JSTestGlobalObject>::callOperation<jsTestGlobalObjectInstanceFunctionTestPrivateFunctionCaller>(state, "testPrivateFunction");
     461    return BindingCaller<JSTestGlobalObject>::callOperation<jsTestGlobalObjectInstanceFunctionTestPrivateFunctionCaller, CastedThisErrorBehavior::Assert>(state, "testPrivateFunction");
    462462}
    463463
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp

    r207324 r207328  
    53535353EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionPrivateMethod(ExecState* state)
    53545354{
    5355     return BindingCaller<JSTestObj>::callOperation<jsTestObjPrototypeFunctionPrivateMethodCaller>(state, "privateMethod");
     5355    return BindingCaller<JSTestObj>::callOperation<jsTestObjPrototypeFunctionPrivateMethodCaller, CastedThisErrorBehavior::Assert>(state, "privateMethod");
    53565356}
    53575357
Note: See TracChangeset for help on using the changeset viewer.