mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
WASM: support multianewarray, fix jbox2d benchmark for WebAssembly
This commit is contained in:
parent
84628b7008
commit
0041130d00
|
@ -225,6 +225,8 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
RuntimeClass.class, Address.class), null).use();
|
RuntimeClass.class, Address.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocateArray",
|
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocateArray",
|
||||||
RuntimeClass.class, int.class, Address.class), null).use();
|
RuntimeClass.class, int.class, Address.class), null).use();
|
||||||
|
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocateMultiArray",
|
||||||
|
RuntimeClass.class, Address.class, int.class, RuntimeArray.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "<clinit>", void.class), null).use();
|
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "<clinit>", void.class), null).use();
|
||||||
|
|
||||||
|
@ -311,10 +313,9 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
classGenerator);
|
classGenerator);
|
||||||
context.addIntrinsic(exceptionHandlingIntrinsic);
|
context.addIntrinsic(exceptionHandlingIntrinsic);
|
||||||
|
|
||||||
WasmGenerator generator = new WasmGenerator(decompiler, classes,
|
WasmGenerator generator = new WasmGenerator(decompiler, classes, context, classGenerator, binaryWriter);
|
||||||
context, classGenerator);
|
|
||||||
|
|
||||||
module.setMemorySize(64);
|
module.setMemorySize(128);
|
||||||
generateMethods(classes, context, generator, module);
|
generateMethods(classes, context, generator, module);
|
||||||
exceptionHandlingIntrinsic.postProcess(shadowStackTransformer.getCallSites());
|
exceptionHandlingIntrinsic.postProcess(shadowStackTransformer.getCallSites());
|
||||||
generateIsSupertypeFunctions(tagRegistry, module, classGenerator);
|
generateIsSupertypeFunctions(tagRegistry, module, classGenerator);
|
||||||
|
|
|
@ -64,6 +64,8 @@ import org.teavm.ast.UnwrapArrayExpr;
|
||||||
import org.teavm.ast.VariableExpr;
|
import org.teavm.ast.VariableExpr;
|
||||||
import org.teavm.ast.WhileStatement;
|
import org.teavm.ast.WhileStatement;
|
||||||
import org.teavm.backend.wasm.WasmRuntime;
|
import org.teavm.backend.wasm.WasmRuntime;
|
||||||
|
import org.teavm.backend.wasm.binary.BinaryWriter;
|
||||||
|
import org.teavm.backend.wasm.binary.DataPrimitives;
|
||||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager;
|
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
@ -129,12 +131,14 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||||
private Set<WasmBlock> usedBlocks = new HashSet<>();
|
private Set<WasmBlock> usedBlocks = new HashSet<>();
|
||||||
private List<Deque<WasmLocal>> temporaryVariablesByType = new ArrayList<>();
|
private List<Deque<WasmLocal>> temporaryVariablesByType = new ArrayList<>();
|
||||||
private WasmLocal stackVariable;
|
private WasmLocal stackVariable;
|
||||||
|
private BinaryWriter binaryWriter;
|
||||||
WasmExpression result;
|
WasmExpression result;
|
||||||
|
|
||||||
WasmGenerationVisitor(WasmGenerationContext context, WasmClassGenerator classGenerator,
|
WasmGenerationVisitor(WasmGenerationContext context, WasmClassGenerator classGenerator,
|
||||||
WasmFunction function, int firstVariable) {
|
BinaryWriter binaryWriter, WasmFunction function, int firstVariable) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.classGenerator = classGenerator;
|
this.classGenerator = classGenerator;
|
||||||
|
this.binaryWriter = binaryWriter;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
this.firstVariable = firstVariable;
|
this.firstVariable = firstVariable;
|
||||||
int typeCount = WasmType.values().length;
|
int typeCount = WasmType.values().length;
|
||||||
|
@ -1128,6 +1132,31 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewMultiArrayExpr expr) {
|
public void visit(NewMultiArrayExpr expr) {
|
||||||
|
ValueType type = expr.getType();
|
||||||
|
|
||||||
|
WasmBlock block = new WasmBlock(false);
|
||||||
|
int dimensionList = -1;
|
||||||
|
for (Expr dimension : expr.getDimensions()) {
|
||||||
|
int dimensionAddress = binaryWriter.append(DataPrimitives.INT.createValue());
|
||||||
|
if (dimensionList < 0) {
|
||||||
|
dimensionList = dimensionAddress;
|
||||||
|
}
|
||||||
|
accept(dimension);
|
||||||
|
block.getBody().add(new WasmStoreInt32(4, new WasmInt32Constant(dimensionAddress), result,
|
||||||
|
WasmInt32Subtype.INT32));
|
||||||
|
}
|
||||||
|
|
||||||
|
int classPointer = classGenerator.getClassPointer(ValueType.arrayOf(type));
|
||||||
|
String allocName = WasmMangling.mangleMethod(new MethodReference(Allocator.class, "allocateMultiArray",
|
||||||
|
RuntimeClass.class, Address.class, int.class, RuntimeArray.class));
|
||||||
|
WasmCall call = new WasmCall(allocName);
|
||||||
|
call.getArguments().add(new WasmInt32Constant(classPointer));
|
||||||
|
call.getArguments().add(new WasmInt32Constant(dimensionList));
|
||||||
|
call.getArguments().add(new WasmInt32Constant(expr.getDimensions().size()));
|
||||||
|
call.setLocation(expr.getLocation());
|
||||||
|
|
||||||
|
block.getBody().add(call);
|
||||||
|
result = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.backend.wasm.generate;
|
||||||
import org.teavm.ast.RegularMethodNode;
|
import org.teavm.ast.RegularMethodNode;
|
||||||
import org.teavm.ast.VariableNode;
|
import org.teavm.ast.VariableNode;
|
||||||
import org.teavm.ast.decompilation.Decompiler;
|
import org.teavm.ast.decompilation.Decompiler;
|
||||||
|
import org.teavm.backend.wasm.binary.BinaryWriter;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmLocal;
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
@ -35,13 +36,15 @@ public class WasmGenerator {
|
||||||
private ClassHolderSource classSource;
|
private ClassHolderSource classSource;
|
||||||
private WasmGenerationContext context;
|
private WasmGenerationContext context;
|
||||||
private WasmClassGenerator classGenerator;
|
private WasmClassGenerator classGenerator;
|
||||||
|
private BinaryWriter binaryWriter;
|
||||||
|
|
||||||
public WasmGenerator(Decompiler decompiler, ClassHolderSource classSource,
|
public WasmGenerator(Decompiler decompiler, ClassHolderSource classSource,
|
||||||
WasmGenerationContext context, WasmClassGenerator classGenerator) {
|
WasmGenerationContext context, WasmClassGenerator classGenerator, BinaryWriter binaryWriter) {
|
||||||
this.decompiler = decompiler;
|
this.decompiler = decompiler;
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.classGenerator = classGenerator;
|
this.classGenerator = classGenerator;
|
||||||
|
this.binaryWriter = binaryWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generate(MethodReference methodReference, MethodHolder bodyMethod) {
|
public WasmFunction generate(MethodReference methodReference, MethodHolder bodyMethod) {
|
||||||
|
@ -66,7 +69,7 @@ public class WasmGenerator {
|
||||||
function.setResult(WasmGeneratorUtil.mapType(methodReference.getReturnType()));
|
function.setResult(WasmGeneratorUtil.mapType(methodReference.getReturnType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmGenerationVisitor visitor = new WasmGenerationVisitor(context, classGenerator, function,
|
WasmGenerationVisitor visitor = new WasmGenerationVisitor(context, classGenerator, binaryWriter, function,
|
||||||
firstVariable);
|
firstVariable);
|
||||||
methodAst.getBody().acceptVisitor(visitor);
|
methodAst.getBody().acceptVisitor(visitor);
|
||||||
function.getBody().add(visitor.result);
|
function.getBody().add(visitor.result);
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.teavm.model.instructions.BinaryBranchingInstruction;
|
||||||
import org.teavm.model.instructions.CloneArrayInstruction;
|
import org.teavm.model.instructions.CloneArrayInstruction;
|
||||||
import org.teavm.model.instructions.ConstructArrayInstruction;
|
import org.teavm.model.instructions.ConstructArrayInstruction;
|
||||||
import org.teavm.model.instructions.ConstructInstruction;
|
import org.teavm.model.instructions.ConstructInstruction;
|
||||||
|
import org.teavm.model.instructions.ConstructMultiArrayInstruction;
|
||||||
import org.teavm.model.instructions.DoubleConstantInstruction;
|
import org.teavm.model.instructions.DoubleConstantInstruction;
|
||||||
import org.teavm.model.instructions.ExitInstruction;
|
import org.teavm.model.instructions.ExitInstruction;
|
||||||
import org.teavm.model.instructions.FloatConstantInstruction;
|
import org.teavm.model.instructions.FloatConstantInstruction;
|
||||||
|
@ -209,8 +210,8 @@ public class ExceptionHandlingShadowStackContributor {
|
||||||
|
|
||||||
private boolean isCallInstruction(Instruction insn) {
|
private boolean isCallInstruction(Instruction insn) {
|
||||||
if (insn instanceof InitClassInstruction || insn instanceof ConstructInstruction
|
if (insn instanceof InitClassInstruction || insn instanceof ConstructInstruction
|
||||||
|| insn instanceof ConstructArrayInstruction || insn instanceof CloneArrayInstruction
|
|| insn instanceof ConstructArrayInstruction || insn instanceof ConstructMultiArrayInstruction
|
||||||
|| insn instanceof RaiseInstruction) {
|
|| insn instanceof CloneArrayInstruction || insn instanceof RaiseInstruction) {
|
||||||
return true;
|
return true;
|
||||||
} else if (insn instanceof InvokeInstruction) {
|
} else if (insn instanceof InvokeInstruction) {
|
||||||
return managedMethodRepository.isManaged(((InvokeInstruction) insn).getMethod());
|
return managedMethodRepository.isManaged(((InvokeInstruction) insn).getMethod());
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.teavm.model.Variable;
|
||||||
import org.teavm.model.instructions.CloneArrayInstruction;
|
import org.teavm.model.instructions.CloneArrayInstruction;
|
||||||
import org.teavm.model.instructions.ConstructArrayInstruction;
|
import org.teavm.model.instructions.ConstructArrayInstruction;
|
||||||
import org.teavm.model.instructions.ConstructInstruction;
|
import org.teavm.model.instructions.ConstructInstruction;
|
||||||
|
import org.teavm.model.instructions.ConstructMultiArrayInstruction;
|
||||||
import org.teavm.model.instructions.InitClassInstruction;
|
import org.teavm.model.instructions.InitClassInstruction;
|
||||||
import org.teavm.model.instructions.IntegerConstantInstruction;
|
import org.teavm.model.instructions.IntegerConstantInstruction;
|
||||||
import org.teavm.model.instructions.InvocationType;
|
import org.teavm.model.instructions.InvocationType;
|
||||||
|
@ -149,6 +150,7 @@ public class GCShadowStackContributor {
|
||||||
}
|
}
|
||||||
if (insn instanceof InvokeInstruction || insn instanceof InitClassInstruction
|
if (insn instanceof InvokeInstruction || insn instanceof InitClassInstruction
|
||||||
|| insn instanceof ConstructInstruction || insn instanceof ConstructArrayInstruction
|
|| insn instanceof ConstructInstruction || insn instanceof ConstructArrayInstruction
|
||||||
|
|| insn instanceof ConstructMultiArrayInstruction
|
||||||
|| insn instanceof CloneArrayInstruction || insn instanceof RaiseInstruction) {
|
|| insn instanceof CloneArrayInstruction || insn instanceof RaiseInstruction) {
|
||||||
if (insn instanceof InvokeInstruction
|
if (insn instanceof InvokeInstruction
|
||||||
&& !managedMethodRepository.isManaged(((InvokeInstruction) insn).getMethod())) {
|
&& !managedMethodRepository.isManaged(((InvokeInstruction) insn).getMethod())) {
|
||||||
|
|
|
@ -47,6 +47,21 @@ public final class Allocator {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RuntimeArray allocateMultiArray(RuntimeClass tag, Address dimensions, int dimensionCount) {
|
||||||
|
int size = dimensions.getInt();
|
||||||
|
RuntimeArray array = allocateArray(tag, dimensions.getInt()).toStructure();
|
||||||
|
if (dimensionCount > 1) {
|
||||||
|
Address arrayData = Structure.add(RuntimeArray.class, array, 1).toAddress();
|
||||||
|
arrayData = Address.align(arrayData, Address.sizeOf());
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
RuntimeArray innerArray = allocateMultiArray(tag.itemType, dimensions.add(4), dimensionCount - 1);
|
||||||
|
arrayData.putAddress(innerArray.toAddress());
|
||||||
|
arrayData = arrayData.add(Address.sizeOf());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
public static native void fillZero(Address address, int count);
|
public static native void fillZero(Address address, int count);
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,9 @@
|
||||||
<resource>
|
<resource>
|
||||||
<directory>${project.build.directory}/generated/js</directory>
|
<directory>${project.build.directory}/generated/js</directory>
|
||||||
</resource>
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.build.directory}/generated/wasm</directory>
|
||||||
|
</resource>
|
||||||
</webResources>
|
</webResources>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
@ -126,6 +129,7 @@
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/gwt/*</exclude>
|
<exclude>**/gwt/*</exclude>
|
||||||
<exclude>**/teavm/*</exclude>
|
<exclude>**/teavm/*</exclude>
|
||||||
|
<exclude>**/benchmark/jvm/*</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
|
@ -30,7 +30,7 @@ public final class WasmBenchmarkStarter {
|
||||||
private static Scene scene = new Scene();
|
private static Scene scene = new Scene();
|
||||||
private static int currentSecond;
|
private static int currentSecond;
|
||||||
private static long startMillisecond;
|
private static long startMillisecond;
|
||||||
private static int timeSpentCalculating;
|
private static double timeSpentCalculating;
|
||||||
|
|
||||||
private WasmBenchmarkStarter() {
|
private WasmBenchmarkStarter() {
|
||||||
}
|
}
|
||||||
|
@ -43,17 +43,15 @@ public final class WasmBenchmarkStarter {
|
||||||
@Export(name = "tick")
|
@Export(name = "tick")
|
||||||
public static void tick() {
|
public static void tick() {
|
||||||
double start = performanceTime();
|
double start = performanceTime();
|
||||||
System.out.println("About to calculate frame");
|
|
||||||
scene.calculate();
|
scene.calculate();
|
||||||
System.out.println("Frame calculated successfully");
|
|
||||||
double end = performanceTime();
|
double end = performanceTime();
|
||||||
int second = (int) ((System.currentTimeMillis() - startMillisecond) / 1000);
|
int second = (int) ((System.currentTimeMillis() - startMillisecond) / 1000);
|
||||||
if (second > currentSecond) {
|
if (second > currentSecond) {
|
||||||
reportPerformance(second, timeSpentCalculating);
|
reportPerformance(second, (int) timeSpentCalculating);
|
||||||
timeSpentCalculating = 0;
|
timeSpentCalculating = 0;
|
||||||
currentSecond = second;
|
currentSecond = second;
|
||||||
}
|
}
|
||||||
timeSpentCalculating += (int) (end - start);
|
timeSpentCalculating += end - start;
|
||||||
render();
|
render();
|
||||||
repeatAfter(scene.timeUntilNextStep());
|
repeatAfter(scene.timeUntilNextStep());
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<li><a href="teavm.html">TeaVM</a></li>
|
<li><a href="teavm.html">TeaVM</a></li>
|
||||||
<li><a href="gwt.html">GWT</a></li>
|
<li><a href="gwt.html">GWT</a></li>
|
||||||
<li><a href="bck2brwsr.html">Bck2Brwsr VM</a></li>
|
<li><a href="bck2brwsr.html">Bck2Brwsr VM</a></li>
|
||||||
|
<li><a href="teavm-wasm.html">TeaVM (experimental WebAssembly backend)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -19,17 +19,17 @@ var Benchmark = function() {
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
this.module = null;
|
this.module = null;
|
||||||
this.line = "";
|
this.line = "";
|
||||||
|
this.resultTableBody = document.getElementById("result-table-body");
|
||||||
}
|
}
|
||||||
Benchmark.prototype.runAll = function() {
|
Benchmark.prototype.runAll = function() {
|
||||||
load(this, function() { this.module.exports.main(); }.bind(this));
|
load(this, function() { this.module.exports.main(); }.bind(this));
|
||||||
}
|
};
|
||||||
|
|
||||||
function tick(benchmark) {
|
function tick(benchmark) {
|
||||||
var exports = benchmark.module.exports;
|
var exports = benchmark.module.exports;
|
||||||
exports.tick();
|
exports.tick();
|
||||||
console.log("tick");
|
|
||||||
var exception = exports.sys$catchException();
|
var exception = exports.sys$catchException();
|
||||||
if (exception != null) {
|
if (exception !== 0) {
|
||||||
console.log("Exception: " + exception);
|
console.log("Exception: " + exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,41 +49,79 @@ var Benchmark = function() {
|
||||||
|
|
||||||
function load(benchmark, callback) {
|
function load(benchmark, callback) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.responseType = "arraybuffer";
|
||||||
xhr.open("GET", "teavm-wasm/classes.wasm");
|
xhr.open("GET", "teavm-wasm/classes.wasm");
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onload = function() {
|
||||||
var response = xhr.response;
|
var response = xhr.response;
|
||||||
if (!response) {
|
if (!response) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var canvas = benchmark.canvas;
|
||||||
var importObj = {
|
var importObj = {
|
||||||
runtime: {
|
runtime: {
|
||||||
currentTimeMillis: currentTimeMillis,
|
currentTimeMillis: currentTimeMillis,
|
||||||
isNaN: isNaN,
|
isNaN: isNaN,
|
||||||
isFinite: isFinite,
|
isFinite: isFinite,
|
||||||
getNaN: function() { return NaN; },
|
getNaN: function() { return NaN; },
|
||||||
putchar: function() { putchar(benchmark); }
|
putchar: function(code) { putchar(benchmark, code); }
|
||||||
},
|
},
|
||||||
benchmark: {
|
benchmark: {
|
||||||
performanceTime: function() { return window.performance.now() || 0; },
|
performanceTime: function() { return window.performance.now() || 0; },
|
||||||
reportPerformance: function(second, timeSpentComputing) {
|
reportPerformance: function(second, timeSpentComputing) {
|
||||||
console.log("Second: " + second + ", time: " + 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) {
|
repeatAfter: function(time) {
|
||||||
console.log("repeatAfter");
|
setTimeout(tick.bind(null, benchmark), time);
|
||||||
setTimeout(tick.bind(benchmark), time);
|
|
||||||
},
|
},
|
||||||
setupCanvas: function() {
|
setupCanvas: function() {
|
||||||
var canvas = benchmark.canvas;
|
canvas.fillStyle = "white";
|
||||||
canvas.setFillStyle("white");
|
canvas.strokeStyle = "grey";
|
||||||
context.setStrokeStyle("grey");
|
|
||||||
canvas.fillRect(0, 0, 600, 600);
|
canvas.fillRect(0, 0, 600, 600);
|
||||||
canvas.translate(0, 600);
|
canvas.translate(0, 600);
|
||||||
canvas.scale(1, -1);
|
canvas.scale(1, -1);
|
||||||
canvas.scale(100, 100);
|
canvas.scale(100, 100);
|
||||||
canvas.setLineWidth(0.01);
|
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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
canvas: benchmark.canvas,
|
|
||||||
math: Math,
|
math: Math,
|
||||||
debug: {
|
debug: {
|
||||||
traceMemoryAccess: function(callSite, address) {
|
traceMemoryAccess: function(callSite, address) {
|
||||||
|
@ -94,11 +132,13 @@ var Benchmark = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
benchmark.module = Wasm.instantiateModule(new Uint8Array(response), importObj)
|
WebAssembly.compile(response).then(function(module) {
|
||||||
callback();
|
benchmark.module = new WebAssembly.Instance(module, importObj);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Benchmark;
|
return Benchmark;
|
||||||
}();
|
}();
|
Loading…
Reference in New Issue
Block a user