Skip to content

Commit 9a7661e

Browse files
committed
[JSC] In IPInt slowpaths return (<exception value>, SlowPathExceptionTag) as we do in JS
https://bugs.webkit.org/show_bug.cgi?id=291848 Reviewed by Daniel Liu. The changes IPInt slow paths order of return values to match JS. - on success: (value, 0) - on failure: (exception, SlowPathExceptionTag=1) On JSVALUE32_64 we can then return: - on success: (payload, tag) - on failure: (exception, SlowPathExceptionTag=InvalidTag) We also remove WASM_THROW and use IPINT_THROW with operationCallMayThrow in call_indirect. * Source/JavaScriptCore/llint/InPlaceInterpreter.asm: * Source/JavaScriptCore/llint/InPlaceInterpreter64.asm: * Source/JavaScriptCore/wasm/WasmIPIntSlowPaths.cpp: (JSC::IPInt::WASM_IPINT_EXTERN_CPP_DECL): Canonical link: https://commits.webkit.org/294069@main
1 parent 2f89cb3 commit 9a7661e

File tree

3 files changed

+55
-68
lines changed

3 files changed

+55
-68
lines changed

Source/JavaScriptCore/llint/InPlaceInterpreter.asm

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,18 @@ macro ipintReloadMemory()
324324
end
325325
end
326326

327+
# Call site tracking
328+
329+
macro saveCallSiteIndex()
330+
if X86_64
331+
loadp UnboxedWasmCalleeStackSlot[cfr], ws0
332+
end
333+
loadp Wasm::IPIntCallee::m_bytecode[ws0], t0
334+
negp t0
335+
addp PC, t0
336+
storei t0, CallSiteIndex[cfr]
337+
end
338+
327339
# Operation Calls
328340

329341
macro operationCall(fn)
@@ -347,10 +359,7 @@ macro operationCall(fn)
347359
end
348360

349361
macro operationCallMayThrow(fn)
350-
loadp Wasm::IPIntCallee::m_bytecode[ws0], t0
351-
negp t0
352-
addp PC, t0
353-
storei t0, CallSiteIndex[cfr]
362+
saveCallSiteIndex()
354363

355364
move wasmInstance, a0
356365
push PC, MC
@@ -360,8 +369,8 @@ macro operationCallMayThrow(fn)
360369
push PL, IB
361370
end
362371
fn()
363-
bpneq r0, (constexpr JSC::IPInt::SlowPathExceptionTag), .continuation
364-
storei r1, ArgumentCountIncludingThis + PayloadOffset[cfr]
372+
bpneq r1, (constexpr JSC::IPInt::SlowPathExceptionTag), .continuation
373+
storei r0, ArgumentCountIncludingThis + PayloadOffset[cfr]
365374
jmp _wasm_throw_from_slow_path_trampoline
366375
.continuation:
367376
if ARM64 or ARM64E

Source/JavaScriptCore/llint/InPlaceInterpreter64.asm

Lines changed: 31 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -177,18 +177,6 @@ macro popFloat64(reg)
177177
popv reg
178178
end
179179

180-
# Call site tracking
181-
182-
macro saveCallSiteIndex()
183-
if X86_64
184-
loadp UnboxedWasmCalleeStackSlot[cfr], ws0
185-
end
186-
loadp Wasm::IPIntCallee::m_bytecode[ws0], t0
187-
move PC, t1
188-
subq t0, t1
189-
storei t1, CallSiteIndex[cfr]
190-
end
191-
192180
# Entering IPInt
193181

