diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index 9f2ffb12c..1bebd8336 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -7,10 +7,12 @@ use std::slice; use std::str; use std::sync::Arc; use std::{ffi::c_void, mem, ptr}; -use wasmer_runtime::{ImportObject, Instance, Memory, Table, Value}; +use wasmer_runtime::{Global, ImportObject, Instance, Memory, Table, Value}; use wasmer_runtime_core::export::{Context, Export, FuncPointer}; use wasmer_runtime_core::import::{LikeNamespace, Namespace}; -use wasmer_runtime_core::types::{ElementType, FuncSig, MemoryDescriptor, TableDescriptor, Type}; +use wasmer_runtime_core::types::{ + ElementType, FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type, +}; use wasmer_runtime_core::units::Pages; #[allow(non_camel_case_types)] @@ -79,6 +81,13 @@ pub struct wasmer_value_t { value: wasmer_value, } +#[repr(C)] +#[derive(Clone)] +pub struct wasmer_global_descriptor_t { + mutable: bool, + kind: wasmer_value_tag, +} + #[repr(C)] #[derive(Clone)] pub struct wasmer_memory_t(); @@ -87,6 +96,10 @@ pub struct wasmer_memory_t(); #[derive(Clone)] pub struct wasmer_table_t(); +#[repr(C)] +#[derive(Clone)] +pub struct wasmer_global_t(); + #[repr(C)] pub struct wasmer_limits_t { pub min: uint32_t, @@ -196,6 +209,59 @@ pub extern "C" fn wasmer_table_destroy(table: *mut wasmer_table_t) { } } +#[no_mangle] +pub unsafe extern "C" fn wasmer_global_new( + value: wasmer_value_t, + mutable: bool, +) -> *mut wasmer_global_t { + let global = if mutable { + Global::new_mutable(value.into()) + } else { + Global::new(value.into()) + }; + unsafe { Box::into_raw(Box::new(global)) as *mut wasmer_global_t } +} + +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub extern "C" fn wasmer_global_get(global: *mut wasmer_global_t) -> wasmer_value_t { + let global = unsafe { Box::from_raw(global as *mut Global) }; + let value: wasmer_value_t = global.get().into(); + Box::into_raw(global); + value +} + +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub extern "C" fn wasmer_global_set(global: *mut wasmer_global_t, value: wasmer_value_t) { + let global = unsafe { Box::from_raw(global as *mut Global) }; + global.set(value.into()); + Box::into_raw(global); +} + +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub extern "C" fn wasmer_global_get_descriptor( + global: *mut wasmer_global_t, +) -> wasmer_global_descriptor_t { + let global = unsafe { Box::from_raw(global as *mut Global) }; + let descriptor = global.descriptor(); + let desc = wasmer_global_descriptor_t { + mutable: descriptor.mutable, + kind: descriptor.ty.into(), + }; + Box::into_raw(global); + desc +} + +#[allow(clippy::cast_ptr_alignment)] +#[no_mangle] +pub extern "C" fn wasmer_global_destroy(global: *mut wasmer_global_t) { + if !global.is_null() { + drop(unsafe { Box::from_raw(global as *mut Global) }); + } +} + #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub extern "C" fn wasmer_import_object_destroy(import_object: *mut wasmer_import_object_t) { @@ -396,6 +462,41 @@ impl From for Value { } } +impl From for wasmer_value_t { + fn from(val: Value) -> Self { + match val { + Value::I32(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_I32, + value: wasmer_value { I32: x }, + }, + Value::I64(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_I64, + value: wasmer_value { I64: x }, + }, + Value::F32(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_F32, + value: wasmer_value { F32: x }, + }, + Value::F64(x) => wasmer_value_t { + tag: wasmer_value_tag::WASM_F64, + value: wasmer_value { F64: x }, + }, + } + } +} + +impl From for wasmer_value_tag { + fn from(ty: Type) -> Self { + match ty { + Type::I32 => wasmer_value_tag::WASM_I32, + Type::I64 => wasmer_value_tag::WASM_I64, + Type::F32 => wasmer_value_tag::WASM_F32, + Type::F64 => wasmer_value_tag::WASM_F64, + _ => panic!("not implemented"), + } + } +} + impl From for Type { fn from(v: wasmer_value_tag) -> Self { unsafe { diff --git a/lib/runtime-c-api/tests/.gitignore b/lib/runtime-c-api/tests/.gitignore index 8ac4f1ab0..6a96cd53f 100644 --- a/lib/runtime-c-api/tests/.gitignore +++ b/lib/runtime-c-api/tests/.gitignore @@ -9,6 +9,7 @@ install_manifest.txt compile_commands.json CTestTestfile.cmake _deps +test-globals test-instantiate test-import-function test-memory diff --git a/lib/runtime-c-api/tests/CMakeLists.txt b/lib/runtime-c-api/tests/CMakeLists.txt index 58b1ac3cd..d15934df5 100644 --- a/lib/runtime-c-api/tests/CMakeLists.txt +++ b/lib/runtime-c-api/tests/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required (VERSION 2.6) project (WasmerCApiTests) +add_executable(test-globals test-globals.c) add_executable(test-instantiate test-instantiate.c) add_executable(test-import-function test-import-function.c) add_executable(test-memory test-memory.c) @@ -16,6 +17,8 @@ if(NOT WASMER_LIB) message(FATAL_ERROR "wasmer library not found") endif() +target_link_libraries(test-globals + general ${WASMER_LIB}) target_link_libraries(test-instantiate general ${WASMER_LIB}) target_link_libraries(test-import-function @@ -28,6 +31,7 @@ target_link_libraries(test-tables general ${WASMER_LIB}) enable_testing() +add_test(test-globals test-globals) add_test(test-instantiate test-instantiate) add_test(test-import-function test-import-function) add_test(test-memory test-memory) diff --git a/lib/runtime-c-api/tests/test-globals.c b/lib/runtime-c-api/tests/test-globals.c new file mode 100644 index 000000000..a694d2e75 --- /dev/null +++ b/lib/runtime-c-api/tests/test-globals.c @@ -0,0 +1,30 @@ +#include +#include "../wasmer.h" +#include +#include + +int main() +{ + wasmer_value_t val; + val.tag = WASM_I32; + val.value.I32 = 7; + wasmer_global_t *global = wasmer_global_new(val, true); + + wasmer_value_t get_val = wasmer_global_get(global); + assert( get_val.value.I32 == 7); + + wasmer_value_t val2; + val2.tag = WASM_I32; + val2.value.I32 = 14; + wasmer_global_set(global, val2); + + wasmer_value_t new_get_val = wasmer_global_get(global); + assert( new_get_val.value.I32 == 14); + + wasmer_global_descriptor_t desc = wasmer_global_get_descriptor(global); + assert(desc.mutable_); + assert(desc.kind == WASM_I32); + + wasmer_global_destroy(global); + return 0; +} diff --git a/lib/runtime-c-api/wasmer.h b/lib/runtime-c-api/wasmer.h index 08f891fa8..c6e649bd4 100644 --- a/lib/runtime-c-api/wasmer.h +++ b/lib/runtime-c-api/wasmer.h @@ -37,6 +37,10 @@ typedef struct wasmer_instance_context_t wasmer_instance_context_t; typedef struct wasmer_instance_t wasmer_instance_t; +typedef struct { + +} wasmer_global_t; + typedef union { int32_t I32; int64_t I64; @@ -49,6 +53,11 @@ typedef struct { wasmer_value value; } wasmer_value_t; +typedef struct { + bool mutable_; + wasmer_value_tag kind; +} wasmer_global_descriptor_t; + typedef struct { } wasmer_memory_t; @@ -62,6 +71,16 @@ typedef struct { } wasmer_table_t; +void wasmer_global_destroy(wasmer_global_t *global); + +wasmer_value_t wasmer_global_get(wasmer_global_t *global); + +wasmer_global_descriptor_t wasmer_global_get_descriptor(wasmer_global_t *global); + +wasmer_global_t *wasmer_global_new(wasmer_value_t value, bool mutable_); + +void wasmer_global_set(wasmer_global_t *global, wasmer_value_t value); + void wasmer_import_object_destroy(wasmer_import_object_t *import_object); wasmer_import_object_t *wasmer_import_object_new(void); diff --git a/lib/runtime-c-api/wasmer.hh b/lib/runtime-c-api/wasmer.hh index c0d266489..7ac6b1e19 100644 --- a/lib/runtime-c-api/wasmer.hh +++ b/lib/runtime-c-api/wasmer.hh @@ -35,6 +35,10 @@ struct wasmer_instance_context_t; struct wasmer_instance_t; +struct wasmer_global_t { + +}; + union wasmer_value { int32_t I32; int64_t I64; @@ -47,6 +51,11 @@ struct wasmer_value_t { wasmer_value value; }; +struct wasmer_global_descriptor_t { + bool mutable_; + wasmer_value_tag kind; +}; + struct wasmer_memory_t { }; @@ -62,6 +71,16 @@ struct wasmer_table_t { extern "C" { +void wasmer_global_destroy(wasmer_global_t *global); + +wasmer_value_t wasmer_global_get(wasmer_global_t *global); + +wasmer_global_descriptor_t wasmer_global_get_descriptor(wasmer_global_t *global); + +wasmer_global_t *wasmer_global_new(wasmer_value_t value, bool mutable_); + +void wasmer_global_set(wasmer_global_t *global, wasmer_value_t value); + void wasmer_import_object_destroy(wasmer_import_object_t *import_object); wasmer_import_object_t *wasmer_import_object_new();