aboutsummaryrefslogtreecommitdiff
path: root/tools/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/translate.c')
-rw-r--r--tools/translate.c74
1 files changed, 55 insertions, 19 deletions
diff --git a/tools/translate.c b/tools/translate.c
index 8b28aad..27532ad 100644
--- a/tools/translate.c
+++ b/tools/translate.c
@@ -259,17 +259,16 @@ static int typecheck_call(struct translation *data, struct function *callee)
return 0;
}
-static int typecheck_local_get(struct translation *data, uint32_t localidx)
+static int typecheck_local_get_set(struct translation *data, uint32_t localidx,
+ bool set)
{
uint32_t args_count = data->function->type->args.count;
char type = localidx < args_count ?
data->function->type->args.types[localidx] :
data->function->locals[localidx - args_count];
- if (rescheck_generic(&data->types_stack, type))
- return -1;
-
- return 0;
+ return (set ? argcheck_generic : rescheck_generic)
+ (&data->types_stack, type);
}
/** DEFINE INSTRUCTION TRANSLATION FUNCTIONS **/
@@ -277,6 +276,31 @@ static int typecheck_local_get(struct translation *data, uint32_t localidx)
/* Translate complex - those routines have to be defined manually */
#define TC(wasm_opcode, name, argtypes, restype)
+static int _translate_loop(struct translation *data)
+{
+ struct resulttype block_args, block_results;
+ char type_storage;
+ static const uint8_t loop_end_marker_code = WASM_END;
+ static const struct end_markers loop_end_markers = {
+ .count = 1,
+ .codes = &loop_end_marker_code
+ };
+
+ if (parse_blocktype(data->handle, &block_args, &block_results,
+ &type_storage, data->module))
+ goto fail;
+
+ if (translate_expr(data, &block_args, &block_results,
+ &loop_end_markers, NULL, true))
+ goto fail;
+
+ return 0;
+
+fail:
+ PRERR("Couldn't translate loop instruction\n");
+ return -1;
+}
+
static int _translate_if(struct translation *data)
{
struct types *backed_stack;
@@ -488,9 +512,7 @@ static int _translate_call(struct translation *data)
return i_call(ptr(target), &data->function->translated_body);
}
-static int typecheck_local_get(struct translation *data, uint32_t localidx);
-
-static int _translate_local_get(struct translation *data)
+static int translate_local_get_set(struct translation *data, bool set)
{
uint32_t localidx;
uint32_t args_count = data->function->type->args.count;
@@ -509,7 +531,7 @@ static int _translate_local_get(struct translation *data)
return -1;
}
- if (typecheck_local_get(data, localidx))
+ if (typecheck_local_get_set(data, localidx, set))
return -1;
offset_on_frame = all_locals_count - localidx + 1;
@@ -517,11 +539,27 @@ static int _translate_local_get(struct translation *data)
if (localidx >= args_count)
offset_on_frame -= 1;
- if (i_load (im(STACK_FRAME_BACKUP_ADDR), expr) ||
- i_load_p(im(4 * offset_on_frame), expr))
+ if (i_load(im(STACK_FRAME_BACKUP_ADDR), expr))
return -1;
- return 0;
+ if (set) {
+ return
+ i_swap ( expr) ||
+ i_store_p(im(4 * offset_on_frame), expr);
+ } else {
+ return
+ i_load_p(im(4 * offset_on_frame), expr);
+ }
+}
+
+static int _translate_local_get(struct translation *data)
+{
+ return translate_local_get_set(data, false);
+}
+
+static int _translate_local_set(struct translation *data)
+{
+ return translate_local_get_set(data, true);
}
static int _translate_const(struct translation *data)
@@ -610,12 +648,10 @@ static int translate_instr(struct translation *data, uint8_t wasm_opcode)
tc_routines = typecheck_routines + wasm_opcode;
- if (tc_routines->argcheck(&data->types_stack) ||
- tc_routines->rescheck(&data->types_stack) ||
- translation_routines[wasm_opcode](data))
- return -1;
-
- return 0;
+ return
+ tc_routines->argcheck(&data->types_stack) ||
+ translation_routines[wasm_opcode](data) ||
+ tc_routines->rescheck(&data->types_stack);
}
static int parse_blocktype(FILE *handle, struct resulttype *args,
@@ -666,7 +702,7 @@ static int parse_blocktype(FILE *handle, struct resulttype *args,
goto fail;
}
- if (typeidx <= module->functypes_count) {
+ if (typeidx >= module->functypes_count) {
PRERR(MSG_BAD_IDX("type index"));
goto fail;
}