mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:01:42 +00:00
[wasm] Add WasmMemory class.
Also, port the old wasm memory tests, and fix some NNBD issues. Bug: https://github.com/dart-lang/sdk/issues/37882 Change-Id: I131ba5836bb0a3dd946cf9b0fa3f2e186b6b132e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/162801 Commit-Queue: Liam Appelbe <liama@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
53e707f26d
commit
cc8fd04924
|
@ -16,9 +16,9 @@ class WasmFunction {
|
|||
Pointer<WasmerValue> _args;
|
||||
Pointer<WasmerValue> _result;
|
||||
|
||||
WasmFunction(this._name, this._func, this._argTypes, this._returnType) {
|
||||
_args = allocate<WasmerValue>(count: _argTypes.length);
|
||||
_result = allocate<WasmerValue>();
|
||||
WasmFunction(this._name, this._func, this._argTypes, this._returnType)
|
||||
: _args = allocate<WasmerValue>(count: _argTypes.length),
|
||||
_result = allocate<WasmerValue>() {
|
||||
for (var i = 0; i < _argTypes.length; ++i) {
|
||||
_args[i].tag = _argTypes[i];
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class WasmFunction {
|
|||
_args[i].f64 = arg;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
dynamic apply(List<dynamic> args) {
|
||||
|
|
|
@ -14,9 +14,7 @@ class WasmModule {
|
|||
Pointer<WasmerModule> _module;
|
||||
|
||||
/// Compile a module.
|
||||
WasmModule(Uint8List data) {
|
||||
_module = WasmRuntime().compile(data);
|
||||
}
|
||||
WasmModule(Uint8List data) : _module = WasmRuntime().compile(data) {}
|
||||
|
||||
/// Instantiate the module with the given imports.
|
||||
WasmInstance instantiate(WasmImports imports) {
|
||||
|
@ -49,9 +47,9 @@ class WasmImports {
|
|||
int _length;
|
||||
|
||||
/// Create an imports object.
|
||||
WasmImports([this._capacity = 4]) : _length = 0 {
|
||||
_imports = allocate<WasmerImport>(count: this._capacity);
|
||||
}
|
||||
WasmImports([this._capacity = 4])
|
||||
: _imports = allocate<WasmerImport>(count: _capacity),
|
||||
_length = 0 {}
|
||||
|
||||
/// Returns the number of imports.
|
||||
int get length => _length;
|
||||
|
@ -61,12 +59,13 @@ class WasmImports {
|
|||
class WasmInstance {
|
||||
Pointer<WasmerModule> _module;
|
||||
Pointer<WasmerInstance> _instance;
|
||||
Map<String, WasmFunction> _functions;
|
||||
Pointer<WasmerMemory>? _exportedMemory;
|
||||
Map<String, WasmFunction> _functions = {};
|
||||
|
||||
WasmInstance(this._module, WasmImports imports) {
|
||||
WasmInstance(this._module, WasmImports imports)
|
||||
: _instance = WasmRuntime()
|
||||
.instantiate(_module, imports._imports, imports.length) {
|
||||
var runtime = WasmRuntime();
|
||||
_instance = runtime.instantiate(_module, imports._imports, imports.length);
|
||||
_functions = {};
|
||||
var exps = runtime.exports(_instance);
|
||||
for (var e in exps) {
|
||||
var kind = runtime.exportKind(e);
|
||||
|
@ -75,6 +74,9 @@ class WasmInstance {
|
|||
var f = runtime.exportToFunction(e);
|
||||
_functions[name] = WasmFunction(
|
||||
name, f, runtime.getArgTypes(f), runtime.getReturnType(f));
|
||||
} else if (kind == WasmerImpExpKindMemory) {
|
||||
// WASM currently allows only one memory per module.
|
||||
_exportedMemory = runtime.exportToMemory(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,4 +86,55 @@ class WasmInstance {
|
|||
dynamic lookupFunction(String name) {
|
||||
return _functions[name];
|
||||
}
|
||||
|
||||
/// Returns the memory exported from this instance.
|
||||
WasmMemory get memory {
|
||||
if (_exportedMemory == null) {
|
||||
throw Exception("Wasm module did not export its memory.");
|
||||
}
|
||||
return WasmMemory._fromExport(_exportedMemory as Pointer<WasmerMemory>);
|
||||
}
|
||||
}
|
||||
|
||||
/// WasmMemory contains the memory of a WasmInstance.
|
||||
class WasmMemory {
|
||||
Pointer<WasmerMemory> _mem;
|
||||
late Uint8List _view;
|
||||
|
||||
WasmMemory._fromExport(this._mem) {
|
||||
_view = WasmRuntime().memoryView(_mem);
|
||||
}
|
||||
|
||||
/// Create a new memory with the given number of initial pages, and optional
|
||||
/// maximum number of pages.
|
||||
WasmMemory(int pages, [int? maxPages])
|
||||
: _mem = WasmRuntime().newMemory(pages, maxPages) {
|
||||
_view = WasmRuntime().memoryView(_mem);
|
||||
}
|
||||
|
||||
/// The WASM spec defines the page size as 64KiB.
|
||||
static const int kPageSizeInBytes = 64 * 1024;
|
||||
|
||||
/// Returns the length of the memory in pages.
|
||||
int get lengthInPages {
|
||||
return WasmRuntime().memoryLength(_mem);
|
||||
}
|
||||
|
||||
/// Returns the length of the memory in bytes.
|
||||
int get lengthInBytes => _view.lengthInBytes;
|
||||
|
||||
/// Returns the byte at the given index.
|
||||
int operator [](int index) => _view[index];
|
||||
|
||||
/// Sets the byte at the given index to value.
|
||||
void operator []=(int index, int value) {
|
||||
_view[index] = value;
|
||||
}
|
||||
|
||||
/// Grow the memory by deltaPages.
|
||||
void grow(int deltaPages) {
|
||||
var runtime = WasmRuntime();
|
||||
runtime.growMemory(_mem, deltaPages);
|
||||
_view = runtime.memoryView(_mem);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,41 +24,47 @@ class WasmExportDescriptor {
|
|||
}
|
||||
|
||||
class WasmRuntime {
|
||||
static WasmRuntime _inst;
|
||||
static WasmRuntime? _inst;
|
||||
|
||||
DynamicLibrary _lib;
|
||||
WasmerCompileFn _compile;
|
||||
WasmerInstantiateFn _instantiate;
|
||||
WasmerInstanceExportsFn _instance_exports;
|
||||
WasmerExportsLenFn _exports_len;
|
||||
WasmerExportsGetFn _exports_get;
|
||||
WasmerExportKindFn _export_kind;
|
||||
WasmerExportToFuncFn _export_to_func;
|
||||
WasmerExportFuncReturnsArityFn _export_func_returns_arity;
|
||||
WasmerExportFuncReturnsFn _export_func_returns;
|
||||
WasmerExportFuncParamsArityFn _export_func_params_arity;
|
||||
WasmerExportFuncParamsFn _export_func_params;
|
||||
WasmerExportFuncCallFn _export_func_call;
|
||||
WasmerExportNamePtrFn _export_name_ptr;
|
||||
WasmerExportDescriptorsFn _export_descriptors;
|
||||
WasmerExportDescriptorsDestroyFn _export_descriptors_destroy;
|
||||
WasmerExportDescriptorsLenFn _export_descriptors_len;
|
||||
WasmerExportDescriptorsGetFn _export_descriptors_get;
|
||||
WasmerExportDescriptorKindFn _export_descriptor_kind;
|
||||
WasmerExportDescriptorNamePtrFn _export_descriptor_name_ptr;
|
||||
WasmerImportDescriptorModuleNamePtrFn _import_descriptor_module_name_ptr;
|
||||
WasmerImportDescriptorNamePtrFn _import_descriptor_name_ptr;
|
||||
WasmerImportDescriptorsFn _import_descriptors;
|
||||
WasmerImportDescriptorsDestroyFn _import_descriptors_destroy;
|
||||
WasmerImportDescriptorsLenFn _import_descriptors_len;
|
||||
WasmerImportDescriptorsGetFn _import_descriptors_get;
|
||||
WasmerImportDescriptorKindFn _import_descriptor_kind;
|
||||
late WasmerCompileFn _compile;
|
||||
late WasmerInstantiateFn _instantiate;
|
||||
late WasmerInstanceExportsFn _instance_exports;
|
||||
late WasmerExportsLenFn _exports_len;
|
||||
late WasmerExportsGetFn _exports_get;
|
||||
late WasmerExportKindFn _export_kind;
|
||||
late WasmerExportToFuncFn _export_to_func;
|
||||
late WasmerExportFuncReturnsArityFn _export_func_returns_arity;
|
||||
late WasmerExportFuncReturnsFn _export_func_returns;
|
||||
late WasmerExportFuncParamsArityFn _export_func_params_arity;
|
||||
late WasmerExportFuncParamsFn _export_func_params;
|
||||
late WasmerExportFuncCallFn _export_func_call;
|
||||
late WasmerExportNamePtrFn _export_name_ptr;
|
||||
late WasmerExportDescriptorsFn _export_descriptors;
|
||||
late WasmerExportDescriptorsDestroyFn _export_descriptors_destroy;
|
||||
late WasmerExportDescriptorsLenFn _export_descriptors_len;
|
||||
late WasmerExportDescriptorsGetFn _export_descriptors_get;
|
||||
late WasmerExportDescriptorKindFn _export_descriptor_kind;
|
||||
late WasmerExportDescriptorNamePtrFn _export_descriptor_name_ptr;
|
||||
late WasmerImportDescriptorModuleNamePtrFn _import_descriptor_module_name_ptr;
|
||||
late WasmerImportDescriptorNamePtrFn _import_descriptor_name_ptr;
|
||||
late WasmerImportDescriptorsFn _import_descriptors;
|
||||
late WasmerImportDescriptorsDestroyFn _import_descriptors_destroy;
|
||||
late WasmerImportDescriptorsLenFn _import_descriptors_len;
|
||||
late WasmerImportDescriptorsGetFn _import_descriptors_get;
|
||||
late WasmerImportDescriptorKindFn _import_descriptor_kind;
|
||||
late WasmerExportToMemoryFn _export_to_memory;
|
||||
late WasmerMemoryNewPtrFn _memory_new_ptr;
|
||||
late WasmerMemoryGrowFn _memory_grow;
|
||||
late WasmerMemoryLengthFn _memory_length;
|
||||
late WasmerMemoryDataFn _memory_data;
|
||||
late WasmerMemoryDataLengthFn _memory_data_length;
|
||||
|
||||
factory WasmRuntime() {
|
||||
if (_inst == null) {
|
||||
_inst = WasmRuntime._init();
|
||||
}
|
||||
return _inst;
|
||||
return _inst as WasmRuntime;
|
||||
}
|
||||
|
||||
static String _getLibName() {
|
||||
|
@ -96,9 +102,8 @@ class WasmRuntime {
|
|||
return commonLibDir;
|
||||
}
|
||||
|
||||
WasmRuntime._init() {
|
||||
var libPath = path.join(_getLibDir(), _getLibName());
|
||||
_lib = DynamicLibrary.open(libPath);
|
||||
WasmRuntime._init()
|
||||
: _lib = DynamicLibrary.open(path.join(_getLibDir(), _getLibName())) {
|
||||
_compile = _lib.lookupFunction<NativeWasmerCompileFn, WasmerCompileFn>(
|
||||
'wasmer_compile');
|
||||
_instantiate =
|
||||
|
@ -171,6 +176,22 @@ class WasmRuntime {
|
|||
_import_descriptor_name_ptr = _lib.lookupFunction<
|
||||
NativeWasmerImportDescriptorNamePtrFn,
|
||||
WasmerImportDescriptorNamePtrFn>('wasmer_import_descriptor_name_ptr');
|
||||
_export_to_memory = _lib.lookupFunction<NativeWasmerExportToMemoryFn,
|
||||
WasmerExportToMemoryFn>('wasmer_export_to_memory');
|
||||
_memory_new_ptr =
|
||||
_lib.lookupFunction<NativeWasmerMemoryNewPtrFn, WasmerMemoryNewPtrFn>(
|
||||
'wasmer_memory_new_ptr');
|
||||
_memory_grow =
|
||||
_lib.lookupFunction<NativeWasmerMemoryGrowFn, WasmerMemoryGrowFn>(
|
||||
'wasmer_memory_grow');
|
||||
_memory_length =
|
||||
_lib.lookupFunction<NativeWasmerMemoryLengthFn, WasmerMemoryLengthFn>(
|
||||
'wasmer_memory_length');
|
||||
_memory_data =
|
||||
_lib.lookupFunction<NativeWasmerMemoryDataFn, WasmerMemoryDataFn>(
|
||||
'wasmer_memory_data');
|
||||
_memory_data_length = _lib.lookupFunction<NativeWasmerMemoryDataLengthFn,
|
||||
WasmerMemoryDataLengthFn>('wasmer_memory_data_length');
|
||||
}
|
||||
|
||||
Pointer<WasmerModule> compile(Uint8List data) {
|
||||
|
@ -331,4 +352,48 @@ class WasmRuntime {
|
|||
throw Exception("Failed to call WASM function");
|
||||
}
|
||||
}
|
||||
|
||||
Pointer<WasmerMemory> exportToMemory(Pointer<WasmerExport> export) {
|
||||
var memPtrPtr = allocate<Pointer<WasmerMemory>>();
|
||||
var result = _export_to_memory(export, memPtrPtr);
|
||||
if (result != WasmerResultOk) {
|
||||
free(memPtrPtr);
|
||||
throw Exception("Failed to get exported memory");
|
||||
}
|
||||
Pointer<WasmerMemory> memPtr = memPtrPtr.value;
|
||||
free(memPtrPtr);
|
||||
return memPtr;
|
||||
}
|
||||
|
||||
Pointer<WasmerMemory> newMemory(int pages, int? maxPages) {
|
||||
var memPtrPtr = allocate<Pointer<WasmerMemory>>();
|
||||
var limPtr = allocate<WasmerLimits>();
|
||||
limPtr.ref.min = pages;
|
||||
limPtr.ref.has_max = maxPages != null ? 1 : 0;
|
||||
limPtr.ref.max = maxPages ?? 0;
|
||||
var result = _memory_new_ptr(memPtrPtr, limPtr);
|
||||
free(limPtr);
|
||||
if (result != WasmerResultOk) {
|
||||
free(memPtrPtr);
|
||||
throw Exception("Failed to create memory");
|
||||
}
|
||||
Pointer<WasmerMemory> memPtr = memPtrPtr.value;
|
||||
free(memPtrPtr);
|
||||
return memPtr;
|
||||
}
|
||||
|
||||
void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
|
||||
var result = _memory_grow(memory, deltaPages);
|
||||
if (result != WasmerResultOk) {
|
||||
throw Exception("Failed to grow memory");
|
||||
}
|
||||
}
|
||||
|
||||
int memoryLength(Pointer<WasmerMemory> memory) {
|
||||
return _memory_length(memory);
|
||||
}
|
||||
|
||||
Uint8List memoryView(Pointer<WasmerMemory> memory) {
|
||||
return _memory_data(memory).asTypedList(_memory_data_length(memory));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,34 +67,37 @@ class WasmerImportDescriptors extends Struct {}
|
|||
// wasmer_import_descriptor_t
|
||||
class WasmerImportDescriptor extends Struct {}
|
||||
|
||||
// wasmer_memory_t
|
||||
class WasmerMemory extends Struct {}
|
||||
|
||||
// wasmer_import_t
|
||||
class WasmerImport extends Struct {
|
||||
Pointer<Uint8> module_name;
|
||||
external Pointer<Uint8> module_name;
|
||||
|
||||
@Uint32()
|
||||
int module_name_length;
|
||||
external int module_name_length;
|
||||
|
||||
Pointer<Uint8> import_name;
|
||||
external Pointer<Uint8> import_name;
|
||||
|
||||
@Uint32()
|
||||
int import_name_length;
|
||||
external int import_name_length;
|
||||
|
||||
// wasmer_import_export_kind
|
||||
@Uint32()
|
||||
int tag;
|
||||
external int tag;
|
||||
|
||||
// wasmer_import_export_value, which is a union of wasmer_import_func_t*,
|
||||
// wasmer_table_t*, wasmer_memory_t*, and wasmer_global_t*. The tag determines
|
||||
// which type it is.
|
||||
Pointer<Void> value;
|
||||
external Pointer<Void> value;
|
||||
}
|
||||
|
||||
// wasmer_byte_array
|
||||
class WasmerByteArray extends Struct {
|
||||
Pointer<Uint8> bytes;
|
||||
external Pointer<Uint8> bytes;
|
||||
|
||||
@Uint32()
|
||||
int length;
|
||||
external int length;
|
||||
|
||||
Uint8List get list => bytes.asTypedList(length);
|
||||
String get string => utf8.decode(list);
|
||||
|
@ -104,13 +107,13 @@ class WasmerByteArray extends Struct {
|
|||
class WasmerValue extends Struct {
|
||||
// wasmer_value_tag
|
||||
@Uint32()
|
||||
int tag;
|
||||
external int tag;
|
||||
|
||||
// wasmer_value, which is a union of int32_t, int64_t, float, and double. The
|
||||
// tag determines which type it is. It's declared as an int64_t because that's
|
||||
// large enough to hold all the types. We use ByteData to get the other types.
|
||||
@Int64()
|
||||
int value;
|
||||
external int value;
|
||||
|
||||
int get _off32 => Endian.host == Endian.little ? 0 : 4;
|
||||
int get i64 => value;
|
||||
|
@ -122,8 +125,10 @@ class WasmerValue extends Struct {
|
|||
set i64(int val) => value = val;
|
||||
set _val(ByteData bytes) => value = bytes.getInt64(0, Endian.host);
|
||||
set i32(int val) => _val = ByteData(8)..setInt32(_off32, val, Endian.host);
|
||||
set f32(num val) => _val = ByteData(8)..setFloat32(_off32, val, Endian.host);
|
||||
set f64(num val) => _val = ByteData(8)..setFloat64(0, val, Endian.host);
|
||||
set f32(num val) =>
|
||||
_val = ByteData(8)..setFloat32(_off32, val as double, Endian.host);
|
||||
set f64(num val) =>
|
||||
_val = ByteData(8)..setFloat64(0, val as double, Endian.host);
|
||||
|
||||
bool get isI32 => tag == WasmerValueTagI32;
|
||||
bool get isI64 => tag == WasmerValueTagI64;
|
||||
|
@ -131,6 +136,19 @@ class WasmerValue extends Struct {
|
|||
bool get isF64 => tag == WasmerValueTagF64;
|
||||
}
|
||||
|
||||
// wasmer_limits_t
|
||||
class WasmerLimits extends Struct {
|
||||
@Uint32()
|
||||
external int min;
|
||||
|
||||
// bool
|
||||
@Uint8()
|
||||
external int has_max;
|
||||
|
||||
@Uint32()
|
||||
external int max;
|
||||
}
|
||||
|
||||
// wasmer_compile
|
||||
typedef NativeWasmerCompileFn = Uint32 Function(
|
||||
Pointer<Pointer<WasmerModule>>, Pointer<Uint8>, Uint32);
|
||||
|
@ -286,3 +304,33 @@ typedef NativeWasmerExportFuncCallFn = Uint32 Function(
|
|||
Uint32);
|
||||
typedef WasmerExportFuncCallFn = int Function(Pointer<WasmerExportFunc>,
|
||||
Pointer<WasmerValue>, int, Pointer<WasmerValue>, int);
|
||||
|
||||
// wasmer_export_to_memory
|
||||
typedef NativeWasmerExportToMemoryFn = Uint32 Function(
|
||||
Pointer<WasmerExport>, Pointer<Pointer<WasmerMemory>>);
|
||||
typedef WasmerExportToMemoryFn = int Function(
|
||||
Pointer<WasmerExport>, Pointer<Pointer<WasmerMemory>>);
|
||||
|
||||
// wasmer_memory_new_ptr
|
||||
typedef NativeWasmerMemoryNewPtrFn = Uint32 Function(
|
||||
Pointer<Pointer<WasmerMemory>>, Pointer<WasmerLimits>);
|
||||
typedef WasmerMemoryNewPtrFn = int Function(
|
||||
Pointer<Pointer<WasmerMemory>>, Pointer<WasmerLimits>);
|
||||
|
||||
// wasmer_memory_grow
|
||||
typedef NativeWasmerMemoryGrowFn = Uint32 Function(
|
||||
Pointer<WasmerMemory>, Uint32);
|
||||
typedef WasmerMemoryGrowFn = int Function(Pointer<WasmerMemory>, int);
|
||||
|
||||
// wasmer_memory_length
|
||||
typedef NativeWasmerMemoryLengthFn = Uint32 Function(Pointer<WasmerMemory>);
|
||||
typedef WasmerMemoryLengthFn = int Function(Pointer<WasmerMemory>);
|
||||
|
||||
// wasmer_memory_data
|
||||
typedef NativeWasmerMemoryDataFn = Pointer<Uint8> Function(
|
||||
Pointer<WasmerMemory>);
|
||||
typedef WasmerMemoryDataFn = Pointer<Uint8> Function(Pointer<WasmerMemory>);
|
||||
|
||||
// wasmer_memory_data_length
|
||||
typedef NativeWasmerMemoryDataLengthFn = Uint32 Function(Pointer<WasmerMemory>);
|
||||
typedef WasmerMemoryDataLengthFn = int Function(Pointer<WasmerMemory>);
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
// Test errors thrown by WasmMemory.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:wasm";
|
||||
import "package:wasm/wasm.dart";
|
||||
import "dart:typed_data";
|
||||
|
||||
void main() {
|
||||
Expect.throwsArgumentError(() => WasmMemory(1000000000));
|
||||
var mem = WasmMemory(1000);
|
||||
Expect.throwsArgumentError(() => mem.grow(1000000000));
|
||||
Expect.throws(() => WasmMemory(1000000000));
|
||||
var mem = WasmMemory(100);
|
||||
Expect.throws(() => mem.grow(1000000000));
|
||||
mem = WasmMemory(100, 200);
|
||||
Expect.throws(() => mem.grow(300));
|
||||
}
|
||||
|
|
|
@ -5,22 +5,19 @@
|
|||
// Test that we can create a WasmMemory, edit it, and grow it.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:wasm";
|
||||
import "package:wasm/wasm.dart";
|
||||
import "dart:typed_data";
|
||||
|
||||
void main() {
|
||||
var mem = WasmMemory(1000);
|
||||
Expect.equals(1000, mem.lengthInPages);
|
||||
Expect.equals(1000 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
var mem = WasmMemory(100);
|
||||
Expect.equals(100, mem.lengthInPages);
|
||||
Expect.equals(100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
|
||||
mem[123] = 45;
|
||||
Expect.equals(45, mem[123]);
|
||||
|
||||
mem.grow(100);
|
||||
Expect.equals(1100, mem.lengthInPages);
|
||||
Expect.equals(1100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
mem.grow(10);
|
||||
Expect.equals(110, mem.lengthInPages);
|
||||
Expect.equals(110 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
Expect.equals(45, mem[123]);
|
||||
|
||||
Expect.throwsArgumentError(() => WasmMemory(1000000000));
|
||||
Expect.throwsArgumentError(() => mem.grow(1000000000));
|
||||
}
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
// Test errors thrown by WasmMemory.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:wasm";
|
||||
import "package:wasm/wasm.dart";
|
||||
import "dart:typed_data";
|
||||
|
||||
void main() {
|
||||
Expect.throwsArgumentError(() => WasmMemory(1000000000));
|
||||
var mem = WasmMemory(1000);
|
||||
Expect.throwsArgumentError(() => mem.grow(1000000000));
|
||||
Expect.throws(() => WasmMemory(1000000000));
|
||||
var mem = WasmMemory(100);
|
||||
Expect.throws(() => mem.grow(1000000000));
|
||||
mem = WasmMemory(100, 200);
|
||||
Expect.throws(() => mem.grow(300));
|
||||
}
|
||||
|
|
|
@ -5,22 +5,19 @@
|
|||
// Test that we can create a WasmMemory, edit it, and grow it.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
import "dart:wasm";
|
||||
import "package:wasm/wasm.dart";
|
||||
import "dart:typed_data";
|
||||
|
||||
void main() {
|
||||
var mem = WasmMemory(1000);
|
||||
Expect.equals(1000, mem.lengthInPages);
|
||||
Expect.equals(1000 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
var mem = WasmMemory(100);
|
||||
Expect.equals(100, mem.lengthInPages);
|
||||
Expect.equals(100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
|
||||
mem[123] = 45;
|
||||
Expect.equals(45, mem[123]);
|
||||
|
||||
mem.grow(100);
|
||||
Expect.equals(1100, mem.lengthInPages);
|
||||
Expect.equals(1100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
mem.grow(10);
|
||||
Expect.equals(110, mem.lengthInPages);
|
||||
Expect.equals(110 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
|
||||
Expect.equals(45, mem[123]);
|
||||
|
||||
Expect.throwsArgumentError(() => WasmMemory(1000000000));
|
||||
Expect.throwsArgumentError(() => mem.grow(1000000000));
|
||||
}
|
||||
|
|
6
third_party/wasmer/wasmer_wrapper.cc
vendored
6
third_party/wasmer/wasmer_wrapper.cc
vendored
|
@ -36,4 +36,10 @@ void wasmer_import_descriptor_name_ptr(
|
|||
wasmer_byte_array* out_name) {
|
||||
*out_name = wasmer_import_descriptor_name(import_descriptor);
|
||||
}
|
||||
|
||||
// Wraps wasmer_memory_new.
|
||||
wasmer_result_t wasmer_memory_new_ptr(wasmer_memory_t** memory,
|
||||
wasmer_limits_t* limits) {
|
||||
return wasmer_memory_new(memory, *limits);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue