Search in sources :

Example 1 with WASMCompileResult

use of de.mirkosertic.bytecoder.backend.wasm.WASMCompileResult in project Bytecoder by mirkosertic.

the class BytecoderMavenMojo method execute.

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
    File theBaseDirectory = new File(buldDirectory);
    File theBytecoderDirectory = new File(theBaseDirectory, "bytecoder");
    theBytecoderDirectory.mkdirs();
    try {
        ClassLoader theLoader = prepareClassLoader();
        Class theTargetClass = theLoader.loadClass(mainClass);
        CompileTarget theCompileTarget = new CompileTarget(theLoader, CompileTarget.BackendType.valueOf(backend));
        File theBytecoderFileName = new File(theBytecoderDirectory, theCompileTarget.generatedFileName());
        BytecodeMethodSignature theSignature = new BytecodeMethodSignature(BytecodePrimitiveTypeRef.VOID, new BytecodeTypeRef[] { new BytecodeArrayTypeRef(BytecodeObjectTypeRef.fromRuntimeClass(String.class), 1) });
        CompileOptions theOptions = new CompileOptions(new Slf4JLogger(), debugOutput, KnownOptimizer.ALL);
        CompileResult theCode = theCompileTarget.compileToJS(theOptions, theTargetClass, "main", theSignature);
        try (PrintWriter theWriter = new PrintWriter(new FileWriter(theBytecoderFileName))) {
            theWriter.println(theCode.getData());
        }
        if (optimizeWithGoogleClosure) {
            Compiler theCompiler = new Compiler();
            CompilerOptions theClosureOptions = new CompilerOptions();
            theClosureOptions.setLanguageIn(CompilerOptions.LanguageMode.ECMASCRIPT5_STRICT);
            theClosureOptions.setLanguageOut(CompilerOptions.LanguageMode.ECMASCRIPT5_STRICT);
            CompilationLevel.valueOf(closureOptimizationLevel).setOptionsForCompilationLevel(theClosureOptions);
            List<SourceFile> theSourceFiles = CommandLineRunner.getBuiltinExterns(CompilerOptions.Environment.BROWSER);
            theSourceFiles.add(SourceFile.fromCode("bytecoder.js", (String) theCode.getData()));
            theCompiler.compile(new ArrayList<>(), theSourceFiles, theClosureOptions);
            String theClosureCode = theCompiler.toSource();
            File theBytecoderClosureFileName = new File(theBytecoderDirectory, "bytecoder-closure.js");
            try (PrintWriter theWriter = new PrintWriter(new FileWriter(theBytecoderClosureFileName))) {
                theWriter.println(theClosureCode);
            }
        }
        if (theCode instanceof WASMCompileResult) {
            WASMCompileResult theWASMCompileResult = (WASMCompileResult) theCode;
            int[] theWASM = wat2wasm(theWASMCompileResult);
            File theBytecoderWASMFileName = new File(theBytecoderDirectory, "bytecoder.wasm");
            try (FileOutputStream theFos = new FileOutputStream(theBytecoderWASMFileName)) {
                for (int aTheWASM : theWASM) {
                    theFos.write(aTheWASM);
                }
            }
        }
    } catch (Exception e) {
        throw new MojoExecutionException("Error running bytecoder", e);
    }
}
Also used : Compiler(com.google.javascript.jscomp.Compiler) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) WASMCompileResult(de.mirkosertic.bytecoder.backend.wasm.WASMCompileResult) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) FileWriter(java.io.FileWriter) CompileOptions(de.mirkosertic.bytecoder.backend.CompileOptions) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) BytecodeArrayTypeRef(de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef) FileOutputStream(java.io.FileOutputStream) CompileTarget(de.mirkosertic.bytecoder.backend.CompileTarget) CompilerOptions(com.google.javascript.jscomp.CompilerOptions) URLClassLoader(java.net.URLClassLoader) WASMCompileResult(de.mirkosertic.bytecoder.backend.wasm.WASMCompileResult) CompileResult(de.mirkosertic.bytecoder.backend.CompileResult) SourceFile(com.google.javascript.jscomp.SourceFile) SourceFile(com.google.javascript.jscomp.SourceFile) File(java.io.File) Slf4JLogger(de.mirkosertic.bytecoder.unittest.Slf4JLogger) PrintWriter(java.io.PrintWriter)

Example 2 with WASMCompileResult

use of de.mirkosertic.bytecoder.backend.wasm.WASMCompileResult 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);
    }
}
Also used : WebDriver(org.openqa.selenium.WebDriver) RemoteWebDriver(org.openqa.selenium.remote.RemoteWebDriver) Description(org.junit.runner.Description) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) WASMCompileResult(de.mirkosertic.bytecoder.backend.wasm.WASMCompileResult) FileWriter(java.io.FileWriter) CompileOptions(de.mirkosertic.bytecoder.backend.CompileOptions) IOException(java.io.IOException) ControlFlowProcessingException(de.mirkosertic.bytecoder.ssa.ControlFlowProcessingException) BytecodeObjectTypeRef(de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef) FileOutputStream(java.io.FileOutputStream) CompileTarget(de.mirkosertic.bytecoder.backend.CompileTarget) ControlFlowProcessingException(de.mirkosertic.bytecoder.ssa.ControlFlowProcessingException) File(java.io.File) LogEntry(org.openqa.selenium.logging.LogEntry) Failure(org.junit.runner.notification.Failure) PrintWriter(java.io.PrintWriter)

Aggregations

CompileOptions (de.mirkosertic.bytecoder.backend.CompileOptions)2 CompileTarget (de.mirkosertic.bytecoder.backend.CompileTarget)2 WASMCompileResult (de.mirkosertic.bytecoder.backend.wasm.WASMCompileResult)2 BytecodeMethodSignature (de.mirkosertic.bytecoder.core.BytecodeMethodSignature)2 File (java.io.File)2 FileOutputStream (java.io.FileOutputStream)2 FileWriter (java.io.FileWriter)2 IOException (java.io.IOException)2 PrintWriter (java.io.PrintWriter)2 Compiler (com.google.javascript.jscomp.Compiler)1 CompilerOptions (com.google.javascript.jscomp.CompilerOptions)1 SourceFile (com.google.javascript.jscomp.SourceFile)1 CompileResult (de.mirkosertic.bytecoder.backend.CompileResult)1 BytecodeArrayTypeRef (de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef)1 BytecodeObjectTypeRef (de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef)1 ControlFlowProcessingException (de.mirkosertic.bytecoder.ssa.ControlFlowProcessingException)1 Slf4JLogger (de.mirkosertic.bytecoder.unittest.Slf4JLogger)1 MalformedURLException (java.net.MalformedURLException)1 URLClassLoader (java.net.URLClassLoader)1 MojoExecutionException (org.apache.maven.plugin.MojoExecutionException)1