8067136: BrowserJSObjectLinker does not handle call on JSObjects

Wed, 10 Dec 2014 19:42:01 +0530

author
sundar
date
Wed, 10 Dec 2014 19:42:01 +0530
changeset 1120
abee60d8d469
parent 1119
0172b56c9f4d
child 1121
403f4402f8d2

8067136: BrowserJSObjectLinker does not handle call on JSObjects
Reviewed-by: attila, hannesw, lagergren

samples/browser_dom.js file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8067136.js file | annotate | diff | comparison | revisions
test/script/basic/JDK-8067136.js.EXPECTED file | annotate | diff | comparison | revisions
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/samples/browser_dom.js	Wed Dec 10 19:42:01 2014 +0530
     1.3 @@ -0,0 +1,91 @@
     1.4 +#// Usage: jjs -fx browser.js
     1.5 +
     1.6 +/*
     1.7 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     1.8 + *
     1.9 + * Redistribution and use in source and binary forms, with or without
    1.10 + * modification, are permitted provided that the following conditions
    1.11 + * are met:
    1.12 + *
    1.13 + *   - Redistributions of source code must retain the above copyright
    1.14 + *     notice, this list of conditions and the following disclaimer.
    1.15 + *
    1.16 + *   - Redistributions in binary form must reproduce the above copyright
    1.17 + *     notice, this list of conditions and the following disclaimer in the
    1.18 + *     documentation and/or other materials provided with the distribution.
    1.19 + *
    1.20 + *   - Neither the name of Oracle nor the names of its
    1.21 + *     contributors may be used to endorse or promote products derived
    1.22 + *     from this software without specific prior written permission.
    1.23 + *
    1.24 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
    1.25 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    1.26 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.27 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    1.28 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    1.29 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    1.30 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    1.31 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    1.32 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    1.33 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    1.34 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.35 + */
    1.36 +
    1.37 +if (!$OPTIONS._fx) {
    1.38 +    print("Usage: jjs -fx browser.js");
    1.39 +    exit(1);
    1.40 +}
    1.41 +
    1.42 +// JavaFX classes used
    1.43 +var ChangeListener = Java.type("javafx.beans.value.ChangeListener");
    1.44 +var Scene     = Java.type("javafx.scene.Scene");
    1.45 +var WebView   = Java.type("javafx.scene.web.WebView");
    1.46 +var EventListener = Java.type("org.w3c.dom.events.EventListener");
    1.47 +
    1.48 +// JavaFX start method
    1.49 +function start(stage) {
    1.50 +    start.title = "Web View";
    1.51 +    var wv = new WebView();
    1.52 +    wv.engine.loadContent(<<EOF
    1.53 +<html>
    1.54 +<head>
    1.55 +<title>
    1.56 +This is the title
    1.57 +</title>
    1.58 +<script>
    1.59 +// click count for OK button
    1.60 +var okCount = 0;
    1.61 +</script>
    1.62 +</head>
    1.63 +<body>
    1.64 +Button from the input html<br>
    1.65 +<button type="button" onclick="okCount++">OK</button><br>
    1.66 +</body>
    1.67 +</html>
    1.68 +EOF, "text/html");
    1.69 +
    1.70 +    // attach onload handler
    1.71 +    wv.engine.loadWorker.stateProperty().addListener(
    1.72 +        new ChangeListener() {
    1.73 +            changed: function() {
    1.74 +               // DOM document element
    1.75 +               var document = wv.engine.document;
    1.76 +               // DOM manipulation
    1.77 +               var btn = document.createElement("button");
    1.78 +               var n = 0;
    1.79 +               // attach a button handler - nashorn function!
    1.80 +               btn.onclick = new EventListener(function() {
    1.81 +                   n++; print("You clicked " + n + " time(s)");
    1.82 +                   print("you clicked OK " + wv.engine.executeScript("okCount"));
    1.83 +               });
    1.84 +               // attach text to button
    1.85 +               var t = document.createTextNode("Click Me!"); 
    1.86 +               btn.appendChild(t);
    1.87 +               // attach button to the document
    1.88 +               document.body.appendChild(btn); 
    1.89 +           }
    1.90 +        }
    1.91 +    );
    1.92 +    stage.scene = new Scene(wv, 750, 500);
    1.93 +    stage.show();
    1.94 +}
     2.1 --- a/src/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java	Tue Dec 09 13:15:27 2014 -0800
     2.2 +++ b/src/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java	Wed Dec 10 19:42:01 2014 +0530
     2.3 @@ -29,6 +29,7 @@
     2.4  import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_GETSLOT;
     2.5  import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_SETMEMBER;
     2.6  import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_SETSLOT;
     2.7 +import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_CALL;
     2.8  import java.lang.invoke.MethodHandle;
     2.9  import java.lang.invoke.MethodHandles;
    2.10  import jdk.internal.dynalink.CallSiteDescriptor;
    2.11 @@ -123,6 +124,8 @@
    2.12              case "setProp":
    2.13              case "setElem":
    2.14                  return c > 2 ? findSetMethod(desc) : findSetIndexMethod();
    2.15 +            case "call":
    2.16 +                return findCallMethod(desc);
    2.17              default:
    2.18                  return null;
    2.19          }
    2.20 @@ -148,6 +151,11 @@
    2.21          return new GuardedInvocation(JSOBJECTLINKER_PUT, IS_JSOBJECT_GUARD);
    2.22      }
    2.23  
    2.24 +    private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) {
    2.25 +        final MethodHandle call = MH.insertArguments(JSOBJECT_CALL, 1, "call");
    2.26 +        return new GuardedInvocation(MH.asCollector(call, Object[].class, desc.getMethodType().parameterCount() - 1), IS_JSOBJECT_GUARD);
    2.27 +    }
    2.28 +
    2.29      @SuppressWarnings("unused")
    2.30      private static boolean isJSObject(final Object self) {
    2.31          return jsObjectClass.isInstance(self);
    2.32 @@ -207,6 +215,7 @@
    2.33          static final MethodHandle JSOBJECT_GETSLOT       = findJSObjectMH_V("getSlot", Object.class, int.class).asType(MH.type(Object.class, Object.class, int.class));
    2.34          static final MethodHandle JSOBJECT_SETMEMBER     = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class).asType(MH.type(Void.TYPE, Object.class, String.class, Object.class));
    2.35          static final MethodHandle JSOBJECT_SETSLOT       = findJSObjectMH_V("setSlot", Void.TYPE, int.class, Object.class).asType(MH.type(Void.TYPE, Object.class, int.class, Object.class));
    2.36 +        static final MethodHandle JSOBJECT_CALL          = findJSObjectMH_V("call", Object.class, String.class, Object[].class).asType(MH.type(Object.class, Object.class, String.class, Object[].class));
    2.37  
    2.38          private static MethodHandle findJSObjectMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
    2.39              checkJSObjectClass();
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/script/basic/JDK-8067136.js	Wed Dec 10 19:42:01 2014 +0530
     3.3 @@ -0,0 +1,69 @@
     3.4 +/*
     3.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +/**
    3.28 + * JDK-8067136: BrowserJSObjectLinker does not handle call on JSObjects
    3.29 + *
    3.30 + * @test
    3.31 + * @option -scripting
    3.32 + * @run
    3.33 + */
    3.34 +
    3.35 +// call on netscape.javascript.JSObject
    3.36 +
    3.37 +function main() {
    3.38 +    var JSObject;
    3.39 +    try {
    3.40 +        JSObject = Java.type("netscape.javascript.JSObject");
    3.41 +    } catch (e) {
    3.42 +        if (e instanceof java.lang.ClassNotFoundException) {
    3.43 +            // pass vacuously by emitting the .EXPECTED file content
    3.44 +            var str = readFully(__DIR__ + "JDK-8067136.js.EXPECTED");
    3.45 +            print(str.substring(0, str.length - 1));
    3.46 +            return;
    3.47 +        } else{
    3.48 +            fail("unexpected exception for JSObject", e);
    3.49 +        }
    3.50 +    }
    3.51 +    test(JSObject);
    3.52 +}
    3.53 +
    3.54 +function test(JSObject) {
    3.55 +    var obj = new (Java.extend(JSObject))() {
    3.56 +        getMember: function(name) {
    3.57 +            if (name == "func") {
    3.58 +                return new (Java.extend(JSObject)) {
    3.59 +                    call: function(n) {
    3.60 +                        print("func called");
    3.61 +                    }
    3.62 +                }
    3.63 +            }
    3.64 +            return name.toUpperCase();
    3.65 +        },
    3.66 +
    3.67 +    };
    3.68 +
    3.69 +    obj.func();
    3.70 +}
    3.71 +
    3.72 +main();
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/script/basic/JDK-8067136.js.EXPECTED	Wed Dec 10 19:42:01 2014 +0530
     4.3 @@ -0,0 +1,1 @@
     4.4 +func called

mercurial