soundandform / m3 Goto Github PK
View Code? Open in Web Editor NEWA high performance WebAssembly interpreter in C. Moved here:
Home Page: https://github.com/wasm3/wasm3
License: MIT License
A high performance WebAssembly interpreter in C. Moved here:
Home Page: https://github.com/wasm3/wasm3
License: MIT License
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?
I tried running compiled wasm files from https://webassembly.studio/
empty c project, helloworld in c and empty rust project
they all end with "Aborted"
(on debian arm64)
the following result is from the empty c project:
parse | load module: 526 bytes
parse | found magic + version
parse | ** Type [2]
parse | () -> nil
parse | () -> i32
parse | ** Function [2]
parse | <skipped (id: 4)>
parse | <skipped (id: 5)>
parse | ** Global [3]
parse | - add global: [0] i32
compile | 0 | 0x01 .. nop
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66560)
compile | 2 | 0x0b end
parse | - add global: [1] i32
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66560)
compile | 2 | 0x0b end
parse | - add global: [2] i32
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 1024)
compile | 2 | 0x0b end
parse | ** Export [4]
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: 1; kind: 0; export: 'main';
parse | ** Code [2]
parse | - func size: 2; locals: 0
parse | - func size: 4; locals: 0
parse | ** Custom: '.debug_info'
parse | ** Custom: '.debug_macinfo'
parse | ** Custom: '.debug_abbrev'
parse | ** Custom: '.debug_line'
parse | ** Custom: '.debug_str'
parse | ** Custom: 'name'
parse | naming function [0]: __wasm_call_ctors
runtime | initializing global: 0
compile | 0 | 0x01 .. nop
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66560)
compile | 2 | 0x0b end
runtime | initializing global: 1
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 66560)
compile | 2 | 0x0b end
exec | *** trapping ***
runtime | initializing global: 2
compile | 0 | 0x00 .. unreachable
compile | 1 | 0x41 .. i32.const
compile | | .......... (const i32 = 1024)
compile | 2 | 0x0b end
exec | *** trapping ***
-- m3 runtime -------------------------------------------------
stack-size: 32768
Aborted
On README I read:
Traps: The spec says "Signed and unsigned operators trap whenever the result cannot be represented in the result type." Really? That's cool, but how can the behavior of source languages be modeled (efficiently)? C integer operations wrap and sometimes that's what you want.
Where does the spec say this? I can't find it. https://webassembly.github.io/spec/core/exec/numerics.html is pretty clear that addition is done modulo 2^N, for example.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.