# HG changeset patch # User Jaroslav Tulach # Date 1356806769 -3600 # Node ID 2adac52f955e4b9e066b3da8c45b2a361c39341c # Parent 4c761961487209a9189df821cfc52609712c7ea6 Constructors are not assigned to prototype, as they are not inherited. newInstance checks for access rights. diff -r 4c7619614872 -r 2adac52f955e emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Sat Dec 29 19:44:58 2012 +0100 +++ b/emul/src/main/java/java/lang/Class.java Sat Dec 29 19:46:09 2012 +0100 @@ -210,15 +210,32 @@ * * */ - @JavaScriptBody(args = "self", body = - "var inst = self.cnstr();" - + "inst.cons__V(inst);" - + "return inst;" + @JavaScriptBody(args = { "self", "illegal" }, body = + "\nvar c = self.cnstr;" + + "\nif (c['cons__V']) {" + + "\n if ((c.cons__V.access & 0x1) != 0) {" + + "\n var inst = c();" + + "\n c.cons__V(inst);" + + "\n return inst;" + + "\n }" + + "\n return illegal;" + + "\n}" + + "\nreturn null;" ) + private static native Object newInstance0(Class self, Object illegal); + public T newInstance() throws InstantiationException, IllegalAccessException { - throw new UnsupportedOperationException(); + Object illegal = new Object(); + Object inst = newInstance0(this, illegal); + if (inst == null) { + throw new InstantiationException(getName()); + } + if (inst == illegal) { + throw new IllegalAccessException(); + } + return (T)inst; } /** diff -r 4c7619614872 -r 2adac52f955e javap/src/main/java/org/apidesign/javap/MethodData.java --- a/javap/src/main/java/org/apidesign/javap/MethodData.java Sat Dec 29 19:44:58 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java Sat Dec 29 19:46:09 2012 +0100 @@ -25,9 +25,9 @@ package org.apidesign.javap; -import java.io.*; -import org.apidesign.bck2brwsr.core.JavaScriptBody; +import java.io.DataInputStream; +import java.io.IOException; import static org.apidesign.javap.RuntimeConstants.*; /** @@ -387,4 +387,8 @@ attrs.copyInto(arr); return ClassData.findAttr(n, arr); } + + public boolean isConstructor() { + return "".equals(getName()); + } } diff -r 4c7619614872 -r 2adac52f955e vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 29 19:44:58 2012 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 29 19:46:09 2012 +0100 @@ -135,19 +135,27 @@ } continue; } + String prefix; String mn; if (m.isStatic()) { - mn = generateStaticMethod("\n c.", m, toInitilize); + prefix = "\n c."; + mn = generateStaticMethod(prefix, m, toInitilize); } else { - mn = generateInstanceMethod("\n c.", m); + if (m.isConstructor()) { + prefix = "\n CLS."; + mn = generateInstanceMethod(prefix, m); + } else { + prefix = "\n c."; + mn = generateInstanceMethod(prefix, m); + } } byte[] runAnno = m.findAnnotationData(false); if (runAnno != null) { - out.append("\n c.").append(mn).append(".anno = {"); + out.append(prefix).append(mn).append(".anno = {"); generateAnno(jc, out, runAnno); out.append("\n };"); } - out.append("\n c.").append(mn).append(".access = " + m.getAccess()).append(";"); + out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";"); } out.append("\n c.constructor = CLS;"); out.append("\n c.$instOf_").append(className).append(" = true;"); @@ -1122,7 +1130,7 @@ final String classInternalName = jc.getClassName(e.catch_cpx); addReference(classInternalName); out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {"); - out.append("gt="+e.handler_pc+"; continue;"); + out.append("gt="+e.handler_pc+"; stA0 = e; continue;"); out.append("} "); } else { //finally - todo @@ -1311,6 +1319,9 @@ final String in = mi[0]; out.append(accessClass(in.replace('/', '_'))); out.append("(false)."); + if (mn.startsWith("cons_")) { + out.append("constructor."); + } out.append(mn); out.append('('); if (numArguments > 0) { diff -r 4c7619614872 -r 2adac52f955e vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Sat Dec 29 19:44:58 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Sat Dec 29 19:46:09 2012 +0100 @@ -74,6 +74,16 @@ @Test public void jsNewInstance() throws Exception { assertExec("Check new instance", Classes.class, "newInstance__Z", Double.valueOf(1)); } + @Test public void javaNoNewInstance() throws Exception { + assertEquals("java.lang.InstantiationException:java.lang.Float", + Classes.newInstanceNoPubConstructor() + ); + } + @Test public void jsNoNewInstance() throws Exception { + assertExec("Check problems with new instance", Classes.class, "newInstanceNoPubConstructor__Ljava_lang_String_2", + "java.lang.InstantiationException:java.lang.Float" + ); + } @Test public void jsAnnotation() throws Exception { assertExec("Check class annotation", Classes.class, "getMarker__I", Double.valueOf(10)); } diff -r 4c7619614872 -r 2adac52f955e vm/src/test/java/org/apidesign/vm4brwsr/Classes.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Sat Dec 29 19:44:58 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Sat Dec 29 19:46:09 2012 +0100 @@ -72,6 +72,14 @@ } throw new IllegalStateException("Not a subtype: " + ioe); } + public static String newInstanceNoPubConstructor() throws Exception { + try { + Float f = Float.class.newInstance(); + return "wrong, can't instantiate: " + f; + } catch (Exception ex) { + return (ex.getClass().getName() + ":" + ex.getMessage()).toString().toString(); + } + } public static int getMarker() { if (!Classes.class.isAnnotationPresent(ClassesMarker.class)) { return -2;