Git Product home page Git Product logo

wasmvm's Introduction

WasmVM

A standalone WebAssembly virtual machine

online document

正體中文

Prerequisite

  • CMake >= 3.16

  • C compiler with C11 standard

Notice

  1. This project uses "Taiwan Traditional Chinese" as primary, English as secondary language in documents.

Other languages (Ex: Simplified Chinese) are only used as references or translations.

Build

  1. Run CMake
mkdir build && cd build && cmake ..
  1. Run Make
make -j4

Generate HTML documents

  1. Run CMake
mkdir build && cd build && cmake ..
  1. Run Make
make docs

The generated document will under build/docs/html

wasmvm's People

Contributors

aarc0305 avatar haruzheng avatar howjmay avatar jkrvivian avatar kevinbird61 avatar loggy007 avatar luishsu avatar metalheadken avatar naetw avatar oiz5201618 avatar punchshadow avatar yanjiuntw avatar yuhao-kuo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wasmvm's Issues

Local variable

Local variable stack

  • Class of local variable stack
  • Cooperate with Module class (no local section).

Native function 支援

雖然已經實作 function 功能,但是沒有支援 Native function

目前我也還沒想到要如何實作...

Note

  1. 要能符合 1.0 Specification 的驗證

優化

目前只有完成整個系統的架構,並讓他可以進行基本的運作
還沒有對系統進行優化

優化的重點:

  1. 預防 Or 解決潛在的危險

  2. 增進執行效率

  3. 減少使用的資源

實作 Runtime 的 i32 算數指令

Runtime function 是每個指令真正運行的函式,目前先實作算數指令,從 Stack 取出數值,運算之後再把結果填回去

已指定的清單:

實作 Core

Core 是執行程式的部件,會逐步從函式中取出指令,根據 opcode 執行對應的 runtime function

有點像是 CPU 裡“核心”的概念,用不同的 Thread 去模擬不同核心數

目前正開放討論實作方法!

System call [0xE1 - 0x100]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 Call100.h 和 Call100.cpp

Steps

  • timer_getoverrun
  • timer_delete
  • clock_settime
  • clock_gettime
  • clock_getres
  • clock_nanosleep
  • exit_group
  • epoll_wait
  • epoll_ctl
  • tgkill
  • utimes
  • vserver
  • mbind
  • set_mempolicy
  • get_mempolicy
  • mq_open
  • mq_unlink
  • mq_timedsend
  • mq_timedreceive
  • mq_notify
  • mq_getsetattr
  • kexec_load
  • waitid
  • add_key
  • request_key
  • keyctl
  • ioprio_set
  • ioprio_get
  • inotify_init
  • inotify_add_watch
  • inotify_rm_watch
  • migrate_pages

Core structure

Description

The core is composed with

  • Operand Stack

  • Running loop to run Fetch -> Decode cycle

  • Program Counter...etc

Implement classes of the core with the components above.

Product

Implement classes of the core with the components above.

System call [0x81 - 0xA0]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 CallA0.h 和 CallA0.cpp

Steps

  • rt_sigqueueinfo
  • rt_sigsuspend
  • sigaltstack
  • utime
  • mknod
  • uselib
  • personality
  • ustat
  • statfs
  • fstatfs
  • sysfs
  • getpriority
  • setpriority
  • sched_setparam
  • sched_getparam
  • sched_setscheduler
  • sched_getscheduler
  • sched_get_priority_max
  • sched_get_priority_min
  • sched_rr_get_interval
  • mlock
  • munlock
  • mlockall
  • munlockall
  • vhangup
  • modify_ldt
  • pivot_root
  • sysctl
  • prctl
  • arch_prctl
  • adjtimex
  • setrlimit

擴充 Syscall 的測試資料

目前已完成一些 System call ,可以開始加上測試資料

Note

請參照 tests 裡 unreachable 和 nop 的格式實作

Steps

  • System call [0x00-0x40]

Memory Instructions (integer)

  • i32.load

  • i32.load8_s

  • i32.load8_u

  • i32.load16_s

  • i32.load16_u

  • i32.store

  • i32.store8

  • i32.store16

  • i64.load

  • i64.load8_s

  • i64.load8_u

  • i64.load16_s

  • i64.load16_u

  • i64.load32_s

  • i64.load32_u

  • i64.store8

  • i64.store16

  • i64.store32

  • i64.store

  • current_memory

  • grow_memory

