This commit is contained in:
Jesse Wilson
2025-02-18 23:49:30 -05:00
parent 1eff69cc8e
commit 3aafd54196
10 changed files with 61 additions and 11 deletions

View File

@@ -16,8 +16,11 @@
package app.cash.zipline
class WasmFunction private constructor(
/** A pointer to a `wasm_function_inst_t`. */
private val pointer: Long,
/** TODO: implement support for populating these values. */
private val paramTypes: Array<WasmValueType>,
/** TODO: implement support for populating these values. */
private val resultTypes: Array<WasmValueType>,
) {
fun call(args: List<WasmValue>): List<WasmValue> {

View File

@@ -16,9 +16,13 @@
package app.cash.zipline
class WasmModule private constructor(
/** A pointer to a `wasm_module_t`, or 0 after [close]. */
private val pointer: Long,
/** A pointer to a `jbyte*`, or 0 after [close]. */
private val wasmDataBuf: Long,
/** TODO: implement support for [WasmExport.Table], [WasmExport.Global], [WasmExport.Memory]. */
private val exports: Array<WasmExport?>,
) : AutoCloseable {
external fun exports(): Array<WasmExport>
external fun createInstance(
stackSize: Long = 64 * 1024,

View File

@@ -16,10 +16,10 @@
package app.cash.zipline
class WasmModuleInstance private constructor(
/** A pointer to a `wasm_module_inst_t`. */
private val pointer: Long,
) : AutoCloseable {
// external fun main()
/** Returns the named function, or null if no such function exists. */
external fun function(name: String): WasmFunction?
external override fun close()

View File

@@ -16,6 +16,7 @@
package app.cash.zipline
class WasmRuntime private constructor(
/** A pointer to a `ZiplineWasmRuntime`. */
private val pointer: Long,
) : AutoCloseable {
external fun createModule(wasmData: ByteArray): WasmModule

View File

@@ -16,10 +16,10 @@
package app.cash.zipline
sealed class WasmValue {
class I32Value(val value: Int) : WasmValue()
class I64Value(val value: Long) : WasmValue()
class F32Value(val value: Float) : WasmValue()
class F64Value(val value: Double) : WasmValue()
class I32(val value: Int) : WasmValue()
class I64(val value: Long) : WasmValue()
class F32(val value: Float) : WasmValue()
class F64(val value: Double) : WasmValue()
// WASM_V128
// WASM_EXTERNREF
// WASM_FUNCREF

View File

@@ -63,7 +63,8 @@ Java_app_cash_zipline_WasmModule_close(JNIEnv* env, jobject receiver)
{
const auto receiverPointer = setPointerField(env, receiver, 0);
if (receiverPointer != 0) {
wasm_runtime_unload(reinterpret_cast<wasm_module_t>(receiverPointer));
const auto module = reinterpret_cast<wasm_module_t>(receiverPointer);
ZiplineWasmModule(module).close(env, receiver);
}
}

View File

@@ -37,3 +37,14 @@ jobject ZiplineWasmModule::createInstance(JNIEnv *env, jlong stackSize, jlong he
const auto resultPointer = reinterpret_cast<jlong>(result);
return createJavaWrapper(env, "app/cash/zipline/WasmModuleInstance", resultPointer);
}
void ZiplineWasmModule::close(JNIEnv *env, jobject receiver) {
wasm_runtime_unload(wasmModule);
const auto moduleClass = env->FindClass("app/cash/zipline/WasmModule");
const auto wasmDataBufField = env->GetFieldID(moduleClass, "wasmDataBuf", "J");
const auto wasmDataBufPointer = env->GetLongField(receiver, wasmDataBufField);
env->SetLongField(receiver, wasmDataBufField, 0);
const auto wasmDataBuf = reinterpret_cast<jbyte*>(wasmDataBufPointer);
delete wasmDataBuf;
}

View File

@@ -26,6 +26,7 @@ public:
ZiplineWasmModule(wasm_module_t wasmModule);
jobject createInstance(JNIEnv *env, jlong stackSize, jlong heapSize);
void close(JNIEnv *env, jobject receiver);
wasm_module_t wasmModule;
};

View File

@@ -30,10 +30,11 @@ ZiplineWasmRuntime::~ZiplineWasmRuntime() {
jobject ZiplineWasmRuntime::createModule(JNIEnv* env, jbyteArray wasmData) {
char errorBuf[128] = { 0 };
const auto wasmDataBuf = env->GetByteArrayElements(wasmData, NULL);
const auto wasmDataSize = env->GetArrayLength(wasmData);
const auto wasmDataBuf = new jbyte[wasmDataSize];
env->GetByteArrayRegion(wasmData, 0, wasmDataSize, wasmDataBuf);
const auto wasmModule = wasm_runtime_load(reinterpret_cast<uint8_t*>(wasmDataBuf), wasmDataSize, errorBuf, sizeof(errorBuf));
env->ReleaseByteArrayElements(wasmData, wasmDataBuf, JNI_ABORT);
if (!wasmModule) {
std::cout << "in wasm_runtime_load %s\n" << errorBuf << std::endl;
@@ -41,6 +42,33 @@ jobject ZiplineWasmRuntime::createModule(JNIEnv* env, jbyteArray wasmData) {
return NULL;
}
const auto wasmExportClass = env->FindClass("app/cash/zipline/WasmExport");
const auto wasmModuleClass = env->FindClass("app/cash/zipline/WasmModule");
const auto exportCount = wasm_runtime_get_export_count(wasmModule);
const auto exportsArray = env->NewObjectArray(exportCount, wasmExportClass, NULL);
for (int i = 0; i < exportCount; i++) {
env->SetObjectArrayElement(exportsArray, i, createExport(env, wasmModule, i));
}
const auto resultPointer = reinterpret_cast<jlong>(wasmModule);
return createJavaWrapper(env, "app/cash/zipline/WasmModule", resultPointer);
const auto wasmDataBufPointer = reinterpret_cast<jlong>(wasmDataBuf);
const auto resultConstructor = env->GetMethodID(wasmModuleClass, "<init>", "(JJ[Lapp/cash/zipline/WasmExport;)V");
return env->NewObject(wasmModuleClass, resultConstructor, resultPointer, wasmDataBufPointer, exportsArray);
}
jobject ZiplineWasmRuntime::createExport(JNIEnv* env, wasm_module_t wasmModule, int32_t index) {
wasm_export_t exportType;
wasm_runtime_get_export_type(wasmModule, index, &exportType);
if (exportType.kind == WASM_IMPORT_EXPORT_KIND_FUNC) {
const auto resultClass = env->FindClass("app/cash/zipline/WasmExport$Function");
const auto resultConstructor = env->GetMethodID(resultClass, "<init>", "(Ljava/lang/String;)V");
const auto name = env->NewStringUTF(exportType.name);
return env->NewObject(resultClass, resultConstructor, name);
}
return NULL;
}

View File

@@ -27,6 +27,7 @@ public:
~ZiplineWasmRuntime();
jobject createModule(JNIEnv* env, jbyteArray wasmData);
jobject createExport(JNIEnv* env, wasm_module_t wasmModule, int32_t index);
};
#endif //ZIPLINE_WASM_RUNTIME_H