# HG changeset patch # User Jaroslav Tulach # Date 1469089560 -7200 # Node ID d8f27be841711125f1912568d46f1d6a35fa1fd1 # Parent 031e46d048d8b9bf260bd5eae23ba852fe6675f8# Parent 86f56d4643571e2b1c85660d16636ab63a121292 Merging boot-truffle into main development branch diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/pom.xml Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,139 @@ + + + 4.0.0 + + org.netbeans.html + pom + 2.0-SNAPSHOT + + Presenter via Truffle + net.java.html.boot.truffle + 2.0-SNAPSHOT + bundle + + NONE + net.java.html.boot.truffle + ${java.home}/language/js/trufflejs.jar + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${publicPackages} + net.java.html.boot.truffle + + + + + org.netbeans.html + html4j-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + + + + + + + org.netbeans.api + org-openide-util-lookup + provided + + + com.oracle.truffle + truffle-api + 0.15 + + + com.oracle.truffle + truffle-dsl-processor + 0.15 + provided + + + org.netbeans.html + net.java.html.boot + ${project.version} + jar + + + org.testng + testng + test + + + ${project.groupId} + net.java.html.json.tck + ${project.version} + test + + + org.glassfish.grizzly + grizzly-http-server + ${grizzly.version} + test + + + org.glassfish.grizzly + grizzly-websockets-server + ${grizzly.version} + test + jar + + + org.glassfish.grizzly + grizzly-http-servlet + ${grizzly.version} + test + + + javax.servlet + javax.servlet-api + test + 3.1.0 + + + org.netbeans.html + ko4j + ${project.version} + test + jar + + + ${project.groupId} + ko-ws-tyrus + ${project.version} + test + jar + + + + + graalvm + + + ${trufflejs} + + + + + com.oracle.graaljs + truffle-js + 0.07 + ${trufflejs} + system + + + + + diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/FnRootNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/FnRootNode.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,80 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.InteropException; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; + +final class FnRootNode extends RootNode { + @Child + private Node execute; + private final TruffleObject fn; + + FnRootNode(TruffleObject fn, int arity) { + super(TruffleLanguage.class, null, null); + // one more argument for this + this.execute = Message.createExecute(arity + 1).createNode(); + this.fn = fn; + } + + @Override + public Object execute(VirtualFrame frame) { + try { + final Object[] args = frame.getArguments(); + Object result = ForeignAccess.sendExecute(execute, frame, fn, args); + return result; + } catch (InteropException ex) { + throw raise(RuntimeException.class, ex); + } + } + + private static E raise(Class castTo, Throwable t) throws E { + throw (E)t; + } +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/IsArrayNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/IsArrayNode.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,68 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; + +final class IsArrayNode extends RootNode { + @Child + private Node check; + + IsArrayNode() { + super(TruffleLanguage.class, null, null); + this.check = Message.HAS_SIZE.createNode(); + } + + @Override + public Object execute(VirtualFrame frame) { + final Object[] args = frame.getArguments(); + Object result = ForeignAccess.sendHasSize(check, frame, (TruffleObject) args[0]); + return result; + } +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/IsNullNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/IsNullNode.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,68 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; + +final class IsNullNode extends RootNode { + @Child + private Node check; + + IsNullNode() { + super(TruffleLanguage.class, null, null); + this.check = Message.IS_NULL.createNode(); + } + + @Override + public Object execute(VirtualFrame frame) { + final Object[] args = frame.getArguments(); + Object result = ForeignAccess.sendIsNull(check, frame, (TruffleObject) args[0]); + return result; + } +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/JavaArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/JavaArray.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,102 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import java.lang.reflect.Array; + +@MessageResolution(receiverType = JavaArray.class, language = TrufflePresenter.JavaLang.class) +final class JavaArray extends JavaValue implements TruffleObject { + final TrufflePresenter.WrapArray wrap; + final Object arr; + + public JavaArray(TrufflePresenter.WrapArray wrap, Object arr) { + this.arr = arr; + this.wrap = wrap; + } + + @Override + public ForeignAccess getForeignAccess() { + return JavaArrayForeign.ACCESS; + } + + @Override + public Object get() { + return arr; + } + + static boolean isInstance(TruffleObject obj) { + return obj instanceof JavaArray; + } + + static boolean isArray(Object obj) { + return obj != null && obj.getClass().getComponentType() != null; + } + + @Resolve(message = "READ") + static abstract class ReadNode extends Node { + protected Object access(JavaArray arr, int index) { + Object obj = Array.get(arr.arr, index); + return toJavaScript(obj, arr.wrap); + } + } + + @Resolve(message = "HAS_SIZE") + static abstract class HasSizeNode extends Node { + protected boolean access(JavaArray arr) { + return true; + } + } + + @Resolve(message = "GET_SIZE") + static abstract class GetSizeNode extends Node { + protected int access(JavaArray arr) { + return Array.getLength(arr.arr); + } + } + +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/JavaObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/JavaObject.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,82 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; + +@MessageResolution(receiverType = JavaObject.class, language = TrufflePresenter.JavaLang.class) +final class JavaObject extends JavaValue implements TruffleObject { + final Object obj; + + JavaObject(Object obj) { + this.obj = obj; + } + + + @Override + public ForeignAccess getForeignAccess() { + return JavaObjectForeign.ACCESS; + } + + public static boolean isInstance(TruffleObject obj) { + return obj instanceof JavaObject; + } + + @Override + public Object get() { + return obj; + } + + @Resolve(message = "HAS_SIZE") + static abstract class NoSizeNode extends Node { + + protected boolean access(JavaObject obj) { + return false; + } + } + +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/JavaValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/JavaValue.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,91 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.java.JavaInterop; + +abstract class JavaValue { + public abstract Object get(); + + static Object toJavaScript(Object conv, TrufflePresenter.WrapArray wrap) { + if (conv instanceof TruffleObject) { + return conv; + } + if (JavaArray.isArray(conv)) { + conv = wrap.copy(new JavaArray(wrap, conv)); + } + if (conv instanceof Character) { + conv = (int) (Character) conv; + } + if (conv == null || conv.getClass().getSimpleName().equals("$JsCallbacks$")) { // NOI18N + conv = JavaInterop.asTruffleObject(conv); + } else if (!isJSReady(conv)) { + conv = new JavaObject(conv); + } + return conv; + } + + private static boolean isJSReady(Object obj) { + if (obj == null) { + return true; + } + if (obj instanceof String) { + return true; + } + if (obj instanceof Number) { + return true; + } + if (obj instanceof Character) { + return true; + } + if (obj instanceof Boolean) { + return true; + } + if (obj instanceof TruffleObject) { + return true; + } + return false; + } + +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/TrufflePresenter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/TrufflePresenter.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,262 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.java.JavaInterop; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import java.io.Closeable; +import java.io.IOException; +import java.io.Reader; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.boot.spi.Fn.Presenter; + +/** + * Implementation of {@link Presenter} that delegates to Truffle. + * + * @author Jaroslav Tulach + */ +final class TrufflePresenter implements Fn.KeepAlive, + Presenter, Fn.FromJavaScript, Fn.ToJavaScript, Executor { + + private Eval eval; + private WrapArray copy; + private final Executor exc; + private final CallTarget isNull; + private final CallTarget isArray; + + TrufflePresenter(Executor exc, TruffleObject eval) { + this.exc = exc; + this.eval = eval == null ? null : JavaInterop.asJavaFunction(Eval.class, eval); + this.isNull = Truffle.getRuntime().createCallTarget(new IsNullNode()); + this.isArray = Truffle.getRuntime().createCallTarget(new IsArrayNode()); + } + + @Override + public Fn defineFn(String code, String... names) { + return defineImpl(code, names, null); + } + + @Override + public Fn defineFn(String code, String[] names, boolean[] keepAlive) { + return defineImpl(code, names, keepAlive); + } + + private FnImpl defineImpl(String code, String[] names, boolean[] keepAlive) { + StringBuilder sb = new StringBuilder(); + sb.append("(function() {\n"); + sb.append(" return function("); + String sep = ""; + for (String n : names) { + sb.append(sep).append(n); + sep = ","; + } + sb.append(") {\n"); + sb.append(code); + sb.append("\n };\n"); + sb.append("})()\n"); + + TruffleObject fn = (TruffleObject) getEval().eval(sb.toString()); + return new FnImpl(this, fn, names.length); + } + + @Override + public void displayPage(URL page, Runnable onPageLoad) { + if (onPageLoad != null) { + onPageLoad.run(); + } + } + + @Override + public void loadScript(Reader code) throws Exception { + Source src = Source.newBuilder(code). + name("unknown.js"). + mimeType("text/javascript"). + build(); + getEval().eval(src.getCode()); + } + + interface WrapArray { + public Object copy(Object arr); + } + + interface Eval { + public Object eval(String code); + } + + final Object checkArray(Object val) throws Exception { + if (val instanceof TruffleObject) { + final TruffleObject truffleObj = (TruffleObject)val; + boolean hasSize = (boolean) isArray.call(truffleObj); + if (hasSize) { + List list = JavaInterop.asJavaObject(List.class, truffleObj); + Object[] arr = list.toArray(); + for (int i = 0; i < arr.length; i++) { + arr[i] = toJava(arr[i]); + } + return arr; + } + } + return val; + } + + @Override + public Object toJava(Object jsArray) { + if (jsArray instanceof JavaValue) { + jsArray = ((JavaValue) jsArray).get(); + } + if (jsArray instanceof TruffleObject) { + boolean checkNull = (boolean) isNull.call(jsArray); + if (checkNull) { + return null; + } + } + try { + return checkArray(jsArray); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + @Override + public Object toJavaScript(Object conv) { + return JavaValue.toJavaScript(conv, getWrap()); + } + + @Override + public void execute(final Runnable command) { + if (Fn.activePresenter() == this) { + command.run(); + return; + } + + class Wrap implements Runnable { + + @Override + public void run() { + try (Closeable c = Fn.activate(TrufflePresenter.this)) { + command.run(); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + } + final Runnable wrap = new Wrap(); + if (exc == null) { + wrap.run(); + } else { + exc.execute(wrap); + } + } + + private Eval getEval() { + if (eval == null) { + try { + PolyglotEngine engine = PolyglotEngine.newBuilder().build(); + TruffleObject fn = (TruffleObject) engine.eval( + Source.newBuilder("eval.bind(this)"). + mimeType("text/javascript"). + name("eval.js").build() + ).get(); + eval = JavaInterop.asJavaFunction(Eval.class, fn); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + return eval; + } + + private WrapArray getWrap() { + if (copy == null) { + TruffleObject fn = (TruffleObject) getEval().eval("(function(arr) {\n" + + " var n = [];\n" + + " for (var i = 0; i < arr.length; i++) {\n" + + " n[i] = arr[i];\n" + + " }\n" + + " return n;\n" + + "}).bind(this)" + ); + copy = JavaInterop.asJavaFunction(WrapArray.class, fn); + } + return copy; + } + + private class FnImpl extends Fn { + + private final CallTarget fn; + + public FnImpl(Presenter presenter, TruffleObject fn, int arity) { + super(presenter); + this.fn = Truffle.getRuntime().createCallTarget(new FnRootNode(fn, arity)); + } + + @Override + public Object invoke(Object thiz, Object... args) throws Exception { + List all = new ArrayList<>(args.length + 1); + all.add(thiz == null ? fn : toJavaScript(thiz)); + for (Object conv : args) { + conv = toJavaScript(conv); + all.add(conv); + } + Object ret = fn.call(all.toArray()); + if (ret instanceof JavaValue) { + ret = ((JavaValue)ret).get(); + } + if (ret == fn) { + return null; + } + return toJava(ret); + } + } + + static abstract class JavaLang extends TruffleLanguage { + } +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/main/java/net/java/html/boot/truffle/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/main/java/net/java/html/boot/truffle/package.html Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,51 @@ + + +