實作 Executor

Executor 是執行程式的元件,包含 SysCall, Core 和 Store

目前正開放討論實作方法!

System call [0x61 - 0x80]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 Call80.h 和 Call80.cpp

Steps

  • getrlimit
  • getrusage
  • sysinfo
  • times
  • ptrace
  • getuid
  • syslog
  • getgid
  • setuid
  • setgid
  • geteuid
  • getegid
  • setpgid
  • getppid
  • getpgrp
  • setsid
  • setreuid
  • setregid
  • getgroups
  • setgroups
  • setresuid
  • getresuid
  • setresgid
  • getresgid
  • getpgid
  • setfsuid
  • setfsgid
  • getsid
  • capget
  • capset
  • rt_sigpending
  • rt_sigtimedwait

System call [0xC1 - 0xE0]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 CallE0.h 和 CallE0.cpp

Steps

  • fgetxattr
  • listxattr
  • llistxattr
  • flistxattr
  • removexattr
  • lremovexattr
  • fremovexattr
  • tkill
  • time
  • futex
  • sched_setaffinity
  • sched_getaffinity
  • set_thread_area
  • io_setup
  • io_destroy
  • io_getevents
  • io_submit
  • io_cancel
  • get_thread_area
  • lookup_dcookie
  • epoll_create
  • epoll_ctl_old
  • epoll_wait_old
  • remap_file_pages
  • getdents64
  • set_tid_address
  • restart_syscall
  • semtimedop
  • fadvise64
  • timer_create
  • timer_settime
  • timer_gettime

Numeric Instructions (integer)

  • inn.const
  • inn.eqz
  • inn.eq , inn.ne, inn.lt_sx, inn.gt_sx, inn.le_sx, inn.ge_sx
  • inn.clz, inn.ctz, inn.popcnt
  • inn.add, inn.sub, inn.mul, inn.div_sx, inn.rem_sx
  • inn.and, inn.or, inn.xor
  • inn.shl, inn.shr_sx, inn_rotl, inn_rotr

System call [0xA1 - 0xC0]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 CallC0.h 和 CallC0.cpp

Steps

  • chroot
  • sync
  • acct
  • settimeofday
  • mount
  • umount
  • swapon
  • swapoff
  • reboot
  • sethostname
  • setdomainname
  • iopl/ptregs
  • ioperm
  • create_module
  • init_module
  • delete_module
  • get_kernel_syms
  • query_module
  • quotactl
  • nfsservctl
  • getpmsg
  • putpmsg
  • afs_syscall
  • tuxcall
  • security
  • gettid
  • readahead
  • setxattr
  • lsetxattr
  • fsetxattr
  • getxattr
  • lgetxattr

擴充各指令的測試資料

現在已經有 CTest 的測試設定,但是只有 unreachable 和 nop 的測試資料。
需要擴充其他指令和 Syscall 測試資料

Note

請參照 tests 裡 unreachable 和 nop 的格式實作

Steps

  • Control Instructions

  • Memory Instructions

  • Variable Instructions

  • Parameter Instructions

  • Numeric Instructions

System call [0x101 - 0x120]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 Call120.h 和 Call120.cpp

Steps

  • openat
  • mkdirat
  • mknodat
  • fchownat
  • futimesat
  • newfstatat
  • unlinkat
  • renameat
  • linkat
  • symlinkat
  • readlinkat
  • fchmodat
  • faccessat
  • pselect6
  • ppoll
  • unshare
  • set_robust_list
  • get_robust_list
  • splice
  • tee
  • sync_file_range
  • vmsplice
  • move_pages
  • utimensat
  • epoll_pwait
  • signalfd
  • timerfd_create
  • eventfd
  • fallocate
  • timerfd_settime
  • timerfd_gettime
  • accept4

Build failure on Aarch64/Linux target

While building on Aarch64/Linux, cmake complained as following:

[ 13%] Building CXX object src/Syscall/CMakeFiles/WasmVM_Syscall.dir/Call20.cpp.o
/tmp/WasmVM/src/Syscall/Call20.cpp: In function ‘void Call::sysFstat(Store&, Stack&)’:
/tmp/WasmVM/src/Syscall/Call20.cpp:226:33: error: no match for call to ‘(Stack) ()’
   Value* fd = (Value*)coreStack().data;
                                 ^
