1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 25 05:14:25 2016 +0100
1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 25 05:53:21 2016 +0100
1.3 @@ -103,7 +103,11 @@
1.4 return "(refs_" + classOperation + " || (refs_" + classOperation + " = " + accessClass(classOperation) + "(false)))";
1.5 }
1.6
1.7 - protected String accessField(String object, String[] fieldInfoName)
1.8 + protected FieldData findField(String[] fieldInfoName) throws IOException {
1.9 + return null;
1.10 + }
1.11 +
1.12 + protected String accessField(String object, FieldData data, String[] fieldInfoName)
1.13 throws IOException {
1.14 String mangledName = "_" + fieldInfoName[1];
1.15 return object + "." + mangledName;
1.16 @@ -1419,12 +1423,21 @@
1.17 int indx = readUShortArg(byteCodes, i);
1.18 String[] fi = jc.getFieldInfoName(indx);
1.19 final int type = VarType.fromFieldType(fi[2].charAt(0));
1.20 - final String mangleClass = mangleClassName(fi[0]);
1.21 - final String mangleClassAccess = accessClassFalse(mangleClass);
1.22 - smapper.replace(this, type, "@2.call(@1)",
1.23 - smapper.getA(0),
1.24 - accessField(mangleClassAccess, fi)
1.25 - );
1.26 + FieldData field = findField(fi);
1.27 + if (field == null) {
1.28 + final String mangleClass = mangleClassName(fi[0]);
1.29 + final String mangleClassAccess = accessClassFalse(mangleClass);
1.30 + smapper.replace(this, type, "@2.call(@1)",
1.31 + smapper.getA(0),
1.32 + accessField(mangleClassAccess, null, fi)
1.33 + );
1.34 + } else {
1.35 + final String fieldOwner = mangleClassName(field.cls.getClassName());
1.36 + smapper.replace(this, type, "@1.@2",
1.37 + smapper.getA(0),
1.38 + accessField(fieldOwner, field, fi)
1.39 + );
1.40 + }
1.41 i += 2;
1.42 addReference(fi[0]);
1.43 break;
1.44 @@ -1433,12 +1446,23 @@
1.45 int indx = readUShortArg(byteCodes, i);
1.46 String[] fi = jc.getFieldInfoName(indx);
1.47 final int type = VarType.fromFieldType(fi[2].charAt(0));
1.48 - final String mangleClass = mangleClassName(fi[0]);
1.49 - final String mangleClassAccess = accessClassFalse(mangleClass);
1.50 - emit(smapper, this, "@3.call(@2, @1);",
1.51 - smapper.popT(type),
1.52 - smapper.popA(),
1.53 - accessField(mangleClassAccess, fi));
1.54 + FieldData field = findField(fi);
1.55 + if (field == null) {
1.56 + final String mangleClass = mangleClassName(fi[0]);
1.57 + final String mangleClassAccess = accessClassFalse(mangleClass);
1.58 + emit(smapper, this, "@3.call(@2, @1);",
1.59 + smapper.popT(type),
1.60 + smapper.popA(),
1.61 + accessField(mangleClassAccess, null, fi)
1.62 + );
1.63 + } else {
1.64 + final String fieldOwner = mangleClassName(field.cls.getClassName());
1.65 + emit(smapper, this, "@2.@3 = @1;",
1.66 + smapper.popT(type),
1.67 + smapper.popA(),
1.68 + accessField(fieldOwner, field, fi)
1.69 + );
1.70 + }
1.71 i += 2;
1.72 addReference(fi[0]);
1.73 break;
1.74 @@ -1448,7 +1472,7 @@
1.75 String[] fi = jc.getFieldInfoName(indx);
1.76 final int type = VarType.fromFieldType(fi[2].charAt(0));
1.77 String ac = accessClassFalse(mangleClassName(fi[0]));
1.78 - String af = accessField(ac, fi);
1.79 + String af = accessField(ac, null, fi);
1.80 smapper.assign(this, type, af + "()");
1.81 i += 2;
1.82 addReference(fi[0]);
2.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon Jan 25 05:14:25 2016 +0100
2.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon Jan 25 05:53:21 2016 +0100
2.3 @@ -310,15 +310,22 @@
2.4 }
2.5
2.6 @Override
2.7 - protected String accessField(String object, String[] fieldInfoName)
2.8 + protected FieldData findField(String[] fieldInfoName) throws IOException {
2.9 + FieldData field = classDataCache.findField(
2.10 + fieldInfoName[0], fieldInfoName[1], fieldInfoName[2]
2.11 + );
2.12 + return field != null && canAccessDirectly(field.cls) ? field : null;
2.13 + }
2.14 +
2.15 + @Override
2.16 + protected String accessField(String object, FieldData field, String[] fieldInfoName)
2.17 throws IOException {
2.18 - final FieldData field =
2.19 - classDataCache.findField(fieldInfoName[0],
2.20 - fieldInfoName[1],
2.21 - fieldInfoName[2]);
2.22 - String mangledName = "_" + fieldInfoName[1];
2.23 - return accessNonVirtualMember(object, mangledName,
2.24 - (field != null) ? field.cls : null);
2.25 + if (field != null) {
2.26 + return "fld_" + object + "_" + field.getName();
2.27 + } else {
2.28 + String mangledName = "_" + fieldInfoName[1];
2.29 + return accessNonVirtualMember(object, mangledName, null);
2.30 + }
2.31 }
2.32
2.33 @Override
2.34 @@ -403,11 +410,9 @@
2.35 return (exportedMethodFinder.getFound() != null);
2.36 }
2.37
2.38 - private String accessNonVirtualMember(String object,
2.39 - String mangledName,
2.40 - ClassData declaringClass) {
2.41 + private boolean canAccessDirectly(ClassData declaringClass) {
2.42 if (declaringClass == null) {
2.43 - return object + "['" + mangledName + "']";
2.44 + return false;
2.45 }
2.46 final String className = declaringClass.getClassName();
2.47 if (
2.48 @@ -415,9 +420,17 @@
2.49 "java/lang/reflect/Array".equals(className) ||
2.50 isExternalClass(className)
2.51 ) {
2.52 - return object + "['" + mangledName + "']";
2.53 + return false;
2.54 }
2.55 - return object + "." + mangledName;
2.56 + return true;
2.57 + }
2.58 +
2.59 + private String accessNonVirtualMember(
2.60 + String object, String mangledName, ClassData declaringClass
2.61 + ) {
2.62 + return canAccessDirectly(declaringClass) ?
2.63 + object + "." + mangledName :
2.64 + object + "['" + mangledName + "']";
2.65 }
2.66
2.67 private final class ExportedMethodFinder