import, export, function index and signatures

This commit is contained in:
hrigar committed 2026-03-20 21:24:57 +05:30
1 parent a1cb9f0afa
commit 16df0f8513
5 files changed
+655

No files matched your search

+592
View File
@@ -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
+51
View File
@@ -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
+3
View File
@@ -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.
+9
View File
@@ -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
)
)