Skip to content

Commit

Permalink
implement Extended Constant Expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
partic2 committed Jul 4, 2023
1 parent bdcc0a8 commit 882b9fc
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 40 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ endif()

if (BUILD_TESTING)
enable_testing()
execute_process(COMMAND ${WAT2WASM} "--enable-multi-memory" "test1.wat" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests" COMMAND_ECHO STDOUT)
execute_process(COMMAND ${WAT2WASM} "--enable-multi-memory" "--enable-extended-const" "test1.wat" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests" COMMAND_ECHO STDOUT)
execute_process(COMMAND ${WAT2WASM} "--enable-multi-memory" "extension1.wat" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests" COMMAND_ECHO STDOUT)
execute_process(COMMAND ${WAT2WASM} "unary.wat" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests" COMMAND_ECHO STDOUT)
execute_process(COMMAND ${WAT2WASM} "binary.wat" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests" COMMAND_ECHO STDOUT)
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,16 @@ Multi-value
Non-trapping Float-to-int Conversions (For performance, the behavior depend on the host.)
Bulk Memory Operations(Conditional Segment Initialization is not support yet.)
Bulk Memory Operations(Conditional Segment Initialization is not supported yet.)
Memory64(support i64 index, offset and align are still 32bit.)
Reference types
Multiple memories
Extended Constant Expressions
Simple namespace support
## NOT Implemented
Expand Down
9 changes: 9 additions & 0 deletions pwart/def.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,15 @@ static struct{
#define WASMOPC_i32_shl 0x74
#define WASMOPC_i64_shl 0x86

#define WASMOPC_i32_add 0x6a
#define WASMOPC_i32_sub 0x6b
#define WASMOPC_i32_mul 0x6c
#define WASMOPC_i64_add 0x7c
#define WASMOPC_i64_sub 0x7d
#define WASMOPC_i64_mul 0x7e

#define WASMOPC_end 0x0b

static struct pwart_global_compile_config pwart_gcfg={
.stack_flags=0,
.misc_flags=PWART_MISC_FLAGS_LOCALS_ZERO_INIT
Expand Down
145 changes: 108 additions & 37 deletions pwart/extfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,48 +481,119 @@ static Type func_type_ref_ref_i32_void={.params=types_ref_ref_i32,.results=types
static Type func_type_memoryfill={.params=types_ref_i32_i32_ref_i32,.results=types_void};

static char *waexpr_run_const(ModuleCompiler *m, void *result) {
int opcode=m->bytes[m->pc];
m->pc++;
switch (opcode) {
case 0x41: // i32.const
*(uint32_t *)result = read_LEB_signed(m->bytes, &m->pc, 32);
break;
case 0x42: // i64.const
*(uint64_t *)result = read_LEB_signed(m->bytes, &m->pc, 64);
break;
case 0x43: // f32.const
*(float *)result = *(float *)(m->bytes + m->pc);
m->pc += 4;
break;
case 0x44: // f64.const
*(double *)result = *(double *)(m->bytes + m->pc);
m->pc += 8;
break;
case 0x23: // global.get
{
uint32_t arg = read_LEB(m->bytes, &m->pc, 32);
StackValue *sv = dynarr_get(m->globals, StackValue, arg);
if (stackvalue_GetSizeAndAlign(sv, NULL) == 8) {
*(uint64_t *)result = *(uint64_t *)(sv->val.opw);
} else {
*(uint32_t *)result = *(uint32_t *)(sv->val.opw);
int opcode=0;
//const stack
uint64_t stack[16];
void *sp=&stack;
int eof=0;
while(m->pc<=m->byte_count && !eof){
opcode=m->bytes[m->pc];
m->pc++;
switch (opcode) {
case 0x41: // i32.const
*(uint32_t *)sp = read_LEB_signed(m->bytes, &m->pc, 32);
sp+=4;
break;
case 0x42: // i64.const
*(uint64_t *)sp = read_LEB_signed(m->bytes, &m->pc, 64);
sp+=8;
break;
case 0x43: // f32.const
//use memmove to avoid align error
memmove(sp,m->bytes + m->pc,4);
m->pc += 4;
sp+=4;
break;
case 0x44: // f64.const
//use memmove to avoid align error
memmove(sp,m->bytes + m->pc,8);
m->pc += 8;
sp+=8;
break;
case 0x23: // global.get
{
uint32_t arg = read_LEB(m->bytes, &m->pc, 32);
StackValue *sv = dynarr_get(m->globals, StackValue, arg);
if (stackvalue_GetSizeAndAlign(sv, NULL) == 8) {
*(uint64_t *)sp = *(uint64_t *)(sv->val.opw);
sp+=8;
} else {
*(uint32_t *)sp = *(uint32_t *)(sv->val.opw);
sp+=4;
}
} break;
case 0xd0: //ref.null
*(void **)sp=NULL;
sp+=m->target_ptr_size/8;
break;
case 0xd2: //ref.func
{
uint32_t arg = read_LEB(m->bytes, &m->pc, 32);
*(WasmFunction **)sp = dynarr_get(m->functions,WasmFunction,arg);
sp+=m->target_ptr_size/8;
}break;
case WASMOPC_i32_add:
{
uint32_t *arg1=((void *)sp)-8;
uint32_t *arg2=arg1+1;
sp-=8;
*(uint32_t *)sp=*arg1+*arg2;
sp+=4;
}break;
case WASMOPC_i32_sub:
{
uint32_t *arg1=((void *)sp)-8;
uint32_t *arg2=arg1+1;
sp-=8;
*(uint32_t *)sp=*arg1-*arg2;
sp+=4;
}break;
case WASMOPC_i32_mul:
{
uint32_t *arg1=((void *)sp)-8;
uint32_t *arg2=arg1+1;
sp-=8;
*(uint32_t *)sp=(*arg1) * (*arg2);
sp+=4;
}break;
case WASMOPC_i64_add:
{
uint64_t *arg1=((void *)sp)-16;
uint64_t *arg2=arg1+1;
sp-=16;
*(uint64_t *)sp=*arg1+*arg2;
sp+=8;
}break;
case WASMOPC_i64_sub:
{
uint64_t *arg1=((void *)sp)-16;
uint64_t *arg2=arg1+1;
sp-=16;
*(uint64_t *)sp=*arg1-*arg2;
sp+=8;
}break;
case WASMOPC_i64_mul:
{
uint64_t *arg1=((void *)sp)-16;
uint64_t *arg2=arg1+1;
sp-=16;
*(uint64_t *)sp=(*arg1) * (*arg2);
sp+=8;
}break;
case WASMOPC_end:
eof=1;
m->pc--;
break;
default:
return "Unsupport const expr";
break;
}
} break;
case 0xd0: //ref.null
*(void **)result=NULL;
break;
case 0xd2: //ref.func
{
uint32_t arg = read_LEB(m->bytes, &m->pc, 32);
*(WasmFunction **)result = dynarr_get(m->functions,WasmFunction,arg);
}
default:
return "Unsupport const expr";
break;
}

if(m->bytes[m->pc]!=0xb){
return "const expr miss end instruction.";
}
memcpy(result,&stack,sp-(void *)stack);
m->pc++;
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ include $(PWART_SOURCE_ROOT)/pwart/make_config.mk
test:build_pwart
- rm testexe || rm testexe.exe
$(CC) $(PWART_CFLAGS) $(CFLAGS) -o testexe testmain.c $(PWART_LDFLAGS) $(LDFLAGS)
$(WAT2WASM) --enable-multi-memory test1.wat
$(WAT2WASM) --enable-multi-memory --enable-extended-const test1.wat
$(WAT2WASM) unary.wat
$(WAT2WASM) binary.wat
$(WAT2WASM) control.wat
Expand Down
11 changes: 11 additions & 0 deletions tests/test1.wat
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
(elem 0 (i32.const 0) $addTwo )
(global $one i32 (i32.const 1))
(global $two i32 (i32.const 2))
(global $three (mut i32) (i32.add (i32.const 1)(i32.const 2)))

;; function 0
(func $nop
Expand Down Expand Up @@ -270,9 +271,19 @@
call $ref_string_length
)

;; function 10 expect 4
(func $miscTest1 (result i32)
global.get $three
i32.const 1
i32.add
global.set $three
global.get $three
)

(export "addTwo" (func $addTwo))
(export "test1" (func $test1))
(export "test2" (func $test2))
(export "test3" (func $test3))
(export "builtinFuncTest" (func $builtinFuncTest))
(export "miscTest1" (func $miscTest1))
)
14 changes: 14 additions & 0 deletions tests/testmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ int test1() {
pwart_wasm_function fib_main = pwart_get_export_function(ctx, "fib_main");
pwart_wasm_function builtinFuncTest =
pwart_get_export_function(ctx, "builtinFuncTest");
pwart_wasm_function miscTest1 =
pwart_get_export_function(ctx, "miscTest1");


pwart_free_module_compiler(m);

Expand Down Expand Up @@ -232,6 +235,17 @@ int test1() {
return 0;
}

// miscTest1 test
sp = stackbase;
sp = stackbase;
pwart_call_wasm_function(miscTest1, sp);
ri32 = geti32(&sp);
printf("11.miscTest1 test, expect %x got %x\n",
4,ri32);
if (4!=ri32) {
return 0;
}

pwart_free_module_state(ctx);
}
free(data);
Expand Down

0 comments on commit 882b9fc

Please sign in to comment.