import, export, function index and signatures
This commit is contained in:
1 parent
a1cb9f0afa
commit
16df0f8513
5 files changed
+655
No files matched your search
@@ -50,16 +50,38 @@ parse_sections:
|
||||
mov eax, [sec_id]
|
||||
cmp eax, SECT_TYPE
|
||||
je .type
|
||||
cmp eax, SECT_IMPORT
|
||||
je .import
|
||||
cmp eax, SECT_FUNCTION
|
||||
je .func
|
||||
cmp eax, SECT_EXPORT
|
||||
je .export
|
||||
cmp eax, SECT_CODE
|
||||
je .code
|
||||
jmp .skip
|
||||
|
||||
.type:
|
||||
call parse_type_section
|
||||
jmp .skip
|
||||
.import:
|
||||
call parse_import_section
|
||||
jmp .skip
|
||||
.func:
|
||||
call parse_func_section
|
||||
jmp .skip
|
||||
.export:
|
||||
call parse_export_section
|
||||
jmp .skip
|
||||
.code:
|
||||
call parse_code_section
|
||||
|
||||
.skip:
|
||||
mov esi, [sec_next]
|
||||
jmp .next
|
||||
|
||||
.done:
|
||||
call build_func_index
|
||||
call print_func_signatures
|
||||
popad
|
||||
ret
|
||||
|
||||
@@ -205,3 +227,573 @@ print_valtype:
|
||||
call print_str
|
||||
pop esi
|
||||
ret
|
||||
|
||||
MAX_FUNCS = 64
|
||||
MAX_EXPORTS = 64
|
||||
MAX_IMPORTS = 64
|
||||
|
||||
IMPORT_KIND_FUNC = 0
|
||||
IMPORT_KIND_TABLE = 1
|
||||
IMPORT_KIND_MEMORY = 2
|
||||
IMPORT_KIND_GLOBAL = 3
|
||||
|
||||
parse_import_section:
|
||||
pushad
|
||||
mov esi, [sec_content]
|
||||
|
||||
call decode_leb128_u32
|
||||
mov [import_count], eax
|
||||
mov ecx, eax
|
||||
xor ebx, ebx
|
||||
mov dword [import_func_count], 0
|
||||
|
||||
.next_import:
|
||||
test ecx, ecx
|
||||
jz .imports_done
|
||||
push ecx
|
||||
|
||||
; module name
|
||||
call decode_leb128_u32
|
||||
mov edx, eax
|
||||
mov [import_mod_name_lens + ebx*4], eax
|
||||
mov [import_mod_name_ptrs + ebx*4], esi
|
||||
|
||||
push esi edx
|
||||
mov esi, msg_indent
|
||||
call print_str
|
||||
mov esi, msg_import_word
|
||||
call print_str
|
||||
mov esi, msg_quote
|
||||
call print_str
|
||||
pop edx esi
|
||||
push edx
|
||||
mov ecx, edx
|
||||
call print_n
|
||||
push esi
|
||||
mov esi, msg_quote
|
||||
call print_str
|
||||
mov esi, msg_dot
|
||||
call print_str
|
||||
pop esi
|
||||
pop edx
|
||||
|
||||
add esi, edx
|
||||
|
||||
; field name
|
||||
call decode_leb128_u32
|
||||
mov edx, eax
|
||||
mov [import_field_name_lens + ebx*4], eax
|
||||
mov [import_field_name_ptrs + ebx*4], esi
|
||||
|
||||
push esi edx
|
||||
mov esi, msg_quote
|
||||
call print_str
|
||||
pop edx esi
|
||||
push edx
|
||||
mov ecx, edx
|
||||
call print_n
|
||||
push esi
|
||||
mov esi, msg_quote
|
||||
call print_str
|
||||
pop esi
|
||||
pop edx
|
||||
|
||||
add esi, edx
|
||||
|
||||
; kind byte
|
||||
movzx eax, byte [esi]
|
||||
inc esi
|
||||
mov [import_kinds + ebx*4], eax
|
||||
|
||||
cmp eax, IMPORT_KIND_FUNC
|
||||
je .imp_func
|
||||
cmp eax, IMPORT_KIND_TABLE
|
||||
je .imp_table
|
||||
cmp eax, IMPORT_KIND_MEMORY
|
||||
je .imp_memory
|
||||
cmp eax, IMPORT_KIND_GLOBAL
|
||||
je .imp_global
|
||||
jmp .imp_next
|
||||
|
||||
.imp_func:
|
||||
call decode_leb128_u32
|
||||
mov [import_desc + ebx*4], eax
|
||||
push esi
|
||||
mov esi, msg_arrow
|
||||
call print_str
|
||||
mov esi, msg_func_word
|
||||
call print_str
|
||||
pop esi
|
||||
push esi
|
||||
mov esi, msg_type_word
|
||||
call print_str
|
||||
mov eax, [import_desc + ebx*4]
|
||||
call print_dec
|
||||
mov esi, msg_newline
|
||||
call print_str
|
||||
pop esi
|
||||
inc dword [import_func_count]
|
||||
jmp .imp_next
|
||||
|
||||
.imp_table:
|
||||
inc esi
|
||||
movzx eax, byte [esi]
|
||||
inc esi
|
||||
push eax
|
||||
call decode_leb128_u32
|
||||
pop edx
|
||||
test edx, 1
|
||||
jz .imp_table_print
|
||||
call decode_leb128_u32
|
||||
.imp_table_print:
|
||||
push esi
|
||||
mov esi, msg_arrow
|
||||
call print_str
|
||||
mov esi, msg_ek_table
|
||||
call print_str
|
||||
mov esi, msg_newline
|
||||
call print_str
|
||||
pop esi
|
||||
jmp .imp_next
|
||||
|
||||
.imp_memory:
|
||||
movzx eax, byte [esi]
|
||||
inc esi
|
||||
push eax
|
||||
call decode_leb128_u32
|
||||
pop edx
|
||||
test edx, 1
|
||||
jz .imp_mem_print
|
||||
call decode_leb128_u32
|
||||
.imp_mem_print:
|
||||
push esi
|
||||
mov esi, msg_arrow
|
||||
call print_str
|
||||
mov esi, msg_ek_memory
|
||||
call print_str
|
||||
mov esi, msg_newline
|
||||
call print_str
|
||||
pop esi
|
||||
jmp .imp_next
|
||||
|
||||
.imp_global:
|
||||
add esi, 2
|
||||
push esi
|
||||
mov esi, msg_arrow
|
||||
call print_str
|
||||
mov esi, msg_ek_global
|
||||
call print_str
|
||||
mov esi, msg_newline
|
||||
call print_str
|
||||
pop esi
|
||||
|
||||
.imp_next:
|
||||
pop ecx
|
||||
inc ebx
|
||||
dec ecx
|
||||
jmp .next_import
|
||||
|
||||
.imports_done:
|
||||
popad
|
||||
ret
|
||||
|
||||
parse_func_section:
|
||||
pushad
|
||||
mov esi, [sec_content]
|
||||
|
||||
call decode_leb128_u32
|
||||
mov [func_count], eax
|
||||
mov ecx, eax
|
||||
xor ebx, ebx
|
||||
|
||||
.next_func:
|
||||
test ecx, ecx
|
||||
jz .funcs_done
|
||||
|
||||
push ecx
|
||||
call decode_leb128_u32
|
||||
mov [func_type_idx + ebx*4], eax
|
||||
mov edx, eax
|
||||
|
||||
push esi
|
||||
mov esi, msg_indent
|
||||
call print_str
|
||||
mov esi, msg_func_word
|
||||
call print_str
|
||||
mov eax, ebx
|
||||
call print_dec
|
||||
mov esi, msg_arrow_type
|
||||
call print_str
|
||||
mov eax, edx
|
||||
call print_dec
|
||||
mov esi, msg_newline
|
||||
call print_str
|
||||
pop esi
|
||||
pop ecx
|
||||
|
||||
inc ebx
|
||||
dec ecx
|
||||
jmp .next_func
|
||||
|
||||
.funcs_done:
|
||||
popad
|
||||
ret
|
||||
|
||||
parse_export_section:
|
||||
pushad
|
||||
mov esi, [sec_content]
|
||||
|
||||
call decode_leb128_u32
|
||||
mov [export_count], eax
|
||||
mov ecx, eax
|
||||
xor ebx, ebx
|
||||
|
||||
.next_export:
|
||||
test ecx, ecx
|
||||
jz .exports_done
|
||||
push ecx
|
||||
|
||||
call decode_leb128_u32
|
||||
mov edx, eax
|
||||
mov [export_name_lens + ebx*4], eax
|
||||
mov [export_name_ptrs + ebx*4], esi
|
||||
|
||||
push esi edx
|
||||
mov esi, msg_indent
|
||||
call print_str
|
||||
mov esi, msg_export_q
|
||||
call print_str
|
||||
pop edx esi
|
||||
push edx
|
||||
mov ecx, edx
|
||||
call print_n
|
||||
push esi
|
||||
mov esi, msg_quote
|
||||
call print_str
|
||||
pop esi
|
||||
pop edx
|
||||
|
||||
add esi, edx
|
||||
|
||||
movzx eax, byte [esi]
|
||||
inc esi
|
||||
mov [export_kinds + ebx*4], eax
|
||||
push eax
|
||||
|
||||
call decode_leb128_u32
|
||||
mov [export_indices + ebx*4], eax
|
||||
mov edx, eax
|
||||
|
||||
push esi
|
||||
mov esi, msg_arrow
|
||||
call print_str
|
||||
pop esi
|
||||
pop eax
|
||||
push esi
|
||||
call print_export_kind
|
||||
mov eax, edx
|
||||
call print_dec
|
||||
mov esi, msg_newline
|
||||
call print_str
|
||||
pop esi
|
||||
|
||||
pop ecx
|
||||
inc ebx
|
||||
dec ecx
|
||||
jmp .next_export
|
||||
|
||||
.exports_done:
|
||||
popad
|
||||
ret
|
||||
|
||||
print_export_kind:
|
||||
push esi
|
||||
cmp eax, 0
|
||||
je .ek_func
|
||||
cmp eax, 1
|
||||
je .ek_table
|
||||
cmp eax, 2
|
||||
je .ek_memory
|
||||
cmp eax, 3
|
||||
je .ek_global
|
||||
mov esi, msg_ek_unknown
|
||||
call print_str
|
||||
pop esi
|
||||
ret
|
||||
.ek_func:
|
||||
mov esi, msg_ek_func
|
||||
jmp .ek_print
|
||||
.ek_table:
|
||||
mov esi, msg_ek_table
|
||||
jmp .ek_print
|
||||
.ek_memory:
|
||||
mov esi, msg_ek_memory
|
||||
jmp .ek_print
|
||||
.ek_global:
|
||||
mov esi, msg_ek_global
|
||||
.ek_print:
|
||||
call print_str
|
||||
pop esi
|
||||
ret
|
||||
|
||||
parse_code_section:
|
||||
pushad
|
||||
mov esi, [sec_content]
|
||||
|
||||
call decode_leb128_u32
|
||||
mov [code_count], eax
|
||||
mov ecx, eax
|
||||
xor ebx, ebx
|
||||
|
||||
.next_body:
|
||||
test ecx, ecx
|
||||
jz .bodies_done
|
||||
push ecx
|
||||
|
||||
call decode_leb128_u32
|
||||
mov edx, eax
|
||||
mov [code_body_sizes + ebx*4], eax
|
||||
mov [code_body_ptrs + ebx*4], esi
|
||||
|
||||
push esi edx
|
||||
mov esi, msg_indent
|
||||
call print_str
|
||||
mov esi, msg_body_word
|
||||
call print_str
|
||||
mov eax, ebx
|
||||
call print_dec
|
||||
mov esi, msg_colon
|
||||
call print_str
|
||||
pop edx esi
|
||||
push esi
|
||||
mov eax, edx
|
||||
call print_dec
|
||||
mov esi, msg_bytes
|
||||
call print_str
|
||||
pop esi
|
||||
|
||||
add esi, edx
|
||||
|
||||
pop ecx
|
||||
inc ebx
|
||||
dec ecx
|
||||
jmp .next_body
|
||||
|
||||
.bodies_done:
|
||||
popad
|
||||
ret
|
||||
|
||||
build_func_index:
|
||||
pushad
|
||||
xor ebx, ebx
|
||||
xor edx, edx
|
||||
|
||||
mov ecx, [import_count]
|
||||
xor eax, eax
|
||||
.imp_loop:
|
||||
test ecx, ecx
|
||||
jz .imp_done
|
||||
cmp dword [import_kinds + eax*4], IMPORT_KIND_FUNC
|
||||
jne .imp_skip
|
||||
push dword [import_desc + eax*4]
|
||||
pop dword [fidx_type + ebx*4]
|
||||
mov dword [fidx_is_import + ebx*4], 1
|
||||
mov [fidx_import_idx + ebx*4], eax
|
||||
inc ebx
|
||||
.imp_skip:
|
||||
inc eax
|
||||
dec ecx
|
||||
jmp .imp_loop
|
||||
.imp_done:
|
||||
|
||||
mov ecx, [func_count]
|
||||
xor edx, edx
|
||||
.local_loop:
|
||||
test ecx, ecx
|
||||
jz .local_done
|
||||
push dword [func_type_idx + edx*4]
|
||||
pop dword [fidx_type + ebx*4]
|
||||
mov dword [fidx_is_import + ebx*4], 0
|
||||
mov [fidx_local_idx + ebx*4], edx
|
||||
inc ebx
|
||||
inc edx
|
||||
dec ecx
|
||||
jmp .local_loop
|
||||
.local_done:
|
||||
mov [fidx_total], ebx
|
||||
|
||||
push esi
|
||||
mov esi, msg_fidx_hdr
|
||||
call print_str
|
||||
mov eax, ebx
|
||||
call print_dec
|
||||
mov esi, msg_fidx_entries
|
||||
call print_str
|
||||
|
||||
xor ecx, ecx
|
||||
.print_loop:
|
||||
cmp ecx, [fidx_total]
|
||||
jae .print_done
|
||||
push ecx
|
||||
mov esi, msg_indent
|
||||
call print_str
|
||||
mov esi, msg_func_word
|
||||
call print_str
|
||||
mov eax, ecx
|
||||
call print_dec
|
||||
mov esi, msg_arrow_type
|
||||
call print_str
|
||||
mov eax, [fidx_type + ecx*4]
|
||||
call print_dec
|
||||
cmp dword [fidx_is_import + ecx*4], 0
|
||||
je .not_imported
|
||||
mov esi, msg_fidx_imported
|
||||
call print_str
|
||||
jmp .entry_done
|
||||
.not_imported:
|
||||
mov esi, msg_fidx_local
|
||||
call print_str
|
||||
.entry_done:
|
||||
pop ecx
|
||||
inc ecx
|
||||
jmp .print_loop
|
||||
.print_done:
|
||||
pop esi
|
||||
popad
|
||||
ret
|
||||
|
||||
print_func_signatures:
|
||||
pushad
|
||||
mov esi, msg_funcsig_hdr
|
||||
call print_str
|
||||
|
||||
xor ecx, ecx
|
||||
.next_sig:
|
||||
cmp ecx, [fidx_total]
|
||||
jae .sigs_done
|
||||
push ecx
|
||||
|
||||
mov eax, [fidx_type + ecx*4]
|
||||
mov [sig_cur_type], eax
|
||||
|
||||
mov esi, msg_indent
|
||||
call print_str
|
||||
mov edx, [sig_cur_type]
|
||||
mov eax, [type_result_counts + edx*4]
|
||||
test eax, eax
|
||||
jz .void_ret
|
||||
mov esi, [type_result_ptrs + edx*4]
|
||||
movzx eax, byte [esi]
|
||||
call print_valtype
|
||||
jmp .print_name
|
||||
.void_ret:
|
||||
mov esi, msg_vt_void
|
||||
call print_str
|
||||
|
||||
.print_name:
|
||||
mov esi, msg_space
|
||||
call print_str
|
||||
|
||||
pop ecx
|
||||
push ecx
|
||||
call find_func_name
|
||||
test edx, edx
|
||||
jz .anon_name
|
||||
mov esi, eax
|
||||
push ecx
|
||||
mov ecx, edx
|
||||
call print_n
|
||||
pop ecx
|
||||
jmp .print_params
|
||||
|
||||
.anon_name:
|
||||
push ecx
|
||||
mov esi, msg_func_word
|
||||
call print_str
|
||||
pop ecx
|
||||
push ecx
|
||||
mov eax, ecx
|
||||
call print_dec
|
||||
pop ecx
|
||||
|
||||
.print_params:
|
||||
mov esi, msg_oparen
|
||||
call print_str
|
||||
|
||||
mov edx, [sig_cur_type]
|
||||
mov eax, [type_param_counts + edx*4]
|
||||
test eax, eax
|
||||
jz .no_params
|
||||
mov edi, [type_param_ptrs + edx*4]
|
||||
xor ebx, ebx
|
||||
.param_loop:
|
||||
cmp ebx, [type_param_counts + edx*4]
|
||||
jae .no_params
|
||||
test ebx, ebx
|
||||
jz .no_comma
|
||||
push esi
|
||||
mov esi, msg_comma
|
||||
call print_str
|
||||
pop esi
|
||||
.no_comma:
|
||||
movzx eax, byte [edi + ebx]
|
||||
call print_valtype
|
||||
inc ebx
|
||||
jmp .param_loop
|
||||
|
||||
.no_params:
|
||||
mov esi, msg_cparen_nl
|
||||
call print_str
|
||||
|
||||
pop ecx
|
||||
inc ecx
|
||||
jmp .next_sig
|
||||
|
||||
.sigs_done:
|
||||
popad
|
||||
ret
|
||||
|
||||
; ecx = function index
|
||||
; returns: eax = name pointer, edx = name length (0 if anonymous)
|
||||
find_func_name:
|
||||
push ebx esi edi
|
||||
|
||||
cmp dword [fidx_is_import + ecx*4], 0
|
||||
je .check_exports
|
||||
mov eax, [fidx_import_idx + ecx*4]
|
||||
mov edx, [import_field_name_lens + eax*4]
|
||||
mov eax, [import_field_name_ptrs + eax*4]
|
||||
jmp .found
|
||||
|
||||
.check_exports:
|
||||
xor ebx, ebx
|
||||
.exp_loop:
|
||||
cmp ebx, [export_count]
|
||||
jae .not_found
|
||||
cmp dword [export_kinds + ebx*4], 0
|
||||
jne .exp_next
|
||||
cmp [export_indices + ebx*4], ecx
|
||||
jne .exp_next
|
||||
mov edx, [export_name_lens + ebx*4]
|
||||
mov eax, [export_name_ptrs + ebx*4]
|
||||
jmp .found
|
||||
.exp_next:
|
||||
inc ebx
|
||||
jmp .exp_loop
|
||||
|
||||
.not_found:
|
||||
xor edx, edx
|
||||
.found:
|
||||
pop edi esi ebx
|
||||
ret
|
||||
|
||||
; esi = bytes, ecx = count
|
||||
print_n:
|
||||
push eax ebx ecx edx
|
||||
mov edx, ecx
|
||||
mov ecx, esi
|
||||
mov ebx, STDOUT
|
||||
mov eax, SYS_WRITE
|
||||
int 0x80
|
||||
pop edx ecx ebx eax
|
||||
ret
|
||||
@@ -219,7 +219,28 @@ msg_vt_i32 db 'i32', 0
|
||||
msg_vt_i64 db 'i64', 0
|
||||
msg_vt_f32 db 'f32', 0
|
||||
msg_vt_f64 db 'f64', 0
|
||||
msg_vt_void db 'void', 0
|
||||
msg_vt_unknown db '?', 0
|
||||
msg_space db ' ', 0
|
||||
msg_func_word db 'func ', 0
|
||||
msg_body_word db 'body ', 0
|
||||
msg_export_q db 'export "', 0
|
||||
msg_quote db '"', 0
|
||||
msg_arrow db ' -> ', 0
|
||||
msg_arrow_type db ' -> type ', 0
|
||||
msg_import_word db 'import ', 0
|
||||
msg_dot db '.', 0
|
||||
msg_fidx_hdr db 'Function index: ', 0
|
||||
msg_fidx_entries db ' entries', 10, 0
|
||||
msg_fidx_imported db ' (imported)', 10, 0
|
||||
msg_fidx_local db ' (local)', 10, 0
|
||||
msg_funcsig_hdr db 'Function signatures:', 10, 0
|
||||
|
||||
msg_ek_func db 'func ', 0
|
||||
msg_ek_table db 'table ', 0
|
||||
msg_ek_memory db 'memory ', 0
|
||||
msg_ek_global db 'global ', 0
|
||||
msg_ek_unknown db 'unknown ', 0
|
||||
|
||||
sec_name_tbl dd sn_custom, sn_type, sn_import, sn_func, sn_table
|
||||
dd sn_memory, sn_global, sn_export, sn_start, sn_element
|
||||
@@ -256,4 +277,34 @@ type_result_counts rd MAX_TYPES
|
||||
type_param_ptrs rd MAX_TYPES
|
||||
type_result_ptrs rd MAX_TYPES
|
||||
|
||||
func_count dd 0
|
||||
func_type_idx rd MAX_FUNCS
|
||||
|
||||
export_count dd 0
|
||||
export_name_ptrs rd MAX_EXPORTS
|
||||
export_name_lens rd MAX_EXPORTS
|
||||
export_kinds rd MAX_EXPORTS
|
||||
export_indices rd MAX_EXPORTS
|
||||
|
||||
import_count dd 0
|
||||
import_func_count dd 0
|
||||
import_mod_name_ptrs rd MAX_IMPORTS
|
||||
import_mod_name_lens rd MAX_IMPORTS
|
||||
import_field_name_ptrs rd MAX_IMPORTS
|
||||
import_field_name_lens rd MAX_IMPORTS
|
||||
import_kinds rd MAX_IMPORTS
|
||||
import_desc rd MAX_IMPORTS
|
||||
|
||||
code_count dd 0
|
||||
code_body_ptrs rd MAX_FUNCS
|
||||
code_body_sizes rd MAX_FUNCS
|
||||
|
||||
fidx_total dd 0
|
||||
fidx_type rd MAX_FUNCS
|
||||
fidx_is_import rd MAX_FUNCS
|
||||
fidx_import_idx rd MAX_FUNCS
|
||||
fidx_local_idx rd MAX_FUNCS
|
||||
|
||||
sig_cur_type dd 0
|
||||
|
||||
file_buf rb FILE_BUF_SIZE
|
||||
@@ -31,6 +31,9 @@ check "bad version" "unsupported wasm" $WASM test/wasm/badver.wasm
|
||||
check "section list" "(Type)" $WASM test/wasm/valid.wasm
|
||||
check "type no params" "() -> (i32)" $WASM test/wasm/valid.wasm
|
||||
check "type two params" "(i32, i32) -> (i32)" $WASM test/wasm/add.wasm
|
||||
check "import parsed" 'import "env"."print_i32"' $WASM test/wasm/import.wasm
|
||||
check "func index" "func 0 -> type 0 (imported)" $WASM test/wasm/import.wasm
|
||||
check "signature" "i32 add(i32, i32)" $WASM test/wasm/add.wasm
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS/$TESTS passed, $FAIL failed"
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
(module
|
||||
(import "env" "print_i32" (func $print_i32 (param i32)))
|
||||
(import "env" "memory" (memory 1))
|
||||
(func (export "main") (result i32)
|
||||
i32.const 42
|
||||
call $print_i32
|
||||
i32.const 0
|
||||
)
|
||||
)
|
||||
Reference in new issue
Block a user