/tmp/WasmVM/src/Syscall/Call20.cpp:243:32: error: ‘pathnameAddr’ was not declared in this scope
   char* bufPtr = memoryData += pathnameAddr->data.i32;
                                ^~~~~~~~~~~~
/tmp/WasmVM/src/Syscall/Call20.cpp: In function ‘void Call::sysSelect(Store&, Stack&)’:
/tmp/WasmVM/src/Syscall/Call20.cpp:550:50: error: ‘data’ was not declared in this scope
   char* readfdsPtr = memoryData += readfdsAddr > data.i32;
                                                  ^~~~

Extra information:

  • g++ -v dumps gcc version 6.3.0.

以純 WabAssembly,加上 Syscall 實作的 libc ABI

WebAssembly 官網上寫著

In the MVP, WebAssembly does not yet have a stable ABI for libraries. Developers will need to ensure that all code linked into an application are compiled with the same compiler and options.

既然沒有 libc ABI,那我們就用 Syscall 來幫忙完成吧!

With Syscall, maybe libc ABI can be implemented by pure Wasm in WasmVM

實作 Instantiator

在 WasmModule 讀取 & 驗證之後,需要透過 Instantiator 把模組轉換成執行時的格式 (Instance),並載入 Executor

Compiler 支援

現在能產生 Wasm binary code 的方式目前還是官方的 wabt 工具

(emscripten 會加入一些他自己的 JavaScript binding,沒法用在 WasmVM)

希望能加入一些工具支援支援現有的編譯器, 或是打造專屬的編譯器,
在不需要 JavaScript binding的情況下產生 WasmVM 能執行的 binary

System call [0x121 - 0x140]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 Call140.h 和 Call140.cpp

Steps

  • signalfd4
  • eventfd2
  • epoll_create1
  • dup3
  • pipe2
  • inotify_init1
  • preadv
  • pwritev
  • rt_tgsigqueueinfo
  • perf_event_open
  • recvmmsg
  • fanotify_init
  • fanotify_mark
  • prlimit64
  • name_to_handle_at
  • open_by_handle_at
  • clock_adjtime
  • syncfs
  • sendmmsg
  • setns
  • getcpu
  • process_vm_readv
  • process_vm_writev
  • kcmp
  • finit_module
  • sched_setattr
  • sched_getattr
  • renameat2
  • seccomp
  • getrandom
  • memfd_create
  • kexec_file_load

Get error during making file

The message I got

src/Syscall/Call20.cpp:506:16: error: cannot initialize a variable of type 'std::int32_t' (aka 'int') with an rvalue of type 'void * std::int32_t ret = brk((void*)programbreakPtr);

make[2]: *** [src/Syscall/CMakeFiles/WasmVM_Syscall.dir/Call20.cpp.o] Error 1

brk function which return a void pointer is not compatible type for variable ret

Do I miss something causing the error?

Java bytecode translator

目前並沒有將 Java bytecode 轉換成 Webassembly 的工具, 主要的原因是 Java 在瀏覽器上執行時會造成一些安全性問題

但是 WasmVM 是運行在原生環境, 所以可以不用像瀏覽器一樣在安全性上有額外的顧慮,
因此將 Java bytecode 轉換成 Webassembly 是可行的, 而且這樣感覺很酷

Potential buffer overrun

Reported by gcc-7.2:

