77#include " instantiate.hpp"
88#include " parser.hpp"
99#include < fizzy/fizzy.h>
10+ #include < cstring>
1011#include < memory>
1112
1213namespace
1314{
15+ inline void set_success (FizzyError* error) noexcept
16+ {
17+ if (error == nullptr )
18+ return ;
19+
20+ error->code = FIZZY_SUCCESS;
21+ error->message [0 ] = ' \0 ' ;
22+ }
23+
24+ // Copying a string into a fixed-size static buffer, guaranteed to not overrun it and to always end
25+ // the destination string with a null terminator. Inspired by strlcpy.
26+ template <size_t N>
27+ inline size_t truncating_strlcpy (char (&dest)[N], const char* src) noexcept
28+ {
29+ static_assert (N >= 4 );
30+
31+ const auto src_len = strlen (src);
32+ const auto copy_len = std::min (src_len, N - 1 );
33+ memcpy (dest, src, copy_len);
34+ if (copy_len < src_len)
35+ {
36+ dest[copy_len - 3 ] = ' .' ;
37+ dest[copy_len - 2 ] = ' .' ;
38+ dest[copy_len - 1 ] = ' .' ;
39+ }
40+ dest[copy_len] = ' \0 ' ;
41+ return copy_len;
42+ }
43+
44+ inline void set_error_code_and_message (
45+ FizzyErrorCode code, const char * message, FizzyError* error) noexcept
46+ {
47+ error->code = code;
48+ truncating_strlcpy (error->message , message);
49+ }
50+
51+ inline void set_error_from_current_exception (FizzyError* error) noexcept
52+ {
53+ if (error == nullptr )
54+ return ;
55+
56+ try
57+ {
58+ throw ;
59+ }
60+ catch (const fizzy::parser_error& e)
61+ {
62+ set_error_code_and_message (FIZZY_ERROR_MALFORMED_MODULE, e.what (), error);
63+ }
64+ catch (const fizzy::validation_error& e)
65+ {
66+ set_error_code_and_message (FIZZY_ERROR_INVALID_MODULE, e.what (), error);
67+ }
68+ catch (const fizzy::instantiate_error& e)
69+ {
70+ set_error_code_and_message (FIZZY_ERROR_INSTANTIATION_FAILED, e.what (), error);
71+ }
72+ catch (const std::exception& e)
73+ {
74+ set_error_code_and_message (FIZZY_ERROR_OTHER, e.what (), error);
75+ }
76+ catch (...)
77+ {
78+ set_error_code_and_message (FIZZY_ERROR_OTHER, " unknown error" , error);
79+ }
80+ }
81+
1482inline const FizzyModule* wrap (const fizzy::Module* module ) noexcept
1583{
1684 return reinterpret_cast <const FizzyModule*>(module );
@@ -360,28 +428,33 @@ inline FizzyExportDescription wrap(const fizzy::Export& exp) noexcept
360428} // namespace
361429
362430extern " C" {
363- bool fizzy_validate (const uint8_t * wasm_binary, size_t wasm_binary_size)
431+ bool fizzy_validate (const uint8_t * wasm_binary, size_t wasm_binary_size, FizzyError* error )
364432{
365433 try
366434 {
367435 fizzy::parse ({wasm_binary, wasm_binary_size});
436+ set_success (error);
368437 return true ;
369438 }
370439 catch (...)
371440 {
441+ set_error_from_current_exception (error);
372442 return false ;
373443 }
374444}
375445
376- const FizzyModule* fizzy_parse (const uint8_t * wasm_binary, size_t wasm_binary_size)
446+ const FizzyModule* fizzy_parse (
447+ const uint8_t * wasm_binary, size_t wasm_binary_size, FizzyError* error)
377448{
378449 try
379450 {
380451 auto module = fizzy::parse ({wasm_binary, wasm_binary_size});
452+ set_success (error);
381453 return wrap (module .release ());
382454 }
383455 catch (...)
384456 {
457+ set_error_from_current_exception (error);
385458 return nullptr ;
386459 }
387460}
@@ -529,7 +602,7 @@ bool fizzy_module_has_start_function(const FizzyModule* module)
529602FizzyInstance* fizzy_instantiate (const FizzyModule* module ,
530603 const FizzyExternalFunction* imported_functions, size_t imported_functions_size,
531604 const FizzyExternalTable* imported_table, const FizzyExternalMemory* imported_memory,
532- const FizzyExternalGlobal* imported_globals, size_t imported_globals_size)
605+ const FizzyExternalGlobal* imported_globals, size_t imported_globals_size, FizzyError* error )
533606{
534607 try
535608 {
@@ -541,18 +614,20 @@ FizzyInstance* fizzy_instantiate(const FizzyModule* module,
541614 auto instance = fizzy::instantiate (std::unique_ptr<const fizzy::Module>(unwrap (module )),
542615 std::move (functions), std::move (table), std::move (memory), std::move (globals));
543616
617+ set_success (error);
544618 return wrap (instance.release ());
545619 }
546620 catch (...)
547621 {
622+ set_error_from_current_exception (error);
548623 return nullptr ;
549624 }
550625}
551626
552627FizzyInstance* fizzy_resolve_instantiate (const FizzyModule* c_module,
553628 const FizzyImportedFunction* c_imported_functions, size_t imported_functions_size,
554629 const FizzyExternalTable* imported_table, const FizzyExternalMemory* imported_memory,
555- const FizzyImportedGlobal* c_imported_globals, size_t imported_globals_size)
630+ const FizzyImportedGlobal* c_imported_globals, size_t imported_globals_size, FizzyError* error )
556631{
557632 try
558633 {
@@ -568,10 +643,12 @@ FizzyInstance* fizzy_resolve_instantiate(const FizzyModule* c_module,
568643 auto instance = fizzy::instantiate (std::move (module ), std::move (resolved_imports),
569644 std::move (table), std::move (memory), std::move (resolved_globals));
570645
646+ set_success (error);
571647 return wrap (instance.release ());
572648 }
573649 catch (...)
574650 {
651+ set_error_from_current_exception (error);
575652 return nullptr ;
576653 }
577654}
0 commit comments