6
6
// To regenerate the file, use the following command
7
7
// "generate_ffi_boilerplate.py".
8
8
9
+ import 'dart:async' ;
9
10
import 'dart:convert' ;
10
11
import 'dart:ffi' ;
11
12
import 'dart:io' ;
@@ -58,6 +59,15 @@ class WasmRuntime {
58
59
59
60
DynamicLibrary _lib;
60
61
late Pointer <WasmerEngine > _engine;
62
+ late WasmerWasiConfigInheritStderrFn _wasi_config_inherit_stderr;
63
+ late WasmerWasiConfigInheritStdoutFn _wasi_config_inherit_stdout;
64
+ late WasmerWasiConfigNewFn _wasi_config_new;
65
+ late WasmerWasiEnvDeleteFn _wasi_env_delete;
66
+ late WasmerWasiEnvNewFn _wasi_env_new;
67
+ late WasmerWasiEnvReadStderrFn _wasi_env_read_stderr;
68
+ late WasmerWasiEnvReadStdoutFn _wasi_env_read_stdout;
69
+ late WasmerWasiEnvSetMemoryFn _wasi_env_set_memory;
70
+ late WasmerWasiGetImportsFn _wasi_get_imports;
61
71
late WasmerByteVecDeleteFn _byte_vec_delete;
62
72
late WasmerByteVecNewFn _byte_vec_new;
63
73
late WasmerByteVecNewEmptyFn _byte_vec_new_empty;
@@ -120,11 +130,11 @@ class WasmRuntime {
120
130
late WasmerValtypeVecNewFn _valtype_vec_new;
121
131
late WasmerValtypeVecNewEmptyFn _valtype_vec_new_empty;
122
132
late WasmerValtypeVecNewUninitializedFn _valtype_vec_new_uninitialized;
133
+ late WasmerWasmerLastErrorLengthFn _wasmer_last_error_length;
134
+ late WasmerWasmerLastErrorMessageFn _wasmer_last_error_message;
123
135
124
136
factory WasmRuntime () {
125
- WasmRuntime inst = _inst ?? WasmRuntime ._init ();
126
- _inst = inst;
127
- return inst;
137
+ return _inst ?? = WasmRuntime ._init ();
128
138
}
129
139
130
140
static String _getLibName () {
@@ -165,6 +175,29 @@ class WasmRuntime {
165
175
166
176
WasmRuntime ._init ()
167
177
: _lib = DynamicLibrary .open (path.join (_getLibDir (), _getLibName ())) {
178
+ _wasi_config_inherit_stderr = _lib.lookupFunction<
179
+ NativeWasmerWasiConfigInheritStderrFn ,
180
+ WasmerWasiConfigInheritStderrFn > ('wasi_config_inherit_stderr' );
181
+ _wasi_config_inherit_stdout = _lib.lookupFunction<
182
+ NativeWasmerWasiConfigInheritStdoutFn ,
183
+ WasmerWasiConfigInheritStdoutFn > ('wasi_config_inherit_stdout' );
184
+ _wasi_config_new =
185
+ _lib.lookupFunction <NativeWasmerWasiConfigNewFn , WasmerWasiConfigNewFn >(
186
+ 'wasi_config_new' );
187
+ _wasi_env_delete =
188
+ _lib.lookupFunction <NativeWasmerWasiEnvDeleteFn , WasmerWasiEnvDeleteFn >(
189
+ 'wasi_env_delete' );
190
+ _wasi_env_new =
191
+ _lib.lookupFunction <NativeWasmerWasiEnvNewFn , WasmerWasiEnvNewFn >(
192
+ 'wasi_env_new' );
193
+ _wasi_env_read_stderr = _lib.lookupFunction< NativeWasmerWasiEnvReadStderrFn ,
194
+ WasmerWasiEnvReadStderrFn > ('wasi_env_read_stderr' );
195
+ _wasi_env_read_stdout = _lib.lookupFunction< NativeWasmerWasiEnvReadStdoutFn ,
196
+ WasmerWasiEnvReadStdoutFn > ('wasi_env_read_stdout' );
197
+ _wasi_env_set_memory = _lib.lookupFunction< NativeWasmerWasiEnvSetMemoryFn ,
198
+ WasmerWasiEnvSetMemoryFn > ('wasi_env_set_memory' );
199
+ _wasi_get_imports = _lib.lookupFunction< NativeWasmerWasiGetImportsFn ,
200
+ WasmerWasiGetImportsFn > ('wasi_get_imports' );
168
201
_byte_vec_delete =
169
202
_lib.lookupFunction <NativeWasmerByteVecDeleteFn , WasmerByteVecDeleteFn >(
170
203
'wasm_byte_vec_delete' );
@@ -329,6 +362,12 @@ class WasmRuntime {
329
362
NativeWasmerValtypeVecNewUninitializedFn ,
330
363
WasmerValtypeVecNewUninitializedFn > (
331
364
'wasm_valtype_vec_new_uninitialized' );
365
+ _wasmer_last_error_length = _lib.lookupFunction<
366
+ NativeWasmerWasmerLastErrorLengthFn ,
367
+ WasmerWasmerLastErrorLengthFn > ('wasmer_last_error_length' );
368
+ _wasmer_last_error_message = _lib.lookupFunction<
369
+ NativeWasmerWasmerLastErrorMessageFn ,
370
+ WasmerWasmerLastErrorMessageFn > ('wasmer_last_error_message' );
332
371
333
372
_engine = _engine_new ();
334
373
}
@@ -351,11 +390,7 @@ class WasmRuntime {
351
390
free (dataPtr);
352
391
free (dataVec);
353
392
354
- if (modulePtr == nullptr) {
355
- throw Exception ("Wasm module compile failed" );
356
- }
357
-
358
- return modulePtr;
393
+ return _checkNotEqual (modulePtr, nullptr, "Wasm module compile failed." );
359
394
}
360
395
361
396
List <WasmExportDescriptor > exportDescriptors (Pointer <WasmerModule > module) {
@@ -399,12 +434,8 @@ class WasmRuntime {
399
434
400
435
Pointer <WasmerInstance > instantiate (Pointer <WasmerStore > store,
401
436
Pointer <WasmerModule > module, Pointer <Pointer <WasmerExtern >> imports) {
402
- var instancePtr = _instance_new (store, module, imports, nullptr);
403
- if (instancePtr == nullptr) {
404
- throw Exception ("Wasm module instantiation failed" );
405
- }
406
-
407
- return instancePtr;
437
+ return _checkNotEqual (_instance_new (store, module, imports, nullptr),
438
+ nullptr, "Wasm module instantiation failed." );
408
439
}
409
440
410
441
Pointer <WasmerExternVec > exports (Pointer <WasmerInstance > instancePtr) {
@@ -464,19 +495,13 @@ class WasmRuntime {
464
495
limPtr.ref.max = maxPages ?? wasm_limits_max_default;
465
496
var memType = _memorytype_new (limPtr);
466
497
free (limPtr);
467
- Pointer <WasmerMemory > memPtr = _memory_new (store, memType);
468
-
469
- if (memPtr == nullptr) {
470
- throw Exception ("Failed to create memory" );
471
- }
472
- return memPtr;
498
+ return _checkNotEqual (
499
+ _memory_new (store, memType), nullptr, "Failed to create memory." );
473
500
}
474
501
475
502
void growMemory (Pointer <WasmerMemory > memory, int deltaPages) {
476
- var result = _memory_grow (memory, deltaPages);
477
- if (result == 0 ) {
478
- throw Exception ("Failed to grow memory" );
479
- }
503
+ _checkNotEqual (
504
+ _memory_grow (memory, deltaPages), 0 , "Failed to grow memory." );
480
505
}
481
506
482
507
int memoryLength (Pointer <WasmerMemory > memory) {
@@ -497,9 +522,89 @@ class WasmRuntime {
497
522
store, funcType, func.cast (), env.cast (), finalizer.cast ());
498
523
}
499
524
525
+ Pointer <WasmerWasiConfig > newWasiConfig () {
526
+ var name = allocate <Uint8 >();
527
+ name[0 ] = 0 ;
528
+ var config = _wasi_config_new (name);
529
+ free (name);
530
+ return _checkNotEqual (config, nullptr, "Failed to create WASI config." );
531
+ }
532
+
533
+ void captureWasiStdout (Pointer <WasmerWasiConfig > config) {
534
+ _wasi_config_inherit_stdout (config);
535
+ }
536
+
537
+ void captureWasiStderr (Pointer <WasmerWasiConfig > config) {
538
+ _wasi_config_inherit_stderr (config);
539
+ }
540
+
541
+ Pointer <WasmerWasiEnv > newWasiEnv (Pointer <WasmerWasiConfig > config) {
542
+ return _checkNotEqual (
543
+ _wasi_env_new (config), nullptr, "Failed to create WASI environment." );
544
+ }
545
+
546
+ void wasiEnvSetMemory (
547
+ Pointer <WasmerWasiEnv > env, Pointer <WasmerMemory > memory) {
548
+ _wasi_env_set_memory (env, memory);
549
+ }
550
+
551
+ void getWasiImports (Pointer <WasmerStore > store, Pointer <WasmerModule > mod,
552
+ Pointer <WasmerWasiEnv > env, Pointer <Pointer <WasmerExtern >> imports) {
553
+ _checkNotEqual (_wasi_get_imports (store, mod, env, imports), 0 ,
554
+ "Failed to fill WASI imports." );
555
+ }
556
+
557
+ Stream <List <int >> getWasiStdoutStream (Pointer <WasmerWasiEnv > env) {
558
+ return Stream .fromIterable (_WasiStreamIterable (env, _wasi_env_read_stdout));
559
+ }
560
+
561
+ Stream <List <int >> getWasiStderrStream (Pointer <WasmerWasiEnv > env) {
562
+ return Stream .fromIterable (_WasiStreamIterable (env, _wasi_env_read_stderr));
563
+ }
564
+
565
+ String _getLastError () {
566
+ var length = _wasmer_last_error_length ();
567
+ var buf = allocate <Uint8 >(count: length);
568
+ _wasmer_last_error_message (buf, length);
569
+ String message = utf8.decode (buf.asTypedList (length));
570
+ free (buf);
571
+ return message;
572
+ }
573
+
574
+ T _checkNotEqual <T >(T x, T y, String errorMessage) {
575
+ if (x == y) {
576
+ throw Exception ("$errorMessage \n ${_getLastError ()}" );
577
+ }
578
+ return x;
579
+ }
580
+
500
581
static String getSignatureString (
501
582
String name, List <int > argTypes, int returnType) {
502
583
return "${wasmerValKindName (returnType )} $name " +
503
584
"(${argTypes .map (wasmerValKindName ).join (", " )})" ;
504
585
}
505
586
}
587
+
588
+ class _WasiStreamIterator implements Iterator <List <int >> {
589
+ static final int _bufferLength = 1024 ;
590
+ Pointer <WasmerWasiEnv > _env;
591
+ Function _reader;
592
+ Pointer <Uint8 > _buf = allocate <Uint8 >(count: _bufferLength);
593
+ int _length = 0 ;
594
+ _WasiStreamIterator (this ._env, this ._reader) {}
595
+
596
+ bool moveNext () {
597
+ _length = _reader (_env, _buf, _bufferLength);
598
+ return true ;
599
+ }
600
+
601
+ List <int > get current => _buf.asTypedList (_length);
602
+ }
603
+
604
+ class _WasiStreamIterable extends Iterable <List <int >> {
605
+ Pointer <WasmerWasiEnv > _env;
606
+ Function _reader;
607
+ _WasiStreamIterable (this ._env, this ._reader) {}
608
+ @override
609
+ Iterator <List <int >> get iterator => _WasiStreamIterator (_env, _reader);
610
+ }
0 commit comments