File: stack_limits.S

package info (click to toggle)
emscripten 3.1.69%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 121,860 kB
  • sloc: ansic: 636,110; cpp: 425,974; javascript: 78,401; python: 58,404; sh: 49,154; pascal: 5,237; makefile: 3,366; asm: 2,415; lisp: 1,869
file content (139 lines) | stat: -rw-r--r-- 3,686 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
.globl emscripten_stack_init
.globl emscripten_stack_set_limits
.globl emscripten_stack_get_free
.globl emscripten_stack_get_base
.globl emscripten_stack_get_end

#ifdef __wasm64__
#define PTR i64
#define ALIGN 3
#define PTRSTORE .int64
#else
#define PTR i32
#define ALIGN 2
#define PTRSTORE .int32
#endif

.globaltype __stack_pointer, PTR

.section .globals,"",@

# TODO(sbc): It would be nice if these we initialized directly
# using PTR.const rather than using the `emscripten_stack_init`
.globaltype __stack_end, PTR
__stack_end:
.globaltype __stack_base, PTR
__stack_base:

.section .text,"",@

emscripten_stack_get_base:
  .functype emscripten_stack_get_base () -> (PTR)
  global.get __stack_base
  end_function

emscripten_stack_get_end:
  .functype emscripten_stack_get_end () -> (PTR)
  global.get __stack_end
  end_function

emscripten_stack_init:
  # Initialize __stack_end and __stack_base.
  # This must be called before emscripten_stack_get_end,
  # emscripten_stack_get_base, or emscripten_stack_get_free are called
  .functype emscripten_stack_init () -> ()

  # What llvm calls __stack_high is the high address from where is grows
  # downwards.  We call this the stack base here in emscripten.
#ifdef __PIC__
  global.get __stack_high@GOT
#else
  PTR.const __stack_high
#endif
  global.set __stack_base

  # What llvm calls __stack_low is that end of the stack
#ifdef __PIC__
  global.get __stack_low@GOT
#else
  PTR.const __stack_low
#endif
  # Align up to 16 bytes
  PTR.const 0xf
  PTR.add
  PTR.const -0x10
  PTR.and
  global.set __stack_end

  end_function

emscripten_stack_set_limits:
  .functype emscripten_stack_set_limits (PTR, PTR) -> ()
  local.get 0
  global.set __stack_base
  local.get 1
  global.set __stack_end
  end_function

emscripten_stack_get_free:
  .functype emscripten_stack_get_free () -> (PTR)
  global.get __stack_pointer
  global.get __stack_end
  PTR.sub
  end_function

#ifdef __EMSCRIPTEN_WASM_WORKERS__
# TODO: Relocate the following to its own file wasm_worker.S, but need to figure out how to reference
# __stack_base and __stack_end globals from a separate file as externs in order for that to work.
.globl _emscripten_wasm_worker_initialize
_emscripten_wasm_worker_initialize:
  .functype _emscripten_wasm_worker_initialize (PTR /*stackLowestAddress*/, i32 /*stackSize*/) -> ()

  // __stack_end = stackLowestAddress + (__builtin_wasm_tls_size() + 15) & -16;
  local.get 0
  .globaltype __tls_size, PTR, immutable
  global.get __tls_size
  PTR.add
  PTR.const 0xf
  PTR.add
  PTR.const -0x10
  PTR.and
  global.set __stack_end

  // __stack_base = stackLowestAddress + stackSize;
  local.get 0
  local.get 1
#ifdef __wasm64__
  i64.extend_i32_u
#endif
  PTR.add
  global.set __stack_base

// TODO: We'd like to do this here to avoid JS side calls to __set_stack_limits.
//       (or even better, we'd like to avoid duplicate versions of the stack variables)
// See https://github.com/emscripten-core/emscripten/issues/16496
//  global.get __stack_base
//  global.get __stack_end
//  .functype __set_stack_limits (PTR, PTR) -> ()
//  call __set_stack_limits

  // __wasm_init_tls(stackLowestAddress);
  local.get 0
  .functype __wasm_init_tls (PTR) -> ()
  call __wasm_init_tls

  // N.b. The function __wasm_init_tls above does not need
  // __stack_pointer initialized, and it destroys the value it was set to.
  // So we must initialize __stack_pointer only *after* completing __wasm_init_tls:

  // __stack_pointer = __stack_base;
  global.get __stack_base
  global.set __stack_pointer

  end_function
#endif

# Add emscripten_stack_init to static ctors
.section .init_array.1,"",@
.p2align ALIGN
PTRSTORE emscripten_stack_init