142
142
// / into
143
143
// / __wasm_setjmp(env, label, functionInvocationId)
144
144
// /
145
+ // / __wasm_setjmp records the necessary info (the label and
146
+ // / functionInvocationId) to the "env".
145
147
// / A BB with setjmp is split into two after setjmp call in order to
146
148
// / make the post-setjmp BB the possible destination of longjmp BB.
147
149
// /
152
154
// / __THREW__ = 0;
153
155
// / %__threwValue.val = __threwValue;
154
156
// / if (%__THREW__.val != 0 & %__threwValue.val != 0) {
155
- // / %label = testSetjmp(mem[%__THREW__.val], setjmpTable,
156
- // / setjmpTableSize);
157
+ // / %label = __wasm_setjmp_test(%__THREW__.val, functionInvocationId);
157
158
// / if (%label == 0)
158
159
// / emscripten_longjmp(%__THREW__.val, %__threwValue.val);
159
160
// / setTempRet0(%__threwValue.val);
167
168
// / ...
168
169
// / default: goto splitted next BB
169
170
// / }
170
- // / testSetjmp examines setjmpTable to see if there is a matching setjmp
171
- // / call. After calling an invoke wrapper, if a longjmp occurred, __THREW__
172
- // / will be the address of matching jmp_buf buffer and __threwValue be the
173
- // / second argument to longjmp. mem[%__THREW__.val] is a setjmp ID that is
174
- // / stored in saveSetjmp. testSetjmp returns a setjmp label, a unique ID to
175
- // / each setjmp callsite. Label 0 means this longjmp buffer does not
176
- // / correspond to one of the setjmp callsites in this function, so in this
177
- // / case we just chain the longjmp to the caller. Label -1 means no longjmp
178
- // / occurred. Otherwise we jump to the right post-setjmp BB based on the
179
- // / label.
171
+ // /
172
+ // / __wasm_setjmp_test examines the jmp buf to see if it was for a matching
173
+ // / setjmp call. After calling an invoke wrapper, if a longjmp occurred,
174
+ // / __THREW__ will be the address of matching jmp_buf buffer and
175
+ // / __threwValue be the second argument to longjmp.
176
+ // / __wasm_setjmp_test returns a setjmp label, a unique ID to each setjmp
177
+ // / callsite. Label 0 means this longjmp buffer does not correspond to one
178
+ // / of the setjmp callsites in this function, so in this case we just chain
179
+ // / the longjmp to the caller. Label -1 means no longjmp occurred.
180
+ // / Otherwise we jump to the right post-setjmp BB based on the label.
180
181
// /
181
182
// / * Wasm setjmp / longjmp handling
182
183
// / This mode still uses some Emscripten library functions but not JavaScript's
193
194
// / If there are calls to setjmp()
194
195
// /
195
196
// / 2) and 3): The same as 2) and 3) in Emscripten SjLj.
196
- // / (setjmpTable/setjmpTableSize initialization + setjmp callsite
197
- // / transformation)
197
+ // / (functionInvocationId initialization + setjmp callsite transformation)
198
198
// /
199
199
// / 4) Create a catchpad with a wasm.catch() intrinsic, which returns the value
200
- // / thrown by __wasm_longjmp function. In Emscripten library, we have this
201
- // / struct:
200
+ // / thrown by __wasm_longjmp function. In the runtime library, we have an
201
+ // / equivalent of the following struct:
202
202
// /
203
203
// / struct __WasmLongjmpArgs {
204
204
// / void *env;
205
205
// / int val;
206
206
// / };
207
- // / struct __WasmLongjmpArgs __wasm_longjmp_args;
208
207
// /
209
- // / The thrown value here is a pointer to __wasm_longjmp_args struct object. We
210
- // / use this struct to transfer two values by throwing a single value. Wasm
211
- // / throw and catch instructions are capable of throwing and catching multiple
212
- // / values, but it also requires multivalue support that is currently not very
213
- // / reliable.
208
+ // / The thrown value here is a pointer to the struct. We use this struct to
209
+ // / transfer two values by throwing a single value. Wasm throw and catch
210
+ // / instructions are capable of throwing and catching multiple values, but
211
+ // / it also requires multivalue support that is currently not very reliable.
214
212
// / TODO Switch to throwing and catching two values without using the struct
215
213
// /
216
214
// / All longjmpable function calls will be converted to an invoke that will
217
215
// / unwind to this catchpad in case a longjmp occurs. Within the catchpad, we
218
- // / test the thrown values using testSetjmp function as we do for Emscripten
219
- // / SjLj. The main difference is, in Emscripten SjLj, we need to transform every
220
- // / longjmpable callsite into a sequence of code including testSetjmp() call; in
221
- // / Wasm SjLj we do the testing in only one place, in this catchpad.
216
+ // / test the thrown values using __wasm_setjmp_test function as we do for
217
+ // / Emscripten SjLj. The main difference is, in Emscripten SjLj, we need to
218
+ // / transform every longjmpable callsite into a sequence of code including
219
+ // / __wasm_setjmp_test() call; in Wasm SjLj we do the testing in only one
220
+ // / place, in this catchpad.
222
221
// /
223
- // / After testing calling testSetjmp(), if the longjmp does not correspond to
224
- // / one of the setjmps within the current function, it rethrows the longjmp
225
- // / by calling __wasm_longjmp(). If it corresponds to one of setjmps in the
226
- // / function, we jump to the beginning of the function, which contains a switch
227
- // / to each post-setjmp BB. Again, in Emscripten SjLj, this switch is added for
228
- // / every longjmpable callsite; in Wasm SjLj we do this only once at the top of
229
- // / the function. (after functionInvocationId initialization)
222
+ // / After testing calling __wasm_setjmp_test(), if the longjmp does not
223
+ // / correspond to one of the setjmps within the current function, it rethrows
224
+ // / the longjmp by calling __wasm_longjmp(). If it corresponds to one of
225
+ // / setjmps in the function, we jump to the beginning of the function, which
226
+ // / contains a switch to each post-setjmp BB. Again, in Emscripten SjLj, this
227
+ // / switch is added for every longjmpable callsite; in Wasm SjLj we do this
228
+ // / only once at the top of the function. (after functionInvocationId
229
+ // / initialization)
230
230
// /
231
231
// / The below is the pseudocode for what we have described
232
232
// /
@@ -680,8 +680,9 @@ static bool isEmAsmCall(const Value *Callee) {
680
680
CalleeName == " emscripten_asm_const_async_on_main_thread" ;
681
681
}
682
682
683
- // Generate testSetjmp function call seqence with preamble and postamble.
684
- // The code this generates is equivalent to the following JavaScript code:
683
+ // Generate __wasm_setjmp_test function call seqence with preamble and
684
+ // postamble. The code this generates is equivalent to the following
685
+ // JavaScript code:
685
686
// %__threwValue.val = __threwValue;
686
687
// if (%__THREW__.val != 0 & %__threwValue.val != 0) {
687
688
// %label = __wasm_setjmp_test(%__THREW__.val, functionInvocationId);
@@ -1269,8 +1270,8 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
1269
1270
Instruction *FunctionInvocationId;
1270
1271
IRB.SetInsertPoint (Entry->getTerminator ()->getIterator ());
1271
1272
// This alloca'ed pointer is used by the runtime to identify function
1272
- // inovactions . It's just for pointer comparisons. It will never
1273
- // be dereferenced.
1273
+ // invocations . It's just for pointer comparisons. It will never be
1274
+ // dereferenced.
1274
1275
FunctionInvocationId =
1275
1276
IRB.CreateAlloca (IRB.getInt32Ty (), nullptr , " functionInvocationId" );
1276
1277
FunctionInvocationId->setDebugLoc (FirstDL);
@@ -1493,7 +1494,7 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForEmscriptenSjLj(
1493
1494
1494
1495
IRB.SetInsertPoint (NormalBB);
1495
1496
IRB.CreateBr (Tail);
1496
- BB = NormalBB; // New insertion point to insert testSetjmp ()
1497
+ BB = NormalBB; // New insertion point to insert __wasm_setjmp_test ()
1497
1498
}
1498
1499
}
1499
1500
@@ -1502,9 +1503,9 @@ void WebAssemblyLowerEmscriptenEHSjLj::handleLongjmpableCallsForEmscriptenSjLj(
1502
1503
// right setjmp-tail if so
1503
1504
ToErase.push_back (BB->getTerminator ());
1504
1505
1505
- // Generate a function call to testSetjmp function and preamble/postamble
1506
- // code to figure out (1) whether longjmp occurred (2) if longjmp
1507
- // occurred, which setjmp it corresponds to
1506
+ // Generate a function call to __wasm_setjmp_test function and
1507
+ // preamble/postamble code to figure out (1) whether longjmp
1508
+ // occurred (2) if longjmp occurred , which setjmp it corresponds to
1508
1509
Value *Label = nullptr ;
1509
1510
Value *LongjmpResult = nullptr ;
1510
1511
BasicBlock *EndBB = nullptr ;
0 commit comments