Constructors are not assigned to prototype, as they are not inherited. newInstance checks for access rights.
1.1 --- a/emul/src/main/java/java/lang/Class.java Sat Dec 29 19:44:58 2012 +0100
1.2 +++ b/emul/src/main/java/java/lang/Class.java Sat Dec 29 19:46:09 2012 +0100
1.3 @@ -210,15 +210,32 @@
1.4 * </ul>
1.5 *
1.6 */
1.7 - @JavaScriptBody(args = "self", body =
1.8 - "var inst = self.cnstr();"
1.9 - + "inst.cons__V(inst);"
1.10 - + "return inst;"
1.11 + @JavaScriptBody(args = { "self", "illegal" }, body =
1.12 + "\nvar c = self.cnstr;"
1.13 + + "\nif (c['cons__V']) {"
1.14 + + "\n if ((c.cons__V.access & 0x1) != 0) {"
1.15 + + "\n var inst = c();"
1.16 + + "\n c.cons__V(inst);"
1.17 + + "\n return inst;"
1.18 + + "\n }"
1.19 + + "\n return illegal;"
1.20 + + "\n}"
1.21 + + "\nreturn null;"
1.22 )
1.23 + private static native Object newInstance0(Class<?> self, Object illegal);
1.24 +
1.25 public T newInstance()
1.26 throws InstantiationException, IllegalAccessException
1.27 {
1.28 - throw new UnsupportedOperationException();
1.29 + Object illegal = new Object();
1.30 + Object inst = newInstance0(this, illegal);
1.31 + if (inst == null) {
1.32 + throw new InstantiationException(getName());
1.33 + }
1.34 + if (inst == illegal) {
1.35 + throw new IllegalAccessException();
1.36 + }
1.37 + return (T)inst;
1.38 }
1.39
1.40 /**
2.1 --- a/javap/src/main/java/org/apidesign/javap/MethodData.java Sat Dec 29 19:44:58 2012 +0100
2.2 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java Sat Dec 29 19:46:09 2012 +0100
2.3 @@ -25,9 +25,9 @@
2.4
2.5 package org.apidesign.javap;
2.6
2.7 -import java.io.*;
2.8 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
2.9
2.10 +import java.io.DataInputStream;
2.11 +import java.io.IOException;
2.12 import static org.apidesign.javap.RuntimeConstants.*;
2.13
2.14 /**
2.15 @@ -387,4 +387,8 @@
2.16 attrs.copyInto(arr);
2.17 return ClassData.findAttr(n, arr);
2.18 }
2.19 +
2.20 + public boolean isConstructor() {
2.21 + return "<init>".equals(getName());
2.22 + }
2.23 }
3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 29 19:44:58 2012 +0100
3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 29 19:46:09 2012 +0100
3.3 @@ -135,19 +135,27 @@
3.4 }
3.5 continue;
3.6 }
3.7 + String prefix;
3.8 String mn;
3.9 if (m.isStatic()) {
3.10 - mn = generateStaticMethod("\n c.", m, toInitilize);
3.11 + prefix = "\n c.";
3.12 + mn = generateStaticMethod(prefix, m, toInitilize);
3.13 } else {
3.14 - mn = generateInstanceMethod("\n c.", m);
3.15 + if (m.isConstructor()) {
3.16 + prefix = "\n CLS.";
3.17 + mn = generateInstanceMethod(prefix, m);
3.18 + } else {
3.19 + prefix = "\n c.";
3.20 + mn = generateInstanceMethod(prefix, m);
3.21 + }
3.22 }
3.23 byte[] runAnno = m.findAnnotationData(false);
3.24 if (runAnno != null) {
3.25 - out.append("\n c.").append(mn).append(".anno = {");
3.26 + out.append(prefix).append(mn).append(".anno = {");
3.27 generateAnno(jc, out, runAnno);
3.28 out.append("\n };");
3.29 }
3.30 - out.append("\n c.").append(mn).append(".access = " + m.getAccess()).append(";");
3.31 + out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";");
3.32 }
3.33 out.append("\n c.constructor = CLS;");
3.34 out.append("\n c.$instOf_").append(className).append(" = true;");
3.35 @@ -1122,7 +1130,7 @@
3.36 final String classInternalName = jc.getClassName(e.catch_cpx);
3.37 addReference(classInternalName);
3.38 out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {");
3.39 - out.append("gt="+e.handler_pc+"; continue;");
3.40 + out.append("gt="+e.handler_pc+"; stA0 = e; continue;");
3.41 out.append("} ");
3.42 } else {
3.43 //finally - todo
3.44 @@ -1311,6 +1319,9 @@
3.45 final String in = mi[0];
3.46 out.append(accessClass(in.replace('/', '_')));
3.47 out.append("(false).");
3.48 + if (mn.startsWith("cons_")) {
3.49 + out.append("constructor.");
3.50 + }
3.51 out.append(mn);
3.52 out.append('(');
3.53 if (numArguments > 0) {
4.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Sat Dec 29 19:44:58 2012 +0100
4.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Sat Dec 29 19:46:09 2012 +0100
4.3 @@ -74,6 +74,16 @@
4.4 @Test public void jsNewInstance() throws Exception {
4.5 assertExec("Check new instance", Classes.class, "newInstance__Z", Double.valueOf(1));
4.6 }
4.7 + @Test public void javaNoNewInstance() throws Exception {
4.8 + assertEquals("java.lang.InstantiationException:java.lang.Float",
4.9 + Classes.newInstanceNoPubConstructor()
4.10 + );
4.11 + }
4.12 + @Test public void jsNoNewInstance() throws Exception {
4.13 + assertExec("Check problems with new instance", Classes.class, "newInstanceNoPubConstructor__Ljava_lang_String_2",
4.14 + "java.lang.InstantiationException:java.lang.Float"
4.15 + );
4.16 + }
4.17 @Test public void jsAnnotation() throws Exception {
4.18 assertExec("Check class annotation", Classes.class, "getMarker__I", Double.valueOf(10));
4.19 }
5.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Sat Dec 29 19:44:58 2012 +0100
5.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Sat Dec 29 19:46:09 2012 +0100
5.3 @@ -72,6 +72,14 @@
5.4 }
5.5 throw new IllegalStateException("Not a subtype: " + ioe);
5.6 }
5.7 + public static String newInstanceNoPubConstructor() throws Exception {
5.8 + try {
5.9 + Float f = Float.class.newInstance();
5.10 + return "wrong, can't instantiate: " + f;
5.11 + } catch (Exception ex) {
5.12 + return (ex.getClass().getName() + ":" + ex.getMessage()).toString().toString();
5.13 + }
5.14 + }
5.15 public static int getMarker() {
5.16 if (!Classes.class.isAnnotationPresent(ClassesMarker.class)) {
5.17 return -2;