Bug runtime out of memory
I tried to run a minimal example to open a glfw window using this library.
I started the program using ./m3 glfw.wasm
The file glfw.wasm converted to glfw.wat looks like this:
(module
(type (;0;) (func (result i32)))
(type (;1;) (func (param i32 i32 i32 i32 i32) (result i32)))
(type (;2;) (func))
(type (;3;) (func (param i32) (result i32)))
(type (;4;) (func (param i32)))
(import "env" "glfwInit" (func $glfwInit (type 0)))
(import "env" "glfwCreateWindow" (func $glfwCreateWindow (type 1)))
(import "env" "glfwTerminate" (func $glfwTerminate (type 2)))
(import "env" "glfwWindowShouldClose" (func $glfwWindowShouldClose (type 3)))
(import "env" "glfwSwapBuffers" (func $glfwSwapBuffers (type 4)))
(import "env" "glfwPollEvents" (func $glfwPollEvents (type 2)))
(func $__wasm_call_ctors (type 2))
(func $startGlfw (type 2)
(local i32 i32)
global.get 0
i32.const 16
i32.sub
local.tee 0
global.set 0
block ;; label = @1
call $glfwInit
i32.eqz
br_if 0 (;@1;)
block ;; label = @2
i32.const 640
i32.const 480
i32.const 1024
i32.const 0
i32.const 0
call $glfwCreateWindow
local.tee 1
br_if 0 (;@2;)
call $glfwTerminate
local.get 0
i32.const 16
i32.add
global.set 0
return
end
block ;; label = @2
loop ;; label = @3
local.get 1
call $glfwWindowShouldClose
br_if 1 (;@2;)
local.get 1
call $glfwSwapBuffers
call $glfwPollEvents
br 0 (;@3;)
end
end
call $glfwTerminate
local.get 0
i32.const 16
i32.add
global.set 0
return
end
local.get 0
i32.const 16
i32.add
global.set 0)
(table (;0;) 1 1 funcref)
(memory (;0;) 2)
(global (;0;) (mut i32) (i32.const 66576))
(global (;1;) i32 (i32.const 66576))
(global (;2;) i32 (i32.const 1036))
(global (;3;) i32 (i32.const 1024))
(export "memory" (memory 0))
(export "__heap_base" (global 1))
(export "__data_end" (global 2))
(export "startGlfw" (func $startGlfw))
(export "__unnamed_1" (global 3))
(data (;0;) (i32.const 1024) "Hello World\00"))
The error message I get looks like this:
-- m3 configuration --------------------------------------------
sizeof M3MemPage : 65536 bytes
sizeof M3Compilation : 8592 bytes
----------------------------------------------------------------
parse | load module: 1052 bytes
parse | found magic + version
parse | ** Type [5]
parse | () -> i32
parse | (i32, i32, i32, i32, i32) -> i32
parse | () -> nil
parse | (i32) -> i32
parse | (i32) -> nil
parse | ** Import [6]
parse | - kind: 0; 'env.glfwInit'
parse | - kind: 0; 'env.glfwCreateWindow'
parse | - kind: 0; 'env.glfwTerminate'
parse | - kind: 0; 'env.glfwWindowShouldClose'
parse | - kind: 0; 'env.glfwSwapBuffers'
parse | - kind: 0; 'env.glfwPollEvents'
parse | ** Function [2]
parse | <skipped (id: 4)>
parse | <skipped (id: 5)>
parse | ** Global [4]
parse | - add global: [0] i32
compile | 0 | 0x01 .. nop
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66576)
compile | 2 | 0x0b end
parse | - add global: [1] i32
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66576)
compile | 2 | 0x0b end
parse | - add global: [2] i32
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 1036)
compile | 2 | 0x0b end
parse | - add global: [3] i32
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 1024)
compile | 2 | 0x0b end
parse | ** Export [5]
parse | - index: 0; kind: 2; export: 'memory';
parse | - index: 1; kind: 3; export: '__heap_base';
parse | - index: 2; kind: 3; export: '__data_end';
parse | - index: 7; kind: 0; export: 'startGlfw';
parse | - index: 3; kind: 3; export: '__unnamed_1';
parse | ** Code [2]
parse | - func size: 2; locals: 0
parse | - func size: 141; locals: 1
parse | - 2 locals; type: 'i32'
parse | ** Data [1]
compile | 0 | 0x41 .. i32.const
compile | | .......... (const i32 = 1024)
compile | 1 | 0x0b end
parse | segment [0] memory: 0; expr-size: 4; size: 12
parse | ** Custom: '.debug_info'
parse | ** Custom: '.debug_macinfo'
parse | ** Custom: '.debug_pubtypes'
parse | ** Custom: '.debug_abbrev'
parse | ** Custom: '.debug_line'
parse | ** Custom: '.debug_str'
parse | ** Custom: '.debug_pubnames'
parse | ** Custom: 'name'
parse | naming function [6]: __wasm_call_ctors
-- m3 configuration --------------------------------------------
sizeof M3MemPage : 65536 bytes
sizeof M3Compilation : 8592 bytes
----------------------------------------------------------------
runtime | initializing global: 0
compile | 0 | 0x01 .. nop
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66576)
compile | 2 | 0x0b end
runtime | initializing global: 1
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66576)
compile | 2 | 0x0b end
exec | *** trapping ***
runtime | initializing global: 2
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 1036)
compile | 2 | 0x0b end
exec | *** trapping ***
runtime | initializing global: 3
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 1024)
compile | 2 | 0x0b end
exec | *** trapping ***
compile | 0 | 0x41 .. i32.const
compile | | .......... (const i32 = 1024)
compile | 1 | 0x0b end
runtime | loading data segment: 0 offset: 1024
result: runtime ran out of memory ()
The bug happens when calling m3_LoadModule.
Any idea what's going on here? Is it a bug or may there be some problem with my wasm?
The bug is caused by some (incomplete) logic in module initialization. As a side note, M3 engine currently lacks a lot of things, and memory management is one of them. I've spent some time fixing different things as you can see in #2 and in my fork here: https://github.com/vshymanskyy/wasm3 So I hope to get to this particular issue soon
@porky11 please check out #3