WasmVM/src/Component/Decoder.cpp: In static member function ‘static void Decoder::decode(Store&, Stack&)’:
WasmVM/src/Component/Decoder.cpp:22:6: warning: ‘sprintf’ writing a terminating nul past the end of the destination [-Wformat-overflow=]
 void Decoder::decode(Store& store, Stack& coreStack) {
      ^~~~~~~
WasmVM/src/Component/Decoder.cpp:829:14: note: ‘sprintf’ output 3 bytes into a destination of size 2
       sprintf(codeChr, "%02x", ((std::uint32_t)bincode) & 0xff);
       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The casting from unsigned 32-bit integer is not exactly what sprintf expects.

Fetch & Decode Structure

Description

Fetch & Decode is to:

  • Get instruction from memory
  • Parse the opcode to instructions
  • Prepare data that prepared for execution
  • Move the program counter.

As we discussed, Fetch & Decode can be independent function, or merged together.

Memory and Program Counter should be passed by parameters of reference.

Definition can be stored in an independent header file.

Product

One or more functions, within Fetch, Decode namespace

Control Instructions

  • nop
  • unreachable
  • block
  • loop
  • if
  • br
  • br_if
  • br_table
  • return
  • call (parameter)
  • call_indirect (later)
  • end

定義 Wasm Structure 的標頭檔

在 decoder 之外直接操作 bytecode 或 Runtime Instance
語意上和擴充彈性都很糟
因此我們需要先定義出 Wasm 規格內的資料結構,透過這些資料結構來操作
可以參考 doc/images/WasmStructure.svg 把 WasmStructure 都定義在 src/include/structures

System call [0x141 - ]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 Call160.h 和 Call160.cpp

Steps

  • bpf
  • execveat/ptregs
  • userfaultfd
  • membarrier
  • mlock2
  • copy_file_range
  • preadv2
  • pwritev2
  • pkey_mprotect
  • pkey_alloc
  • pkey_free

Integer - floating conversion Instructions

  • i32.wrap/i64
  • i32.trunc_s/f32
  • i32.trunc_u/f32
  • i32.trunc_s/f64
  • i32.trunc_u/f64
  • i64.extend_s/i32
  • i64.extend_u/i32
  • i64.trunc_s/f32
  • i64.trunc_u/f32
  • i64.trunc_s/f64
  • i64.trunc_u/f64
  • f32.convert_s/i32
  • f32.convert_u/i32
  • f32.convert_s/i64
  • f32.convert_u/i64
  • f32.demote/f64
  • f64.convert_s/i32
  • f64.convert_u/i32
  • f64.convert_s/i64
  • f64.convert_u/i64
  • f64.promote/f32
  • i32.reinterpret/f32
  • i64.reinterpret/f64
  • f32.reinterpret/i32
  • f64.reinterpret/i64

System call [0x00-0x40]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel,

利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將 編號 0x00-0x20 的實作寫在 Call20.h 和 Call20.cpp, 編號 0x21-0x40 的實作寫在 Call40.h 和 Call40.cpp

Steps

  • Read
  • Write
  • Open
  • Close
  • Newstat
  • Newfstat
  • Newlstat
  • Poll
  • Lseek
  • Mmap
  • Mprotect
  • Munmap
  • Brk
  • RT_Sigaction
  • RT_Sigprocmask
  • Ioctl
  • Pread64
  • Pwrite64
  • Readv
  • Writev
  • Access
  • Pipe
  • Select
  • Sched_yield
  • Mremap
  • Msync
  • Mincore
  • Madvise
  • Shmget
  • Shmat
  • Shmctl
  • Dup

  • Dup2
  • Pause
  • Nanosleep
  • Getitimer
  • Alarm
  • Setitimer
  • Getpid
  • Sendfile64
  • Socket
  • Connect
  • Accept
  • Sendto
  • Recvfrom
  • Sendmsg
  • Recvmsg
  • Shutdown
  • Bind
  • Listen
  • Getsockname
  • Getpeername
  • Socketpair
  • Setsockopt
  • Getsockopt
  • Clone
    • fn is the function index of the module in WebAssembly manner
    • child_stack is the direct memory address got by mmap
  • Fork
  • Vfork
  • Execve
  • Exit
  • Wait4
  • Kill
  • Newuname
  • Semget

System call [0x41 - 0x60]

仿造其他架構中 syscall 的運作方式,

我們打算在 WasmVM 參考 linux 4.10 kernel, 利用 unreachable 實作 System call

Note

  1. 請參考 syscall_64.tbl 的編號和名稱

  2. 請在 src/Syscall/Syscode.h 裡,參考其他 Syscall 的格式定義對應的編號

  3. 請在 src/Syscall/Syscall.cpp 裡, 加上對應的case 判斷

  4. 請將實作寫在 Call60.h 和 Call60.cpp

Steps

  • semop
  • semctl
  • shmdt
  • msgget
  • msgsnd
  • msgrcv
  • msgctl
  • fcntl
  • flock
  • fsync
  • fdatasync
  • truncate
  • ftruncate
  • getdents
  • getcwd
  • chdir
  • fchdir
  • rename
  • mkdir
  • rmdir
  • creat
  • link
  • unlink
  • symlink
  • readlink
  • chmod
  • fchmod
  • chown
  • fchown
  • lchown
  • umask
  • gettimeofday

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.