mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 09:41:36 +00:00
add example of how stack might be managed
This commit is contained in:
parent
bdcd2b8146
commit
b27d3a088d
@ -222,6 +222,92 @@ contributors:
|
||||
)
|
||||
)
|
||||
(export "apply_cos64" (func $apply_cos64))
|
||||
|
||||
;; Demonstration of how this C code might be written by hand
|
||||
;;
|
||||
;; typedef struct {
|
||||
;; int a;
|
||||
;; int b;
|
||||
;; } sum_struct_t;
|
||||
;;
|
||||
;; sum_struct_t sum_struct_create(int a, int b) {
|
||||
;; return (sum_struct_t){a, b};
|
||||
;; }
|
||||
;;
|
||||
;; int sum_local() {
|
||||
;; sum_struct_t s = sum_struct_create(40, 2);
|
||||
;; return s.a + s.b;
|
||||
;; }
|
||||
;;
|
||||
;; Wasm is a stack-based language, but for returning values more complicated
|
||||
;; than an int/float, a memory stack has to be manually managed. One ;;
|
||||
;; approach is to use a mutable global to store the stack_ptr. We give
|
||||
;; ourselves 1MiB of mem-stack and grow it downwards.
|
||||
;;
|
||||
;; Note: we are differentiating from the memstack (stack stored in memory)
|
||||
;; and the "stack", which wasm implicitly uses to to pass and return values.
|
||||
(global $memstack_ptr (mut i32) (i32.const 65536))
|
||||
|
||||
;; structs can only be returned by reference
|
||||
(func $sum_struct_create
|
||||
(param $sum_struct_ptr i32)
|
||||
(param $var$a i32)
|
||||
(param $var$b i32)
|
||||
;; c// sum_struct_ptr->a = a;
|
||||
(i32.store
|
||||
(get_local $sum_struct_ptr)
|
||||
(get_local $var$a)
|
||||
)
|
||||
|
||||
;; c// sum_struct_ptr->b = b;
|
||||
(i32.store offset=4
|
||||
(get_local $sum_struct_ptr)
|
||||
(get_local $var$b)
|
||||
)
|
||||
)
|
||||
|
||||
(func $sum_local (result i32)
|
||||
(local $var$sum_struct$a i32)
|
||||
(local $var$sum_struct$b i32)
|
||||
(local $local_memstack_ptr i32)
|
||||
|
||||
;; reserve stack space
|
||||
(i32.sub
|
||||
(get_global $memstack_ptr)
|
||||
(i32.const 8)
|
||||
)
|
||||
tee_local $local_memstack_ptr ;; tee both stores and returns given value
|
||||
set_global $memstack_ptr
|
||||
|
||||
;; call the function, storing the result in the stack
|
||||
(call $sum_struct_create
|
||||
((;$sum_struct_ptr=;) get_local $local_memstack_ptr)
|
||||
((;$var$a=;) i32.const 40)
|
||||
((;$var$b=;) i32.const 2)
|
||||
)
|
||||
|
||||
;; retrieve values from struct
|
||||
(set_local $var$sum_struct$a
|
||||
(i32.load offset=0 (get_local $local_memstack_ptr))
|
||||
)
|
||||
(set_local $var$sum_struct$b
|
||||
(i32.load offset=4 (get_local $local_memstack_ptr))
|
||||
)
|
||||
|
||||
;; unreserve stack space
|
||||
(set_global $memstack_ptr
|
||||
(i32.add
|
||||
(get_local $local_memstack_ptr)
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
(i32.add
|
||||
(get_local $var$sum_struct$a)
|
||||
(get_local $var$sum_struct$b)
|
||||
)
|
||||
)
|
||||
(export "sum_local" (func $sum_local))
|
||||
)
|
||||
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user