Wasm backend: copy wasm-runtime.js to the output directory. Fix wasm benchmark according latest changes

This commit is contained in:
Alexey Andreev 2018-05-13 19:45:25 +03:00
parent c9ebe2e2e9
commit 8cf69db8bb
3 changed files with 94 additions and 117 deletions

View File

@ -15,10 +15,13 @@
*/
package org.teavm.backend.wasm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -419,6 +422,8 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
if (cEmitted) {
emitC(module, buildTarget, getBaseName(outputName) + ".wasm.c");
}
emitRuntime(buildTarget, getBaseName(outputName) + ".wasm-runtime.js");
}
private class IntrinsicFactoryContext implements WasmIntrinsicFactoryContext {
@ -469,6 +474,22 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
}
}
private void emitRuntime(BuildTarget buildTarget, String outputName) throws IOException {
ClassLoader loader = controller.getClassLoader();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
loader.getResourceAsStream("org/teavm/backend/wasm/wasm-runtime.js"), StandardCharsets.UTF_8));
Writer writer = new OutputStreamWriter(buildTarget.createResource(outputName),
StandardCharsets.UTF_8)) {
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
writer.append(line).append('\n');
}
}
}
private void generateMethods(ListableClassHolderSource classes, WasmGenerationContext context,
WasmGenerator generator, WasmClassGenerator classGenerator, BinaryWriter binaryWriter, WasmModule module) {
List<MethodHolder> methods = new ArrayList<>();

View File

@ -18,6 +18,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>TeaVM WebAssembly jbox2d benchmark</title>
<script src="teavm-wasm/classes.wasm-runtime.js" type="text/javascript"></script>
<script src="teavm-wasm.js" type="text/javascript"></script>
</head>
<body>
@ -39,7 +40,7 @@
var canvas = document.getElementById("benchmark-canvas");
document.body.onload = function() {
var benchmark = new Benchmark(canvas.getContext("2d"));
benchmark.runAll();
benchmark.load();
}
</script>
</body>

View File

@ -18,131 +18,86 @@ var Benchmark = function() {
function Benchmark(canvas) {
this.canvas = canvas;
this.instance = null;
this.line = "";
this.resultTableBody = document.getElementById("result-table-body");
}
Benchmark.prototype.runAll = function() {
load(this, function() { this.instance.exports.main(); }.bind(this));
Benchmark.prototype.load = function() {
TeaVM.wasm.run("teavm-wasm/classes.wasm", {
installImports: installImports.bind(this),
callback: function(result) {
this.instance = result.instance;
}.bind(this)
});
};
function tick(benchmark) {
var exports = benchmark.instance.exports;
function installImports(o) {
var canvas = this.canvas;
o.benchmark = {
performanceTime: function() { return window.performance.now() || 0; },
reportPerformance: function(second, timeSpentComputing) {
var row = document.createElement("tr");
this.resultTableBody.appendChild(row);
var secondCell = document.createElement("td");
row.appendChild(secondCell);
secondCell.appendChild(document.createTextNode(second.toString()));
var timeCell = document.createElement("td");
row.appendChild(timeCell);
timeCell.appendChild(document.createTextNode(timeSpentComputing.toString()));
}.bind(this),
repeatAfter: function(time) {
setTimeout(tick.bind(this), time);
}.bind(this),
setupCanvas: function() {
canvas.fillStyle = "white";
canvas.strokeStyle = "grey";
canvas.fillRect(0, 0, 600, 600);
canvas.translate(0, 600);
canvas.scale(1, -1);
canvas.scale(100, 100);
canvas.lineWidth = 0.01;
}
};
o.canvas = {
save: function() {
canvas.save();
},
restore: function() {
canvas.restore();
},
beginPath: function() {
canvas.beginPath();
},
closePath: function() {
canvas.closePath();
},
stroke: function() {
canvas.stroke();
},
moveTo: function(x, y) {
canvas.moveTo(x, y);
},
lineTo: function(x, y) {
canvas.lineTo(x, y);
},
translate: function(x, y) {
canvas.translate(x, y);
},
rotate: function(angle) {
canvas.rotate(angle);
},
arc: function(cx, cy, radius, startAngle, endAngle, counterClockwise) {
canvas.arc(cx, cy, radius, startAngle, endAngle, counterClockwise);
}
};
}
function tick() {
var exports = this.instance.exports;
exports.tick();
var exception = exports.sys$catchException();
var exception = exports.sys_catchException();
if (exception !== 0) {
console.log("Exception: " + exception);
}
}
function currentTimeMillis() {
return new Date().getTime();
}
function putchar(benchmark, charCode) {
if (charCode == 10) {
console.log(benchmark.line);
benchmark.line = "";
} else {
benchmark.line += String.fromCharCode(charCode);
}
}
function load(benchmark, callback) {
var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";
xhr.open("GET", "teavm-wasm/classes.wasm");
xhr.onload = function() {
var response = xhr.response;
if (!response) {
return;
}
var canvas = benchmark.canvas;
var importObj = {
runtime: {
currentTimeMillis: currentTimeMillis,
isNaN: isNaN,
isFinite: isFinite,
getNaN: function() { return NaN; },
putchar: function(code) { putchar(benchmark, code); }
},
benchmark: {
performanceTime: function() { return window.performance.now() || 0; },
reportPerformance: function(second, timeSpentComputing) {
var row = document.createElement("tr");
benchmark.resultTableBody.appendChild(row);
var secondCell = document.createElement("td");
row.appendChild(secondCell);
secondCell.appendChild(document.createTextNode(second.toString()));
var timeCell = document.createElement("td");
row.appendChild(timeCell);
timeCell.appendChild(document.createTextNode(timeSpentComputing.toString()));
},
repeatAfter: function(time) {
setTimeout(tick.bind(null, benchmark), time);
},
setupCanvas: function() {
canvas.fillStyle = "white";
canvas.strokeStyle = "grey";
canvas.fillRect(0, 0, 600, 600);
canvas.translate(0, 600);
canvas.scale(1, -1);
canvas.scale(100, 100);
canvas.lineWidth = 0.01;
}
},
canvas: {
save: function() {
canvas.save();
},
restore: function() {
canvas.restore();
},
beginPath: function() {
canvas.beginPath();
},
closePath: function() {
canvas.closePath();
},
stroke: function() {
canvas.stroke();
},
moveTo: function(x, y) {
canvas.moveTo(x, y);
},
lineTo: function(x, y) {
canvas.lineTo(x, y);
},
translate: function(x, y) {
canvas.translate(x, y);
},
rotate: function(angle) {
canvas.rotate(angle);
},
arc: function(cx, cy, radius, startAngle, endAngle, counterClockwise) {
canvas.arc(cx, cy, radius, startAngle, endAngle, counterClockwise);
}
},
math: Math,
debug: {
traceMemoryAccess: function(callSite, address) {
if (address >= 63 * 65536) {
console.log("Memory access #" + callSite + " at " + address);
}
return address;
}
}
};
WebAssembly.instantiate(response, importObj).then(function(resultObject) {
benchmark.instance = resultObject.instance;
console.log("Initialized")
callback();
}).catch(function(error) {
console.log("Error : " + error);
});
};
xhr.send();
}
return Benchmark;
}();