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 }