1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon May 06 18:06:08 2013 +0200
1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Tue May 07 19:01:14 2013 +0200
1.3 @@ -32,12 +32,14 @@
1.4
1.5 private final Bck2Brwsr.Resources resources;
1.6 private final ExportedSymbols exportedSymbols;
1.7 + private final StringArray invokerMethods;
1.8
1.9 private VM(Appendable out, Bck2Brwsr.Resources resources) {
1.10 super(out);
1.11 this.resources = resources;
1.12 this.classDataCache = new ClassDataCache(resources);
1.13 this.exportedSymbols = new ExportedSymbols(resources);
1.14 + this.invokerMethods = new StringArray();
1.15 }
1.16
1.17 static {
1.18 @@ -67,7 +69,20 @@
1.19
1.20 private void doCompile(StringArray names) throws IOException {
1.21 generatePrologue();
1.22 + out.append(
1.23 + "\n var invoker = function Invoker() {"
1.24 + + "\n return Invoker.target[Invoker.method]"
1.25 + + ".apply(Invoker.target, arguments);"
1.26 + + "\n };");
1.27 generateBody(names);
1.28 + for (String invokerMethod: invokerMethods.toArray()) {
1.29 + out.append("\n invoker." + invokerMethod + " = function(target) {"
1.30 + + "\n invoker.target = target;"
1.31 + + "\n invoker.method = '" + invokerMethod + "';"
1.32 + + "\n return invoker;"
1.33 + + "\n };");
1.34 + }
1.35 + out.append("\n");
1.36 generateEpilogue();
1.37 }
1.38
1.39 @@ -268,16 +283,64 @@
1.40 }
1.41
1.42 @Override
1.43 - protected String accessMember(String object, String mangledName,
1.44 - String[] fieldInfoName) throws IOException {
1.45 - final ClassData declaringClass =
1.46 + protected String accessField(String object, String mangledName,
1.47 + String[] fieldInfoName) throws IOException {
1.48 + final FieldData field =
1.49 + classDataCache.findField(fieldInfoName[0],
1.50 + fieldInfoName[1],
1.51 + fieldInfoName[2]);
1.52 + return accessNonVirtualMember(object, mangledName,
1.53 + (field != null) ? field.cls : null);
1.54 + }
1.55 +
1.56 + @Override
1.57 + protected String accessStaticMethod(
1.58 + String object,
1.59 + String mangledName,
1.60 + String[] fieldInfoName) throws IOException {
1.61 + final MethodData method =
1.62 + classDataCache.findMethod(fieldInfoName[0],
1.63 + fieldInfoName[1],
1.64 + fieldInfoName[2]);
1.65 + return accessNonVirtualMember(object, mangledName,
1.66 + (method != null) ? method.cls : null);
1.67 + }
1.68 +
1.69 + @Override
1.70 + protected String accessVirtualMethod(
1.71 + String object,
1.72 + String mangledName,
1.73 + String[] fieldInfoName) throws IOException {
1.74 + final ClassData referencedClass =
1.75 classDataCache.getClassData(fieldInfoName[0]);
1.76 - if (declaringClass == null) {
1.77 - return object + "['" + mangledName + "']";
1.78 + final MethodData method =
1.79 + classDataCache.findMethod(referencedClass,
1.80 + fieldInfoName[1],
1.81 + fieldInfoName[2]);
1.82 +
1.83 + if ((method != null)
1.84 + && (((method.access & ByteCodeParser.ACC_FINAL) != 0)
1.85 + || ((referencedClass.getAccessFlags()
1.86 + & ByteCodeParser.ACC_FINAL) != 0)
1.87 + || !exportedSymbols.isExported(method))) {
1.88 + return object + "." + mangledName;
1.89 }
1.90
1.91 - // TODO
1.92 - return object + "." + mangledName;
1.93 + return accessThroughInvoker(object, mangledName);
1.94 + }
1.95 +
1.96 + private String accessThroughInvoker(String object, String mangledName) {
1.97 + if (!invokerMethods.contains(mangledName)) {
1.98 + invokerMethods.add(mangledName);
1.99 + }
1.100 + return "invoker." + mangledName + '(' + object + ')';
1.101 + }
1.102 +
1.103 + private static String accessNonVirtualMember(String object,
1.104 + String mangledName,
1.105 + ClassData declaringClass) {
1.106 + return (declaringClass != null) ? object + "." + mangledName
1.107 + : object + "['" + mangledName + "']";
1.108 }
1.109
1.110 private static final class Standalone extends VM {