5#include "wasm/machine.h" 
    6#include "wasm/asyncify.h" 
    8void *rb_wasm_get_stack_pointer(
void);
 
   10static void *base_stack_pointer = NULL;
 
   13  base_stack_pointer = rb_wasm_get_stack_pointer();
 
   17void dump_memory(uint8_t *base, uint8_t *end) {
 
   18  size_t chunk_size = 16;
 
   20  for (uint8_t *ptr = base; ptr <= end; ptr += chunk_size) {
 
   22    for (
size_t offset = 0; offset < chunk_size; offset++) {
 
   23      printf(
" %02x", *(ptr + offset));
 
   29bool find_in_stack(uint32_t target, 
void *base, 
void *end) {
 
   30  for (uint32_t *ptr = base; ptr <= (uint32_t *)end; ptr++) {
 
   38void *_rb_wasm_stack_mem[2];
 
   39void rb_wasm_mark_mem_range(
void *start, 
void *end) {
 
   40  _rb_wasm_stack_mem[0] = start;
 
   41  _rb_wasm_stack_mem[1] = end;
 
   44#define check_live(target, ctx) do {            \ 
   45    rb_wasm_scan_stack(rb_wasm_mark_mem_range); \ 
   46    _check_live(target, ctx);                   \ 
   49void _check_live(uint32_t target, 
const char *ctx) {
 
   50  printf(
"checking %#x ... ", target);
 
   51  bool found_in_locals = 
false, found_in_stack = 
false;
 
   52  if (find_in_stack(target, _rb_wasm_stack_mem[0], _rb_wasm_stack_mem[1])) {
 
   53    found_in_stack = 
true;
 
   55  rb_wasm_scan_locals(rb_wasm_mark_mem_range);
 
   56  if (find_in_stack(target, _rb_wasm_stack_mem[0], _rb_wasm_stack_mem[1])) {
 
   57    found_in_locals = 
true;
 
   59  if (found_in_locals && found_in_stack) {
 
   60    printf(
"ok (found in C stack and Wasm locals)\n");
 
   61  } 
else if (found_in_stack) {
 
   62    printf(
"ok (found in C stack)\n");
 
   63  } 
else if (found_in_locals) {
 
   64    printf(
"ok (found in Wasm locals)\n");
 
   66    printf(
"not found: %s\n", ctx);
 
   71void new_frame(uint32_t val, uint32_t depth) {
 
   73    dump_memory(rb_wasm_get_stack_pointer(), base_stack_pointer);
 
   74    for (uint32_t i = 0; i < 5; i++) {
 
   75      check_live(0x00bab10c + i, 
"argument value");
 
   78    new_frame(val, depth - 1);
 
   82uint32_t return_value(
void) {
 
   86uint32_t check_return_value(
void) {
 
   87  check_live(0xabadbabe, 
"returned value");
 
   91void take_two_args(uint32_t a, uint32_t b) {
 
   95int start(
int argc, 
char **argv) {
 
   98  register uint32_t facefeed;
 
   99  deadbeef = 0xdeadbeef;
 
  100  facefeed = 0xfacefeed;
 
  102  check_live(0xdeadbeef, 
"local variable");
 
  103  check_live(0xfacefeed, 
"local reg variable");
 
  105  new_frame(0x00bab10c, 5);
 
  107  take_two_args(return_value(), check_return_value());
 
  112int main(
int argc, 
char **argv) {
 
  113  extern int rb_wasm_rt_start(
int (main)(
int argc, 
char **argv), 
int argc, 
char **argv);
 
  114  return rb_wasm_rt_start(start, argc, argv);