16
16
17
17
namespace dart {
18
18
19
- static void ThrowIfFailed (wasmer_result_t status) {
20
- if (status == wasmer_result_t ::WASMER_OK) return ;
21
- int len = wasmer_last_error_length ();
22
- auto error = std::unique_ptr<char []>(new char [len]);
23
- int read_len = wasmer_last_error_message (error.get (), len);
24
- ASSERT (read_len == len);
19
+ static void ThrowWasmerError () {
25
20
TransitionNativeToVM transition (Thread::Current ());
26
- Exceptions::ThrowArgumentError (
27
- String::Handle (String::NewFormatted (" Wasmer error: %s" , error.get ())));
21
+ String& error = String::Handle ();
22
+ {
23
+ int len = wasmer_last_error_length ();
24
+ auto raw_error = std::unique_ptr<char []>(new char [len]);
25
+ int read_len = wasmer_last_error_message (raw_error.get (), len);
26
+ ASSERT (read_len == len);
27
+ error = String::NewFormatted (" Wasmer error: %s" , raw_error.get ());
28
+ }
29
+ Exceptions::ThrowArgumentError (error);
28
30
}
29
31
30
32
template <typename T>
@@ -181,11 +183,10 @@ class WasmFunction {
181
183
return dart_ret == _ret;
182
184
}
183
185
184
- wasmer_value_t Call (const wasmer_value_t * params) {
185
- wasmer_value_t result;
186
- ThrowIfFailed (wasmer_export_func_call (_fn, params, _args.length (), &result,
187
- IsVoid () ? 0 : 1 ));
188
- return result;
186
+ bool Call (const wasmer_value_t * params, wasmer_value_t * result) {
187
+ return wasmer_export_func_call (_fn, params, _args.length (), result,
188
+ IsVoid () ? 0 : 1 ) ==
189
+ wasmer_result_t ::WASMER_OK;
189
190
}
190
191
191
192
void Print (std::ostream& o, const char * name) const {
@@ -226,20 +227,29 @@ class WasmFunction {
226
227
227
228
class WasmInstance {
228
229
public:
229
- explicit WasmInstance (wasmer_module_t * module, WasmImports* imports) {
230
+ WasmInstance () : _instance(nullptr ), _exports(nullptr ) {}
231
+
232
+ bool Instantiate (wasmer_module_t * module, WasmImports* imports) {
230
233
// Instantiate module.
231
- ThrowIfFailed (wasmer_module_instantiate (
232
- module, &_instance, imports->RawImports (), imports->NumImports ()));
234
+ if (wasmer_module_instantiate (module, &_instance, imports->RawImports (),
235
+ imports->NumImports ()) !=
236
+ wasmer_result_t ::WASMER_OK) {
237
+ return false ;
238
+ }
233
239
234
240
// Load all functions.
235
241
wasmer_instance_exports (_instance, &_exports);
236
242
intptr_t num_exports = wasmer_exports_len (_exports);
237
243
for (intptr_t i = 0 ; i < num_exports; ++i) {
238
244
wasmer_export_t * exp = wasmer_exports_get (_exports, i);
239
245
if (wasmer_export_kind (exp ) == wasmer_import_export_kind::WASM_FUNCTION) {
240
- AddFunction (exp );
246
+ if (!AddFunction (exp )) {
247
+ return false ;
248
+ }
241
249
}
242
250
}
251
+
252
+ return true ;
243
253
}
244
254
245
255
~WasmInstance () {
@@ -248,25 +258,31 @@ class WasmInstance {
248
258
delete[] kv->key ;
249
259
delete kv->value ;
250
260
}
251
- wasmer_exports_destroy (_exports);
252
- wasmer_instance_destroy (_instance);
261
+ if (_exports != nullptr ) {
262
+ wasmer_exports_destroy (_exports);
263
+ }
264
+ if (_instance != nullptr ) {
265
+ wasmer_instance_destroy (_instance);
266
+ }
253
267
}
254
268
255
269
WasmFunction* GetFunction (const char * name,
256
270
const MallocGrowableArray<classid_t >& dart_args,
257
- classid_t dart_ret) {
271
+ classid_t dart_ret,
272
+ String* error) {
258
273
WasmFunction* fn = _functions.LookupValue (name);
259
274
if (fn == nullptr ) {
260
- Exceptions::ThrowArgumentError ( String::Handle ( String::NewFormatted (
275
+ *error = String::NewFormatted (
261
276
" Couldn't find a function called %s in the WASM module's exports" ,
262
- name))) ;
277
+ name);
263
278
return nullptr ;
264
279
}
265
280
if (!fn->SignatureMatches (dart_args, dart_ret)) {
266
281
std::stringstream sig;
267
282
fn->Print (sig, name);
268
- Exceptions::ThrowArgumentError (String::Handle (String::NewFormatted (
269
- " Function signature doesn't match: %s" , sig.str ().c_str ())));
283
+ *error = String::NewFormatted (" Function signature doesn't match: %s" ,
284
+ sig.str ().c_str ());
285
+ return nullptr ;
270
286
}
271
287
return fn;
272
288
}
@@ -301,21 +317,33 @@ class WasmInstance {
301
317
return 0 ;
302
318
}
303
319
304
- void AddFunction (wasmer_export_t * exp) {
320
+ bool AddFunction (wasmer_export_t * exp) {
305
321
const wasmer_export_func_t * fn = wasmer_export_to_func (exp );
306
322
307
323
uint32_t num_rets;
308
- ThrowIfFailed (wasmer_export_func_returns_arity (fn, &num_rets));
324
+ if (wasmer_export_func_returns_arity (fn, &num_rets) !=
325
+ wasmer_result_t ::WASMER_OK) {
326
+ return false ;
327
+ }
309
328
ASSERT (num_rets <= 1 );
310
329
wasmer_value_tag wasm_ret;
311
- ThrowIfFailed (wasmer_export_func_returns (fn, &wasm_ret, num_rets));
330
+ if (wasmer_export_func_returns (fn, &wasm_ret, num_rets) !=
331
+ wasmer_result_t ::WASMER_OK) {
332
+ return false ;
333
+ }
312
334
classid_t ret = num_rets == 0 ? kWasmVoidCid : ToDartType (wasm_ret);
313
335
314
336
uint32_t num_args;
315
- ThrowIfFailed (wasmer_export_func_params_arity (fn, &num_args));
337
+ if (wasmer_export_func_params_arity (fn, &num_args) !=
338
+ wasmer_result_t ::WASMER_OK) {
339
+ return false ;
340
+ }
316
341
auto wasm_args =
317
342
std::unique_ptr<wasmer_value_tag[]>(new wasmer_value_tag[num_args]);
318
- ThrowIfFailed (wasmer_export_func_params (fn, wasm_args.get (), num_args));
343
+ if (wasmer_export_func_params (fn, wasm_args.get (), num_args) !=
344
+ wasmer_result_t ::WASMER_OK) {
345
+ return false ;
346
+ }
319
347
MallocGrowableArray<classid_t > args;
320
348
for (intptr_t i = 0 ; i < num_args; ++i) {
321
349
args.Add (ToDartType (wasm_args[i]));
@@ -329,6 +357,7 @@ class WasmInstance {
329
357
name[name_bytes.bytes_len ] = ' \0 ' ;
330
358
331
359
_functions.Insert ({name, new WasmFunction (std::move (args), ret, fn)});
360
+ return true ;
332
361
}
333
362
334
363
DISALLOW_COPY_AND_ASSIGN (WasmInstance);
@@ -353,7 +382,11 @@ DEFINE_NATIVE_ENTRY(Wasm_initModule, 0, 2) {
353
382
wasmer_module_t * module;
354
383
{
355
384
TransitionVMToNative transition (thread);
356
- ThrowIfFailed (wasmer_compile (&module, data_copy.get (), len));
385
+ if (wasmer_compile (&module, data_copy.get (), len) !=
386
+ wasmer_result_t ::WASMER_OK) {
387
+ data_copy.reset ();
388
+ ThrowWasmerError ();
389
+ }
357
390
}
358
391
359
392
mod_wrap.SetNativeField (0 , reinterpret_cast <intptr_t >(module));
@@ -436,7 +469,9 @@ DEFINE_NATIVE_ENTRY(Wasm_initMemory, 0, 3) {
436
469
descriptor.max .has_some = true ;
437
470
descriptor.max .some = max_size;
438
471
}
439
- ThrowIfFailed (wasmer_memory_new (&memory, descriptor));
472
+ if (wasmer_memory_new (&memory, descriptor) != wasmer_result_t ::WASMER_OK) {
473
+ ThrowWasmerError ();
474
+ }
440
475
mem_wrap.SetNativeField (0 , reinterpret_cast <intptr_t >(memory));
441
476
FinalizablePersistentHandle::New (thread->isolate (), mem_wrap, memory,
442
477
FinalizeWasmMemory, init_size);
@@ -451,7 +486,10 @@ DEFINE_NATIVE_ENTRY(Wasm_growMemory, 0, 2) {
451
486
452
487
wasmer_memory_t * memory =
453
488
reinterpret_cast <wasmer_memory_t *>(mem_wrap.GetNativeField (0 ));
454
- ThrowIfFailed (wasmer_memory_grow (memory, delta.AsInt64Value ()));
489
+ if (wasmer_memory_grow (memory, delta.AsInt64Value ()) !=
490
+ wasmer_result_t ::WASMER_OK) {
491
+ ThrowWasmerError ();
492
+ }
455
493
return WasmMemoryToExternalTypedData (memory);
456
494
}
457
495
@@ -469,10 +507,17 @@ DEFINE_NATIVE_ENTRY(Wasm_initInstance, 0, 3) {
469
507
WasmImports* imports =
470
508
reinterpret_cast <WasmImports*>(imp_wrap.GetNativeField (0 ));
471
509
472
- WasmInstance* inst;
510
+ WasmInstance* inst = nullptr ;
473
511
{
474
512
TransitionVMToNative transition (thread);
475
- inst = new WasmInstance (module, imports);
513
+ inst = new WasmInstance ();
514
+ if (!inst->Instantiate (module, imports)) {
515
+ delete inst;
516
+ inst = nullptr ;
517
+ }
518
+ }
519
+ if (inst == nullptr ) {
520
+ ThrowWasmerError ();
476
521
}
477
522
478
523
inst_wrap.SetNativeField (0 , reinterpret_cast <intptr_t >(inst));
@@ -495,17 +540,27 @@ DEFINE_NATIVE_ENTRY(Wasm_initFunction, 0, 4) {
495
540
WasmInstance* inst =
496
541
reinterpret_cast <WasmInstance*>(inst_wrap.GetNativeField (0 ));
497
542
498
- Function& sig = Function::Handle (fn_type.signature ());
499
- Array& args = Array::Handle (sig.parameter_types ());
500
- MallocGrowableArray<classid_t > dart_args;
501
- for (intptr_t i = sig.NumImplicitParameters (); i < args.Length (); ++i) {
502
- dart_args.Add (
503
- AbstractType::Cast (Object::Handle (args.At (i))).type_class_id ());
543
+ WasmFunction* fn;
544
+ String& error = String::Handle (zone);
545
+
546
+ {
547
+ Function& sig = Function::Handle (fn_type.signature ());
548
+ Array& args = Array::Handle (sig.parameter_types ());
549
+ MallocGrowableArray<classid_t > dart_args;
550
+ for (intptr_t i = sig.NumImplicitParameters (); i < args.Length (); ++i) {
551
+ dart_args.Add (
552
+ AbstractType::Cast (Object::Handle (args.At (i))).type_class_id ());
553
+ }
554
+ classid_t dart_ret =
555
+ AbstractType::Handle (sig.result_type ()).type_class_id ();
556
+
557
+ std::unique_ptr<char []> name_raw = ToUTF8 (name);
558
+ fn = inst->GetFunction (name_raw.get (), dart_args, dart_ret, &error);
504
559
}
505
- classid_t dart_ret = AbstractType::Handle (sig.result_type ()).type_class_id ();
506
560
507
- std::unique_ptr<char []> name_raw = ToUTF8 (name);
508
- WasmFunction* fn = inst->GetFunction (name_raw.get (), dart_args, dart_ret);
561
+ if (fn == nullptr ) {
562
+ Exceptions::ThrowArgumentError (error);
563
+ }
509
564
510
565
fn_wrap.SetNativeField (0 , reinterpret_cast <intptr_t >(fn));
511
566
// Don't need a finalizer because WasmFunctions are owned their WasmInstance.
@@ -535,15 +590,19 @@ DEFINE_NATIVE_ENTRY(Wasm_callFunction, 0, 2) {
535
590
for (intptr_t i = 0 ; i < args.Length (); ++i) {
536
591
if (!ToWasmValue (Number::Cast (Object::Handle (args.At (i))), fn->args ()[i],
537
592
¶ms[i])) {
593
+ params.reset ();
538
594
Exceptions::ThrowArgumentError (String::Handle (
539
595
String::NewFormatted (" Arg %" Pd " is the wrong type." , i)));
540
596
}
541
597
}
542
598
543
599
wasmer_value_t ret;
544
600
{
545
- TransitionVMToNative transition (Thread::Current ());
546
- ret = fn->Call (params.get ());
601
+ TransitionVMToNative transition (thread);
602
+ if (!fn->Call (params.get (), &ret)) {
603
+ params.reset ();
604
+ ThrowWasmerError ();
605
+ }
547
606
}
548
607
return fn->IsVoid () ? Object::null () : ToDartObject (ret);
549
608
}
0 commit comments