rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java
branchclosure
changeset 1085 6a4ef883e233
parent 1084 f5c9934a252c
child 1086 2ac4283ee209
     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 {