Changeset 146840 in webkit


Ignore:
Timestamp:
Mar 25, 2013 7:35:54 PM (11 years ago)
Author:
timothy@apple.com
Message:

Make the Web Inspector console work in strict mode with JavaScriptCore.

https://webkit.org/b/65829
rdar://problem/11271238

Reviewed by Oliver Hunt.

Source/WebCore:

  • bindings/js/JSInjectedScriptHostCustom.cpp:

(WebCore::JSInjectedScriptHost::evaluate):
Return the evalFunction directly.

  • inspector/InjectedScriptHost.h:

(WebCore::InjectedScriptHost::evaluateReturnsEvalFunction):
Added. Return true on JSC and false on V8.

  • inspector/InjectedScriptHost.idl:

Added evaluateReturnsEvalFunction and change evaluate to an attribute on JSC.

  • inspector/InjectedScriptSource.js:

(InjectedScript.prototype._evaluateOn): Change from using 'with' statements to creating
a closure that evaluates the expression. The command line APIs are passed as parameters
to the closure so they are in scope but not injected. This allows the code evaluated in
the console to stay in strict mode (if is was already set), or to get strict mode by
prefixing expressions with 'use strict';.

LayoutTests:

  • inspector/debugger/mutation-observer-suspend-while-paused.html: Tweaked.
  • inspector/console/command-line-api-expected.txt: Updated.
  • platform/mac/http/tests/inspector/console-resource-errors-expected.txt: Added.
  • platform/mac/http/tests/inspector/console-websocket-error-expected.txt: Updated.
  • platform/mac/inspector/console/console-eval-syntax-error-expected.txt: Added.
  • platform/mac/inspector/debugger/debugger-pause-in-eval-script-expected.txt: Added.
  • platform/mac/inspector/extensions/extensions-eval-expected.txt: Added.

Added new expectations to match the new console evaluate approach.

