@@ -74,24 +74,37 @@ void initTypes() {
7474 block_types[4 ].results = block_type_results[3 ];
7575}
7676
77- Type *get_block_type (uint8_t value_type) {
78- switch (value_type) {
79- case 0x40 :
80- return &block_types[0 ];
81- case I32:
82- return &block_types[1 ];
83- case I64:
84- return &block_types[2 ];
85- case F32:
86- return &block_types[3 ];
87- case F64:
88- return &block_types[4 ];
89- default :
90- FATAL (" invalid block_type value_type: %d\n " , value_type);
77+ Type *get_block_type (Module *m, uint8_t type) {
78+ uint8_t *pos = &type;
79+ int64_t type_s = read_LEB_signed (&pos, 33 );
80+
81+ if (type_s < 0 ) {
82+ switch (type) {
83+ case 0x40 :
84+ return &block_types[0 ]; // empty
85+ case I32:
86+ return &block_types[1 ];
87+ case I64:
88+ return &block_types[2 ];
89+ case F32:
90+ return &block_types[3 ];
91+ case F64:
92+ return &block_types[4 ];
93+ default :
94+ FATAL (" invalid block_type value_type: %d\n " , type);
95+ return nullptr ;
96+ }
97+ } else {
98+ if ((uint32_t )type_s >= m->type_count ) {
99+ FATAL (" block_type index out of bounds: %lld >= %u\n " ,
100+ type_s, m->type_count );
91101 return nullptr ;
102+ }
103+ return &m->types [type_s];
92104 }
93105}
94106
107+
95108// TODO: calculate this while parsing types
96109uint64_t get_type_mask (Type *type) {
97110 uint64_t mask = 0x80 ;
@@ -215,7 +228,7 @@ void find_blocks(Module *m) {
215228 case 0x04 : // if
216229 block = (Block *)acalloc (1 , sizeof (Block), " Block" );
217230 block->block_type = opcode;
218- block->type = get_block_type (*(pos + 1 ));
231+ block->type = get_block_type (m, *(pos + 1 ));
219232 block->start_ptr = pos;
220233 blockstack[++top] = block;
221234 m->block_lookup [pos] = block;
@@ -261,7 +274,7 @@ void WARDuino::run_init_expr(Module *m, uint8_t type, uint8_t **pc) {
261274 WARDuino::instance ()->program_state = WARDUINOinit;
262275 Block block;
263276 block.block_type = 0x01 ;
264- block.type = get_block_type (type);
277+ block.type = get_block_type (m, type);
265278 block.start_ptr = *pc;
266279
267280 m->pc_ptr = *pc;
@@ -899,8 +912,7 @@ WARDuino::WARDuino() {
899912}
900913
901914// Return value of false means exception occurred
902- bool WARDuino::invoke (Module *m, uint32_t fidx, uint32_t arity,
903- StackValue *args) {
915+ bool WARDuino::invoke (Module *m, uint32_t fidx, uint32_t arity, StackValue *args, uint32_t max_results, StackValue *out_results, uint32_t *out_result_count) {
904916 bool result;
905917 m->sp = -1 ;
906918 m->fp = -1 ;
@@ -918,9 +930,29 @@ bool WARDuino::invoke(Module *m, uint32_t fidx, uint32_t arity,
918930 result = interpreter->interpret (m);
919931 dbg_trace (" Interpretation ended\n " );
920932 dbg_dump_stack (m);
921- return result;
933+
934+ if (!result) {
935+ if (out_result_count) *out_result_count = 0 ;
936+ return false ;
937+ }
938+
939+ uint32_t rescount = 0 ;
940+ Type *ftype = m->functions [fidx].type ;
941+ rescount = ftype->result_count ;
942+
943+ if (out_result_count)
944+ {
945+ *out_result_count = rescount > max_results ? max_results : rescount;
946+
947+ for (uint32_t i = 0 ; i < *out_result_count; ++i) {
948+ out_results[i] = m->stack [m->sp - (rescount - 1 ) + i];
949+ }
950+ }
951+
952+ return true ;
922953}
923954
955+
924956void WARDuino::setInterpreter (Interpreter *interpreter) {
925957 this ->interpreter = interpreter;
926958}
@@ -930,9 +962,15 @@ int WARDuino::run_module(Module *m) {
930962
931963 // execute main
932964 if (fidx != UNDEF) {
933- this ->invoke (m, fidx);
934- return m->stack ->value .uint32 ;
965+ StackValue outputs[8 ];
966+ uint32_t out_count = 0 ;
967+ bool ok = this ->invoke (m, fidx, 0 , nullptr , 8 , outputs, &out_count);
968+ if (!ok) {
969+ return 0 ;
970+ }
971+ return (int )outputs[0 ].value .uint32 ;
935972 }
973+ fflush (stdout);
936974
937975 // wait
938976 m->warduino ->debugger ->pauseRuntime (m);
0 commit comments