Created
January 30, 2019 15:26
-
-
Save appcypher/e42c865696d8d8b8e2702337c04ba94d to your computer and use it in GitHub Desktop.
A syscall webassembly example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(module | |
(type $t1 (func (param i32))) | |
(type $t2 (func (param i32 i32 i32) (result i32))) | |
(type $t3 (func (param i32) (result i32))) | |
(type $t4 (func (param i32 i32) (result i32))) | |
(func $putchar (import "env" "putchar") (type $t1)) | |
(func $printf (import "env" "printf") (type $t4)) | |
(func $sys_open (import "env" "sys_open") (type $t2)) | |
(func $sys_read (import "env" "sys_read") (type $t2)) | |
(func $sys_close (import "env" "sys_close") (type $t3)) | |
(func $sys_exit (import "env" "sys_exit") (type $t1)) | |
(memory 1) | |
(data $filename (i32.const 0) "/Users/xxxx/Desktop/hello.txt\00") | |
(func $main (export "_main") | |
;; declare variables | |
(local $string_buf_addr i32) | |
(local $string_buf_len i32) | |
(local $file_access_flag i32) | |
(local $file_permission_flag i32) | |
(local $file_descriptor i32) | |
;; set variables | |
(set_local $string_buf_addr (i32.const 72)) ;; string_buf_addr at offset 72 | |
(set_local $string_buf_len (i32.const 10)) ;; string_buf_len is 5 | |
(set_local $file_access_flag (i32.const 02)) ;; file_access_flag has O_RDWR permission | |
(set_local $file_permission_flag (i32.const 700)) ;; file_permission_flag has S_IRWXU permission | |
;; open file | |
(call $sys_open (i32.const 0) (get_local $file_access_flag) (get_local $file_permission_flag)) ;; (path: u32, flags: c_int, mode: c_int) -> c_int | |
(set_local $file_descriptor) ;; set file_descriptor to the value returned by sys_open | |
;; read file content | |
(call $sys_read (get_local $file_descriptor) (get_local $string_buf_addr) (get_local $string_buf_len)) ;; (fd: c_int, buf: u32, count: size_t) -> ssize_t | |
(drop) ;; ignoring errors | |
;; close file | |
(call $sys_close (get_local $file_descriptor)) ;; (fd: c_int) -> c_int | |
(drop) ;; ignoring errors | |
;; print file content | |
(call $printf (get_local $string_buf_addr) (i32.const 0)) | |
(drop) ;; ignoring errors | |
;; exit | |
(call $exit (i32.const 0)) | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is one of the webassembly files I wrote from scratch and it characterizes the situation I found myself in while trying to create an Emscripten-compatible host binding for Wasmer.
This code is interesting to me because it is one of the wasm code I wrote to interface with low-level ABIs (syscalls). Here I exposed the bare minimum functions for opening, reading, printing, and closing a file and it was an eureka moment when I got that working. It was the first step towards figuring out how to implement Emscripten APIs.
A week later this code became obsolete because I found out Emscripten has a totally different calling convention but the code is still there today. It is a foot mark in the history of the runtime's development.
You can still use this code today by exposing the right
libc
functions. Most notablyread
,open
,close
,printf
,putchar
andexit
.Another interesting code would be the implementation of
is_canonical_nan
based on WebAssembly's specification.