rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java
branchflow
changeset 1812 4fef6b767f61
parent 1787 ea12a3bb4b33
child 1813 5c30fa1c8c5b
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Tue Feb 24 11:12:53 2015 +0100
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Wed Mar 11 18:58:39 2015 +0100
     1.3 @@ -82,12 +82,12 @@
     1.4      private final Resources res;
     1.5      private final Boolean extension;
     1.6      private final StringArray classpath;
     1.7 +    private final Flow.Analyzer flow;
     1.8  
     1.9      private Bck2Brwsr(
    1.10 -            ObfuscationLevel level, 
    1.11 -            StringArray exported, StringArray classes, StringArray resources, 
    1.12 -            Resources res, 
    1.13 -            Boolean extension, StringArray classpath
    1.14 +        ObfuscationLevel level, StringArray exported,
    1.15 +        StringArray classes, StringArray resources, Resources res,
    1.16 +        Boolean extension, StringArray classpath, Flow.Analyzer flow
    1.17      ) {
    1.18          this.level = level;
    1.19          this.exported = exported;
    1.20 @@ -96,6 +96,7 @@
    1.21          this.res = res;
    1.22          this.extension = extension;
    1.23          this.classpath = classpath;
    1.24 +        this.flow = flow;
    1.25      }
    1.26      
    1.27      /** Helper method to generate virtual machine from bytes served by a <code>resources</code>
    1.28 @@ -135,7 +136,7 @@
    1.29          return new Bck2Brwsr(
    1.30              ObfuscationLevel.NONE, 
    1.31              new StringArray(), new StringArray(), new StringArray(), 
    1.32 -            null, false, null
    1.33 +            null, false, null, null
    1.34          );
    1.35      }
    1.36      
    1.37 @@ -156,7 +157,7 @@
    1.38      public Bck2Brwsr addExported(String... exported) {
    1.39          return new Bck2Brwsr(
    1.40              level, this.exported.addAndNew(exported), 
    1.41 -            classes, resources, res, extension, classpath
    1.42 +            classes, resources, res, extension, classpath, flow
    1.43          );
    1.44      }
    1.45  
    1.46 @@ -197,7 +198,7 @@
    1.47          } else {
    1.48              return new Bck2Brwsr(level, exported, 
    1.49                  this.classes.addAndNew(classes), resources, res,
    1.50 -                extension, classpath);
    1.51 +                extension, classpath, flow);
    1.52          }
    1.53      }
    1.54      
    1.55 @@ -217,7 +218,7 @@
    1.56              return this;
    1.57          } else {
    1.58              return new Bck2Brwsr(level, exported, this.classes, 
    1.59 -                this.resources.addAndNew(resources), res, extension, classpath
    1.60 +                this.resources.addAndNew(resources), res, extension, classpath, flow
    1.61              );
    1.62          }
    1.63      }
    1.64 @@ -231,7 +232,7 @@
    1.65       * @since 0.5
    1.66       */
    1.67      public Bck2Brwsr obfuscation(ObfuscationLevel level) {
    1.68 -        return new Bck2Brwsr(level, exported, classes, resources, res, extension, classpath);
    1.69 +        return new Bck2Brwsr(level, exported, classes, resources, res, extension, classpath, flow);
    1.70      }
    1.71      
    1.72      /** A way to change the provider of additional resources (classes) for the 
    1.73 @@ -245,7 +246,7 @@
    1.74      public Bck2Brwsr resources(Resources res) {
    1.75          return new Bck2Brwsr(
    1.76              level, exported, classes, resources, 
    1.77 -            res, extension, classpath
    1.78 +            res, extension, classpath, flow
    1.79          );
    1.80      }
    1.81  
    1.82 @@ -272,7 +273,7 @@
    1.83          return new Bck2Brwsr(
    1.84              level, exported, classes, 
    1.85              resources, res, true, 
    1.86 -            StringArray.asList(classpath)
    1.87 +            StringArray.asList(classpath), flow
    1.88          );
    1.89      }
    1.90      
    1.91 @@ -289,7 +290,7 @@
    1.92      public Bck2Brwsr standalone(boolean includeVM) {
    1.93          return new Bck2Brwsr(
    1.94              level, exported, classes, resources, 
    1.95 -            res, includeVM ? false : null, null
    1.96 +            res, includeVM ? false : null, null, flow
    1.97          );
    1.98      }
    1.99  
   1.100 @@ -319,6 +320,21 @@
   1.101          return resources(new LdrRsrcs(loader, ignoreBootClassPath));
   1.102      }
   1.103      
   1.104 +    /** A way to register flow analyzer. Such analyzer can optimize the
   1.105 +     * representation of cycles inside of method bodies.
   1.106 +     * 
   1.107 +     * @param flow the analyzer to be consulted with each method body
   1.108 +     * @return new instance of the compiler with all values being the same, just 
   1.109 +     *   different flow analyzer
   1.110 +     * @since 0.15
   1.111 +     */
   1.112 +    public Bck2Brwsr flowAnalyzer(Flow.Analyzer flow) {
   1.113 +        return new Bck2Brwsr(
   1.114 +            level, exported, classes, resources, res, 
   1.115 +            extension, classpath, flow
   1.116 +        );
   1.117 +    }
   1.118 +    
   1.119      /** Generates virtual machine based on previous configuration of the 
   1.120       * compiler.
   1.121       * 
   1.122 @@ -373,6 +389,10 @@
   1.123      StringArray classpath() {
   1.124          return classpath;
   1.125      }
   1.126 +    
   1.127 +    Flow.Analyzer flow() {
   1.128 +        return flow;
   1.129 +    }
   1.130  
   1.131      /** Provider of resources (classes and other files). The 
   1.132       * {@link #generate(java.lang.Appendable, org.apidesign.vm4brwsr.Bck2Brwsr.Resources, java.lang.String[]) 
   1.133 @@ -391,4 +411,51 @@
   1.134           */
   1.135          public InputStream get(String resource) throws IOException;
   1.136      }
   1.137 +
   1.138 +    /** Represents control flow inside single method.
   1.139 +     * Passed into {@link Analyzer#analyze(byte[], org.apidesign.vm4brwsr.Bck2Brwsr.Flow)}
   1.140 +     * method that can be registed via {@link Bck2Brwsr#flowAnalyzer(org.apidesign.vm4brwsr.Bck2Brwsr.Flow.Analyzer)}
   1.141 +     * method.
   1.142 +     * 
   1.143 +     * @since 0.15
   1.144 +     */
   1.145 +    public static final class Flow {
   1.146 +        private final byte[] byteCode;
   1.147 +        Flow(byte[] byteCode) {
   1.148 +            this.byteCode = byteCode;
   1.149 +        }
   1.150 +        
   1.151 +        /** Access to bytecode of the method to analyse.
   1.152 +         * 
   1.153 +         * @return unmodifiable bytecode of the instructions in the method body
   1.154 +         */
   1.155 +        public byte[] getMethodByteCode() {
   1.156 +            return byteCode;
   1.157 +        }
   1.158 +        
   1.159 +        public void registerCycle(int offset) {
   1.160 +        }
   1.161 +        
   1.162 +        public void registerIf(int offset) {
   1.163 +        }
   1.164 +        
   1.165 +        /** Provider of advanced analysis of the code flow inside of
   1.166 +         * method bodies. Register via {@link Bck2Brwsr#flowAnalyzer(org.apidesign.vm4brwsr.Bck2Brwsr.Flow.Analyzer)}
   1.167 +         * when constructing the {@link Bck2Brwsr#newCompiler() compiler}.
   1.168 +         * 
   1.169 +         * @since 0.15
   1.170 +         */
   1.171 +        public interface Analyzer {
   1.172 +            /** Called to analyze method bodies and offer better control flow.
   1.173 +             * 
   1.174 +             * 
   1.175 +             * @param request flow computation request and also a
   1.176 +             *    callback interface with methods to define the flow
   1.177 +             * @return <code>true</code> if the analysis was successful,
   1.178 +             *   <code>false</code> otherwise
   1.179 +             */
   1.180 +            public boolean analyze(Flow request);
   1.181 +        }
   1.182 +    }
   1.183 +    
   1.184  }