use of de.mirkosertic.bytecoder.ssa.ControlFlowProcessingException in project Bytecoder by mirkosertic.
the class BytecoderUnitTestRunner method testWASMBackendFrameworkMethod.
private void testWASMBackendFrameworkMethod(FrameworkMethod aFrameworkMethod, RunNotifier aRunNotifier) {
Description theDescription = Description.createTestDescription(testClass.getJavaClass(), aFrameworkMethod.getName() + " WASM Backend ");
aRunNotifier.fireTestStarted(theDescription);
WebDriver theDriver = null;
try {
CompileTarget theCompileTarget = new CompileTarget(testClass.getJavaClass().getClassLoader(), CompileTarget.BackendType.wasm);
BytecodeMethodSignature theSignature = theCompileTarget.toMethodSignature(aFrameworkMethod.getMethod());
BytecodeObjectTypeRef theTypeRef = new BytecodeObjectTypeRef(testClass.getName());
CompileOptions theOptions = new CompileOptions(LOGGER, true, KnownOptimizer.ALL);
WASMCompileResult theResult = (WASMCompileResult) theCompileTarget.compileToJS(theOptions, testClass.getJavaClass(), aFrameworkMethod.getName(), theSignature);
String theFileName = theCompileTarget.toClassName(theTypeRef) + "." + theCompileTarget.toMethodName(aFrameworkMethod.getName(), theSignature) + ".html";
File theWorkingDirectory = new File(".");
initializeSeleniumDriver();
File theMavenTargetDir = new File(theWorkingDirectory, "target");
File theGeneratedFilesDir = new File(theMavenTargetDir, "bytecoderwat");
theGeneratedFilesDir.mkdirs();
File theGeneratedFile = new File(theGeneratedFilesDir, theFileName);
// Copy WABT Tools
File theWABTFile = new File(theGeneratedFilesDir, "libwabt.js");
try (FileOutputStream theOS = new FileOutputStream(theWABTFile)) {
IOUtils.copy(getClass().getResourceAsStream("/libwabt.js"), theOS);
}
PrintWriter theWriter = new PrintWriter(theGeneratedFile);
theWriter.println("<html>");
theWriter.println(" <body>");
theWriter.println(" <h1>Module code</h1>");
theWriter.println(" <pre id=\"modulecode\">");
theWriter.println(theResult.getData());
theWriter.println(" </pre>");
theWriter.println(" <h1>Compilation result</h1>");
theWriter.println(" <pre id=\"compileresult\">");
theWriter.println(" </pre>");
theWriter.println(" <script src=\"libwabt.js\">");
theWriter.println(" </script>");
theWriter.println(" <script>");
theWriter.println(" var runningInstance;");
theWriter.println(" var runningInstanceMemory;");
theWriter.println();
theWriter.println(" function bytecoder_IntInMemory(value) {");
theWriter.println(" return runningInstanceMemory[value]");
theWriter.println(" + (runningInstanceMemory[value + 1] * 256)");
theWriter.println(" + (runningInstanceMemory[value + 2] * 256 * 256)");
theWriter.println(" + (runningInstanceMemory[value + 3] * 256 * 256 * 256);");
theWriter.println(" }");
theWriter.println();
theWriter.println(" function bytecoder_logByteArrayAsString(acaller, value) {");
theWriter.println(" var theLength = bytecoder_IntInMemory(value + 16);");
theWriter.println(" var theData = '';");
theWriter.println(" value = value + 20;");
theWriter.println(" for (var i=0;i<theLength;i++) {");
theWriter.println(" var theCharCode = bytecoder_IntInMemory(value);");
theWriter.println(" value = value + 4;");
theWriter.println(" theData+= String.fromCharCode(theCharCode);");
theWriter.println(" }");
theWriter.println(" console.log(theData);");
theWriter.println(" }");
theWriter.println();
theWriter.println(" function bytecoder_logDebug(caller,value) {");
theWriter.println(" console.log(value);");
theWriter.println(" }");
theWriter.println();
theWriter.println(" function compile() {");
theWriter.println(" console.log('Test started');");
theWriter.println(" try {");
theWriter.println(" var module = wabt.parseWat('test.wast', document.getElementById(\"modulecode\").innerText);");
theWriter.println(" module.resolveNames();");
theWriter.println(" module.validate();");
theWriter.println(" var binaryOutput = module.toBinary({log: true, write_debug_names:true});");
theWriter.println(" document.getElementById(\"compileresult\").innerText = binaryOutput.log;");
theWriter.println(" var binaryBuffer = binaryOutput.buffer;");
theWriter.println(" console.log('Size of compiled WASM binary is ' + binaryBuffer.length);");
theWriter.println();
theWriter.println(" var theInstantiatePromise = WebAssembly.instantiate(binaryBuffer, {");
theWriter.println(" system: {");
theWriter.println(" currentTimeMillis: function() {return Date.now();},");
theWriter.println(" nanoTime: function() {return Date.now() * 1000000;},");
theWriter.println(" logDebug: bytecoder_logDebug,");
theWriter.println(" writeByteArrayToConsole: bytecoder_logByteArrayAsString,");
theWriter.println(" },");
theWriter.println(" printstream: {");
theWriter.println(" logDebug: bytecoder_logDebug,");
theWriter.println(" },");
theWriter.println(" math: {");
theWriter.println(" floor: function (thisref, p1) {return Math.floor(p1);},");
theWriter.println(" ceil: function (thisref, p1) {return Math.ceil(p1);},");
theWriter.println(" sin: function (thisref, p1) {return Math.sin(p1);},");
theWriter.println(" cos: function (thisref, p1) {return Math.cos(p1);},");
theWriter.println(" round: function (thisref, p1) {return Math.round(p1);},");
theWriter.println(" float_rem: function(a, b) {return a % b;},");
theWriter.println(" sqrt: function(thisref, p1) {return Math.sqrt(p1);},");
theWriter.println(" add: function(thisref, p1, p2) {return p1 + p2;},");
theWriter.println(" float_rem: function(a, b) {return a % b;},");
theWriter.println(" max: function(p1, p2) { return Math.max(p1, p2);},");
theWriter.println(" min: function(p1, p2) { return Math.min(p1, p2);},");
theWriter.println(" },");
theWriter.println(" strictmath: {");
theWriter.println(" floor: function (thisref, p1) {return Math.floor(p1);},");
theWriter.println(" ceil: function (thisref, p1) {return Math.ceil(p1);},");
theWriter.println(" sin: function (thisref, p1) {return Math.sin(p1);},");
theWriter.println(" cos: function (thisref, p1) {return Math.cos(p1);},");
theWriter.println(" round: function (thisref, p1) {return Math.round(p1);},");
theWriter.println(" float_rem: function(a, b) {return a % b;},");
theWriter.println(" sqrt: function(thisref, p1) {return Math.sqrt(p1);},");
theWriter.println(" add: function(thisref, p1, p2) {return p1 + p2;},");
theWriter.println(" },");
theWriter.println(" profiler: {");
theWriter.println(" logMemoryLayoutBlock: function(aCaller, aStart, aUsed, aNext) {");
theWriter.println(" if (aUsed == 1) return;");
theWriter.println(" console.log(' Block at ' + aStart + ' status is ' + aUsed + ' points to ' + aNext);");
theWriter.println(" console.log(' Block size is ' + bytecoder_IntInMemory(aStart));");
theWriter.println(" console.log(' Object type ' + bytecoder_IntInMemory(aStart + 12));");
theWriter.println(" }");
theWriter.println(" }");
theWriter.println(" });");
theWriter.println(" theInstantiatePromise.then(");
theWriter.println(" function (resolved) {");
theWriter.println(" var wasmModule = resolved.module;");
theWriter.println(" runningInstance = resolved.instance;");
theWriter.println(" runningInstanceMemory = new Uint8Array(runningInstance.exports.memory.buffer);");
theWriter.println(" runningInstance.exports.initMemory(0);");
theWriter.println(" console.log(\"Memory initialized\")");
theWriter.println(" runningInstance.exports.logMemoryLayout(0);");
theWriter.println(" console.log(\"Used memory in bytes \" + runningInstance.exports.usedMem());");
theWriter.println(" console.log(\"Free memory in bytes \" + runningInstance.exports.freeMem());");
theWriter.println(" runningInstance.exports.bootstrap(0);");
theWriter.println(" console.log(\"Used memory after bootstrap in bytes \" + runningInstance.exports.usedMem());");
theWriter.println(" console.log(\"Free memory after bootstrap in bytes \" + runningInstance.exports.freeMem());");
theWriter.println(" runningInstance.exports.logMemoryLayout(0);");
theWriter.println(" console.log(\"Creating test instance\")");
theWriter.print(" var theTest = runningInstance.exports.newObject(0,");
theWriter.print(theResult.getSizeOf(theTypeRef));
theWriter.print(",");
theWriter.print(theResult.getTypeIDFor(theTypeRef));
theWriter.print(",");
theWriter.print(theResult.getVTableIndexOf(theTypeRef));
theWriter.println(", 0);");
theWriter.println(" runningInstance.exports.logMemoryLayout(0);");
theWriter.println(" console.log(\"Bootstrapped\")");
theWriter.println(" try {");
theWriter.println(" runningInstance.exports.logMemoryLayout(0);");
theWriter.println(" console.log(\"Starting main method\")");
theWriter.println(" runningInstance.exports.main(theTest);");
theWriter.println(" console.log(\"Main finished\")");
theWriter.println(" runningInstance.exports.logMemoryLayout(0);");
theWriter.println(" wasmHexDump(runningInstanceMemory);");
theWriter.println(" console.log(\"Test finished OK\")");
theWriter.println(" } catch (e) {");
theWriter.println(" console.log(\"Test threw error\")");
theWriter.println(" runningInstance.exports.logMemoryLayout(0);");
theWriter.println(" wasmHexDump(runningInstanceMemory);");
theWriter.println(" throw e;");
theWriter.println(" }");
theWriter.println(" },");
theWriter.println(" function (rejected) {");
theWriter.println(" console.log(\"Error instantiating webassembly\");");
theWriter.println(" console.log(rejected);");
theWriter.println(" }");
theWriter.println(" );");
theWriter.println(" } catch (e) {");
theWriter.println(" document.getElementById(\"compileresult\").innerText = e.toString();");
theWriter.println(" console.log(e.toString());");
theWriter.println(" console.log(e.stack);");
theWriter.println(" if (runningInstance) {");
theWriter.println(" runningInstance.exports.logMemoryLayout(0);");
theWriter.println(" wasmHexDump(runningInstanceMemory);");
theWriter.println(" }");
theWriter.println(" }");
theWriter.println(" }");
theWriter.println();
theWriter.println(" function wasmHexDump(memory) {");
theWriter.println(" var theStart = 0;");
theWriter.println(" console.log('HEX DUMP');");
theWriter.println(" console.log('=================================================================================');");
theWriter.println(" for (var i=0;i<200;i++) {");
theWriter.println(" var theLine = '' + theStart;");
theWriter.println(" while(theLine.length < 15) {");
theWriter.println(" theLine+= ' ';");
theWriter.println(" }");
theWriter.println(" theLine+= ' : ';");
theWriter.println(" for (var j=0;j<32;j++) {");
theWriter.println(" var theByte = memory[theStart++];");
theWriter.println(" var theData = '' + theByte;");
theWriter.println(" while(theData.length < 3) {");
theWriter.println(" theData = ' ' + theData;");
theWriter.println(" }");
theWriter.println(" theLine += theData;");
theWriter.println(" theLine += ' ';");
theWriter.println(" }");
theWriter.println(" console.log(theLine);");
theWriter.println(" }");
theWriter.println(" console.log('DONE');");
theWriter.println(" }");
theWriter.println();
theWriter.println(" compile();");
theWriter.println(" </script>");
theWriter.println(" </body>");
theWriter.println("</html>");
theWriter.flush();
theWriter.close();
try (PrintWriter theWATWriter = new PrintWriter(new FileWriter(new File(theGeneratedFilesDir, theCompileTarget.toClassName(theTypeRef) + "." + theCompileTarget.toMethodName(aFrameworkMethod.getName(), theSignature) + ".wat")))) {
theWATWriter.println(theResult.getData());
}
// Invoke test in browser
theDriver = newDriverForTest();
theDriver.get(theGeneratedFile.toURI().toURL().toString());
long theStart = System.currentTimeMillis();
boolean theTestSuccedded = false;
while (!theTestSuccedded && System.currentTimeMillis() - theStart < 10 * 1000) {
List<LogEntry> theAll = theDriver.manage().logs().get(LogType.BROWSER).getAll();
for (LogEntry theEntry : theAll) {
String theMessage = theEntry.getMessage();
System.out.println(theMessage);
if (theMessage.contains("Test finished OK")) {
theTestSuccedded = true;
}
}
if (!theTestSuccedded) {
Thread.sleep(100);
}
}
if (!theTestSuccedded) {
aRunNotifier.fireTestFailure(new Failure(theDescription, new RuntimeException("Test did not succeed!")));
}
} catch (ControlFlowProcessingException e) {
System.out.println(e.getGraph().toDOT());
aRunNotifier.fireTestFailure(new Failure(theDescription, e));
} catch (Exception e) {
aRunNotifier.fireTestFailure(new Failure(theDescription, e));
} finally {
if (theDriver != null) {
theDriver.close();
}
aRunNotifier.fireTestFinished(theDescription);
}
}
use of de.mirkosertic.bytecoder.ssa.ControlFlowProcessingException in project Bytecoder by mirkosertic.
the class BytecoderUnitTestRunner method testJSBackendFrameworkMethod.
private void testJSBackendFrameworkMethod(FrameworkMethod aFrameworkMethod, RunNotifier aRunNotifier) {
Description theDescription = Description.createTestDescription(testClass.getJavaClass(), aFrameworkMethod.getName() + " JS Backend ");
aRunNotifier.fireTestStarted(theDescription);
WebDriver theDriver = null;
try {
CompileTarget theCompileTarget = new CompileTarget(testClass.getJavaClass().getClassLoader(), CompileTarget.BackendType.js);
BytecodeMethodSignature theSignature = theCompileTarget.toMethodSignature(aFrameworkMethod.getMethod());
BytecodeMethodSignature theGetLastExceptionSignature = new BytecodeMethodSignature(BytecodeObjectTypeRef.fromRuntimeClass(Throwable.class), new BytecodeTypeRef[0]);
BytecodeObjectTypeRef theTypeRef = new BytecodeObjectTypeRef(testClass.getName());
StringWriter theStrWriter = new StringWriter();
PrintWriter theCodeWriter = new PrintWriter(theStrWriter);
CompileOptions theOptions = new CompileOptions(LOGGER, true, KnownOptimizer.ALL);
theCodeWriter.println(theCompileTarget.compileToJS(theOptions, testClass.getJavaClass(), aFrameworkMethod.getName(), theSignature).getData());
String theFilename = theCompileTarget.toClassName(theTypeRef) + "." + theCompileTarget.toMethodName(aFrameworkMethod.getName(), theSignature) + "_js.html";
theCodeWriter.println();
theCodeWriter.println("bytecoder.imports.system = {");
theCodeWriter.println(" currentTimeMillis: function() {");
theCodeWriter.println(" return Date.now();");
theCodeWriter.println(" },");
theCodeWriter.println(" nanoTime: function() {");
theCodeWriter.println(" return Date.now() * 1000000;");
theCodeWriter.println(" },");
theCodeWriter.println(" writeByteArrayToConsole: function(thisRef, p1) {");
theCodeWriter.println(" bytecoder.logByteArrayAsString(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" logDebug: function(p1) {");
theCodeWriter.println(" bytecoder.logDebug(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" arraycopy: function(src, srcPos, dest, destPos, length) {");
theCodeWriter.println(" for (i=0;i<length;i++) {");
theCodeWriter.println(" dest.data[destPos++] = src.data[srcPos++];");
theCodeWriter.println(" }");
theCodeWriter.println(" }");
theCodeWriter.println("};");
theCodeWriter.println("bytecoder.imports.printstream = {");
theCodeWriter.println(" logDebug: function(thisref, p1) {");
theCodeWriter.println(" bytecoder.logDebug(p1);");
theCodeWriter.println(" },");
theCodeWriter.println("};");
theCodeWriter.println("bytecoder.imports.math = {");
theCodeWriter.println(" ceil: function(p1) {");
theCodeWriter.println(" return Math.ceil(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" floor: function(p1) {");
theCodeWriter.println(" return Math.floor(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" sin: function(p1) {");
theCodeWriter.println(" return Math.sin(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" cos: function(p1) {");
theCodeWriter.println(" return Math.cos(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" sqrt: function(p1) {");
theCodeWriter.println(" return Math.sqrt(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" round: function(p1) {");
theCodeWriter.println(" return Math.round(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" NaN: function(p1) {");
theCodeWriter.println(" return NaN;");
theCodeWriter.println(" },");
theCodeWriter.println(" atan2: function(p1, p2) {");
theCodeWriter.println(" return Math.atan2(p1, p2);");
theCodeWriter.println(" },");
theCodeWriter.println(" max: function(p1, p2) {");
theCodeWriter.println(" return Math.max(p1, p2);");
theCodeWriter.println(" },");
theCodeWriter.println(" random: function() {");
theCodeWriter.println(" return Math.random();");
theCodeWriter.println(" },");
theCodeWriter.println(" tan: function(p1) {");
theCodeWriter.println(" return Math.tan(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" toRadians: function(p1) {");
theCodeWriter.println(" return Math.toRadians(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" toDegrees: function(p1) {");
theCodeWriter.println(" return Math.toDegrees(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" min: function (p1, p2) {");
theCodeWriter.println(" return Math.min(p1, p2);");
theCodeWriter.println(" },");
theCodeWriter.println(" add: function(p1, p2) {");
theCodeWriter.println(" return p1 + p2;");
theCodeWriter.println(" }");
theCodeWriter.println("};");
theCodeWriter.println("bytecoder.imports.strictmath = {");
theCodeWriter.println(" sin: function(p1) {");
theCodeWriter.println(" return Math.sin(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" cos: function(p1) {");
theCodeWriter.println(" return Math.cos(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" sqrt: function(p1) {");
theCodeWriter.println(" return Math.sqrt(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" round: function(p1) {");
theCodeWriter.println(" return Math.round(p1);");
theCodeWriter.println(" },");
theCodeWriter.println(" atan2: function(p1, p2) {");
theCodeWriter.println(" return Math.atan2(p1, p2);");
theCodeWriter.println(" },");
theCodeWriter.println("};");
theCodeWriter.println();
theCodeWriter.println("console.log(\"Starting test\");");
theCodeWriter.println("bytecoder.bootstrap();");
theCodeWriter.println("var theTestInstance = new " + theCompileTarget.toClassName(theTypeRef) + ".Create();");
theCodeWriter.println("theTestInstance." + theCompileTarget.toMethodName(aFrameworkMethod.getName(), theSignature) + "(theTestInstance);");
theCodeWriter.println("var theLastException = " + theCompileTarget.toClassName(BytecodeObjectTypeRef.fromRuntimeClass(ExceptionRethrower.class)) + "." + theCompileTarget.toMethodName("getLastOutcomeOrNullAndReset", theGetLastExceptionSignature) + "();");
theCodeWriter.println("if (theLastException) {");
theCodeWriter.println("var theStringData = theLastException.message.data.data;");
theCodeWriter.println(" var theMessage = \"\";");
theCodeWriter.println(" for (var i=0;i<theStringData.length;i++) {");
theCodeWriter.println(" theMessage += String.fromCharCode(theStringData[i]);");
theCodeWriter.println(" }");
theCodeWriter.println(" console.log(\"Test finished with exception. Message = \" + theMessage);");
theCodeWriter.println(" throw theLastException;");
theCodeWriter.println("}");
theCodeWriter.println("console.log(\"Test finished OK\");");
theCodeWriter.flush();
File theWorkingDirectory = new File(".");
initializeSeleniumDriver();
File theMavenTargetDir = new File(theWorkingDirectory, "target");
File theGeneratedFilesDir = new File(theMavenTargetDir, "bytecoderjs");
theGeneratedFilesDir.mkdirs();
File theGeneratedFile = new File(theGeneratedFilesDir, theFilename);
PrintWriter theWriter = new PrintWriter(theGeneratedFile);
theWriter.println("<html><body><script>");
theWriter.println(theStrWriter.toString());
theWriter.println("</script></body></html>");
theWriter.flush();
theWriter.close();
theDriver = newDriverForTest();
theDriver.get(theGeneratedFile.toURI().toURL().toString());
List<LogEntry> theAll = theDriver.manage().logs().get(LogType.BROWSER).getAll();
if (theAll.size() < 1) {
aRunNotifier.fireTestFailure(new Failure(theDescription, new RuntimeException("No console output from browser")));
}
for (LogEntry theEntry : theAll) {
System.out.println(theEntry.getMessage());
}
LogEntry theLast = theAll.get(theAll.size() - 1);
if (!theLast.getMessage().contains("Test finished OK")) {
aRunNotifier.fireTestFailure(new Failure(theDescription, new RuntimeException("Test did not succeed! Got : " + theLast.getMessage())));
}
} catch (ControlFlowProcessingException e) {
System.out.println(e.getGraph().toDOT());
aRunNotifier.fireTestFailure(new Failure(theDescription, e));
} catch (Exception e) {
aRunNotifier.fireTestFailure(new Failure(theDescription, e));
} finally {
if (theDriver != null) {
theDriver.close();
}
aRunNotifier.fireTestFinished(theDescription);
}
}
Aggregations