diff -r ea12a3bb4b33 -r 4fef6b767f61 rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java
--- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Tue Feb 24 11:12:53 2015 +0100
+++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Wed Mar 11 18:58:39 2015 +0100
@@ -82,12 +82,12 @@
private final Resources res;
private final Boolean extension;
private final StringArray classpath;
+ private final Flow.Analyzer flow;
private Bck2Brwsr(
- ObfuscationLevel level,
- StringArray exported, StringArray classes, StringArray resources,
- Resources res,
- Boolean extension, StringArray classpath
+ ObfuscationLevel level, StringArray exported,
+ StringArray classes, StringArray resources, Resources res,
+ Boolean extension, StringArray classpath, Flow.Analyzer flow
) {
this.level = level;
this.exported = exported;
@@ -96,6 +96,7 @@
this.res = res;
this.extension = extension;
this.classpath = classpath;
+ this.flow = flow;
}
/** Helper method to generate virtual machine from bytes served by a resources
@@ -135,7 +136,7 @@
return new Bck2Brwsr(
ObfuscationLevel.NONE,
new StringArray(), new StringArray(), new StringArray(),
- null, false, null
+ null, false, null, null
);
}
@@ -156,7 +157,7 @@
public Bck2Brwsr addExported(String... exported) {
return new Bck2Brwsr(
level, this.exported.addAndNew(exported),
- classes, resources, res, extension, classpath
+ classes, resources, res, extension, classpath, flow
);
}
@@ -197,7 +198,7 @@
} else {
return new Bck2Brwsr(level, exported,
this.classes.addAndNew(classes), resources, res,
- extension, classpath);
+ extension, classpath, flow);
}
}
@@ -217,7 +218,7 @@
return this;
} else {
return new Bck2Brwsr(level, exported, this.classes,
- this.resources.addAndNew(resources), res, extension, classpath
+ this.resources.addAndNew(resources), res, extension, classpath, flow
);
}
}
@@ -231,7 +232,7 @@
* @since 0.5
*/
public Bck2Brwsr obfuscation(ObfuscationLevel level) {
- return new Bck2Brwsr(level, exported, classes, resources, res, extension, classpath);
+ return new Bck2Brwsr(level, exported, classes, resources, res, extension, classpath, flow);
}
/** A way to change the provider of additional resources (classes) for the
@@ -245,7 +246,7 @@
public Bck2Brwsr resources(Resources res) {
return new Bck2Brwsr(
level, exported, classes, resources,
- res, extension, classpath
+ res, extension, classpath, flow
);
}
@@ -272,7 +273,7 @@
return new Bck2Brwsr(
level, exported, classes,
resources, res, true,
- StringArray.asList(classpath)
+ StringArray.asList(classpath), flow
);
}
@@ -289,7 +290,7 @@
public Bck2Brwsr standalone(boolean includeVM) {
return new Bck2Brwsr(
level, exported, classes, resources,
- res, includeVM ? false : null, null
+ res, includeVM ? false : null, null, flow
);
}
@@ -319,6 +320,21 @@
return resources(new LdrRsrcs(loader, ignoreBootClassPath));
}
+ /** A way to register flow analyzer. Such analyzer can optimize the
+ * representation of cycles inside of method bodies.
+ *
+ * @param flow the analyzer to be consulted with each method body
+ * @return new instance of the compiler with all values being the same, just
+ * different flow analyzer
+ * @since 0.15
+ */
+ public Bck2Brwsr flowAnalyzer(Flow.Analyzer flow) {
+ return new Bck2Brwsr(
+ level, exported, classes, resources, res,
+ extension, classpath, flow
+ );
+ }
+
/** Generates virtual machine based on previous configuration of the
* compiler.
*
@@ -373,6 +389,10 @@
StringArray classpath() {
return classpath;
}
+
+ Flow.Analyzer flow() {
+ return flow;
+ }
/** Provider of resources (classes and other files). The
* {@link #generate(java.lang.Appendable, org.apidesign.vm4brwsr.Bck2Brwsr.Resources, java.lang.String[])
@@ -391,4 +411,51 @@
*/
public InputStream get(String resource) throws IOException;
}
+
+ /** Represents control flow inside single method.
+ * Passed into {@link Analyzer#analyze(byte[], org.apidesign.vm4brwsr.Bck2Brwsr.Flow)}
+ * method that can be registed via {@link Bck2Brwsr#flowAnalyzer(org.apidesign.vm4brwsr.Bck2Brwsr.Flow.Analyzer)}
+ * method.
+ *
+ * @since 0.15
+ */
+ public static final class Flow {
+ private final byte[] byteCode;
+ Flow(byte[] byteCode) {
+ this.byteCode = byteCode;
+ }
+
+ /** Access to bytecode of the method to analyse.
+ *
+ * @return unmodifiable bytecode of the instructions in the method body
+ */
+ public byte[] getMethodByteCode() {
+ return byteCode;
+ }
+
+ public void registerCycle(int offset) {
+ }
+
+ public void registerIf(int offset) {
+ }
+
+ /** Provider of advanced analysis of the code flow inside of
+ * method bodies. Register via {@link Bck2Brwsr#flowAnalyzer(org.apidesign.vm4brwsr.Bck2Brwsr.Flow.Analyzer)}
+ * when constructing the {@link Bck2Brwsr#newCompiler() compiler}.
+ *
+ * @since 0.15
+ */
+ public interface Analyzer {
+ /** Called to analyze method bodies and offer better control flow.
+ *
+ *
+ * @param request flow computation request and also a
+ * callback interface with methods to define the flow
+ * @return true
if the analysis was successful,
+ * false
otherwise
+ */
+ public boolean analyze(Flow request);
+ }
+ }
+
}