mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
wasm: fix running tests, add in-browser test runners
This commit is contained in:
parent
b2b7a603b4
commit
c4c1408160
|
@ -114,6 +114,14 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
|
||||||
this(sb.buffer, 0, sb.length());
|
this(sb.buffer, 0, sb.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TString(int length) {
|
||||||
|
this.characters = new char[length];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TString allocate(int size) {
|
||||||
|
return new TString(size);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char charAt(int index) {
|
public char charAt(int index) {
|
||||||
if (index < 0 || index >= characters.length) {
|
if (index < 0 || index >= characters.length) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.teavm.backend.wasm.generate.WasmClassGenerator;
|
||||||
import org.teavm.backend.wasm.generate.WasmDependencyListener;
|
import org.teavm.backend.wasm.generate.WasmDependencyListener;
|
||||||
import org.teavm.backend.wasm.generate.WasmGenerationContext;
|
import org.teavm.backend.wasm.generate.WasmGenerationContext;
|
||||||
import org.teavm.backend.wasm.generate.WasmGenerator;
|
import org.teavm.backend.wasm.generate.WasmGenerator;
|
||||||
|
import org.teavm.backend.wasm.generate.WasmInteropFunctionGenerator;
|
||||||
import org.teavm.backend.wasm.generate.WasmNameProvider;
|
import org.teavm.backend.wasm.generate.WasmNameProvider;
|
||||||
import org.teavm.backend.wasm.generate.WasmSpecialFunctionGenerator;
|
import org.teavm.backend.wasm.generate.WasmSpecialFunctionGenerator;
|
||||||
import org.teavm.backend.wasm.generate.WasmStringPool;
|
import org.teavm.backend.wasm.generate.WasmStringPool;
|
||||||
|
@ -341,6 +342,9 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
|
|
||||||
dependencyAnalyzer.linkField(new FieldReference("java.lang.Object", "monitor"));
|
dependencyAnalyzer.linkField(new FieldReference("java.lang.Object", "monitor"));
|
||||||
|
|
||||||
|
dependencyAnalyzer.linkMethod(new MethodReference(String.class, "allocate", int.class, String.class))
|
||||||
|
.use();
|
||||||
|
|
||||||
ClassDependency runtimeClassDep = dependencyAnalyzer.linkClass(RuntimeClass.class.getName());
|
ClassDependency runtimeClassDep = dependencyAnalyzer.linkClass(RuntimeClass.class.getName());
|
||||||
ClassDependency runtimeObjectDep = dependencyAnalyzer.linkClass(RuntimeObject.class.getName());
|
ClassDependency runtimeObjectDep = dependencyAnalyzer.linkClass(RuntimeObject.class.getName());
|
||||||
ClassDependency runtimeArrayDep = dependencyAnalyzer.linkClass(RuntimeArray.class.getName());
|
ClassDependency runtimeArrayDep = dependencyAnalyzer.linkClass(RuntimeArray.class.getName());
|
||||||
|
@ -431,6 +435,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
WasmGenerator generator = new WasmGenerator(decompiler, classes, context, classGenerator, binaryWriter);
|
WasmGenerator generator = new WasmGenerator(decompiler, classes, context, classGenerator, binaryWriter);
|
||||||
|
|
||||||
generateMethods(classes, context, generator, classGenerator, binaryWriter, module);
|
generateMethods(classes, context, generator, classGenerator, binaryWriter, module);
|
||||||
|
new WasmInteropFunctionGenerator(classGenerator).generateFunctions(module);
|
||||||
exceptionHandlingIntrinsic.postProcess(CallSiteDescriptor.extract(classes, classes.getClassNames()));
|
exceptionHandlingIntrinsic.postProcess(CallSiteDescriptor.extract(classes, classes.getClassNames()));
|
||||||
generateIsSupertypeFunctions(tagRegistry, module, classGenerator);
|
generateIsSupertypeFunctions(tagRegistry, module, classGenerator);
|
||||||
classGenerator.postProcess();
|
classGenerator.postProcess();
|
||||||
|
@ -455,6 +460,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
module.add(initFunction);
|
module.add(initFunction);
|
||||||
module.setStartFunction(initFunction);
|
module.setStartFunction(initFunction);
|
||||||
|
|
||||||
|
|
||||||
for (TeaVMEntryPoint entryPoint : controller.getEntryPoints().values()) {
|
for (TeaVMEntryPoint entryPoint : controller.getEntryPoints().values()) {
|
||||||
String mangledName = names.forMethod(entryPoint.getMethod());
|
String mangledName = names.forMethod(entryPoint.getMethod());
|
||||||
WasmFunction function = module.getFunctions().get(mangledName);
|
WasmFunction function = module.getFunctions().get(mangledName);
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 konsoletyper.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.backend.wasm.generate;
|
||||||
|
|
||||||
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmInt32Subtype;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmLoadInt32;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmReturn;
|
||||||
|
import org.teavm.interop.Address;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
import org.teavm.runtime.Allocator;
|
||||||
|
import org.teavm.runtime.RuntimeArray;
|
||||||
|
import org.teavm.runtime.RuntimeClass;
|
||||||
|
|
||||||
|
public class WasmInteropFunctionGenerator {
|
||||||
|
private WasmClassGenerator classGenerator;
|
||||||
|
|
||||||
|
public WasmInteropFunctionGenerator(WasmClassGenerator classGenerator) {
|
||||||
|
this.classGenerator = classGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateFunctions(WasmModule module) {
|
||||||
|
module.add(allocateString());
|
||||||
|
module.add(stringData());
|
||||||
|
|
||||||
|
module.add(allocateArray("teavm_allocateObjectArray", ValueType.parse(Object.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateStringArray", ValueType.parse(String.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateByteArray", ValueType.parse(byte.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateShortArray", ValueType.parse(short.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateCharArray", ValueType.parse(char.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateIntArray", ValueType.parse(int.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateLongArray", ValueType.parse(long.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateFloatArray", ValueType.parse(float.class)));
|
||||||
|
module.add(allocateArray("teavm_allocateDoubleArray", ValueType.parse(double.class)));
|
||||||
|
module.add(arrayData("teavm_objectArrayData", 4));
|
||||||
|
module.add(arrayData("teavm_byteArrayData", 1));
|
||||||
|
module.add(arrayData("teavm_shortArrayData", 2));
|
||||||
|
module.add(arrayData("teavm_charArrayData", 2));
|
||||||
|
module.add(arrayData("teavm_intArrayData", 4));
|
||||||
|
module.add(arrayData("teavm_longArrayData", 8));
|
||||||
|
module.add(arrayData("teavm_floatArrayData", 4));
|
||||||
|
module.add(arrayData("teavm_doubleArrayData", 8));
|
||||||
|
module.add(arrayLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private WasmFunction allocateString() {
|
||||||
|
WasmFunction function = new WasmFunction("teavm_allocateString");
|
||||||
|
function.setExportName(function.getName());
|
||||||
|
function.setResult(WasmType.INT32);
|
||||||
|
function.getParameters().add(WasmType.INT32);
|
||||||
|
|
||||||
|
WasmLocal sizeLocal = new WasmLocal(WasmType.INT32, "size");
|
||||||
|
function.add(sizeLocal);
|
||||||
|
|
||||||
|
String constructorName = classGenerator.names.forMethod(new MethodReference(String.class, "allocate",
|
||||||
|
int.class, String.class));
|
||||||
|
WasmCall constructorCall = new WasmCall(constructorName);
|
||||||
|
constructorCall.getArguments().add(new WasmGetLocal(sizeLocal));
|
||||||
|
function.getBody().add(constructorCall);
|
||||||
|
|
||||||
|
function.getBody().add(new WasmReturn(constructorCall));
|
||||||
|
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmFunction allocateArray(String name, ValueType type) {
|
||||||
|
WasmFunction function = new WasmFunction(name);
|
||||||
|
function.setExportName(name);
|
||||||
|
function.setResult(WasmType.INT32);
|
||||||
|
function.getParameters().add(WasmType.INT32);
|
||||||
|
|
||||||
|
WasmLocal sizeLocal = new WasmLocal(WasmType.INT32, "size");
|
||||||
|
function.add(sizeLocal);
|
||||||
|
|
||||||
|
int classPointer = classGenerator.getClassPointer(ValueType.arrayOf(type));
|
||||||
|
String allocName = classGenerator.names.forMethod(new MethodReference(Allocator.class, "allocateArray",
|
||||||
|
RuntimeClass.class, int.class, Address.class));
|
||||||
|
WasmCall call = new WasmCall(allocName);
|
||||||
|
call.getArguments().add(new WasmInt32Constant(classPointer));
|
||||||
|
call.getArguments().add(new WasmGetLocal(sizeLocal));
|
||||||
|
|
||||||
|
function.getBody().add(new WasmReturn(call));
|
||||||
|
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmFunction stringData() {
|
||||||
|
WasmFunction function = new WasmFunction("teavm_stringData");
|
||||||
|
function.setExportName(function.getName());
|
||||||
|
function.setResult(WasmType.INT32);
|
||||||
|
function.getParameters().add(WasmType.INT32);
|
||||||
|
|
||||||
|
WasmLocal stringLocal = new WasmLocal(WasmType.INT32, "string");
|
||||||
|
function.add(stringLocal);
|
||||||
|
|
||||||
|
int offset = classGenerator.getFieldOffset(new FieldReference("java.lang.String", "characters"));
|
||||||
|
WasmExpression chars = new WasmLoadInt32(4, new WasmGetLocal(stringLocal), WasmInt32Subtype.INT32, offset);
|
||||||
|
|
||||||
|
function.getBody().add(new WasmReturn(chars));
|
||||||
|
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmFunction arrayData(String name, int alignment) {
|
||||||
|
WasmFunction function = new WasmFunction(name);
|
||||||
|
function.setExportName(function.getName());
|
||||||
|
function.setResult(WasmType.INT32);
|
||||||
|
function.getParameters().add(WasmType.INT32);
|
||||||
|
|
||||||
|
WasmLocal arrayLocal = new WasmLocal(WasmType.INT32, "array");
|
||||||
|
function.add(arrayLocal);
|
||||||
|
|
||||||
|
int start = WasmClassGenerator.align(classGenerator.getClassSize(RuntimeArray.class.getName()),
|
||||||
|
alignment);
|
||||||
|
WasmExpression data = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD,
|
||||||
|
new WasmGetLocal(arrayLocal), new WasmInt32Constant(start));
|
||||||
|
|
||||||
|
function.getBody().add(new WasmReturn(data));
|
||||||
|
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WasmFunction arrayLength() {
|
||||||
|
WasmFunction function = new WasmFunction("teavm_arrayLength");
|
||||||
|
function.setExportName(function.getName());
|
||||||
|
function.setResult(WasmType.INT32);
|
||||||
|
function.getParameters().add(WasmType.INT32);
|
||||||
|
|
||||||
|
WasmLocal arrayLocal = new WasmLocal(WasmType.INT32, "array");
|
||||||
|
function.add(arrayLocal);
|
||||||
|
|
||||||
|
int sizeOffset = classGenerator.getFieldOffset(new FieldReference(RuntimeArray.class.getName(), "size"));
|
||||||
|
|
||||||
|
WasmExpression ptr = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD,
|
||||||
|
new WasmGetLocal(arrayLocal), new WasmInt32Constant(sizeOffset));
|
||||||
|
WasmExpression length = new WasmLoadInt32(4, ptr, WasmInt32Subtype.INT32);
|
||||||
|
|
||||||
|
function.getBody().add(new WasmReturn(length));
|
||||||
|
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
}
|
|
@ -225,7 +225,7 @@ public class WasmCRenderer {
|
||||||
renderFunctionModifiers(sb, function);
|
renderFunctionModifiers(sb, function);
|
||||||
sb.append(WasmCRenderingVisitor.mapType(function.getResult())).append(' ');
|
sb.append(WasmCRenderingVisitor.mapType(function.getResult())).append(' ');
|
||||||
if (function.getImportName() != null) {
|
if (function.getImportName() != null) {
|
||||||
sb.append(!function.getImportModule().isEmpty()
|
sb.append(function.getImportModule() != null && !function.getImportModule().isEmpty()
|
||||||
? function.getImportModule() + "_" + function.getImportName()
|
? function.getImportModule() + "_" + function.getImportName()
|
||||||
: function.getImportName());
|
: function.getImportName());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
|
|
||||||
var TeaVM = TeaVM || {};
|
var TeaVM = TeaVM || {};
|
||||||
TeaVM.wasm = function() {
|
TeaVM.wasm = function() {
|
||||||
|
class JavaError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let lineBuffer = "";
|
let lineBuffer = "";
|
||||||
function putwchar(charCode) {
|
function putwchar(charCode) {
|
||||||
if (charCode === 10) {
|
if (charCode === 10) {
|
||||||
|
@ -87,7 +93,38 @@ TeaVM.wasm = function() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function run(path, options) {
|
function createTeaVM(instance) {
|
||||||
|
let teavm = {
|
||||||
|
memory: instance.exports.memory,
|
||||||
|
instance,
|
||||||
|
catchException: instance.exports.teavm_catchException
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const name of ["allocateString", "stringData", "allocateObjectArray", "allocateStringArray",
|
||||||
|
"allocateByteArray", "allocateShortArray", "allocateCharArray", "allocateIntArray",
|
||||||
|
"allocateLongArray", "allocateFloatArray", "allocateDoubleArray",
|
||||||
|
"objectArrayData", "byteArrayData", "shortArrayData", "charArrayData", "intArrayData",
|
||||||
|
"longArrayData", "floatArrayData", "doubleArrayData", "arrayLength"]) {
|
||||||
|
teavm[name] = wrapExport(instance.exports["teavm_" + name], instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
teavm.main = createMain(teavm, instance.exports.main);
|
||||||
|
|
||||||
|
return teavm;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapExport(fn, instance) {
|
||||||
|
return function() {
|
||||||
|
let result = fn.apply(this, arguments);
|
||||||
|
let ex = instance.exports.teavm_catchException();
|
||||||
|
if (ex !== 0) {
|
||||||
|
throw new JavaError("Uncaught exception occurred in java");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function load(path, options) {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
@ -105,23 +142,49 @@ TeaVM.wasm = function() {
|
||||||
xhr.responseType = "arraybuffer";
|
xhr.responseType = "arraybuffer";
|
||||||
xhr.open("GET", path);
|
xhr.open("GET", path);
|
||||||
|
|
||||||
xhr.onload = function() {
|
return new Promise((resolve, reject) => {
|
||||||
|
xhr.onload = () => {
|
||||||
let response = xhr.response;
|
let response = xhr.response;
|
||||||
if (!response) {
|
if (!response) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebAssembly.instantiate(response, importObj).then(function(resultObject) {
|
WebAssembly.instantiate(response, importObj).then(resultObject => {
|
||||||
importObj.teavm.logString.memory = resultObject.instance.exports.memory;
|
importObj.teavm.logString.memory = resultObject.instance.exports.memory;
|
||||||
resultObject.instance.exports.main();
|
let teavm = createTeaVM(resultObject.instance);
|
||||||
callback(resultObject);
|
teavm.main = createMain(teavm, wrapExport, resultObject.instance.exports.main);
|
||||||
}).catch(function(error) {
|
resolve(teavm);
|
||||||
console.log("Error loading WebAssembly %o", error);
|
}).catch(error => {
|
||||||
errorCallback(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
xhr.send();
|
xhr.send();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { importDefaults: importDefaults, run: run };
|
function createMain(teavm, mainFunction) {
|
||||||
|
return function(args) {
|
||||||
|
if (typeof args === "undefined") {
|
||||||
|
args = [];
|
||||||
|
}
|
||||||
|
return new Promise(resolve => {
|
||||||
|
let javaArgs = teavm.allocateStringArray(mainArgs.length);
|
||||||
|
let javaArgsData = new Uint32Array(teavm.memory, teavm.objectArrayData(javaArgs), args.length);
|
||||||
|
for (let i = 0; i < mainArgs.length; ++i) {
|
||||||
|
let arg = args[i];
|
||||||
|
let javaArg = teavm.allocateString(arg.length);
|
||||||
|
let javaArgAddress = teavm.objectArrayData(teavm.stringData(javaArg));
|
||||||
|
let javaArgData = new Uint16Array(teavm.memory, javaArgAddress, arg.length);
|
||||||
|
for (let j = 0; j < arg.length; ++j) {
|
||||||
|
javaArgData[j] = arg.charCodeAt(j);
|
||||||
|
}
|
||||||
|
javaArgsData[i] = javaArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(wrapExport(mainFunction, teavm.instance)(javaArgs));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { JavaError, importDefaults, load, wrapExport, createTeaVM, createMain };
|
||||||
}();
|
}();
|
||||||
|
|
|
@ -21,12 +21,12 @@ var Benchmark = function() {
|
||||||
this.resultTableBody = document.getElementById("result-table-body");
|
this.resultTableBody = document.getElementById("result-table-body");
|
||||||
}
|
}
|
||||||
Benchmark.prototype.load = function() {
|
Benchmark.prototype.load = function() {
|
||||||
TeaVM.wasm.run("teavm-wasm/classes.wasm", {
|
TeaVM.wasm.load("teavm-wasm/classes.wasm", {
|
||||||
installImports: installImports.bind(this),
|
installImports: installImports.bind(this),
|
||||||
callback: function(result) {
|
}).then(teavm => {
|
||||||
this.instance = result.instance;
|
this.instance = teavm;
|
||||||
}.bind(this)
|
teavm.main();
|
||||||
});
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
function installImports(o) {
|
function installImports(o) {
|
||||||
|
|
|
@ -104,6 +104,7 @@ public class TeaVMTestRunner extends Runner implements Filterable {
|
||||||
static final String TESTNG_PROVIDER = "org.testng.annotations.DataProvider";
|
static final String TESTNG_PROVIDER = "org.testng.annotations.DataProvider";
|
||||||
private static final String PATH_PARAM = "teavm.junit.target";
|
private static final String PATH_PARAM = "teavm.junit.target";
|
||||||
private static final String JS_RUNNER = "teavm.junit.js.runner";
|
private static final String JS_RUNNER = "teavm.junit.js.runner";
|
||||||
|
private static final String WASM_RUNNER = "teavm.junit.wasm.runner";
|
||||||
private static final String THREAD_COUNT = "teavm.junit.threads";
|
private static final String THREAD_COUNT = "teavm.junit.threads";
|
||||||
private static final String JS_ENABLED = "teavm.junit.js";
|
private static final String JS_ENABLED = "teavm.junit.js";
|
||||||
static final String JS_DECODE_STACK = "teavm.junit.js.decodeStack";
|
static final String JS_DECODE_STACK = "teavm.junit.js.decodeStack";
|
||||||
|
@ -191,6 +192,25 @@ public class TeaVMTestRunner extends Runner implements Filterable {
|
||||||
if (cCommand != null) {
|
if (cCommand != null) {
|
||||||
runners.get(RunKind.C).strategy = new CRunStrategy(cCommand);
|
runners.get(RunKind.C).strategy = new CRunStrategy(cCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runStrategyName = System.getProperty(WASM_RUNNER);
|
||||||
|
if (runStrategyName != null) {
|
||||||
|
TestRunStrategy wasmRunStrategy;
|
||||||
|
switch (runStrategyName) {
|
||||||
|
case "browser":
|
||||||
|
wasmRunStrategy = new BrowserRunStrategy(outputDir, "WASM", this::customBrowser);
|
||||||
|
break;
|
||||||
|
case "browser-chrome":
|
||||||
|
wasmRunStrategy = new BrowserRunStrategy(outputDir, "WASM", this::chromeBrowser);
|
||||||
|
break;
|
||||||
|
case "browser-firefox":
|
||||||
|
wasmRunStrategy = new BrowserRunStrategy(outputDir, "WASM", this::firefoxBrowser);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InitializationError("Unknown run strategy: " + runStrategyName);
|
||||||
|
}
|
||||||
|
runners.get(RunKind.WASM).strategy = wasmRunStrategy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Process customBrowser(String url) {
|
private Process customBrowser(String url) {
|
||||||
|
@ -479,6 +499,14 @@ public class TeaVMTestRunner extends Runner implements Filterable {
|
||||||
File testPath = getOutputFile(outputPath, "classTest", configuration.getSuffix(), false, ".wasm");
|
File testPath = getOutputFile(outputPath, "classTest", configuration.getSuffix(), false, ".wasm");
|
||||||
runs.add(createTestRun(configuration, testPath, child, RunKind.WASM, reference.toString(),
|
runs.add(createTestRun(configuration, testPath, child, RunKind.WASM, reference.toString(),
|
||||||
notifier, onSuccess));
|
notifier, onSuccess));
|
||||||
|
File htmlPath = getOutputFile(outputPathForMethod, "test-wasm", configuration.getSuffix(), false, ".html");
|
||||||
|
properties.put("SCRIPT", "../" + testPath.getName() + "-runtime.js");
|
||||||
|
properties.put("IDENTIFIER", reference.toString());
|
||||||
|
try {
|
||||||
|
resourceToFile("teavm-run-test-wasm.html", htmlPath, properties);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TeaVMTestConfiguration<CTarget> configuration : getCConfigurations()) {
|
for (TeaVMTestConfiguration<CTarget> configuration : getCConfigurations()) {
|
||||||
|
@ -526,6 +554,18 @@ public class TeaVMTestRunner extends Runner implements Filterable {
|
||||||
TestRun run = prepareRun(configuration, child, compileResult, notifier, RunKind.WASM, onSuccess);
|
TestRun run = prepareRun(configuration, child, compileResult, notifier, RunKind.WASM, onSuccess);
|
||||||
if (run != null) {
|
if (run != null) {
|
||||||
runs.add(run);
|
runs.add(run);
|
||||||
|
|
||||||
|
File testPath = getOutputFile(outputPath, "test", configuration.getSuffix(), false,
|
||||||
|
".wasm-runtime.js");
|
||||||
|
File htmlPath = getOutputFile(outputPath, "test", configuration.getSuffix(), false, ".html");
|
||||||
|
properties.put("SCRIPT", testPath.getName());
|
||||||
|
properties.put("IDENTIFIER", "");
|
||||||
|
|
||||||
|
try {
|
||||||
|
resourceToFile("teavm-run-test-wasm.html", htmlPath, properties);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="text/javascript" src="test.wasm-runtime.js"></script>
|
<script type="text/javascript" src="${SCRIPT}"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
TeaVM.wasm.run("test.wasm");
|
TeaVM.wasm.load("test.wasm").then(teavm => teavm.main(["${IDENTIFIER}"]));
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -32,7 +32,7 @@ window.addEventListener("message", event => {
|
||||||
case "WASM":
|
case "WASM":
|
||||||
const runtimeFile = request.file + "-runtime.js";
|
const runtimeFile = request.file + "-runtime.js";
|
||||||
appendFiles([runtimeFile], 0, () => {
|
appendFiles([runtimeFile], 0, () => {
|
||||||
launchWasmTest(request.file, equest.argument, response => {
|
launchWasmTest(request.file, request.argument, response => {
|
||||||
event.source.postMessage(response, "*");
|
event.source.postMessage(response, "*");
|
||||||
});
|
});
|
||||||
}, error => {
|
}, error => {
|
||||||
|
@ -112,7 +112,7 @@ function launchWasmTest(path, argument, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TeaVM.wasm.run(path, {
|
TeaVM.wasm.load(path, {
|
||||||
installImports: function(o) {
|
installImports: function(o) {
|
||||||
o.teavm.putwchar = putwchar;
|
o.teavm.putwchar = putwchar;
|
||||||
},
|
},
|
||||||
|
@ -122,7 +122,18 @@ function launchWasmTest(path, argument, callback) {
|
||||||
errorMessage: err.message + '\n' + err.stack
|
errorMessage: err.message + '\n' + err.stack
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
}).then(teavm => {
|
||||||
|
teavm.main(argument ? [argument] : []);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
callback(wrapResponse({ status: "OK" }));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
callback(wrapResponse({
|
||||||
|
status: "failed",
|
||||||
|
errorMessage: err.message + '\n' + err.stack
|
||||||
|
}));
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user