+ Integration with Truffle + useful to execute against node.js running on top of + the GraalVM. +

+ diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/test/java/net/java/html/boot/truffle/SingleCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/test/java/net/java/html/boot/truffle/SingleCase.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,127 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.boot.impl.FnContext; +import org.testng.IHookCallBack; +import org.testng.IHookable; +import org.testng.ITest; +import org.testng.ITestResult; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public final class SingleCase implements ITest, IHookable, Runnable { + static final Executor JS = Executors.newSingleThreadExecutor(); + private final Fn.Presenter p; + private final Method m; + private Object result; + private Object inst; + + SingleCase(Fn.Presenter p, Method m) { + this.p = p; + this.m = m; + } + + @Override + public String getTestName() { + return m.getName(); + } + + @Test + public synchronized void executeTest() throws Exception { + if (result == null) { + JS.execute(this); + wait(); + } + if (result instanceof Exception) { + throw (Exception)result; + } + if (result instanceof Error) { + throw (Error)result; + } + } + + @Override + public synchronized void run() { + boolean notify = true; + try { + FnContext.currentPresenter(p); + if (inst == null) { + inst = m.getDeclaringClass().newInstance(); + } + result = m.invoke(inst); + if (result == null) { + result = this; + } + } catch (InvocationTargetException ex) { + Throwable r = ex.getTargetException(); + if (r instanceof InterruptedException) { + notify = false; + JS.execute(this); + return; + } + result = r; + } catch (Exception ex) { + result = ex; + } finally { + if (notify) { + notifyAll(); + } + FnContext.currentPresenter(null); + } + } + + @Override + public void run(IHookCallBack ihcb, ITestResult itr) { + ihcb.runTestMethod(itr); + } + +} diff -r 031e46d048d8 -r d8f27be84171 boot-truffle/src/test/java/net/java/html/boot/truffle/TruffleJavaScriptTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boot-truffle/src/test/java/net/java/html/boot/truffle/TruffleJavaScriptTest.java Thu Jul 21 10:26:00 2016 +0200 @@ -0,0 +1,156 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.truffle; + +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.PolyglotEngine; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import net.java.html.boot.BrowserBuilder; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.json.tck.JavaScriptTCK; +import org.netbeans.html.json.tck.KOTest; +import org.testng.Assert; +import static org.testng.Assert.assertEquals; +import org.testng.SkipException; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class TruffleJavaScriptTest { + private static Class browserClass; + private static Fn.Presenter browserPresenter; + + public TruffleJavaScriptTest() { + } + + @Factory public static Object[] compatibilityTests() throws Exception { + PolyglotEngine engine = PolyglotEngine.newBuilder().build(); + PolyglotEngine.Value result = null; + try { + result = engine.eval(Source.fromText("6 * 7", "test.js").withMimeType("text/javascript")); + } catch (Exception notSupported) { + if (notSupported.getMessage().contains("text/javascript")) { + return new Object[] { new SkipTest(notSupported.getMessage()) }; + } + } + assertEquals(42, result.as(Number.class).intValue(), "Executed OK"); + + final BrowserBuilder bb = BrowserBuilder.newBrowser(new TrufflePresenter(SingleCase.JS, null)). + loadClass(TruffleJavaScriptTest.class). + loadPage("empty.html"). + invoke("initialized"); + + Executors.newSingleThreadExecutor().submit(new Runnable() { + @Override + public void run() { + bb.showAndWait(); + } + }); + + List res = new ArrayList<>(); + Class test = + loadClass().getClassLoader().loadClass(KOTest.class.getName()). + asSubclass(Annotation.class); + + Class[] arr = (Class[]) loadClass().getDeclaredMethod("tests").invoke(null); + for (Class c : arr) { + if (c.getSimpleName().contains("GC")) { + continue; + } + for (Method m : c.getMethods()) { + if (m.getAnnotation(test) != null) { + res.add(new SingleCase(browserPresenter, m)); + } + } + } + return res.toArray(); + } + + static synchronized Class loadClass() throws InterruptedException { + while (browserClass == null) { + TruffleJavaScriptTest.class.wait(); + } + return browserClass; + } + + public static synchronized void ready(Class browserCls) throws Exception { + browserClass = browserCls; + browserPresenter = Fn.activePresenter(); + TruffleJavaScriptTest.class.notifyAll(); + } + + public static void initialized() throws Exception { + Assert.assertSame(TruffleJavaScriptTest.class.getClassLoader(), + ClassLoader.getSystemClassLoader(), + "No special classloaders" + ); + TruffleJavaScriptTest.ready(Tck.class); + } + + public static final class Tck extends JavaScriptTCK { + + public static Class[] tests() { + return testClasses(); + } + } + + public static class SkipTest { + private final String message; + + public SkipTest(String message) { + this.message = message; + } + + @Test + public void needsGraalVMToExecuteTheTests() { + throw new SkipException(message); + } + } +} diff -r 031e46d048d8 -r d8f27be84171 pom.xml --- a/pom.xml Fri Jul 15 19:12:50 2016 +0200 +++ b/pom.xml Thu Jul 21 10:26:00 2016 +0200 @@ -35,6 +35,7 @@ ko-osgi-test equinox-agentclass-hook boot-script + boot-truffle boot-agent-test xhr4j