Merging the !keepAlive behavior into default branch. Seems to work consistently accross FX and script providers.
1.1 --- a/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java Tue Dec 16 21:49:45 2014 +0100
1.2 +++ b/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java Thu Dec 18 03:29:48 2014 +0100
1.3 @@ -46,6 +46,7 @@
1.4 import java.io.Closeable;
1.5 import java.io.IOException;
1.6 import java.io.Reader;
1.7 +import java.lang.ref.WeakReference;
1.8 import java.net.URL;
1.9 import java.util.ArrayList;
1.10 import java.util.Arrays;
1.11 @@ -54,8 +55,6 @@
1.12 import java.util.logging.Level;
1.13 import java.util.logging.Logger;
1.14 import javafx.application.Platform;
1.15 -import javafx.collections.ObservableList;
1.16 -import javafx.scene.Node;
1.17 import javafx.scene.Parent;
1.18 import javafx.scene.layout.BorderPane;
1.19 import javafx.scene.web.WebEngine;
1.20 @@ -67,8 +66,8 @@
1.21 *
1.22 * @author Jaroslav Tulach
1.23 */
1.24 -public abstract class AbstractFXPresenter
1.25 -implements Fn.Presenter, Fn.ToJavaScript, Fn.FromJavaScript, Executor, Cloneable {
1.26 +public abstract class AbstractFXPresenter implements Fn.Presenter,
1.27 +Fn.KeepAlive, Fn.ToJavaScript, Fn.FromJavaScript, Executor, Cloneable {
1.28 static final Logger LOG = Logger.getLogger(FXPresenter.class.getName());
1.29 protected static int cnt;
1.30 protected Runnable onLoad;
1.31 @@ -92,15 +91,22 @@
1.32
1.33 @Override
1.34 public Fn defineFn(String code, String... names) {
1.35 - return defineJSFn(code, names);
1.36 + return defineJSFn(code, names, null);
1.37 + }
1.38 +
1.39 + @Override
1.40 + public Fn defineFn(String code, String[] names, boolean[] keepAlive) {
1.41 + return defineJSFn(code, names, keepAlive);
1.42 }
1.43
1.44 - final JSFn defineJSFn(String code, String... names) {
1.45 +
1.46 +
1.47 + final JSFn defineJSFn(String code, String[] names, boolean[] keepAlive) {
1.48 StringBuilder sb = new StringBuilder();
1.49 sb.append("(function() {");
1.50 sb.append(" return function(");
1.51 String sep = "";
1.52 - for (String n : names) {
1.53 + if (names != null) for (String n : names) {
1.54 sb.append(sep).append(n);
1.55 sep = ",";
1.56 }
1.57 @@ -115,7 +121,7 @@
1.58 );
1.59 }
1.60 JSObject x = (JSObject) engine.executeScript(sb.toString());
1.61 - return new JSFn(this, x, cnt);
1.62 + return new JSFn(this, x, cnt, keepAlive);
1.63 }
1.64
1.65 @Override
1.66 @@ -208,7 +214,7 @@
1.67 + " k.array= function() {"
1.68 + " return Array.prototype.slice.call(arguments);"
1.69 + " };"
1.70 - + " return k;"
1.71 + + " return k;", null, null
1.72 ).invokeImpl(null, false);
1.73 } catch (Exception ex) {
1.74 throw new IllegalStateException(ex);
1.75 @@ -218,6 +224,9 @@
1.76 }
1.77
1.78 final Object checkArray(Object val) {
1.79 + if (!(val instanceof JSObject)) {
1.80 + return val;
1.81 + }
1.82 int length = ((Number) arraySizeFn().call("array", val, null)).intValue();
1.83 if (length == -1) {
1.84 return val;
1.85 @@ -240,7 +249,7 @@
1.86 + " return l;"
1.87 + " }"
1.88 + " };"
1.89 - + " return k;"
1.90 + + " return k;", null, null
1.91 ).invokeImpl(null, false);
1.92 } catch (Exception ex) {
1.93 throw new IllegalStateException(ex);
1.94 @@ -251,6 +260,9 @@
1.95
1.96 @Override
1.97 public Object toJava(Object jsArray) {
1.98 + if (jsArray instanceof Weak) {
1.99 + jsArray = ((Weak)jsArray).get();
1.100 + }
1.101 return checkArray(jsArray);
1.102 }
1.103
1.104 @@ -300,11 +312,13 @@
1.105 private final JSObject fn;
1.106 private static int call;
1.107 private final int id;
1.108 + private final boolean[] keepAlive;
1.109
1.110 - public JSFn(AbstractFXPresenter p, JSObject fn, int id) {
1.111 + public JSFn(AbstractFXPresenter p, JSObject fn, int id, boolean[] keepAlive) {
1.112 super(p);
1.113 this.fn = fn;
1.114 this.id = id;
1.115 + this.keepAlive = keepAlive;
1.116 }
1.117
1.118 @Override
1.119 @@ -322,14 +336,25 @@
1.120 List<Object> all = new ArrayList<Object>(args.length + 1);
1.121 all.add(thiz == null ? fn : thiz);
1.122 for (int i = 0; i < args.length; i++) {
1.123 - if (arrayChecks && args[i] instanceof Object[]) {
1.124 - Object[] arr = (Object[]) args[i];
1.125 - Object conv = ((AbstractFXPresenter)presenter()).convertArrays(arr);
1.126 - args[i] = conv;
1.127 + Object conv = args[i];
1.128 + if (arrayChecks) {
1.129 + if (args[i] instanceof Object[]) {
1.130 + Object[] arr = (Object[]) args[i];
1.131 + conv = ((AbstractFXPresenter)presenter()).convertArrays(arr);
1.132 + }
1.133 + if (conv != null && keepAlive != null &&
1.134 + !keepAlive[i] && !isJSReady(conv) &&
1.135 + !conv.getClass().getSimpleName().equals("$JsCallbacks$") // NOI18N
1.136 + ) {
1.137 + conv = new Weak(conv);
1.138 + }
1.139 }
1.140 - all.add(args[i]);
1.141 + all.add(conv);
1.142 }
1.143 Object ret = fn.call("call", all.toArray()); // NOI18N
1.144 + if (ret instanceof Weak) {
1.145 + ret = ((Weak)ret).get();
1.146 + }
1.147 if (ret == fn) {
1.148 return null;
1.149 }
1.150 @@ -347,4 +372,29 @@
1.151 }
1.152 }
1.153
1.154 + private static boolean isJSReady(Object obj) {
1.155 + if (obj == null) {
1.156 + return true;
1.157 + }
1.158 + if (obj instanceof String) {
1.159 + return true;
1.160 + }
1.161 + if (obj instanceof Number) {
1.162 + return true;
1.163 + }
1.164 + if (obj instanceof JSObject) {
1.165 + return true;
1.166 + }
1.167 + if (obj instanceof Character) {
1.168 + return true;
1.169 + }
1.170 + return false;
1.171 + }
1.172 +
1.173 + private static final class Weak extends WeakReference<Object> {
1.174 + public Weak(Object referent) {
1.175 + super(referent);
1.176 + assert !(referent instanceof Weak);
1.177 + }
1.178 + } // end of Weak
1.179 }
2.1 --- a/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java Tue Dec 16 21:49:45 2014 +0100
2.2 +++ b/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java Thu Dec 18 03:29:48 2014 +0100
2.3 @@ -45,6 +45,7 @@
2.4 import java.io.Closeable;
2.5 import java.io.IOException;
2.6 import java.io.Reader;
2.7 +import java.lang.ref.WeakReference;
2.8 import java.net.URL;
2.9 import java.util.ArrayList;
2.10 import java.util.List;
2.11 @@ -70,8 +71,8 @@
2.12 *
2.13 * @author Jaroslav Tulach
2.14 */
2.15 -final class ScriptPresenter
2.16 -implements Presenter, Fn.FromJavaScript, Fn.ToJavaScript, Executor {
2.17 +final class ScriptPresenter implements Fn.KeepAlive,
2.18 +Presenter, Fn.FromJavaScript, Fn.ToJavaScript, Executor {
2.19 private static final Logger LOG = Logger.getLogger(ScriptPresenter.class.getName());
2.20 private final ScriptEngine eng;
2.21 private final Executor exc;
2.22 @@ -90,9 +91,14 @@
2.23
2.24 @Override
2.25 public Fn defineFn(String code, String... names) {
2.26 - return defineImpl(code, names);
2.27 + return defineImpl(code, names, null);
2.28 }
2.29 - private FnImpl defineImpl(String code, String... names) {
2.30 +
2.31 + @Override
2.32 + public Fn defineFn(String code, String[] names, boolean[] keepAlive) {
2.33 + return defineImpl(code, names, keepAlive);
2.34 + }
2.35 + private FnImpl defineImpl(String code, String[] names, boolean[] keepAlive) {
2.36 StringBuilder sb = new StringBuilder();
2.37 sb.append("(function() {");
2.38 sb.append(" return function(");
2.39 @@ -112,7 +118,7 @@
2.40 } catch (ScriptException ex) {
2.41 throw new IllegalStateException(ex);
2.42 }
2.43 - return new FnImpl(this, fn);
2.44 + return new FnImpl(this, fn, keepAlive);
2.45 }
2.46
2.47 @Override
2.48 @@ -150,7 +156,7 @@
2.49 private FnImpl wrapArrFn() {
2.50 if (wrapArrImpl == null) {
2.51 try {
2.52 - wrapArrImpl = defineImpl("return Array.prototype.slice.call(arguments);");
2.53 + wrapArrImpl = defineImpl("return Array.prototype.slice.call(arguments);", null, null);
2.54 } catch (Exception ex) {
2.55 throw new IllegalStateException(ex);
2.56 }
2.57 @@ -181,7 +187,7 @@
2.58 + " var l = arr.length;\n"
2.59 + " for (var i = 0; i < l; i++) to[i] = arr[i];\n"
2.60 + " return l;\n"
2.61 - + "}", "arr", "to"
2.62 + + "}", new String[] { "arr", "to" }, null
2.63 );
2.64 } catch (Exception ex) {
2.65 throw new IllegalStateException(ex);
2.66 @@ -192,6 +198,9 @@
2.67
2.68 @Override
2.69 public Object toJava(Object jsArray) {
2.70 + if (jsArray instanceof Weak) {
2.71 + jsArray = ((Weak)jsArray).get();
2.72 + }
2.73 try {
2.74 return checkArray(jsArray);
2.75 } catch (Exception ex) {
2.76 @@ -239,10 +248,12 @@
2.77 private class FnImpl extends Fn {
2.78
2.79 private final Object fn;
2.80 + private final boolean[] keepAlive;
2.81
2.82 - public FnImpl(Presenter presenter, Object fn) {
2.83 + public FnImpl(Presenter presenter, Object fn, boolean[] keepAlive) {
2.84 super(presenter);
2.85 this.fn = fn;
2.86 + this.keepAlive = keepAlive;
2.87 }
2.88
2.89 @Override
2.90 @@ -254,19 +265,28 @@
2.91 List<Object> all = new ArrayList<>(args.length + 1);
2.92 all.add(thiz == null ? fn : thiz);
2.93 for (int i = 0; i < args.length; i++) {
2.94 + Object conv = args[i];
2.95 if (arrayChecks) {
2.96 if (args[i] instanceof Object[]) {
2.97 Object[] arr = (Object[]) args[i];
2.98 - Object conv = ((ScriptPresenter)presenter()).convertArrays(arr);
2.99 - args[i] = conv;
2.100 + conv = ((ScriptPresenter) presenter()).convertArrays(arr);
2.101 }
2.102 - if (args[i] instanceof Character) {
2.103 - args[i] = (int)((Character)args[i]);
2.104 + if (conv != null && keepAlive != null
2.105 + && !keepAlive[i] && !isJSReady(conv)
2.106 + && !conv.getClass().getSimpleName().equals("$JsCallbacks$") // NOI18N
2.107 + ) {
2.108 + conv = new Weak(conv);
2.109 + }
2.110 + if (conv instanceof Character) {
2.111 + conv = (int)(Character)conv;
2.112 }
2.113 }
2.114 - all.add(args[i]);
2.115 + all.add(conv);
2.116 }
2.117 Object ret = ((Invocable)eng).invokeMethod(fn, "call", all.toArray()); // NOI18N
2.118 + if (ret instanceof Weak) {
2.119 + ret = ((Weak)ret).get();
2.120 + }
2.121 if (ret == fn) {
2.122 return null;
2.123 }
2.124 @@ -277,4 +297,31 @@
2.125 }
2.126 }
2.127
2.128 + private static boolean isJSReady(Object obj) {
2.129 + if (obj == null) {
2.130 + return true;
2.131 + }
2.132 + if (obj instanceof String) {
2.133 + return true;
2.134 + }
2.135 + if (obj instanceof Number) {
2.136 + return true;
2.137 + }
2.138 + final String cn = obj.getClass().getName();
2.139 + if (cn.startsWith("jdk.nashorn") || ( // NOI18N
2.140 + cn.contains(".mozilla.") && cn.contains(".Native") // NOI18N
2.141 + )) {
2.142 + return true;
2.143 + }
2.144 + if (obj instanceof Character) {
2.145 + return true;
2.146 + }
2.147 + return false;
2.148 + }
2.149 +
2.150 + private static final class Weak extends WeakReference<Object> {
2.151 + public Weak(Object referent) {
2.152 + super(referent);
2.153 + }
2.154 + }
2.155 }
3.1 --- a/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java Tue Dec 16 21:49:45 2014 +0100
3.2 +++ b/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java Thu Dec 18 03:29:48 2014 +0100
3.3 @@ -150,7 +150,12 @@
3.4 String ident, String fqn, String method, String params
3.5 ) {
3.6 StringBuilder sb = new StringBuilder();
3.7 - sb.append("vm.").append(mangle(fqn, method, params));
3.8 + if (ident != null) {
3.9 + sb.append("vm.raw$");
3.10 + } else {
3.11 + sb.append("vm.");
3.12 + }
3.13 + sb.append(mangle(fqn, method, params));
3.14 sb.append("(");
3.15 if (ident != null) {
3.16 sb.append(ident);
4.1 --- a/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java Tue Dec 16 21:49:45 2014 +0100
4.2 +++ b/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java Thu Dec 18 03:29:48 2014 +0100
4.3 @@ -367,83 +367,8 @@
4.4 for (Map.Entry<String, ExecutableElement> entry : map.entrySet()) {
4.5 final String mangled = entry.getKey();
4.6 final ExecutableElement m = entry.getValue();
4.7 - final boolean isStatic = m.getModifiers().contains(Modifier.STATIC);
4.8 -
4.9 - source.append("\n public java.lang.Object ")
4.10 - .append(mangled)
4.11 - .append("(");
4.12 -
4.13 - String sep = "";
4.14 - if (!isStatic) {
4.15 - source.append(((TypeElement)m.getEnclosingElement()).getQualifiedName());
4.16 - source.append(" self");
4.17 - sep = ", ";
4.18 - }
4.19 -
4.20 - int cnt = 0;
4.21 - StringBuilder convert = new StringBuilder();
4.22 - for (VariableElement ve : m.getParameters()) {
4.23 - source.append(sep);
4.24 - ++cnt;
4.25 - final TypeMirror t = ve.asType();
4.26 - if (!t.getKind().isPrimitive()) {
4.27 - source.append("Object");
4.28 - convert.append(" if (p instanceof org.netbeans.html.boot.spi.Fn.FromJavaScript) {\n");
4.29 - convert.append(" arg").append(cnt).
4.30 - append(" = ((org.netbeans.html.boot.spi.Fn.FromJavaScript)p).toJava(arg").append(cnt).
4.31 - append(");\n");
4.32 - convert.append(" }\n");
4.33 - } else {
4.34 - source.append(t);
4.35 - }
4.36 - source.append(" arg").append(cnt);
4.37 - sep = ", ";
4.38 - }
4.39 - source.append(") throws Throwable {\n");
4.40 - source.append(convert);
4.41 - if (useTryResources()) {
4.42 - source.append(" try (java.io.Closeable a = org.netbeans.html.boot.spi.Fn.activate(p)) { \n");
4.43 - } else {
4.44 - source.append(" java.io.Closeable a = org.netbeans.html.boot.spi.Fn.activate(p); try {\n");
4.45 - }
4.46 - source.append(" ");
4.47 - if (m.getReturnType().getKind() != TypeKind.VOID) {
4.48 - source.append("Object $ret = ");
4.49 - }
4.50 - if (isStatic) {
4.51 - source.append(((TypeElement)m.getEnclosingElement()).getQualifiedName());
4.52 - source.append('.');
4.53 - } else {
4.54 - source.append("self.");
4.55 - }
4.56 - source.append(m.getSimpleName());
4.57 - source.append("(");
4.58 - cnt = 0;
4.59 - sep = "";
4.60 - for (VariableElement ve : m.getParameters()) {
4.61 - source.append(sep);
4.62 - source.append("(").append(ve.asType());
4.63 - source.append(")arg").append(++cnt);
4.64 - sep = ", ";
4.65 - }
4.66 - source.append(");\n");
4.67 - if (m.getReturnType().getKind() == TypeKind.VOID) {
4.68 - source.append(" return null;\n");
4.69 - } else {
4.70 - source.append(" if (p instanceof org.netbeans.html.boot.spi.Fn.ToJavaScript) {\n");
4.71 - source.append(" $ret = ((org.netbeans.html.boot.spi.Fn.ToJavaScript)p).toJavaScript($ret);\n");
4.72 - source.append(" }\n");
4.73 - source.append(" return $ret;\n");
4.74 - }
4.75 - if (useTryResources()) {
4.76 - source.append(" }\n");
4.77 - } else {
4.78 -
4.79 - source.append(" } finally {\n");
4.80 - source.append(" a.close();\n");
4.81 - source.append(" }\n");
4.82 - }
4.83 - source.append(" }\n");
4.84 + generateMethod(false, m, source, mangled);
4.85 + generateMethod(true, m, source, "raw$" + mangled);
4.86 }
4.87 source.append("}\n");
4.88 final String srcName = pkgName + ".$JsCallbacks$";
4.89 @@ -461,6 +386,106 @@
4.90 }
4.91 }
4.92
4.93 + private void generateMethod(boolean selfObj, final ExecutableElement m, StringBuilder source, final String mangled) {
4.94 + final boolean isStatic = m.getModifiers().contains(Modifier.STATIC);
4.95 + if (isStatic && selfObj) {
4.96 + return;
4.97 + }
4.98 + final TypeElement selfType = (TypeElement)m.getEnclosingElement();
4.99 +
4.100 +
4.101 + source.append("\n public java.lang.Object ")
4.102 + .append(mangled)
4.103 + .append("(");
4.104 +
4.105 + String sep = "";
4.106 + StringBuilder convert = new StringBuilder();
4.107 + if (!isStatic) {
4.108 + if (selfObj) {
4.109 + source.append("Object self");
4.110 + convert.append(" if (p instanceof org.netbeans.html.boot.spi.Fn.FromJavaScript) {\n");
4.111 + convert.append(" self").
4.112 + append(" = ((org.netbeans.html.boot.spi.Fn.FromJavaScript)p).toJava(self").
4.113 + append(");\n");
4.114 + convert.append(" }\n");
4.115 + } else {
4.116 + source.append(selfType.getQualifiedName());
4.117 + source.append(" self");
4.118 + }
4.119 + sep = ", ";
4.120 + }
4.121 +
4.122 + int cnt = 0;
4.123 + for (VariableElement ve : m.getParameters()) {
4.124 + source.append(sep);
4.125 + ++cnt;
4.126 + final TypeMirror t = ve.asType();
4.127 + if (!t.getKind().isPrimitive() && !"java.lang.String".equals(t.toString())) { // NOI18N
4.128 + source.append("Object");
4.129 + convert.append(" if (p instanceof org.netbeans.html.boot.spi.Fn.FromJavaScript) {\n");
4.130 + convert.append(" arg").append(cnt).
4.131 + append(" = ((org.netbeans.html.boot.spi.Fn.FromJavaScript)p).toJava(arg").append(cnt).
4.132 + append(");\n");
4.133 + convert.append(" }\n");
4.134 + } else {
4.135 + source.append(t);
4.136 + }
4.137 + source.append(" arg").append(cnt);
4.138 + sep = ", ";
4.139 + }
4.140 + source.append(") throws Throwable {\n");
4.141 + source.append(convert);
4.142 + if (useTryResources()) {
4.143 + source.append(" try (java.io.Closeable a = org.netbeans.html.boot.spi.Fn.activate(p)) { \n");
4.144 + } else {
4.145 + source.append(" java.io.Closeable a = org.netbeans.html.boot.spi.Fn.activate(p); try {\n");
4.146 + }
4.147 + source.append(" ");
4.148 + if (m.getReturnType().getKind() != TypeKind.VOID) {
4.149 + source.append("Object $ret = ");
4.150 + }
4.151 + if (isStatic) {
4.152 + source.append(((TypeElement)m.getEnclosingElement()).getQualifiedName());
4.153 + source.append('.');
4.154 + } else {
4.155 + if (selfObj) {
4.156 + source.append("((");
4.157 + source.append(selfType.getQualifiedName());
4.158 + source.append(")self).");
4.159 + } else {
4.160 + source.append("self.");
4.161 + }
4.162 + }
4.163 + source.append(m.getSimpleName());
4.164 + source.append("(");
4.165 + cnt = 0;
4.166 + sep = "";
4.167 + for (VariableElement ve : m.getParameters()) {
4.168 + source.append(sep);
4.169 + source.append("(").append(ve.asType());
4.170 + source.append(")arg").append(++cnt);
4.171 + sep = ", ";
4.172 + }
4.173 + source.append(");\n");
4.174 + if (m.getReturnType().getKind() == TypeKind.VOID) {
4.175 + source.append(" return null;\n");
4.176 + } else {
4.177 + source.append(" if (p instanceof org.netbeans.html.boot.spi.Fn.ToJavaScript) {\n");
4.178 + source.append(" $ret = ((org.netbeans.html.boot.spi.Fn.ToJavaScript)p).toJavaScript($ret);\n");
4.179 + source.append(" }\n");
4.180 + source.append(" return $ret;\n");
4.181 + }
4.182 + if (useTryResources()) {
4.183 + source.append(" }\n");
4.184 + } else {
4.185 +
4.186 + source.append(" } finally {\n");
4.187 + source.append(" a.close();\n");
4.188 + source.append(" }\n");
4.189 + }
4.190 + source.append(" }\n");
4.191 + }
4.192 +
4.193 private boolean useTryResources() {
4.194 try {
4.195 return processingEnv.getSourceVersion().compareTo(SourceVersion.RELEASE_7) >= 0;
5.1 --- a/boot/src/main/java/org/netbeans/html/boot/spi/Fn.java Tue Dec 16 21:49:45 2014 +0100
5.2 +++ b/boot/src/main/java/org/netbeans/html/boot/spi/Fn.java Thu Dec 18 03:29:48 2014 +0100
5.3 @@ -137,7 +137,7 @@
5.4 }
5.5 if (p instanceof KeepAlive) {
5.6 boolean[] arr;
5.7 - if (!keepParametersAlive) {
5.8 + if (!keepParametersAlive && names.length > 0) {
5.9 arr = new boolean[names.length];
5.10 for (int i = 0; i < arr.length; i++) {
5.11 arr[i] = false;
6.1 --- a/json-tck/src/main/java/net/java/html/js/tests/Bodies.java Tue Dec 16 21:49:45 2014 +0100
6.2 +++ b/json-tck/src/main/java/net/java/html/js/tests/Bodies.java Thu Dec 18 03:29:48 2014 +0100
6.3 @@ -91,10 +91,10 @@
6.4 @JavaScriptBody(args = { "o", "x" }, keepAlive = false, body = "o.x = x;")
6.5 public static native Object setX(Object o, Object x);
6.6
6.7 - @JavaScriptBody(args = { "c" }, keepAlive = false, javacall = true, body =
6.8 - "return c.@net.java.html.js.tests.Sum::sum(II)(40, 2);"
6.9 + @JavaScriptBody(args = { "c", "a", "b" }, keepAlive = false, javacall = true, body =
6.10 + "return c.@net.java.html.js.tests.Sum::sum(II)(a, b);"
6.11 )
6.12 - public static native int sumIndirect(Sum c);
6.13 + public static native int sumIndirect(Sum c, int a, int b);
6.14
6.15 @JavaScriptBody(args = { "arr", "index" }, body = "return arr[index];")
6.16 public static native Object select(Object[] arr, int index);
6.17 @@ -191,6 +191,11 @@
6.18 "return @net.java.html.js.tests.Bodies::problematicString()();"
6.19 )
6.20 public static native String problematicCallback();
6.21 +
6.22 + @JavaScriptBody(args = { "sum" }, javacall = true, body =
6.23 + "return sum.@net.java.html.js.tests.Sum::all(ZBSIJFDCLjava/lang/String;)(false, 1, 2, 3, 5, 6, 7, 32, 'TheEND');\n"
6.24 + )
6.25 + static native String primitiveTypes(Sum sum);
6.26
6.27 static String problematicString() {
6.28 return "{\n" +
7.1 --- a/json-tck/src/main/java/net/java/html/js/tests/GCBodyTest.java Tue Dec 16 21:49:45 2014 +0100
7.2 +++ b/json-tck/src/main/java/net/java/html/js/tests/GCBodyTest.java Thu Dec 18 03:29:48 2014 +0100
7.3 @@ -60,7 +60,7 @@
7.4 return;
7.5 }
7.6 Sum s = new Sum();
7.7 - int res = Bodies.sumIndirect(s);
7.8 + int res = Bodies.sumIndirect(s, 22, 20);
7.9 assert res == 42 : "Expecting 42";
7.10 Reference<?> ref = new WeakReference<Object>(s);
7.11 s = null;
7.12 @@ -85,10 +85,22 @@
7.13 Object obj = assignInst();
7.14 assert ref != null;
7.15
7.16 - Bodies.setX(obj, null);
7.17 - obj = null;
7.18 -
7.19 - assertGC(ref, "Can disappear!");
7.20 + assertGC(ref, "Can disappear as it is keepAlive false!");
7.21 + assert obj != null : "Object is still present";
7.22 + }
7.23 +
7.24 + @KOTest public void strongReceiverBehavior() {
7.25 + Object v = new EmptyInstance();
7.26 + Receiver r = new Receiver(v);
7.27 + r.apply();
7.28 + assert v == r.value : "Value is as expected";
7.29 + }
7.30 +
7.31 + @KOTest public void gcReceiverBehavior() throws InterruptedException {
7.32 + Receiver r = new Receiver(new EmptyInstance());
7.33 + assertGC(r.ref, "The empty instance can be GCed even when referenced from JS");
7.34 + r.apply();
7.35 + assert r.value == null : "Setter called with null value";
7.36 }
7.37
7.38 private static Reference<?> sendRunnable(final int[] arr) {
8.1 --- a/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java Tue Dec 16 21:49:45 2014 +0100
8.2 +++ b/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java Thu Dec 18 03:29:48 2014 +0100
8.3 @@ -213,7 +213,7 @@
8.4
8.5 @KOTest public void callbackWithParameters() throws InterruptedException {
8.6 Sum s = new Sum();
8.7 - int res = Bodies.sumIndirect(s);
8.8 + int res = Bodies.sumIndirect(s, 40, 2);
8.9 assert res == 42 : "Expecting 42";
8.10 }
8.11
8.12 @@ -340,6 +340,11 @@
8.13 assert ret[2].equals("Ciao") : "Expecting Ciao: " + ret[2];
8.14 }
8.15
8.16 + @KOTest public void primitiveTypes() {
8.17 + String all = Bodies.primitiveTypes(new Sum());
8.18 + assert "Ahojfalse12356.07.0 TheEND".equals(all) : "Valid return type: " + all;
8.19 + }
8.20 +
8.21 @KOTest public void problematicString() {
8.22 String orig = Bodies.problematicString();
8.23 String js = Bodies.problematicCallback();
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/json-tck/src/main/java/net/java/html/js/tests/Receiver.java Thu Dec 18 03:29:48 2014 +0100
9.3 @@ -0,0 +1,80 @@
9.4 +/**
9.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
9.6 + *
9.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
9.8 + *
9.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
9.10 + * Other names may be trademarks of their respective owners.
9.11 + *
9.12 + * The contents of this file are subject to the terms of either the GNU
9.13 + * General Public License Version 2 only ("GPL") or the Common
9.14 + * Development and Distribution License("CDDL") (collectively, the
9.15 + * "License"). You may not use this file except in compliance with the
9.16 + * License. You can obtain a copy of the License at
9.17 + * http://www.netbeans.org/cddl-gplv2.html
9.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
9.19 + * specific language governing permissions and limitations under the
9.20 + * License. When distributing the software, include this License Header
9.21 + * Notice in each file and include the License file at
9.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
9.23 + * particular file as subject to the "Classpath" exception as provided
9.24 + * by Oracle in the GPL Version 2 section of the License file that
9.25 + * accompanied this code. If applicable, add the following below the
9.26 + * License Header, with the fields enclosed by brackets [] replaced by
9.27 + * your own identifying information:
9.28 + * "Portions Copyrighted [year] [name of copyright owner]"
9.29 + *
9.30 + * Contributor(s):
9.31 + *
9.32 + * The Original Software is NetBeans. The Initial Developer of the Original
9.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
9.34 + *
9.35 + * If you wish your version of this file to be governed by only the CDDL
9.36 + * or only the GPL Version 2, indicate your decision by adding
9.37 + * "[Contributor] elects to include this software in this distribution
9.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
9.39 + * single choice of license, a recipient has the option to distribute
9.40 + * your version of this file under either the CDDL, the GPL Version 2 or
9.41 + * to extend the choice of license to its licensees as provided above.
9.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
9.43 + * Version 2 license, then the option applies only if the new code is
9.44 + * made subject to such option by the copyright holder.
9.45 + */
9.46 +package net.java.html.js.tests;
9.47 +
9.48 +import java.lang.ref.Reference;
9.49 +import java.lang.ref.WeakReference;
9.50 +import net.java.html.js.JavaScriptBody;
9.51 +
9.52 +/**
9.53 + */
9.54 +public final class Receiver {
9.55 + private final Object fn;
9.56 + Object value;
9.57 + final Reference<Object> ref;
9.58 +
9.59 + public Receiver(Object v) {
9.60 + this.fn = initFn(v);
9.61 + this.ref = new WeakReference<Object>(v);
9.62 + this.value = this;
9.63 + }
9.64 +
9.65 + public void apply() {
9.66 + fnApply(fn, this);
9.67 + }
9.68 +
9.69 + void set(Object v) {
9.70 + value = v;
9.71 + }
9.72 +
9.73 + @JavaScriptBody(args = { "v" }, keepAlive = false, javacall = true,
9.74 + body = "return function(rec) {\n"
9.75 + + " rec.@net.java.html.js.tests.Receiver::set(Ljava/lang/Object;)(v);\n"
9.76 + + "};\n")
9.77 + private static native Object initFn(Object v);
9.78 +
9.79 + @JavaScriptBody(args = { "fn", "thiz" }, body =
9.80 + "fn(thiz);"
9.81 + )
9.82 + private static native void fnApply(Object fn, Receiver thiz);
9.83 +}
10.1 --- a/json-tck/src/main/java/net/java/html/js/tests/Sum.java Tue Dec 16 21:49:45 2014 +0100
10.2 +++ b/json-tck/src/main/java/net/java/html/js/tests/Sum.java Thu Dec 18 03:29:48 2014 +0100
10.3 @@ -60,4 +60,8 @@
10.4 }
10.5 return s;
10.6 }
10.7 +
10.8 + public String all(boolean z, byte b, short s, int i, long l, float f, double d, char ch, String str) {
10.9 + return "Ahoj" + z + b + s + i + l + f + d + ch + str;
10.10 + }
10.11 }
11.1 --- a/pom.xml Tue Dec 16 21:49:45 2014 +0100
11.2 +++ b/pom.xml Thu Dec 18 03:29:48 2014 +0100
11.3 @@ -97,6 +97,7 @@
11.4 <excludes>
11.5 <exclude>*</exclude>
11.6 <exclude>.*/**</exclude>
11.7 + <exclude>*/nb-configuration.xml</exclude>
11.8 <exclude>boot-script/src/test/resources/net/java/html/boot/script/ko4j/env.nashorn.1.2-debug.js</exclude>
11.9 <exclude>src/main/javadoc/resources/teavm.js</exclude>
11.10 </excludes>