Location:
trunk
Files:
5 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r146839 r146840  
     12013-03-25  Timothy Hatcher  <timothy@apple.com>
     2
     3        Make the Web Inspector console work in strict mode with JavaScriptCore.
     4
     5        https://webkit.org/b/65829
     6        rdar://problem/11271238
     7
     8        Reviewed by Oliver Hunt.
     9
     10        * inspector/debugger/mutation-observer-suspend-while-paused.html: Tweaked.
     11        * inspector/console/command-line-api-expected.txt: Updated.
     12
     13        * platform/mac/http/tests/inspector/console-resource-errors-expected.txt: Added.
     14        * platform/mac/http/tests/inspector/console-websocket-error-expected.txt: Updated.
     15        * platform/mac/inspector/console/console-eval-syntax-error-expected.txt: Added.
     16        * platform/mac/inspector/debugger/debugger-pause-in-eval-script-expected.txt: Added.
     17        * platform/mac/inspector/extensions/extensions-eval-expected.txt: Added.
     18        Added new expectations to match the new console evaluate approach.
     19
    1202013-03-25  James Robinson  <jamesr@chromium.org>
    221
  • trunk/LayoutTests/inspector/console/command-line-api-expected.txt

    r144950 r146840  
    1 CONSOLE MESSAGE: line 1182: The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $("#%s")
     1CONSOLE MESSAGE: line 1222: The console function $() has changed from $=getElementById(id) to $=querySelector(selector). You might try $("#%s")
    22Tests that command line api works.
    33
  • trunk/LayoutTests/inspector/debugger/mutation-observer-suspend-while-paused.html

    r138754 r146840  
    88{
    99    var setup =
    10         "var div = document.createElement('div');\n" +
    11         "var deliveryCount = 0;\n" +
     10        "window.testDiv = document.createElement('div');\n" +
     11        "window.deliveryCount = 0;\n" +
    1212        "var observer = new WebKitMutationObserver(function(records) {\n" +
    13         "    deliveryCount++;\n" +
     13        "    window.deliveryCount++;\n" +
    1414        "});\n" +
    15         "observer.observe(div, { attributes: true });";
     15        "observer.observe(window.testDiv, { attributes: true });";
    1616   
    1717    var mutateAndPause =
    1818        "function mutateAndPause() {\n" +
    19         "    div.setAttribute('foo', 'baz');\n" +
     19        "    window.testDiv.setAttribute('foo', 'baz');\n" +
    2020        "    debugger;\n" +
    2121        "};\n" +
     
    3434    function step2()
    3535    {
    36         InspectorTest.evaluateInConsole("div.setAttribute('foo', 'bar')", function() {
     36        InspectorTest.evaluateInConsole("window.testDiv.setAttribute('foo', 'bar')", function() {
    3737            InspectorTest.addResult("setAttribute should have triggered delivery.");
    3838            InspectorTest.evaluateInConsoleAndDump("deliveryCount", step3);
  • trunk/LayoutTests/platform/mac/http/tests/inspector/console-websocket-error-expected.txt

    r133351 r146840  
    88
    99testDNSLookup: Test started. console-websocket-error.html:32
    10 WebSocket network error: The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 2.) ws://nonexistent.domain.invalid/
     10WebSocket network error: The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 2.) http://127.0.0.1:8000/inspector/console-websocket-error.html
    1111testDNSLookup: onclose is called. console-websocket-error.html:43
    1212testSSLCertificate: Test started. console-websocket-error.html:50
    13 WebSocket network error: OSStatus Error -9807: Invalid certificate chain  wss://127.0.0.1:8443/
     13WebSocket network error: OSStatus Error -9807: Invalid certificate chain  http://127.0.0.1:8000/inspector/console-websocket-error.html
    1414testSSLCertificate: onclose is called. console-websocket-error.html:64
    1515
  • trunk/Source/WebCore/ChangeLog

    r146835 r146840  
     12013-03-25  Timothy Hatcher  <timothy@apple.com>
     2
     3        Make the Web Inspector console work in strict mode with JavaScriptCore.
     4
     5        https://webkit.org/b/65829
     6        rdar://problem/11271238
     7
     8        Reviewed by Oliver Hunt.
     9
     10        * bindings/js/JSInjectedScriptHostCustom.cpp:
     11        (WebCore::JSInjectedScriptHost::evaluate):
     12        Return the evalFunction directly.
     13
     14        * inspector/InjectedScriptHost.h:
     15        (WebCore::InjectedScriptHost::evaluateReturnsEvalFunction):
     16        Added. Return true on JSC and false on V8.
     17
     18        * inspector/InjectedScriptHost.idl:
     19        Added evaluateReturnsEvalFunction and change evaluate to an attribute on JSC.
     20
     21        * inspector/InjectedScriptSource.js:
     22        (InjectedScript.prototype._evaluateOn): Change from using 'with' statements to creating
     23        a closure that evaluates the expression. The command line APIs are passed as parameters
     24        to the closure so they are in scope but not injected. This allows the code evaluated in
     25        the console to stay in strict mode (if is was already set), or to get strict mode by
     26        prefixing expressions with 'use strict';.
     27
    1282013-03-25  Tony Chang  <tony@chromium.org>
    229
  • trunk/Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp

    r144950 r146840  
    286286}
    287287
    288 JSValue JSInjectedScriptHost::evaluate(ExecState* exec)
    289 {
    290     JSValue expression = exec->argument(0);
    291     if (!expression.isString())
    292         return throwError(exec, createError(exec, "String argument expected."));
     288JSValue JSInjectedScriptHost::evaluate(ExecState* exec) const
     289{
    293290    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    294     JSFunction* evalFunction = globalObject->evalFunction();
    295     CallData callData;
    296     CallType callType = evalFunction->methodTable()->getCallData(evalFunction, callData);
    297     if (callType == CallTypeNone)
    298         return jsUndefined();
    299     MarkedArgumentBuffer args;
    300     args.append(expression);
    301 
    302     bool wasEvalEnabled = globalObject->evalEnabled();
    303     globalObject->setEvalEnabled(true);
    304     JSValue result = JSC::call(exec, evalFunction, callType, callData, exec->globalThisValue(), args);
    305     globalObject->setEvalEnabled(wasEvalEnabled);
    306 
    307     return result;
     291    return globalObject->evalFunction();
    308292}
    309293
  • trunk/Source/WebCore/inspector/InjectedScriptHost.h

    r144950 r146840  
    105105    void getEventListenersImpl(Node*, Vector<EventListenerInfo>& listenersArray);
    106106
     107    // FIXME: Remove evaluateReturnsEvalFunction once InjectedScriptHost returns eval in evaluate on V8. https://webkit.org/b/113134
     108#if USE(JSC)
     109    bool evaluateReturnsEvalFunction() { return true; }
     110#else
     111    bool evaluateReturnsEvalFunction() { return false; }
     112#endif
     113
    107114    void clearConsoleMessages();
    108115    void copyText(const String& text);
  • trunk/Source/WebCore/inspector/InjectedScriptHost.idl

    r144950 r146840  
    4747    [Custom] Array getEventListeners(in Node node);
    4848
     49    // FIXME: Remove evaluateReturnsEvalFunction once InjectedScriptHost returns eval in evaluate on V8. https://webkit.org/b/113134
     50    readonly attribute boolean evaluateReturnsEvalFunction;
     51
     52#if defined(V8_BINDING) && V8_BINDING
     53    [Custom] any evaluate(in DOMString text);
     54#else
     55    [Custom] readonly attribute any evaluate;
     56#endif
     57
    4958    [Custom] DOMString databaseId(in any database);
    5059    [Custom] DOMString storageId(in any storage);
    51     [Custom] any evaluate(in DOMString text);
     60
    5261    // Only declarative scope (local, with and catch) is accepted. Returns undefined.
    5362    [Custom] any setFunctionVariableValue(in any functionObject, in int scopeIndex, in DOMString variableName, any newValue);
  • trunk/Source/WebCore/inspector/InjectedScriptSource.js

    r146757 r146840  
    551551    _evaluateOn: function(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI)
    552552    {
     553        if (InjectedScriptHost.evaluateReturnsEvalFunction) {
     554            // We can only use this approach if the evaluate function is the true 'eval'. That allows us to use it with
     555            // the 'eval' identifier when calling it. Using 'eval' grants access to the local scope of the closure we
     556            // create that provides the command line APIs.
     557
     558            var thisObject = isEvalOnCallFrame ? object : null;
     559            var parameters = [InjectedScriptHost.evaluate, expression];
     560
     561            if (injectCommandLineAPI) {
     562                // To avoid using a 'with' statement (which fails in strict mode and requires injecting the API object)
     563                // we instead create a closure where we evaluate the expression. The command line APIs are passed as
     564                // parameters to the closure so they are in scope but not injected. This allows the code evaluated in
     565                // the console to stay in strict mode (if is was already set), or to get strict mode by prefixing
     566                // expressions with 'use strict';.
     567
     568                var commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, thisObject);
     569                var parameterNames = Object.getOwnPropertyNames(commandLineAPI);
     570
     571                for (var i = 0; i < parameterNames.length; ++i)
     572                    parameters.push(commandLineAPI[parameterNames[i]]);
     573
     574                var expressionFunctionString = "(function(eval, __currentExpression, " + parameterNames.join(", ") + ") { return eval(__currentExpression); })";
     575            } else {
     576                // Use a closure in this case too to keep the same behavior of 'var' being captured by the closure instead
     577                // of leaking out into the calling scope.
     578
     579                var expressionFunctionString = "(function(eval, __currentExpression) { return eval(__currentExpression); })";
     580            }
     581
     582            var expressionFunction = evalFunction.call(thisObject, expressionFunctionString);
     583            var result = expressionFunction.apply(thisObject, parameters);
     584
     585            if (objectGroup === "console")
     586                this._lastResult = result;
     587
     588            return result;
     589        }
     590
     591        // FIXME: This code path should be removed once V8 also returns 'eval' as the evaluate function. See: https://webkit.org/b/113134
     592
    553593        // Only install command line api object for the time of evaluation.
    554594        // Surround the expression in with statements to inject our command line API so that
Note: See TracChangeset for help on using the changeset viewer.