194182
# MC = location in argumINT bytecode
@@ -581,8 +569,7 @@ ipintOp(_call_indirect, macro()
581569
move MC, a3
582570
advanceMC(IPInt::CallIndirectMetadata::signature)
583571

584-
operationCall(macro() cCall4(_ipint_extern_prepare_call_indirect) end)
585-
btpz r1, _wasm_throw_from_slow_path_trampoline
572+
operationCallMayThrow(macro() cCall4(_ipint_extern_prepare_call_indirect) end)
586573

587574
loadq [sp], IPIntCallCallee
588575
loadq 8[sp], IPIntCallFunctionSlot
@@ -628,8 +615,7 @@ ipintOp(_return_call_indirect, macro()
628615
# Get callIndirectMetadata
629616
move cfr, a1
630617
move MC, a3
631-
operationCall(macro() cCall4(_ipint_extern_prepare_call_indirect) end)
632-
btpz r1, _wasm_throw_from_slow_path_trampoline
618+
operationCallMayThrow(macro() cCall4(_ipint_extern_prepare_call_indirect) end)
633619

634620
loadq [sp], IPIntCallCallee
635621
loadq 8[sp], IPIntCallFunctionSlot
@@ -647,8 +633,7 @@ ipintOp(_call_ref, macro()
647633
loadi IPInt::CallRefMetadata::typeIndex[MC], a2
648634
move sp, a3
649635

650-
operationCall(macro() cCall4(_ipint_extern_prepare_call_ref) end)
651-
btpz r1, _wasm_throw_from_slow_path_trampoline
636+
operationCallMayThrow(macro() cCall4(_ipint_extern_prepare_call_ref) end)
652637
loadq [sp], IPIntCallCallee
653638
loadq 8[sp], IPIntCallFunctionSlot
654639
addq 16, sp
@@ -669,8 +654,7 @@ ipintOp(_return_call_ref, macro()
669654
move cfr, a1
670655
loadi IPInt::TailCallRefMetadata::typeIndex[MC], a2
671656
move sp, a3
672-
operationCall(macro() cCall4(_ipint_extern_prepare_call_ref) end)
673-
btpz r1, _wasm_throw_from_slow_path_trampoline
657+
operationCallMayThrow(macro() cCall4(_ipint_extern_prepare_call_ref) end)
674658
loadq [sp], IPIntCallCallee
675659
loadq 8[sp], IPIntCallFunctionSlot
676660
addq 16, sp
@@ -888,7 +872,7 @@ ipintOp(_table_get, macro()
888872

889873
operationCallMayThrow(macro() cCall3(_ipint_extern_table_get) end)
890874

891-
pushQuad(r1)
875+
pushQuad(r0)
892876

893877
loadb IPInt::Const32Metadata::instructionLength[MC], t0
894878

@@ -3100,7 +3084,7 @@ ipintOp(_ref_func, macro()
31003084
move wasmInstance, a0
31013085
loadi IPInt::Const32Metadata::value[MC], a1
31023086
operationCall(macro() cCall2(_ipint_extern_ref_func) end)
3103-
pushQuad(r1)
3087+
pushQuad(r0)
31043088
loadb IPInt::Const32Metadata::instructionLength[MC], t0
31053089
advancePC(t0)
31063090
advanceMC(constexpr (sizeof(IPInt::Const32Metadata)))
@@ -3270,10 +3254,10 @@ ipintOp(_struct_new, macro()
32703254
loadp IPInt::StructNewMetadata::typeIndex[MC], a1 # type index
32713255
move sp, a2
32723256
operationCallMayThrow(macro() cCall3(_ipint_extern_struct_new) end)
3273-
loadh IPInt::StructNewMetadata::params[MC], t0 # number of parameters popped
3274-
mulq StackValueSize, t0
3275-
addq t0, sp
3276-
pushQuad(r1)
3257+
loadh IPInt::StructNewMetadata::params[MC], t1 # number of parameters popped
3258+
mulq StackValueSize, t1
3259+
addq t1, sp
3260+
pushQuad(r0)
32773261
loadb IPInt::StructNewMetadata::length[MC], t0
32783262
advancePCByReg(t0)
32793263
advanceMC(constexpr (sizeof(IPInt::StructNewMetadata)))
@@ -3283,7 +3267,7 @@ end)
32833267
ipintOp(_struct_new_default, macro()
32843268
loadp IPInt::StructNewDefaultMetadata::typeIndex[MC], a1 # type index
32853269
operationCallMayThrow(macro() cCall2(_ipint_extern_struct_new_default) end)
3286-
pushQuad(r1)
3270+
pushQuad(r0)
32873271
loadb IPInt::StructNewDefaultMetadata::length[MC], t0
32883272
advancePCByReg(t0)
32893273
advanceMC(constexpr (sizeof(IPInt::StructNewDefaultMetadata)))
@@ -3294,7 +3278,7 @@ ipintOp(_struct_get, macro()
32943278
popQuad(a1) # object
32953279
loadi IPInt::StructGetSetMetadata::fieldIndex[MC], a2 # field index
32963280
operationCallMayThrow(macro() cCall3(_ipint_extern_struct_get) end)
3297-
pushQuad(r1)
3281+
pushQuad(r0)
32983282

32993283
loadb IPInt::StructGetSetMetadata::length[MC], t0
33003284
advancePCByReg(t0)
@@ -3306,7 +3290,7 @@ ipintOp(_struct_get_s, macro()
33063290
popQuad(a1) # object
33073291
loadi IPInt::StructGetSetMetadata::fieldIndex[MC], a2 # field index
33083292
operationCallMayThrow(macro() cCall3(_ipint_extern_struct_get_s) end)
3309-
pushQuad(r1)
3293+
pushQuad(r0)
33103294

33113295
loadb IPInt::StructGetSetMetadata::length[MC], t0
33123296
advancePCByReg(t0)
@@ -3318,7 +3302,7 @@ ipintOp(_struct_get_u, macro()
33183302
popQuad(a1) # object
33193303
loadi IPInt::StructGetSetMetadata::fieldIndex[MC], a2 # field index
33203304
operationCallMayThrow(macro() cCall3(_ipint_extern_struct_get) end)
3321-
pushQuad(r1)
3305+
pushQuad(r0)
33223306

33233307
loadb IPInt::StructGetSetMetadata::length[MC], t0
33243308
advancePCByReg(t0)
@@ -3345,7 +3329,7 @@ ipintOp(_array_new, macro()
33453329
popQuad(a2) # default value
33463330
operationCallMayThrow(macro() cCall4(_ipint_extern_array_new) end)
33473331

3348-
pushQuad(r1)
3332+
pushQuad(r0)
33493333

33503334
loadb IPInt::ArrayNewMetadata::length[MC], t0
33513335
advancePCByReg(t0)
@@ -3358,7 +3342,7 @@ ipintOp(_array_new_default, macro()
33583342
popInt32(a2, t0) # length
33593343
operationCallMayThrow(macro() cCall3(_ipint_extern_array_new_default) end)
33603344

3361-
pushQuad(r1)
3345+
pushQuad(r0)
33623346

33633347
loadb IPInt::ArrayNewMetadata::length[MC], t0
33643348
advancePCByReg(t0)
@@ -3377,7 +3361,7 @@ ipintOp(_array_new_fixed, macro()
33773361
lshifti StackValueShift, t3
33783362
addp t3, sp
33793363

3380-
pushQuad(r1)
3364+
pushQuad(r0)
33813365

33823366
loadb IPInt::ArrayNewFixedMetadata::length[MC], t0
33833367
advancePCByReg(t0)
@@ -3391,7 +3375,7 @@ ipintOp(_array_new_data, macro()
33913375
popInt32(a2, t0) # offset
33923376
operationCallMayThrow(macro() cCall4(_ipint_extern_array_new_data) end)
33933377

3394-
pushQuad(r1)
3378+
pushQuad(r0)
33953379

33963380
loadb IPInt::ArrayNewDataMetadata::length[MC], t0
33973381
advancePCByReg(t0)
@@ -3405,7 +3389,7 @@ ipintOp(_array_new_elem, macro()
34053389
popInt32(a2, t0) # offset
34063390
operationCallMayThrow(macro() cCall4(_ipint_extern_array_new_elem) end)
34073391

3408-
pushQuad(r1)
3392+
pushQuad(r0)
34093393

34103394
loadb IPInt::ArrayNewElemMetadata::length[MC], t0
34113395
advancePCByReg(t0)
@@ -3419,7 +3403,7 @@ ipintOp(_array_get, macro()
34193403
popQuad(a2) # array
34203404
operationCallMayThrow(macro() cCall4(_ipint_extern_array_get) end)
34213405

3422-
pushQuad(r1)
3406+
pushQuad(r0)
34233407

34243408
loadb IPInt::ArrayGetSetMetadata::length[MC], t0
34253409
advancePCByReg(t0)
@@ -3433,7 +3417,7 @@ ipintOp(_array_get_s, macro()
34333417
popQuad(a2) # array
34343418
operationCallMayThrow(macro() cCall4(_ipint_extern_array_get_s) end)
34353419

3436-
pushQuad(r1)
3420+
pushQuad(r0)
34373421

34383422
loadb IPInt::ArrayGetSetMetadata::length[MC], t0
34393423
advancePCByReg(t0)
@@ -3447,7 +3431,7 @@ ipintOp(_array_get_u, macro()
34473431
popQuad(a2) # array
34483432
operationCallMayThrow(macro() cCall4(_ipint_extern_array_get) end)
34493433

3450-
pushQuad(r1)
3434+
pushQuad(r0)
34513435

34523436
loadb IPInt::ArrayGetSetMetadata::length[MC], t0
34533437
advancePCByReg(t0)
@@ -3536,7 +3520,7 @@ ipintOp(_ref_test, macro()
35363520
popQuad(a3)
35373521
operationCall(macro() cCall3(_ipint_extern_ref_test) end)
35383522

3539-
pushInt32(r1)
3523+
pushInt32(r0)
35403524

35413525
loadb IPInt::RefTestCastMetadata::length[MC], t0
35423526
advancePCByReg(t0)
@@ -3550,7 +3534,7 @@ ipintOp(_ref_test_nullable, macro()
35503534
popQuad(a3)
35513535
operationCall(macro() cCall3(_ipint_extern_ref_test) end)
35523536

3553-
pushInt32(r1)
3537+
pushInt32(r0)
35543538

35553539
loadb IPInt::RefTestCastMetadata::length[MC], t0
35563540
advancePCByReg(t0)
@@ -3564,7 +3548,7 @@ ipintOp(_ref_cast, macro()
35643548
popQuad(a3)
35653549
operationCallMayThrow(macro() cCall3(_ipint_extern_ref_cast) end)
35663550

3567-
pushInt32(r1)
3551+
pushInt32(r0)
35683552

35693553
loadb IPInt::RefTestCastMetadata::length[MC], t0
35703554
advancePCByReg(t0)
@@ -3578,7 +3562,7 @@ ipintOp(_ref_cast_nullable, macro()
35783562
popQuad(a3)
35793563
operationCallMayThrow(macro() cCall3(_ipint_extern_ref_cast) end)
35803564

3581-
pushInt32(r1)
3565+
pushInt32(r0)
35823566

35833567
loadb IPInt::RefTestCastMetadata::length[MC], t0
35843568
advancePCByReg(t0)
@@ -3596,7 +3580,7 @@ ipintOp(_br_on_cast, macro()
35963580

35973581
advanceMC(constexpr (sizeof(IPInt::RefTestCastMetadata)))
35983582

3599-
bineq r1, 0, _ipint_br
3583+
bineq r0, 0, _ipint_br
36003584
loadb IPInt::BranchMetadata::instructionLength[MC], t0
36013585
advanceMC(constexpr (sizeof(IPInt::BranchMetadata)))
36023586
advancePCByReg(t0)
@@ -3613,7 +3597,7 @@ ipintOp(_br_on_cast_fail, macro()
36133597

36143598
advanceMC(constexpr (sizeof(IPInt::RefTestCastMetadata)))
36153599

3616-
bieq r1, 0, _ipint_br
3600+
bieq r0, 0, _ipint_br
36173601
loadb IPInt::BranchMetadata::instructionLength[MC], t0
36183602
advanceMC(constexpr (sizeof(IPInt::BranchMetadata)))
36193603
advancePCByReg(t0)
@@ -3623,7 +3607,7 @@ end)
36233607
ipintOp(_any_convert_extern, macro()
36243608
popQuad(a1)
36253609
operationCall(macro() cCall2(_ipint_extern_any_convert_extern) end)
3626-
pushQuad(r1)
3610+
pushQuad(r0)
36273611
advancePC(2)
36283612
nextIPIntInstruction()
36293613
end)
@@ -4104,7 +4088,7 @@ ipintOp(_table_grow, macro()
41044088
move MC, a2 # IPInt::tableGrowMetadata
41054089
operationCall(macro() cCall3(_ipint_extern_table_grow) end)
41064090
addp 2*StackValueSize, sp
4107-
pushQuad(t0)
4091+
pushQuad(r0)
41084092
loadb IPInt::TableGrowMetadata::instructionLength[MC], t0
41094093
advancePCByReg(t0)
41104094
advanceMC(constexpr (sizeof(IPInt::TableGrowMetadata)))
@@ -4115,7 +4099,7 @@ ipintOp(_table_size, macro()
41154099
# table.size
41164100
loadi IPInt::Const32Metadata::value[MC], a1
41174101
operationCall(macro() cCall2(_ipint_extern_table_size) end)
4118-
pushQuad(t0)
4102+
pushQuad(r0)
41194103
loadb IPInt::Const32Metadata::instructionLength[MC], t0
41204104
advancePCByReg(t0)
41214105
advanceMC(constexpr (sizeof(IPInt::Const32Metadata)))

Source/JavaScriptCore/wasm/WasmIPIntSlowPaths.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,6 @@ namespace JSC { namespace IPInt {
5959
return encodeResult(first, second); \
6060
} while (false)
6161

62-
#define WASM_THROW(callFrame, exceptionType) do { \
63-
callFrame->setArgumentCountIncludingThis(static_cast<int>(exceptionType)); \
64-
WASM_RETURN_TWO(LLInt::wasmExceptionInstructions(), 0); \
65-
} while (false)
66-
6762
#define WASM_CALL_RETURN(targetInstance, callTarget) do { \
6863
static_assert(callTarget.getTag() == WasmEntryPtrTag); \
6964
callTarget.validate(); \
@@ -73,24 +68,23 @@ namespace JSC { namespace IPInt {
7368
#define IPINT_CALLEE(callFrame) \
7469
static_cast<Wasm::IPIntCallee*>(callFrame->callee().asNativeCallee())
7570

76-
// For operation calls that may throw an exception, we return (0, <val>)
77-
// if it is fine, and (SlowPathExceptionTag, <exception value>) if it is not
78-
// FIXME: match what JS does on 64-bit? i.e. return (<exception>, SlowPathExceptionTag) and (payload, tag) on JSVALUE32_54
71+
// For operation calls that may throw an exception, we return (<val>, 0)
72+
// if it is fine, and (<exception value>, SlowPathExceptionTag) if it is not
7973

8074
#define EXCEPTION_VALUE(type) \
8175
std::bit_cast<void*>(static_cast<uintptr_t>(type))
8276

8377
#define IPINT_THROW(type) \
84-
WASM_RETURN_TWO(std::bit_cast<void*>(SlowPathExceptionTag), EXCEPTION_VALUE(type))
78+
WASM_RETURN_TWO(EXCEPTION_VALUE(type), std::bit_cast<void*>(SlowPathExceptionTag))
8579

8680
#define IPINT_END() WASM_RETURN_TWO(0, 0);
8781

8882
#if CPU(ADDRESS64)
8983
#define IPINT_RETURN(value) \
90-
WASM_RETURN_TWO(0, std::bit_cast<void*>(value));
84+
WASM_RETURN_TWO(std::bit_cast<void*>(value), 0);
9185
#else
9286
#define IPINT_RETURN(value) \
93-
WASM_RETURN_TWO(std::bit_cast<void*>(JSValue::decode(value).tag()), std::bit_cast<void*>(JSValue::decode(value).payload()));
87+
WASM_RETURN_TWO(std::bit_cast<void*>(JSValue::decode(value).payload()), std::bit_cast<void*>(JSValue::decode(value).tag()));
9488
#endif
9589

9690
#if ENABLE(WEBASSEMBLY_BBQJIT)
@@ -942,16 +936,16 @@ WASM_IPINT_EXTERN_CPP_DECL(prepare_call_indirect, CallFrame* callFrame, Wasm::Fu
942936
Wasm::FuncRefTable* table = instance->table(tableIndex)->asFuncrefTable();
943937

944938
if (*functionIndex >= table->length())
945-
WASM_THROW(callFrame, Wasm::ExceptionType::OutOfBoundsCallIndirect);
939+
IPINT_THROW(Wasm::ExceptionType::OutOfBoundsCallIndirect);
946940

947941
const Wasm::FuncRefTable::Function& function = table->function(*functionIndex);
948942

949943
if (function.m_function.typeIndex == Wasm::TypeDefinition::invalidIndex)
950-
WASM_THROW(callFrame, Wasm::ExceptionType::NullTableEntry);
944+
IPINT_THROW(Wasm::ExceptionType::NullTableEntry);
951945

952946
const auto& callSignature = static_cast<Wasm::IPIntCallee*>(callFrame->callee().asNativeCallee())->signature(typeIndex);
953947
if (!Wasm::isSubtypeIndex(function.m_function.typeIndex, callSignature.index()))
954-
WASM_THROW(callFrame, Wasm::ExceptionType::BadSignature);
948+
IPINT_THROW(Wasm::ExceptionType::BadSignature);
955949

956950
Register* calleeReturn = std::bit_cast<Register*>(functionIndex);
957951
EncodedJSValue boxedCallee = CalleeBits::encodeNullCallee();
@@ -980,7 +974,7 @@ WASM_IPINT_EXTERN_CPP_DECL(prepare_call_ref, CallFrame* callFrame, Wasm::TypeInd
980974
JSValue targetReference = JSValue::decode(sp->ref);
981975

982976
if (targetReference.isNull())
983-
WASM_THROW(callFrame, Wasm::ExceptionType::NullReference);
977+
IPINT_THROW(Wasm::ExceptionType::NullReference);
984978

985979
ASSERT(targetReference.isObject());
986980
JSObject* referenceAsObject = jsCast<JSObject*>(targetReference);

0 commit comments

Comments
 (0)