From 4b6ef481a4e284ae178305583ad68bbf62e93c03 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Fri, 4 Oct 2024 07:52:28 -0700 Subject: [PATCH 01/54] Avoid linker OOM with GCC on armv7 https://bugs.webkit.org/show_bug.cgi?id=280881 Reviewed by Nikolas Zimmermann and Adrian Perez de Castro. The option -fdebug-types-section causes ld to OOM when using gcc on armv7. Do not use it for armv7. * Source/cmake/WebKitCompilerFlags.cmake: Canonical link: https://commits.webkit.org/284678@main (cherry picked from commit 799d9937a096b59cf3866dbb34eca7756a7c2cde) --- Source/cmake/WebKitCompilerFlags.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/cmake/WebKitCompilerFlags.cmake b/Source/cmake/WebKitCompilerFlags.cmake index 6bbb9900f5d2..17f835e86a85 100644 --- a/Source/cmake/WebKitCompilerFlags.cmake +++ b/Source/cmake/WebKitCompilerFlags.cmake @@ -137,11 +137,12 @@ if (DEVELOPER_MODE AND DEVELOPER_MODE_FATAL_WARNINGS) endif () if (COMPILER_IS_GCC_OR_CLANG) - if (COMPILER_IS_CLANG OR DEVELOPER_MODE) + if (COMPILER_IS_CLANG OR (DEVELOPER_MODE AND !ARM)) # Split debug information in ".debug_types" / ".debug_info" sections - this leads # to a smaller overall size of the debug information, and avoids linker relocation # errors on e.g. aarch64 (relocation R_AARCH64_ABS32 out of range: 4312197985 is not in [-2147483648, 4294967295]) # But when using GCC this breaks Linux distro debuginfo generation, so limit to DEVELOPER_MODE. + # Also when using GCC this causes ld to run out of memory on armv7, so disable for ARM. WEBKIT_PREPEND_GLOBAL_COMPILER_FLAGS(-fdebug-types-section) endif () From 38d38ddb4d814a183a7d72d2740571f267da19d6 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Tue, 8 Oct 2024 10:28:57 -0700 Subject: [PATCH 02/54] =?UTF-8?q?[ARMv7]=E2=80=8AMuffle=20cast-align=20war?= =?UTF-8?q?ning=20on=20GCC=20for=20spanReinterpretCast=20https://bugs.webk?= =?UTF-8?q?it.org/show=5Fbug.cgi=3Fid=3D280882?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed by Justin Michaud. GCC will complain about differing alignment requirements when casting a 4-byte element span to a 8-byte element span on ARMv7. (Causing the build to fail.) Muffle that warning. * Source/WTF/wtf/StdLibExtras.h: Canonical link: https://commits.webkit.org/284837@main (cherry picked from commit 19cbafd537feb413b961b7213800037dc84bb938) --- Source/WTF/wtf/StdLibExtras.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/WTF/wtf/StdLibExtras.h b/Source/WTF/wtf/StdLibExtras.h index 35a5e57b63cd..6168e5909152 100644 --- a/Source/WTF/wtf/StdLibExtras.h +++ b/Source/WTF/wtf/StdLibExtras.h @@ -683,6 +683,8 @@ template auto valueOrDefault(OptionalType&& optionalValue return optionalValue ? *std::forward(optionalValue) : std::remove_reference_t { }; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" template std::span spanReinterpretCast(std::span span) { @@ -690,6 +692,7 @@ std::span spanReinterpretCast(std::span span) static_assert(std::is_const_v || (!std::is_const_v && !std::is_const_v), "spanCast will not remove constness from source"); return std::span { reinterpret_cast(const_cast*>(span.data())), span.size_bytes() / sizeof(T) }; } +#pragma GCC diagnostic pop template std::span spanConstCast(std::span span) From 1ba1093152d7b92da419d4226cee7316d6b55648 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Tue, 25 Feb 2025 13:49:58 -0800 Subject: [PATCH 03/54] [JSC][armv7] Set callee tag in wasm_to_js_wrapper_entry https://bugs.webkit.org/show_bug.cgi?id=288126 Reviewed by Yusuke Suzuki. Set callee tag in wasm_to_js_wrapper_entry on armv7, like its JITed counterpart WasmToJS.cpp:wasmToJS * Source/JavaScriptCore/llint/WebAssembly.asm: Canonical link: https://commits.webkit.org/291057@main (cherry picked from commit 7c2a5bafb9e54dbb9bb75f2025acedb1ca245437) --- Source/JavaScriptCore/llint/WebAssembly.asm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/JavaScriptCore/llint/WebAssembly.asm b/Source/JavaScriptCore/llint/WebAssembly.asm index 33e7acf05196..147c745bc938 100644 --- a/Source/JavaScriptCore/llint/WebAssembly.asm +++ b/Source/JavaScriptCore/llint/WebAssembly.asm @@ -957,7 +957,9 @@ elsif JSVALUE64 storeq ws1, CalleeScratch[cfr] storeq wasmInstance, WasmInstanceScratch[cfr] else - storep ws1, CalleeScratch[cfr] + storep ws1, CalleeScratch+PayloadOffset[cfr] + move constexpr JSValue::NativeCalleeTag, ws1 + storep ws1, CalleeScratch+TagOffset[cfr] storep wasmInstance, WasmInstanceScratch[cfr] end storep ws0, WasmCallableFunctionScratch[cfr] From 3e17bda20d1b4cdf0e75c898ddf3cd4a4837bce2 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Wed, 26 Feb 2025 06:31:32 -0800 Subject: [PATCH 04/54] Handle wide Air::Arg offsets https://bugs.webkit.org/show_bug.cgi?id=282490 Reviewed by Yusuke Suzuki and Justin Michaud. Contrary to the -O1 and -O2 register allocators, AirAllocateRegistersAndStackAndGenerateCode.cpp calls lowerStackArgs() first and then does register allocation and code generation in a single pass. In that file, callFrameAddr uses the extendedOffsetAddrRegister() as a scratch register in order to access FP/SP offsets that are too wide for an immediate offset. However, extendedOffsetAddrRegister() may be live, since it's also used by lowerStackArgs(). This trivially crashes testCallFunctionWithHellaArguments3 on ARMv7, but a slightly modified version of this test will also crash on ARM64. Specifically, this commit modifies testCallFunctionWithHellaArguments3 to use a number of constant values that are not representable as immediates on ARM64 (otherwise they become Imm Air::Args), resulting in a crashing test at O0. This doesn't affect the other register allocators, as they spill registers by means of Arg::stack() and only later lowerStackArgs() to handle these. We fix this by naively spilling (and immediately reloading) extendedOffsetAddrRegister() whenever we need to use it to access a wide offset in callFrameAddr(). With the fix in place, this patch switches ARMv7 to use the same code paths as ARM64 for handling Air::Args with a wide offset. * Source/JavaScriptCore/b3/B3Common.cpp: (JSC::B3::extendedOffsetAddrRegister): * Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp: (JSC::B3::Air::GenerateAndAllocateRegisters::callFrameAddr): (JSC::B3::Air::GenerateAndAllocateRegisters::withCallFrameAddr): (JSC::B3::Air::GenerateAndAllocateRegisters::flush): (JSC::B3::Air::GenerateAndAllocateRegisters::alloc): (JSC::B3::Air::GenerateAndAllocateRegisters::prepareForGeneration): (JSC::B3::Air::GenerateAndAllocateRegisters::generate): (JSC::B3::Air::callFrameAddr): Deleted. * Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.h: * Source/JavaScriptCore/b3/air/AirCode.cpp: (JSC::B3::Air::Code::Code): * Source/JavaScriptCore/b3/air/AirLowerStackArgs.cpp: (JSC::B3::Air::lowerStackArgs): * Source/JavaScriptCore/b3/testb3_5.cpp: (JSC_DEFINE_NOEXCEPT_JIT_OPERATION): (testCallFunctionWithHellaArguments3): Canonical link: https://commits.webkit.org/291111@main (cherry picked from commit 2dfc93f6bfab85c3e93186f2e065c0232911b677) --- Source/JavaScriptCore/b3/B3Common.cpp | 4 +- ...locateRegistersAndStackAndGenerateCode.cpp | 112 ++++++++++-------- ...AllocateRegistersAndStackAndGenerateCode.h | 4 + Source/JavaScriptCore/b3/air/AirCode.cpp | 5 +- .../b3/air/AirLowerStackArgs.cpp | 8 +- Source/JavaScriptCore/b3/testb3_5.cpp | 16 +-- 6 files changed, 81 insertions(+), 68 deletions(-) diff --git a/Source/JavaScriptCore/b3/B3Common.cpp b/Source/JavaScriptCore/b3/B3Common.cpp index 8ea507081124..fb7faba3556c 100644 --- a/Source/JavaScriptCore/b3/B3Common.cpp +++ b/Source/JavaScriptCore/b3/B3Common.cpp @@ -74,10 +74,8 @@ bool shouldSaveIRBeforePhase() GPRReg extendedOffsetAddrRegister() { RELEASE_ASSERT(isARM64() || isRISCV64() || isARM_THUMB2()); -#if CPU(ARM64) || CPU(RISCV64) +#if CPU(ARM64) || CPU(RISCV64) || CPU(ARM) return MacroAssembler::linkRegister; -#elif CPU(ARM) - return MacroAssembler::dataTempRegister; #elif CPU(X86_64) return GPRReg::InvalidGPRReg; #else diff --git a/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp b/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp index 2c8733e2d0fa..e1ecb4d5fc35 100644 --- a/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp +++ b/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp @@ -148,7 +148,7 @@ void GenerateAndAllocateRegisters::insertBlocksForFlushAfterTerminalPatchpoints( blockInsertionSet.execute(); } -static ALWAYS_INLINE Air::Arg callFrameAddr(Air::Opcode opcode, CCallHelpers& jit, intptr_t offsetFromFP, intptr_t frameSize, Width width) +ALWAYS_INLINE std::pair> GenerateAndAllocateRegisters::callFrameAddr(Air::Opcode opcode, CCallHelpers& jit, intptr_t offsetFromFP, intptr_t frameSize, Width width) { if (isX86()) { ASSERT(Arg::addr(Air::Tmp(GPRInfo::callFrameRegister), offsetFromFP).isValidForm(opcode, width)); @@ -156,26 +156,43 @@ static ALWAYS_INLINE Air::Arg callFrameAddr(Air::Opcode opcode, CCallHelpers& ji auto addr = Arg::addr(Air::Tmp(GPRInfo::callFrameRegister), offsetFromFP); if (addr.isValidForm(opcode, width)) - return addr; + return { addr, { } }; // Try finding a valid offset from the stack pointer register instead. auto offsetFromSP = offsetFromFP + frameSize; addr = Arg::addr(Air::Tmp(MacroAssembler::stackPointerRegister), offsetFromSP); if (addr.isValidForm(opcode, width)) - return addr; + return { addr, { } }; // Try finding a valid indexing of extendedOffsetAddrRegister // into the frame pointer register. // (Have to materialze the offset into extendedOffsetAddrRegister.) GPRReg reg = extendedOffsetAddrRegister(); + + // The extendedOffsetAddrRegister() may be live (from lowerStackArgs) so we + // need to spill it here. We allocate its slot first, so we know that it's + // addressable from FP. + auto spillAddr = Arg::addr(Air::Tmp(GPRInfo::callFrameRegister), wideCallFrameOffsetSpillSlot->offsetFromFP()); + ASSERT(spillAddr.isValidForm(Move, is32Bit() ? Width32 : Width64)); + jit.storeRegWord(reg, spillAddr.asAddress()); + jit.move(CCallHelpers::TrustedImmPtr(offsetFromFP), reg); auto index = Arg::index(Air::Tmp(GPRInfo::callFrameRegister), Air::Tmp(reg), 1, 0); if (index.isValidForm(opcode, width)) - return index; + return { index, spillAddr }; // Resort to computing the absolute address in extendedOffsetAddrRegister. jit.addPtr(GPRInfo::callFrameRegister, reg); - return Arg::addr(Air::Tmp(reg)); + return { Arg::addr(Air::Tmp(reg)), spillAddr }; +} + +template +void GenerateAndAllocateRegisters::withCallFrameAddr(Air::Opcode opcode, CCallHelpers& jit, intptr_t offsetFromFP, intptr_t frameSize, Width width, const Functor& functor) +{ + auto [addr, spillAddr] = callFrameAddr(opcode, jit, offsetFromFP, frameSize, width); + functor(addr); + if (spillAddr) + jit.loadRegWord(spillAddr->asAddress(), extendedOffsetAddrRegister()); } ALWAYS_INLINE void GenerateAndAllocateRegisters::release(Tmp tmp, Reg reg) @@ -196,25 +213,28 @@ ALWAYS_INLINE void GenerateAndAllocateRegisters::flush(Tmp tmp, Reg reg) intptr_t offset = m_map[tmp].spillSlot->offsetFromFP(); JIT_COMMENT(*m_jit, "Flush(", tmp, ", ", reg, ", offset=", offset, ")"); if (tmp.isGP()) { - auto dest = callFrameAddr(Air::Move, *m_jit, offset, m_code.frameSize(), registerWidth()); - if (dest.isAddr()) - m_jit->storeRegWord(reg.gpr(), dest.asAddress()); - else - m_jit->storeRegWord(reg.gpr(), dest.asBaseIndex()); + withCallFrameAddr(Air::Move, *m_jit, offset, m_code.frameSize(), registerWidth(), [&](Air::Arg dest) { + if (dest.isAddr()) + m_jit->storeRegWord(reg.gpr(), dest.asAddress()); + else + m_jit->storeRegWord(reg.gpr(), dest.asBaseIndex()); + }); } else if (B3::conservativeRegisterBytes(B3::FP) == sizeof(double) || !m_code.usesSIMD()) { ASSERT(m_map[tmp].spillSlot->byteSize() == bytesForWidth(Width64)); - auto dest = callFrameAddr(Air::MoveDouble, *m_jit, offset, m_code.frameSize(), Width64); - if (dest.isAddr()) - m_jit->storeDouble(reg.fpr(), dest.asAddress()); - else - m_jit->storeDouble(reg.fpr(), dest.asBaseIndex()); + withCallFrameAddr(Air::MoveDouble, *m_jit, offset, m_code.frameSize(), Width64, [&](Air::Arg dest) { + if (dest.isAddr()) + m_jit->storeDouble(reg.fpr(), dest.asAddress()); + else + m_jit->storeDouble(reg.fpr(), dest.asBaseIndex()); + }); } else { ASSERT(m_map[tmp].spillSlot->byteSize() == bytesForWidth(Width128)); - auto dest = callFrameAddr(Air::MoveVector, *m_jit, offset, m_code.frameSize(), Width128); - if (dest.isAddr()) - m_jit->storeVector(reg.fpr(), dest.asAddress()); - else - m_jit->storeVector(reg.fpr(), dest.asBaseIndex()); + withCallFrameAddr(Air::MoveVector, *m_jit, offset, m_code.frameSize(), Width128, [&](Air::Arg dest) { + if (dest.isAddr()) + m_jit->storeVector(reg.fpr(), dest.asAddress()); + else + m_jit->storeVector(reg.fpr(), dest.asBaseIndex()); + }); } } @@ -244,25 +264,28 @@ ALWAYS_INLINE void GenerateAndAllocateRegisters::alloc(Tmp tmp, Reg reg, Arg::Ro JIT_COMMENT(*m_jit, "Alloc(", tmp, ", ", reg, ", role=", role, ")"); intptr_t offset = m_map[tmp].spillSlot->offsetFromFP(); if (tmp.bank() == GP) { - auto src = callFrameAddr(Air::Move, *m_jit, offset, m_code.frameSize(), registerWidth()); - if (src.isAddr()) - m_jit->loadRegWord(src.asAddress(), reg.gpr()); - else - m_jit->loadRegWord(src.asBaseIndex(), reg.gpr()); + withCallFrameAddr(Air::Move, *m_jit, offset, m_code.frameSize(), registerWidth(), [&](Air::Arg src) { + if (src.isAddr()) + m_jit->loadRegWord(src.asAddress(), reg.gpr()); + else + m_jit->loadRegWord(src.asBaseIndex(), reg.gpr()); + }); } else if (B3::conservativeRegisterBytes(B3::FP) == sizeof(double) || !m_code.usesSIMD()) { ASSERT(m_map[tmp].spillSlot->byteSize() == bytesForWidth(Width64)); - auto src = callFrameAddr(Air::MoveDouble, *m_jit, offset, m_code.frameSize(), Width64); - if (src.isAddr()) - m_jit->loadDouble(src.asAddress(), reg.fpr()); - else - m_jit->loadDouble(src.asBaseIndex(), reg.fpr()); + withCallFrameAddr(Air::MoveDouble, *m_jit, offset, m_code.frameSize(), Width64, [&](Air::Arg src) { + if (src.isAddr()) + m_jit->loadDouble(src.asAddress(), reg.fpr()); + else + m_jit->loadDouble(src.asBaseIndex(), reg.fpr()); + }); } else { ASSERT(m_map[tmp].spillSlot->byteSize() == bytesForWidth(Width128)); - auto src = callFrameAddr(Air::MoveVector, *m_jit, offset, m_code.frameSize(), Width128); - if (src.isAddr()) - m_jit->loadVector(src.asAddress(), reg.fpr()); - else - m_jit->loadVector(src.asBaseIndex(), reg.fpr()); + withCallFrameAddr(Air::MoveVector, *m_jit, offset, m_code.frameSize(), Width128, [&](Air::Arg src) { + if (src.isAddr()) + m_jit->loadVector(src.asAddress(), reg.fpr()); + else + m_jit->loadVector(src.asBaseIndex(), reg.fpr()); + }); } } } @@ -383,8 +406,15 @@ ALWAYS_INLINE bool GenerateAndAllocateRegisters::isDisallowedRegister(Reg reg) return !m_allowedRegisters.contains(reg, IgnoreVectors); } + void GenerateAndAllocateRegisters::prepareForGeneration() { + // We may need to use extendedOffsetAddrRegister() to access a wide + // callframe offset in alloc/flush. But extendedOffsetAddrRegister() may be + // live, since we run lowerStackArgs first, so we need a way to spill it. + // Allocate the stack slot for it first, so that we can be sure it's not at + // a "wide" offset (i.e. that it's addressable with an immediate offset). + wideCallFrameOffsetSpillSlot = m_code.addStackSlot(conservativeRegisterBytes(GP), StackSlotKind::Spill); // We pessimistically assume we use all callee saves. handleCalleeSaves(m_code, RegisterSetBuilder::calleeSaveRegisters()); allocateEscapedStackSlots(m_code); @@ -872,18 +902,6 @@ void GenerateAndAllocateRegisters::generate(CCallHelpers& jit) arg = Arg::addr(Tmp(GPRInfo::callFrameRegister), entry.spillSlot->offsetFromFP()); } }); - int pinnedRegisterUses = 0; - inst.forEachArg([&] (Arg& arg, Arg::Role role, Bank, Width) { - if (arg.isAddr() && arg.isAnyUse(role) && !arg.isValidForm(inst.kind.opcode)) { - GPRReg reg = extendedOffsetAddrRegister(); - m_jit->move(CCallHelpers::TrustedImmPtr(arg.offset()), reg); - m_jit->addPtr(arg.base().gpr(), reg); - arg = Arg::addr(Tmp(reg)); - ++pinnedRegisterUses; - RELEASE_ASSERT(pinnedRegisterUses < 2); - return; - } - }); --instIndex; isReplayingSameInst = true; continue; diff --git a/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.h b/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.h index 94e7591d8dfe..aac8627d941f 100644 --- a/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.h +++ b/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.h @@ -57,6 +57,9 @@ class GenerateAndAllocateRegisters { private: void insertBlocksForFlushAfterTerminalPatchpoints(); + ALWAYS_INLINE std::pair> callFrameAddr(Air::Opcode, CCallHelpers&, intptr_t, intptr_t, Width); + template + void withCallFrameAddr(Air::Opcode, CCallHelpers&, intptr_t, intptr_t, Width, const Functor&); void release(Tmp, Reg); void flush(Tmp, Reg); void spill(Tmp, Reg); @@ -91,6 +94,7 @@ class GenerateAndAllocateRegisters { RegisterSetBuilder m_clobberedToClear; RegisterSet m_allowedRegisters; std::unique_ptr m_liveness; + StackSlot* wideCallFrameOffsetSpillSlot; struct PatchSpillData { MacroAssembler::Jump jump; diff --git a/Source/JavaScriptCore/b3/air/AirCode.cpp b/Source/JavaScriptCore/b3/air/AirCode.cpp index 1fa66bc19459..1d7f9e8f2e53 100644 --- a/Source/JavaScriptCore/b3/air/AirCode.cpp +++ b/Source/JavaScriptCore/b3/air/AirCode.cpp @@ -93,6 +93,7 @@ Code::Code(Procedure& proc) } #endif all.remove(MacroAssembler::fpTempRegister); + all.remove(MacroAssembler::dataTempRegister); // FIXME We should allow this to be used. See the note // in https://commits.webkit.org/257808@main for more // info about why masm is using scratch registers on @@ -120,10 +121,6 @@ Code::Code(Procedure& proc) setRegsInPriorityOrder(bank, result); }); -#if CPU(ARM_THUMB2) - if (auto reg = extendedOffsetAddrRegister()) - pinRegister(reg); -#endif m_pinnedRegs.add(MacroAssembler::framePointerRegister, IgnoreVectors); } diff --git a/Source/JavaScriptCore/b3/air/AirLowerStackArgs.cpp b/Source/JavaScriptCore/b3/air/AirLowerStackArgs.cpp index fbc2461c182b..e3eef1c89eba 100644 --- a/Source/JavaScriptCore/b3/air/AirLowerStackArgs.cpp +++ b/Source/JavaScriptCore/b3/air/AirLowerStackArgs.cpp @@ -129,18 +129,14 @@ void lowerStackArgs(Code& code) if (inst.kind.opcode == Patch) return Arg::extendedOffsetAddr(offsetFromFP); -#if CPU(ARM64) || CPU(RISCV64) +#if CPU(ARM64) || CPU(RISCV64) || CPU(ARM) Air::Tmp tmp = Air::Tmp(extendedOffsetAddrRegister()); Arg largeOffset = Arg::isValidImmForm(offsetFromSP) ? Arg::imm(offsetFromSP) : Arg::bigImm(offsetFromSP); insertionSet.insert(instIndex, Move, inst.origin, largeOffset, tmp); - insertionSet.insert(instIndex, Add64, inst.origin, Air::Tmp(MacroAssembler::stackPointerRegister), tmp); + insertionSet.insert(instIndex, is64Bit() ? Add64 : Add32, inst.origin, Air::Tmp(MacroAssembler::stackPointerRegister), tmp); result = Arg::addr(tmp, 0); return result; -#elif CPU(ARM) - // We solve this in AirAllocateRegistersAndStackAndGenerateCode.cpp. - UNUSED_PARAM(instIndex); - return result; #elif CPU(X86_64) UNUSED_PARAM(instIndex); // Can't happen on x86: immediates are always big enough for frame size. diff --git a/Source/JavaScriptCore/b3/testb3_5.cpp b/Source/JavaScriptCore/b3/testb3_5.cpp index 4af8f3d22e3d..e20a110c2a0f 100644 --- a/Source/JavaScriptCore/b3/testb3_5.cpp +++ b/Source/JavaScriptCore/b3/testb3_5.cpp @@ -2194,18 +2194,18 @@ static void preCommitStackMemory(void* stackLimit) #endif extern "C" { -static JSC_DECLARE_NOEXCEPT_JIT_OPERATION_WITHOUT_WTF_INTERNAL(functionWithHellaArguments3, int, (int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25,int arg26,int arg27,int arg28,int arg29,int arg30,int arg31,int arg32,int arg33,int arg34,int arg35,int arg36,int arg37,int arg38,int arg39,int arg40,int arg41,int arg42,int arg43,int arg44,int arg45,int arg46,int arg47,int arg48,int arg49,int arg50,int arg51,int arg52,int arg53,int arg54,int arg55,int arg56,int arg57,int arg58,int arg59,int arg60,int arg61,int arg62,int arg63,int arg64,int arg65,int arg66,int arg67,int arg68,int arg69,int arg70,int arg71,int arg72,int arg73,int arg74,int arg75,int arg76,int arg77,int arg78,int arg79,int arg80,int arg81,int arg82,int arg83,int arg84,int arg85,int arg86,int arg87,int arg88,int arg89,int arg90,int arg91,int arg92,int arg93,int arg94,int arg95,int arg96,int arg97,int arg98,int arg99,int arg100,int arg101,int arg102,int arg103,int arg104,int arg105,int arg106,int arg107,int arg108,int arg109,int arg110,int arg111,int arg112,int arg113,int arg114,int arg115,int arg116,int arg117,int arg118,int arg119,int arg120,int arg121,int arg122,int arg123,int arg124,int arg125,int arg126,int arg127,int arg128,int arg129,int arg130,int arg131,int arg132,int arg133,int arg134,int arg135,int arg136,int arg137,int arg138,int arg139,int arg140,int arg141,int arg142,int arg143,int arg144,int arg145,int arg146,int arg147,int arg148,int arg149,int arg150,int arg151,int arg152,int arg153,int arg154,int arg155,int arg156,int arg157,int arg158,int arg159,int arg160,int arg161,int arg162,int arg163,int arg164,int arg165,int arg166,int arg167,int arg168,int arg169,int arg170,int arg171,int arg172,int arg173,int arg174,int arg175,int arg176,int arg177,int arg178,int arg179,int arg180,int arg181,int arg182,int arg183,int arg184,int arg185,int arg186,int arg187,int arg188,int arg189,int arg190,int arg191,int arg192,int arg193,int arg194,int arg195,int arg196,int arg197,int arg198,int arg199,int arg200,int arg201,int arg202,int arg203,int arg204,int arg205,int arg206,int arg207,int arg208,int arg209,int arg210,int arg211,int arg212,int arg213,int arg214,int arg215,int arg216,int arg217,int arg218,int arg219,int arg220,int arg221,int arg222,int arg223,int arg224,int arg225,int arg226,int arg227,int arg228,int arg229,int arg230,int arg231,int arg232,int arg233,int arg234,int arg235,int arg236,int arg237,int arg238,int arg239,int arg240,int arg241,int arg242,int arg243,int arg244,int arg245,int arg246,int arg247,int arg248,int arg249,int arg250,int arg251,int arg252,int arg253,int arg254,int arg255,int arg256,int arg257,int arg258,int arg259,int arg260,int arg261,int arg262,int arg263,int arg264,int arg265,int arg266,int arg267,int arg268,int arg269,int arg270,int arg271,int arg272,int arg273,int arg274,int arg275,int arg276,int arg277,int arg278,int arg279,int arg280,int arg281,int arg282,int arg283,int arg284,int arg285,int arg286,int arg287,int arg288,int arg289,int arg290,int arg291,int arg292,int arg293,int arg294,int arg295,int arg296,int arg297,int arg298,int arg299,int arg300,int arg301,int arg302,int arg303,int arg304,int arg305,int arg306,int arg307,int arg308,int arg309,int arg310,int arg311,int arg312,int arg313,int arg314,int arg315,int arg316,int arg317,int arg318,int arg319,int arg320,int arg321,int arg322,int arg323,int arg324,int arg325,int arg326,int arg327,int arg328,int arg329,int arg330,int arg331,int arg332,int arg333,int arg334,int arg335,int arg336,int arg337,int arg338,int arg339,int arg340,int arg341,int arg342,int arg343,int arg344,int arg345,int arg346,int arg347,int arg348,int arg349,int arg350,int arg351,int arg352,int arg353,int arg354,int arg355,int arg356,int arg357,int arg358,int arg359,int arg360,int arg361,int arg362,int arg363,int arg364,int arg365,int arg366,int arg367,int arg368,int arg369,int arg370,int arg371,int arg372,int arg373,int arg374,int arg375,int arg376,int arg377,int arg378,int arg379,int arg380,int arg381,int arg382,int arg383,int arg384,int arg385,int arg386,int arg387,int arg388,int arg389,int arg390,int arg391,int arg392,int arg393,int arg394,int arg395,int arg396,int arg397,int arg398,int arg399,int arg400,int arg401,int arg402,int arg403,int arg404,int arg405,int arg406,int arg407,int arg408,int arg409,int arg410,int arg411,int arg412,int arg413,int arg414,int arg415,int arg416,int arg417,int arg418,int arg419,int arg420,int arg421,int arg422,int arg423,int arg424,int arg425,int arg426,int arg427,int arg428,int arg429,int arg430,int arg431,int arg432,int arg433,int arg434,int arg435,int arg436,int arg437,int arg438,int arg439,int arg440,int arg441,int arg442,int arg443,int arg444,int arg445,int arg446,int arg447,int arg448,int arg449,int arg450,int arg451,int arg452,int arg453,int arg454,int arg455,int arg456,int arg457,int arg458,int arg459,int arg460,int arg461,int arg462,int arg463,int arg464,int arg465,int arg466,int arg467,int arg468,int arg469,int arg470,int arg471,int arg472,int arg473,int arg474,int arg475,int arg476,int arg477,int arg478,int arg479,int arg480,int arg481,int arg482,int arg483,int arg484,int arg485,int arg486,int arg487,int arg488,int arg489,int arg490,int arg491,int arg492,int arg493,int arg494,int arg495,int arg496,int arg497,int arg498,int arg499,int arg500,int arg501,int arg502,int arg503,int arg504,int arg505,int arg506,int arg507,int arg508,int arg509,int arg510,int arg511,int arg512,int arg513,int arg514,int arg515,int arg516,int arg517,int arg518,int arg519,int arg520,int arg521,int arg522,int arg523,int arg524,int arg525,int arg526,int arg527,int arg528,int arg529,int arg530,int arg531,int arg532,int arg533,int arg534,int arg535,int arg536,int arg537,int arg538,int arg539,int arg540,int arg541,int arg542,int arg543,int arg544,int arg545,int arg546,int arg547,int arg548,int arg549,int arg550,int arg551,int arg552,int arg553,int arg554,int arg555,int arg556,int arg557,int arg558,int arg559,int arg560,int arg561,int arg562,int arg563,int arg564,int arg565,int arg566,int arg567,int arg568,int arg569,int arg570,int arg571,int arg572,int arg573,int arg574,int arg575,int arg576,int arg577,int arg578,int arg579,int arg580,int arg581,int arg582,int arg583,int arg584,int arg585,int arg586,int arg587,int arg588,int arg589,int arg590,int arg591,int arg592,int arg593,int arg594,int arg595,int arg596,int arg597,int arg598,int arg599,int arg600,int arg601,int arg602,int arg603,int arg604,int arg605,int arg606,int arg607,int arg608,int arg609,int arg610,int arg611,int arg612,int arg613,int arg614,int arg615,int arg616,int arg617,int arg618,int arg619,int arg620,int arg621,int arg622,int arg623,int arg624,int arg625,int arg626,int arg627,int arg628,int arg629,int arg630,int arg631,int arg632,int arg633,int arg634,int arg635,int arg636,int arg637,int arg638,int arg639,int arg640,int arg641,int arg642,int arg643,int arg644,int arg645,int arg646,int arg647,int arg648,int arg649,int arg650,int arg651,int arg652,int arg653,int arg654,int arg655,int arg656,int arg657,int arg658,int arg659,int arg660,int arg661,int arg662,int arg663,int arg664,int arg665,int arg666,int arg667,int arg668,int arg669,int arg670,int arg671,int arg672,int arg673,int arg674,int arg675,int arg676,int arg677,int arg678,int arg679,int arg680,int arg681,int arg682,int arg683,int arg684,int arg685,int arg686,int arg687,int arg688,int arg689,int arg690,int arg691,int arg692,int arg693,int arg694,int arg695,int arg696,int arg697,int arg698,int arg699,int arg700,int arg701,int arg702,int arg703,int arg704,int arg705,int arg706,int arg707,int arg708,int arg709,int arg710,int arg711,int arg712,int arg713,int arg714,int arg715,int arg716,int arg717,int arg718,int arg719,int arg720,int arg721,int arg722,int arg723,int arg724,int arg725,int arg726,int arg727,int arg728,int arg729,int arg730,int arg731,int arg732,int arg733,int arg734,int arg735,int arg736,int arg737,int arg738,int arg739,int arg740,int arg741,int arg742,int arg743,int arg744,int arg745,int arg746,int arg747,int arg748,int arg749,int arg750,int arg751,int arg752,int arg753,int arg754,int arg755,int arg756,int arg757,int arg758,int arg759,int arg760,int arg761,int arg762,int arg763,int arg764,int arg765,int arg766,int arg767,int arg768,int arg769,int arg770,int arg771,int arg772,int arg773,int arg774,int arg775,int arg776,int arg777,int arg778,int arg779,int arg780,int arg781,int arg782,int arg783,int arg784,int arg785,int arg786,int arg787,int arg788,int arg789,int arg790,int arg791,int arg792,int arg793,int arg794,int arg795,int arg796,int arg797,int arg798,int arg799,int arg800,int arg801,int arg802,int arg803,int arg804,int arg805,int arg806,int arg807,int arg808,int arg809,int arg810,int arg811,int arg812,int arg813,int arg814,int arg815,int arg816,int arg817,int arg818,int arg819,int arg820,int arg821,int arg822,int arg823,int arg824,int arg825,int arg826,int arg827,int arg828,int arg829,int arg830,int arg831,int arg832,int arg833,int arg834,int arg835,int arg836,int arg837,int arg838,int arg839,int arg840,int arg841,int arg842,int arg843,int arg844,int arg845,int arg846,int arg847,int arg848,int arg849,int arg850,int arg851,int arg852,int arg853,int arg854,int arg855,int arg856,int arg857,int arg858,int arg859,int arg860,int arg861,int arg862,int arg863,int arg864,int arg865,int arg866,int arg867,int arg868,int arg869,int arg870,int arg871,int arg872,int arg873,int arg874,int arg875,int arg876,int arg877,int arg878,int arg879,int arg880,int arg881,int arg882,int arg883,int arg884,int arg885,int arg886,int arg887,int arg888,int arg889,int arg890,int arg891,int arg892,int arg893,int arg894,int arg895,int arg896,int arg897,int arg898,int arg899,int arg900,int arg901,int arg902,int arg903,int arg904,int arg905,int arg906,int arg907,int arg908,int arg909,int arg910,int arg911,int arg912,int arg913,int arg914,int arg915,int arg916,int arg917,int arg918,int arg919,int arg920,int arg921,int arg922,int arg923,int arg924,int arg925,int arg926,int arg927,int arg928,int arg929,int arg930,int arg931,int arg932,int arg933,int arg934,int arg935,int arg936,int arg937,int arg938,int arg939,int arg940,int arg941,int arg942,int arg943,int arg944,int arg945,int arg946,int arg947,int arg948,int arg949,int arg950,int arg951,int arg952,int arg953,int arg954,int arg955,int arg956,int arg957,int arg958,int arg959,int arg960,int arg961,int arg962,int arg963,int arg964,int arg965,int arg966,int arg967,int arg968,int arg969,int arg970,int arg971,int arg972,int arg973,int arg974,int arg975,int arg976,int arg977,int arg978,int arg979,int arg980,int arg981,int arg982,int arg983,int arg984,int arg985,int arg986,int arg987,int arg988,int arg989,int arg990,int arg991,int arg992,int arg993,int arg994,int arg995,int arg996,int arg997,int arg998,int arg999,int arg1000,int arg1001,int arg1002,int arg1003,int arg1004,int arg1005,int arg1006,int arg1007,int arg1008,int arg1009,int arg1010,int arg1011,int arg1012,int arg1013,int arg1014,int arg1015,int arg1016,int arg1017,int arg1018,int arg1019,int arg1020,int arg1021,int arg1022,int arg1023,int arg1024,int arg1025,int arg1026,int arg1027,int arg1028,int arg1029,int arg1030,int arg1031,int arg1032,int arg1033,int arg1034,int arg1035,int arg1036,int arg1037,int arg1038,int arg1039,int arg1040,int arg1041,int arg1042,int arg1043,int arg1044,int arg1045,int arg1046,int arg1047,int arg1048,int arg1049,int arg1050,int arg1051,int arg1052,int arg1053,int arg1054,int arg1055,int arg1056,int arg1057,int arg1058,int arg1059,int arg1060,int arg1061,int arg1062,int arg1063,int arg1064,int arg1065,int arg1066,int arg1067,int arg1068,int arg1069,int arg1070,int arg1071,int arg1072,int arg1073,int arg1074,int arg1075,int arg1076,int arg1077,int arg1078,int arg1079,int arg1080,int arg1081,int arg1082,int arg1083,int arg1084,int arg1085,int arg1086,int arg1087,int arg1088,int arg1089,int arg1090,int arg1091,int arg1092,int arg1093,int arg1094,int arg1095,int arg1096,int arg1097,int arg1098,int arg1099,int arg1100,int arg1101,int arg1102,int arg1103,int arg1104,int arg1105,int arg1106,int arg1107,int arg1108,int arg1109,int arg1110,int arg1111,int arg1112,int arg1113,int arg1114,int arg1115,int arg1116,int arg1117,int arg1118,int arg1119,int arg1120,int arg1121,int arg1122,int arg1123,int arg1124,int arg1125,int arg1126,int arg1127,int arg1128,int arg1129,int arg1130,int arg1131,int arg1132,int arg1133,int arg1134,int arg1135,int arg1136,int arg1137,int arg1138,int arg1139,int arg1140,int arg1141,int arg1142,int arg1143,int arg1144,int arg1145,int arg1146,int arg1147,int arg1148,int arg1149,int arg1150,int arg1151,int arg1152,int arg1153,int arg1154,int arg1155,int arg1156,int arg1157,int arg1158,int arg1159,int arg1160,int arg1161,int arg1162,int arg1163,int arg1164,int arg1165,int arg1166,int arg1167,int arg1168,int arg1169,int arg1170,int arg1171,int arg1172,int arg1173,int arg1174,int arg1175,int arg1176,int arg1177,int arg1178,int arg1179,int arg1180,int arg1181,int arg1182,int arg1183,int arg1184,int arg1185,int arg1186,int arg1187,int arg1188,int arg1189,int arg1190,int arg1191,int arg1192,int arg1193,int arg1194,int arg1195,int arg1196,int arg1197,int arg1198,int arg1199,int arg1200,int arg1201,int arg1202,int arg1203,int arg1204,int arg1205,int arg1206,int arg1207,int arg1208,int arg1209,int arg1210,int arg1211,int arg1212,int arg1213,int arg1214,int arg1215,int arg1216,int arg1217,int arg1218,int arg1219,int arg1220,int arg1221,int arg1222,int arg1223,int arg1224,int arg1225,int arg1226,int arg1227,int arg1228,int arg1229,int arg1230,int arg1231,int arg1232,int arg1233,int arg1234,int arg1235,int arg1236,int arg1237,int arg1238,int arg1239,int arg1240,int arg1241,int arg1242,int arg1243,int arg1244,int arg1245,int arg1246,int arg1247,int arg1248,int arg1249,int arg1250,int arg1251,int arg1252,int arg1253,int arg1254,int arg1255,int arg1256,int arg1257,int arg1258,int arg1259,int arg1260,int arg1261,int arg1262,int arg1263,int arg1264,int arg1265,int arg1266,int arg1267,int arg1268,int arg1269,int arg1270,int arg1271,int arg1272,int arg1273,int arg1274,int arg1275,int arg1276,int arg1277,int arg1278,int arg1279,int arg1280,int arg1281,int arg1282,int arg1283,int arg1284,int arg1285,int arg1286,int arg1287,int arg1288,int arg1289,int arg1290,int arg1291,int arg1292,int arg1293,int arg1294,int arg1295,int arg1296,int arg1297,int arg1298,int arg1299,int arg1300,int arg1301,int arg1302,int arg1303,int arg1304,int arg1305,int arg1306,int arg1307,int arg1308,int arg1309,int arg1310,int arg1311,int arg1312,int arg1313,int arg1314,int arg1315,int arg1316,int arg1317,int arg1318,int arg1319,int arg1320,int arg1321,int arg1322,int arg1323,int arg1324,int arg1325,int arg1326,int arg1327,int arg1328,int arg1329,int arg1330,int arg1331,int arg1332,int arg1333,int arg1334,int arg1335,int arg1336,int arg1337,int arg1338,int arg1339,int arg1340,int arg1341,int arg1342,int arg1343,int arg1344,int arg1345,int arg1346,int arg1347,int arg1348,int arg1349,int arg1350,int arg1351,int arg1352,int arg1353,int arg1354,int arg1355,int arg1356,int arg1357,int arg1358,int arg1359,int arg1360,int arg1361,int arg1362,int arg1363,int arg1364,int arg1365,int arg1366,int arg1367,int arg1368,int arg1369,int arg1370,int arg1371,int arg1372,int arg1373,int arg1374,int arg1375,int arg1376,int arg1377,int arg1378,int arg1379,int arg1380,int arg1381,int arg1382,int arg1383,int arg1384,int arg1385,int arg1386,int arg1387,int arg1388,int arg1389,int arg1390,int arg1391,int arg1392,int arg1393,int arg1394,int arg1395,int arg1396,int arg1397,int arg1398,int arg1399,int arg1400,int arg1401,int arg1402,int arg1403,int arg1404,int arg1405,int arg1406,int arg1407,int arg1408,int arg1409,int arg1410,int arg1411,int arg1412,int arg1413,int arg1414,int arg1415,int arg1416,int arg1417,int arg1418,int arg1419,int arg1420,int arg1421,int arg1422,int arg1423,int arg1424,int arg1425,int arg1426,int arg1427,int arg1428,int arg1429,int arg1430,int arg1431,int arg1432,int arg1433,int arg1434,int arg1435,int arg1436,int arg1437,int arg1438,int arg1439,int arg1440,int arg1441,int arg1442,int arg1443,int arg1444,int arg1445,int arg1446,int arg1447,int arg1448,int arg1449,int arg1450,int arg1451,int arg1452,int arg1453,int arg1454,int arg1455,int arg1456,int arg1457,int arg1458,int arg1459,int arg1460,int arg1461,int arg1462,int arg1463,int arg1464,int arg1465,int arg1466,int arg1467,int arg1468,int arg1469,int arg1470,int arg1471,int arg1472,int arg1473,int arg1474,int arg1475,int arg1476,int arg1477,int arg1478,int arg1479,int arg1480,int arg1481,int arg1482,int arg1483,int arg1484,int arg1485,int arg1486,int arg1487,int arg1488,int arg1489,int arg1490,int arg1491,int arg1492,int arg1493,int arg1494,int arg1495,int arg1496,int arg1497,int arg1498,int arg1499,int arg1500,int arg1501,int arg1502,int arg1503,int arg1504,int arg1505,int arg1506,int arg1507,int arg1508,int arg1509,int arg1510,int arg1511,int arg1512,int arg1513,int arg1514,int arg1515,int arg1516,int arg1517,int arg1518,int arg1519,int arg1520,int arg1521,int arg1522,int arg1523,int arg1524,int arg1525,int arg1526,int arg1527,int arg1528,int arg1529,int arg1530,int arg1531,int arg1532,int arg1533,int arg1534,int arg1535,int arg1536,int arg1537,int arg1538,int arg1539,int arg1540,int arg1541,int arg1542,int arg1543,int arg1544,int arg1545,int arg1546,int arg1547,int arg1548,int arg1549,int arg1550,int arg1551,int arg1552,int arg1553,int arg1554,int arg1555,int arg1556,int arg1557,int arg1558,int arg1559,int arg1560,int arg1561,int arg1562,int arg1563,int arg1564,int arg1565,int arg1566,int arg1567,int arg1568,int arg1569,int arg1570,int arg1571,int arg1572,int arg1573,int arg1574,int arg1575,int arg1576,int arg1577,int arg1578,int arg1579,int arg1580,int arg1581,int arg1582,int arg1583,int arg1584,int arg1585,int arg1586,int arg1587,int arg1588,int arg1589,int arg1590,int arg1591,int arg1592,int arg1593,int arg1594,int arg1595,int arg1596,int arg1597,int arg1598,int arg1599,int arg1600,int arg1601,int arg1602,int arg1603,int arg1604,int arg1605,int arg1606,int arg1607,int arg1608,int arg1609,int arg1610,int arg1611,int arg1612,int arg1613,int arg1614,int arg1615,int arg1616,int arg1617,int arg1618,int arg1619,int arg1620,int arg1621,int arg1622,int arg1623,int arg1624,int arg1625,int arg1626,int arg1627,int arg1628,int arg1629,int arg1630,int arg1631,int arg1632,int arg1633,int arg1634,int arg1635,int arg1636,int arg1637,int arg1638,int arg1639,int arg1640,int arg1641,int arg1642,int arg1643,int arg1644,int arg1645,int arg1646,int arg1647,int arg1648,int arg1649,int arg1650,int arg1651,int arg1652,int arg1653,int arg1654,int arg1655,int arg1656,int arg1657,int arg1658,int arg1659,int arg1660,int arg1661,int arg1662,int arg1663,int arg1664,int arg1665,int arg1666,int arg1667,int arg1668,int arg1669,int arg1670,int arg1671,int arg1672,int arg1673,int arg1674,int arg1675,int arg1676,int arg1677,int arg1678,int arg1679,int arg1680,int arg1681,int arg1682,int arg1683,int arg1684,int arg1685,int arg1686,int arg1687,int arg1688,int arg1689,int arg1690,int arg1691,int arg1692,int arg1693,int arg1694,int arg1695,int arg1696,int arg1697,int arg1698,int arg1699,int arg1700,int arg1701,int arg1702,int arg1703,int arg1704,int arg1705,int arg1706,int arg1707,int arg1708,int arg1709,int arg1710,int arg1711,int arg1712,int arg1713,int arg1714,int arg1715,int arg1716,int arg1717,int arg1718,int arg1719,int arg1720,int arg1721,int arg1722,int arg1723,int arg1724,int arg1725,int arg1726,int arg1727,int arg1728,int arg1729,int arg1730,int arg1731,int arg1732,int arg1733,int arg1734,int arg1735,int arg1736,int arg1737,int arg1738,int arg1739,int arg1740,int arg1741,int arg1742,int arg1743,int arg1744,int arg1745,int arg1746,int arg1747,int arg1748,int arg1749,int arg1750,int arg1751,int arg1752,int arg1753,int arg1754,int arg1755,int arg1756,int arg1757,int arg1758,int arg1759,int arg1760,int arg1761,int arg1762,int arg1763,int arg1764,int arg1765,int arg1766,int arg1767,int arg1768,int arg1769,int arg1770,int arg1771,int arg1772,int arg1773,int arg1774,int arg1775,int arg1776,int arg1777,int arg1778,int arg1779,int arg1780,int arg1781,int arg1782,int arg1783,int arg1784,int arg1785,int arg1786,int arg1787,int arg1788,int arg1789,int arg1790,int arg1791,int arg1792,int arg1793,int arg1794,int arg1795,int arg1796,int arg1797,int arg1798,int arg1799,int arg1800,int arg1801,int arg1802,int arg1803,int arg1804,int arg1805,int arg1806,int arg1807,int arg1808,int arg1809,int arg1810,int arg1811,int arg1812,int arg1813,int arg1814,int arg1815,int arg1816,int arg1817,int arg1818,int arg1819,int arg1820,int arg1821,int arg1822,int arg1823,int arg1824,int arg1825,int arg1826,int arg1827,int arg1828,int arg1829,int arg1830,int arg1831,int arg1832,int arg1833,int arg1834,int arg1835,int arg1836,int arg1837,int arg1838,int arg1839,int arg1840,int arg1841,int arg1842,int arg1843,int arg1844,int arg1845,int arg1846,int arg1847,int arg1848,int arg1849,int arg1850,int arg1851,int arg1852,int arg1853,int arg1854,int arg1855,int arg1856,int arg1857,int arg1858,int arg1859,int arg1860,int arg1861,int arg1862,int arg1863,int arg1864,int arg1865,int arg1866,int arg1867,int arg1868,int arg1869,int arg1870,int arg1871,int arg1872,int arg1873,int arg1874,int arg1875,int arg1876,int arg1877,int arg1878,int arg1879,int arg1880,int arg1881,int arg1882,int arg1883,int arg1884,int arg1885,int arg1886,int arg1887,int arg1888,int arg1889,int arg1890,int arg1891,int arg1892,int arg1893,int arg1894,int arg1895,int arg1896,int arg1897,int arg1898,int arg1899,int arg1900,int arg1901,int arg1902,int arg1903,int arg1904,int arg1905,int arg1906,int arg1907,int arg1908,int arg1909,int arg1910,int arg1911,int arg1912,int arg1913,int arg1914,int arg1915,int arg1916,int arg1917,int arg1918,int arg1919,int arg1920,int arg1921,int arg1922,int arg1923,int arg1924,int arg1925,int arg1926,int arg1927,int arg1928,int arg1929,int arg1930,int arg1931,int arg1932,int arg1933,int arg1934,int arg1935,int arg1936,int arg1937,int arg1938,int arg1939,int arg1940,int arg1941,int arg1942,int arg1943,int arg1944,int arg1945,int arg1946,int arg1947,int arg1948,int arg1949,int arg1950,int arg1951,int arg1952,int arg1953,int arg1954,int arg1955,int arg1956,int arg1957,int arg1958,int arg1959,int arg1960,int arg1961,int arg1962,int arg1963,int arg1964,int arg1965,int arg1966,int arg1967,int arg1968,int arg1969,int arg1970,int arg1971,int arg1972,int arg1973,int arg1974,int arg1975,int arg1976,int arg1977,int arg1978,int arg1979,int arg1980,int arg1981,int arg1982,int arg1983,int arg1984,int arg1985,int arg1986,int arg1987,int arg1988,int arg1989,int arg1990,int arg1991,int arg1992,int arg1993,int arg1994,int arg1995,int arg1996,int arg1997,int arg1998,int arg1999,int arg2000,int arg2001,int arg2002,int arg2003,int arg2004,int arg2005,int arg2006,int arg2007,int arg2008,int arg2009,int arg2010,int arg2011,int arg2012,int arg2013,int arg2014,int arg2015,int arg2016,int arg2017,int arg2018,int arg2019,int arg2020,int arg2021,int arg2022,int arg2023,int arg2024,int arg2025,int arg2026,int arg2027,int arg2028,int arg2029,int arg2030,int arg2031,int arg2032,int arg2033,int arg2034,int arg2035,int arg2036,int arg2037,int arg2038,int arg2039,int arg2040,int arg2041,int arg2042,int arg2043,int arg2044,int arg2045,int arg2046,int arg2047,int arg2048,int arg2049,int arg2050,int arg2051,int arg2052,int arg2053,int arg2054,int arg2055,int arg2056,int arg2057,int arg2058,int arg2059,int arg2060,int arg2061,int arg2062,int arg2063,int arg2064,int arg2065,int arg2066,int arg2067,int arg2068,int arg2069,int arg2070,int arg2071,int arg2072,int arg2073,int arg2074,int arg2075,int arg2076,int arg2077,int arg2078,int arg2079,int arg2080,int arg2081,int arg2082,int arg2083,int arg2084,int arg2085,int arg2086,int arg2087,int arg2088,int arg2089,int arg2090,int arg2091,int arg2092,int arg2093,int arg2094,int arg2095,int arg2096,int arg2097,int arg2098,int arg2099,int arg2100,int arg2101,int arg2102,int arg2103,int arg2104,int arg2105,int arg2106,int arg2107,int arg2108,int arg2109,int arg2110,int arg2111,int arg2112,int arg2113,int arg2114,int arg2115,int arg2116,int arg2117,int arg2118,int arg2119,int arg2120,int arg2121,int arg2122,int arg2123,int arg2124,int arg2125,int arg2126,int arg2127,int arg2128,int arg2129,int arg2130,int arg2131,int arg2132,int arg2133,int arg2134,int arg2135,int arg2136,int arg2137,int arg2138,int arg2139,int arg2140,int arg2141,int arg2142,int arg2143,int arg2144,int arg2145,int arg2146,int arg2147,int arg2148,int arg2149,int arg2150,int arg2151,int arg2152,int arg2153,int arg2154,int arg2155,int arg2156,int arg2157,int arg2158,int arg2159,int arg2160,int arg2161,int arg2162,int arg2163,int arg2164,int arg2165,int arg2166,int arg2167,int arg2168,int arg2169,int arg2170,int arg2171,int arg2172,int arg2173,int arg2174,int arg2175,int arg2176,int arg2177,int arg2178,int arg2179,int arg2180,int arg2181,int arg2182,int arg2183,int arg2184,int arg2185,int arg2186,int arg2187,int arg2188,int arg2189,int arg2190,int arg2191,int arg2192,int arg2193,int arg2194,int arg2195,int arg2196,int arg2197,int arg2198,int arg2199,int arg2200,int arg2201,int arg2202,int arg2203,int arg2204,int arg2205,int arg2206,int arg2207,int arg2208,int arg2209,int arg2210,int arg2211,int arg2212,int arg2213,int arg2214,int arg2215,int arg2216,int arg2217,int arg2218,int arg2219,int arg2220,int arg2221,int arg2222,int arg2223,int arg2224,int arg2225,int arg2226,int arg2227,int arg2228,int arg2229,int arg2230,int arg2231,int arg2232,int arg2233,int arg2234,int arg2235,int arg2236,int arg2237,int arg2238,int arg2239,int arg2240,int arg2241,int arg2242,int arg2243,int arg2244,int arg2245,int arg2246,int arg2247,int arg2248,int arg2249,int arg2250,int arg2251,int arg2252,int arg2253,int arg2254,int arg2255,int arg2256,int arg2257,int arg2258,int arg2259,int arg2260,int arg2261,int arg2262,int arg2263,int arg2264,int arg2265,int arg2266,int arg2267,int arg2268,int arg2269,int arg2270,int arg2271,int arg2272,int arg2273,int arg2274,int arg2275,int arg2276,int arg2277,int arg2278,int arg2279,int arg2280,int arg2281,int arg2282,int arg2283,int arg2284,int arg2285,int arg2286,int arg2287,int arg2288,int arg2289,int arg2290,int arg2291,int arg2292,int arg2293,int arg2294,int arg2295,int arg2296,int arg2297,int arg2298,int arg2299,int arg2300,int arg2301,int arg2302,int arg2303,int arg2304,int arg2305,int arg2306,int arg2307,int arg2308,int arg2309,int arg2310,int arg2311,int arg2312,int arg2313,int arg2314,int arg2315,int arg2316,int arg2317,int arg2318,int arg2319,int arg2320,int arg2321,int arg2322,int arg2323,int arg2324,int arg2325,int arg2326,int arg2327,int arg2328,int arg2329,int arg2330,int arg2331,int arg2332,int arg2333,int arg2334,int arg2335,int arg2336,int arg2337,int arg2338,int arg2339,int arg2340,int arg2341,int arg2342,int arg2343,int arg2344,int arg2345,int arg2346,int arg2347,int arg2348,int arg2349,int arg2350,int arg2351,int arg2352,int arg2353,int arg2354,int arg2355,int arg2356,int arg2357,int arg2358,int arg2359,int arg2360,int arg2361,int arg2362,int arg2363,int arg2364,int arg2365,int arg2366,int arg2367,int arg2368,int arg2369,int arg2370,int arg2371,int arg2372,int arg2373,int arg2374,int arg2375,int arg2376,int arg2377,int arg2378,int arg2379,int arg2380,int arg2381,int arg2382,int arg2383,int arg2384,int arg2385,int arg2386,int arg2387,int arg2388,int arg2389,int arg2390,int arg2391,int arg2392,int arg2393,int arg2394,int arg2395,int arg2396,int arg2397,int arg2398,int arg2399,int arg2400,int arg2401,int arg2402,int arg2403,int arg2404,int arg2405,int arg2406,int arg2407,int arg2408,int arg2409,int arg2410,int arg2411,int arg2412,int arg2413,int arg2414,int arg2415,int arg2416,int arg2417,int arg2418,int arg2419,int arg2420,int arg2421,int arg2422,int arg2423,int arg2424,int arg2425,int arg2426,int arg2427,int arg2428,int arg2429,int arg2430,int arg2431,int arg2432,int arg2433,int arg2434,int arg2435,int arg2436,int arg2437,int arg2438,int arg2439,int arg2440,int arg2441,int arg2442,int arg2443,int arg2444,int arg2445,int arg2446,int arg2447,int arg2448,int arg2449,int arg2450,int arg2451,int arg2452,int arg2453,int arg2454,int arg2455,int arg2456,int arg2457,int arg2458,int arg2459,int arg2460,int arg2461,int arg2462,int arg2463,int arg2464,int arg2465,int arg2466,int arg2467,int arg2468,int arg2469,int arg2470,int arg2471,int arg2472,int arg2473,int arg2474,int arg2475,int arg2476,int arg2477,int arg2478,int arg2479,int arg2480,int arg2481,int arg2482,int arg2483,int arg2484,int arg2485,int arg2486,int arg2487,int arg2488,int arg2489,int arg2490,int arg2491,int arg2492,int arg2493,int arg2494,int arg2495,int arg2496,int arg2497,int arg2498,int arg2499,int arg2500,int arg2501,int arg2502,int arg2503,int arg2504,int arg2505,int arg2506,int arg2507,int arg2508,int arg2509,int arg2510,int arg2511,int arg2512,int arg2513,int arg2514,int arg2515,int arg2516,int arg2517,int arg2518,int arg2519,int arg2520,int arg2521,int arg2522,int arg2523,int arg2524,int arg2525,int arg2526,int arg2527,int arg2528,int arg2529,int arg2530,int arg2531,int arg2532,int arg2533,int arg2534,int arg2535,int arg2536,int arg2537,int arg2538,int arg2539,int arg2540,int arg2541,int arg2542,int arg2543,int arg2544,int arg2545,int arg2546,int arg2547,int arg2548,int arg2549,int arg2550,int arg2551,int arg2552,int arg2553,int arg2554,int arg2555,int arg2556,int arg2557,int arg2558,int arg2559,int arg2560,int arg2561,int arg2562,int arg2563,int arg2564,int arg2565,int arg2566,int arg2567,int arg2568,int arg2569,int arg2570,int arg2571,int arg2572,int arg2573,int arg2574,int arg2575,int arg2576,int arg2577,int arg2578,int arg2579,int arg2580,int arg2581,int arg2582,int arg2583,int arg2584,int arg2585,int arg2586,int arg2587,int arg2588,int arg2589,int arg2590,int arg2591,int arg2592,int arg2593,int arg2594,int arg2595,int arg2596,int arg2597,int arg2598,int arg2599,int arg2600,int arg2601,int arg2602,int arg2603,int arg2604,int arg2605,int arg2606,int arg2607,int arg2608,int arg2609,int arg2610,int arg2611,int arg2612,int arg2613,int arg2614,int arg2615,int arg2616,int arg2617,int arg2618,int arg2619,int arg2620,int arg2621,int arg2622,int arg2623,int arg2624,int arg2625,int arg2626,int arg2627,int arg2628,int arg2629,int arg2630,int arg2631,int arg2632,int arg2633,int arg2634,int arg2635,int arg2636,int arg2637,int arg2638,int arg2639,int arg2640,int arg2641,int arg2642,int arg2643,int arg2644,int arg2645,int arg2646,int arg2647,int arg2648,int arg2649,int arg2650,int arg2651,int arg2652,int arg2653,int arg2654,int arg2655,int arg2656,int arg2657,int arg2658,int arg2659,int arg2660,int arg2661,int arg2662,int arg2663,int arg2664,int arg2665,int arg2666,int arg2667,int arg2668,int arg2669,int arg2670,int arg2671,int arg2672,int arg2673,int arg2674,int arg2675,int arg2676,int arg2677,int arg2678,int arg2679,int arg2680,int arg2681,int arg2682,int arg2683,int arg2684,int arg2685,int arg2686,int arg2687,int arg2688,int arg2689,int arg2690,int arg2691,int arg2692,int arg2693,int arg2694,int arg2695,int arg2696,int arg2697,int arg2698,int arg2699,int arg2700,int arg2701,int arg2702,int arg2703,int arg2704,int arg2705,int arg2706,int arg2707,int arg2708,int arg2709,int arg2710,int arg2711,int arg2712,int arg2713,int arg2714,int arg2715,int arg2716,int arg2717,int arg2718,int arg2719,int arg2720,int arg2721,int arg2722,int arg2723,int arg2724,int arg2725,int arg2726,int arg2727,int arg2728,int arg2729,int arg2730,int arg2731,int arg2732,int arg2733,int arg2734,int arg2735,int arg2736,int arg2737,int arg2738,int arg2739,int arg2740,int arg2741,int arg2742,int arg2743,int arg2744,int arg2745,int arg2746,int arg2747,int arg2748,int arg2749,int arg2750,int arg2751,int arg2752,int arg2753,int arg2754,int arg2755,int arg2756,int arg2757,int arg2758,int arg2759,int arg2760,int arg2761,int arg2762,int arg2763,int arg2764,int arg2765,int arg2766,int arg2767,int arg2768,int arg2769,int arg2770,int arg2771,int arg2772,int arg2773,int arg2774,int arg2775,int arg2776,int arg2777,int arg2778,int arg2779,int arg2780,int arg2781,int arg2782,int arg2783,int arg2784,int arg2785,int arg2786,int arg2787,int arg2788,int arg2789,int arg2790,int arg2791,int arg2792,int arg2793,int arg2794,int arg2795,int arg2796,int arg2797,int arg2798,int arg2799,int arg2800,int arg2801,int arg2802,int arg2803,int arg2804,int arg2805,int arg2806,int arg2807,int arg2808,int arg2809,int arg2810,int arg2811,int arg2812,int arg2813,int arg2814,int arg2815,int arg2816,int arg2817,int arg2818,int arg2819,int arg2820,int arg2821,int arg2822,int arg2823,int arg2824,int arg2825,int arg2826,int arg2827,int arg2828,int arg2829,int arg2830,int arg2831,int arg2832,int arg2833,int arg2834,int arg2835,int arg2836,int arg2837,int arg2838,int arg2839,int arg2840,int arg2841,int arg2842,int arg2843,int arg2844,int arg2845,int arg2846,int arg2847,int arg2848,int arg2849,int arg2850,int arg2851,int arg2852,int arg2853,int arg2854,int arg2855,int arg2856,int arg2857,int arg2858,int arg2859,int arg2860,int arg2861,int arg2862,int arg2863,int arg2864,int arg2865,int arg2866,int arg2867,int arg2868,int arg2869,int arg2870,int arg2871,int arg2872,int arg2873,int arg2874,int arg2875,int arg2876,int arg2877,int arg2878,int arg2879,int arg2880,int arg2881,int arg2882,int arg2883,int arg2884,int arg2885,int arg2886,int arg2887,int arg2888,int arg2889,int arg2890,int arg2891,int arg2892,int arg2893,int arg2894,int arg2895,int arg2896,int arg2897,int arg2898,int arg2899,int arg2900,int arg2901,int arg2902,int arg2903,int arg2904,int arg2905,int arg2906,int arg2907,int arg2908,int arg2909,int arg2910,int arg2911,int arg2912,int arg2913,int arg2914,int arg2915,int arg2916,int arg2917,int arg2918,int arg2919,int arg2920,int arg2921,int arg2922,int arg2923,int arg2924,int arg2925,int arg2926,int arg2927,int arg2928,int arg2929,int arg2930,int arg2931,int arg2932,int arg2933,int arg2934,int arg2935,int arg2936,int arg2937,int arg2938,int arg2939,int arg2940,int arg2941,int arg2942,int arg2943,int arg2944,int arg2945,int arg2946,int arg2947,int arg2948,int arg2949,int arg2950,int arg2951,int arg2952,int arg2953,int arg2954,int arg2955,int arg2956,int arg2957,int arg2958,int arg2959,int arg2960,int arg2961,int arg2962,int arg2963,int arg2964,int arg2965,int arg2966,int arg2967,int arg2968,int arg2969,int arg2970,int arg2971,int arg2972,int arg2973,int arg2974,int arg2975,int arg2976,int arg2977,int arg2978,int arg2979,int arg2980,int arg2981,int arg2982,int arg2983,int arg2984,int arg2985,int arg2986,int arg2987,int arg2988,int arg2989,int arg2990,int arg2991,int arg2992,int arg2993,int arg2994,int arg2995,int arg2996,int arg2997,int arg2998,int arg2999,int arg3000,int arg3001,int arg3002,int arg3003,int arg3004,int arg3005,int arg3006,int arg3007,int arg3008,int arg3009,int arg3010,int arg3011,int arg3012,int arg3013,int arg3014,int arg3015,int arg3016,int arg3017,int arg3018,int arg3019,int arg3020,int arg3021,int arg3022,int arg3023,int arg3024,int arg3025,int arg3026,int arg3027,int arg3028,int arg3029,int arg3030,int arg3031,int arg3032,int arg3033,int arg3034,int arg3035,int arg3036,int arg3037,int arg3038,int arg3039,int arg3040,int arg3041,int arg3042,int arg3043,int arg3044,int arg3045,int arg3046,int arg3047,int arg3048,int arg3049,int arg3050,int arg3051,int arg3052,int arg3053,int arg3054,int arg3055,int arg3056,int arg3057,int arg3058,int arg3059,int arg3060,int arg3061,int arg3062,int arg3063,int arg3064,int arg3065,int arg3066,int arg3067,int arg3068,int arg3069,int arg3070,int arg3071,int arg3072,int arg3073,int arg3074,int arg3075,int arg3076,int arg3077,int arg3078,int arg3079,int arg3080,int arg3081,int arg3082,int arg3083,int arg3084,int arg3085,int arg3086,int arg3087,int arg3088,int arg3089,int arg3090,int arg3091,int arg3092,int arg3093,int arg3094,int arg3095,int arg3096,int arg3097,int arg3098,int arg3099,int arg3100,int arg3101,int arg3102,int arg3103,int arg3104,int arg3105,int arg3106,int arg3107,int arg3108,int arg3109,int arg3110,int arg3111,int arg3112,int arg3113,int arg3114,int arg3115,int arg3116,int arg3117,int arg3118,int arg3119,int arg3120,int arg3121,int arg3122,int arg3123,int arg3124,int arg3125,int arg3126,int arg3127,int arg3128,int arg3129,int arg3130,int arg3131,int arg3132,int arg3133,int arg3134,int arg3135,int arg3136,int arg3137,int arg3138,int arg3139,int arg3140,int arg3141,int arg3142,int arg3143,int arg3144,int arg3145,int arg3146,int arg3147,int arg3148,int arg3149,int arg3150,int arg3151,int arg3152,int arg3153,int arg3154,int arg3155,int arg3156,int arg3157,int arg3158,int arg3159,int arg3160,int arg3161,int arg3162,int arg3163,int arg3164,int arg3165,int arg3166,int arg3167,int arg3168,int arg3169,int arg3170,int arg3171,int arg3172,int arg3173,int arg3174,int arg3175,int arg3176,int arg3177,int arg3178,int arg3179,int arg3180,int arg3181,int arg3182,int arg3183,int arg3184,int arg3185,int arg3186,int arg3187,int arg3188,int arg3189,int arg3190,int arg3191,int arg3192,int arg3193,int arg3194,int arg3195,int arg3196,int arg3197,int arg3198,int arg3199,int arg3200,int arg3201,int arg3202,int arg3203,int arg3204,int arg3205,int arg3206,int arg3207,int arg3208,int arg3209,int arg3210,int arg3211,int arg3212,int arg3213,int arg3214,int arg3215,int arg3216,int arg3217,int arg3218,int arg3219,int arg3220,int arg3221,int arg3222,int arg3223,int arg3224,int arg3225,int arg3226,int arg3227,int arg3228,int arg3229,int arg3230,int arg3231,int arg3232,int arg3233,int arg3234,int arg3235,int arg3236,int arg3237,int arg3238,int arg3239,int arg3240,int arg3241,int arg3242,int arg3243,int arg3244,int arg3245,int arg3246,int arg3247,int arg3248,int arg3249,int arg3250,int arg3251,int arg3252,int arg3253,int arg3254,int arg3255,int arg3256,int arg3257,int arg3258,int arg3259,int arg3260,int arg3261,int arg3262,int arg3263,int arg3264,int arg3265,int arg3266,int arg3267,int arg3268,int arg3269,int arg3270,int arg3271,int arg3272,int arg3273,int arg3274,int arg3275,int arg3276,int arg3277,int arg3278,int arg3279,int arg3280,int arg3281,int arg3282,int arg3283,int arg3284,int arg3285,int arg3286,int arg3287,int arg3288,int arg3289,int arg3290,int arg3291,int arg3292,int arg3293,int arg3294,int arg3295,int arg3296,int arg3297,int arg3298,int arg3299,int arg3300,int arg3301,int arg3302,int arg3303,int arg3304,int arg3305,int arg3306,int arg3307,int arg3308,int arg3309,int arg3310,int arg3311,int arg3312,int arg3313,int arg3314,int arg3315,int arg3316,int arg3317,int arg3318,int arg3319,int arg3320,int arg3321,int arg3322,int arg3323,int arg3324,int arg3325,int arg3326,int arg3327,int arg3328,int arg3329,int arg3330,int arg3331,int arg3332,int arg3333,int arg3334,int arg3335,int arg3336,int arg3337,int arg3338,int arg3339,int arg3340,int arg3341,int arg3342,int arg3343,int arg3344,int arg3345,int arg3346,int arg3347,int arg3348,int arg3349,int arg3350,int arg3351,int arg3352,int arg3353,int arg3354,int arg3355,int arg3356,int arg3357,int arg3358,int arg3359,int arg3360,int arg3361,int arg3362,int arg3363,int arg3364,int arg3365,int arg3366,int arg3367,int arg3368,int arg3369,int arg3370,int arg3371,int arg3372,int arg3373,int arg3374,int arg3375,int arg3376,int arg3377,int arg3378,int arg3379,int arg3380,int arg3381,int arg3382,int arg3383,int arg3384,int arg3385,int arg3386,int arg3387,int arg3388,int arg3389,int arg3390,int arg3391,int arg3392,int arg3393,int arg3394,int arg3395,int arg3396,int arg3397,int arg3398,int arg3399,int arg3400,int arg3401,int arg3402,int arg3403,int arg3404,int arg3405,int arg3406,int arg3407,int arg3408,int arg3409,int arg3410,int arg3411,int arg3412,int arg3413,int arg3414,int arg3415,int arg3416,int arg3417,int arg3418,int arg3419,int arg3420,int arg3421,int arg3422,int arg3423,int arg3424,int arg3425,int arg3426,int arg3427,int arg3428,int arg3429,int arg3430,int arg3431,int arg3432,int arg3433,int arg3434,int arg3435,int arg3436,int arg3437,int arg3438,int arg3439,int arg3440,int arg3441,int arg3442,int arg3443,int arg3444,int arg3445,int arg3446,int arg3447,int arg3448,int arg3449,int arg3450,int arg3451,int arg3452,int arg3453,int arg3454,int arg3455,int arg3456,int arg3457,int arg3458,int arg3459,int arg3460,int arg3461,int arg3462,int arg3463,int arg3464,int arg3465,int arg3466,int arg3467,int arg3468,int arg3469,int arg3470,int arg3471,int arg3472,int arg3473,int arg3474,int arg3475,int arg3476,int arg3477,int arg3478,int arg3479,int arg3480,int arg3481,int arg3482,int arg3483,int arg3484,int arg3485,int arg3486,int arg3487,int arg3488,int arg3489,int arg3490,int arg3491,int arg3492,int arg3493,int arg3494,int arg3495,int arg3496,int arg3497,int arg3498,int arg3499,int arg3500,int arg3501,int arg3502,int arg3503,int arg3504,int arg3505,int arg3506,int arg3507,int arg3508,int arg3509,int arg3510,int arg3511,int arg3512,int arg3513,int arg3514,int arg3515,int arg3516,int arg3517,int arg3518,int arg3519,int arg3520,int arg3521,int arg3522,int arg3523,int arg3524,int arg3525,int arg3526,int arg3527,int arg3528,int arg3529,int arg3530,int arg3531,int arg3532,int arg3533,int arg3534,int arg3535,int arg3536,int arg3537,int arg3538,int arg3539,int arg3540,int arg3541,int arg3542,int arg3543,int arg3544,int arg3545,int arg3546,int arg3547,int arg3548,int arg3549,int arg3550,int arg3551,int arg3552,int arg3553,int arg3554,int arg3555,int arg3556,int arg3557,int arg3558,int arg3559,int arg3560,int arg3561,int arg3562,int arg3563,int arg3564,int arg3565,int arg3566,int arg3567,int arg3568,int arg3569,int arg3570,int arg3571,int arg3572,int arg3573,int arg3574,int arg3575,int arg3576,int arg3577,int arg3578,int arg3579,int arg3580,int arg3581,int arg3582,int arg3583,int arg3584,int arg3585,int arg3586,int arg3587,int arg3588,int arg3589,int arg3590,int arg3591,int arg3592,int arg3593,int arg3594,int arg3595,int arg3596,int arg3597,int arg3598,int arg3599,int arg3600,int arg3601,int arg3602,int arg3603,int arg3604,int arg3605,int arg3606,int arg3607,int arg3608,int arg3609,int arg3610,int arg3611,int arg3612,int arg3613,int arg3614,int arg3615,int arg3616,int arg3617,int arg3618,int arg3619,int arg3620,int arg3621,int arg3622,int arg3623,int arg3624,int arg3625,int arg3626,int arg3627,int arg3628,int arg3629,int arg3630,int arg3631,int arg3632,int arg3633,int arg3634,int arg3635,int arg3636,int arg3637,int arg3638,int arg3639,int arg3640,int arg3641,int arg3642,int arg3643,int arg3644,int arg3645,int arg3646,int arg3647,int arg3648,int arg3649,int arg3650,int arg3651,int arg3652,int arg3653,int arg3654,int arg3655,int arg3656,int arg3657,int arg3658,int arg3659,int arg3660,int arg3661,int arg3662,int arg3663,int arg3664,int arg3665,int arg3666,int arg3667,int arg3668,int arg3669,int arg3670,int arg3671,int arg3672,int arg3673,int arg3674,int arg3675,int arg3676,int arg3677,int arg3678,int arg3679,int arg3680,int arg3681,int arg3682,int arg3683,int arg3684,int arg3685,int arg3686,int arg3687,int arg3688,int arg3689,int arg3690,int arg3691,int arg3692,int arg3693,int arg3694,int arg3695,int arg3696,int arg3697,int arg3698,int arg3699,int arg3700,int arg3701,int arg3702,int arg3703,int arg3704,int arg3705,int arg3706,int arg3707,int arg3708,int arg3709,int arg3710,int arg3711,int arg3712,int arg3713,int arg3714,int arg3715,int arg3716,int arg3717,int arg3718,int arg3719,int arg3720,int arg3721,int arg3722,int arg3723,int arg3724,int arg3725,int arg3726,int arg3727,int arg3728,int arg3729,int arg3730,int arg3731,int arg3732,int arg3733,int arg3734,int arg3735,int arg3736,int arg3737,int arg3738,int arg3739,int arg3740,int arg3741,int arg3742,int arg3743,int arg3744,int arg3745,int arg3746,int arg3747,int arg3748,int arg3749,int arg3750,int arg3751,int arg3752,int arg3753,int arg3754,int arg3755,int arg3756,int arg3757,int arg3758,int arg3759,int arg3760,int arg3761,int arg3762,int arg3763,int arg3764,int arg3765,int arg3766,int arg3767,int arg3768,int arg3769,int arg3770,int arg3771,int arg3772,int arg3773,int arg3774,int arg3775,int arg3776,int arg3777,int arg3778,int arg3779,int arg3780,int arg3781,int arg3782,int arg3783,int arg3784,int arg3785,int arg3786,int arg3787,int arg3788,int arg3789,int arg3790,int arg3791,int arg3792,int arg3793,int arg3794,int arg3795,int arg3796,int arg3797,int arg3798,int arg3799,int arg3800,int arg3801,int arg3802,int arg3803,int arg3804,int arg3805,int arg3806,int arg3807,int arg3808,int arg3809,int arg3810,int arg3811,int arg3812,int arg3813,int arg3814,int arg3815,int arg3816,int arg3817,int arg3818,int arg3819,int arg3820,int arg3821,int arg3822,int arg3823,int arg3824,int arg3825,int arg3826,int arg3827,int arg3828,int arg3829,int arg3830,int arg3831,int arg3832,int arg3833,int arg3834,int arg3835,int arg3836,int arg3837,int arg3838,int arg3839,int arg3840,int arg3841,int arg3842,int arg3843,int arg3844,int arg3845,int arg3846,int arg3847,int arg3848,int arg3849,int arg3850,int arg3851,int arg3852,int arg3853,int arg3854,int arg3855,int arg3856,int arg3857,int arg3858,int arg3859,int arg3860,int arg3861,int arg3862,int arg3863,int arg3864,int arg3865,int arg3866,int arg3867,int arg3868,int arg3869,int arg3870,int arg3871,int arg3872,int arg3873,int arg3874,int arg3875,int arg3876,int arg3877,int arg3878,int arg3879,int arg3880,int arg3881,int arg3882,int arg3883,int arg3884,int arg3885,int arg3886,int arg3887,int arg3888,int arg3889,int arg3890,int arg3891,int arg3892,int arg3893,int arg3894,int arg3895,int arg3896,int arg3897,int arg3898,int arg3899,int arg3900,int arg3901,int arg3902,int arg3903,int arg3904,int arg3905,int arg3906,int arg3907,int arg3908,int arg3909,int arg3910,int arg3911,int arg3912,int arg3913,int arg3914,int arg3915,int arg3916,int arg3917,int arg3918,int arg3919,int arg3920,int arg3921,int arg3922,int arg3923,int arg3924,int arg3925,int arg3926,int arg3927,int arg3928,int arg3929,int arg3930,int arg3931,int arg3932,int arg3933,int arg3934,int arg3935,int arg3936,int arg3937,int arg3938,int arg3939,int arg3940,int arg3941,int arg3942,int arg3943,int arg3944,int arg3945,int arg3946,int arg3947,int arg3948,int arg3949,int arg3950,int arg3951,int arg3952,int arg3953,int arg3954,int arg3955,int arg3956,int arg3957,int arg3958,int arg3959,int arg3960,int arg3961,int arg3962,int arg3963,int arg3964,int arg3965,int arg3966,int arg3967,int arg3968,int arg3969,int arg3970,int arg3971,int arg3972,int arg3973,int arg3974,int arg3975,int arg3976,int arg3977,int arg3978,int arg3979,int arg3980,int arg3981,int arg3982,int arg3983,int arg3984,int arg3985,int arg3986,int arg3987,int arg3988,int arg3989,int arg3990,int arg3991,int arg3992,int arg3993,int arg3994,int arg3995,int arg3996,int arg3997,int arg3998,int arg3999,int arg4000,int arg4001,int arg4002,int arg4003,int arg4004,int arg4005,int arg4006,int arg4007,int arg4008,int arg4009,int arg4010,int arg4011,int arg4012,int arg4013,int arg4014,int arg4015,int arg4016,int arg4017,int arg4018,int arg4019,int arg4020,int arg4021,int arg4022,int arg4023,int arg4024,int arg4025,int arg4026,int arg4027,int arg4028,int arg4029,int arg4030,int arg4031,int arg4032,int arg4033,int arg4034,int arg4035,int arg4036,int arg4037,int arg4038,int arg4039,int arg4040,int arg4041,int arg4042,int arg4043,int arg4044,int arg4045,int arg4046,int arg4047,int arg4048,int arg4049,int arg4050,int arg4051,int arg4052,int arg4053,int arg4054,int arg4055,int arg4056,int arg4057,int arg4058,int arg4059,int arg4060,int arg4061,int arg4062,int arg4063,int arg4064,int arg4065,int arg4066,int arg4067,int arg4068,int arg4069,int arg4070,int arg4071,int arg4072,int arg4073,int arg4074,int arg4075,int arg4076,int arg4077,int arg4078,int arg4079,int arg4080,int arg4081,int arg4082,int arg4083,int arg4084,int arg4085,int arg4086,int arg4087,int arg4088,int arg4089,int arg4090,int arg4091,int arg4092,int arg4093,int arg4094,int arg4095,int arg4096,int arg4097,int arg4098,int arg4099,int arg4100,int arg4101,int arg4102,int arg4103,int arg4104,int arg4105,int arg4106,int arg4107,int arg4108,int arg4109,int arg4110,int arg4111,int arg4112,int arg4113,int arg4114,int arg4115,int arg4116,int arg4117,int arg4118,int arg4119,int arg4120,int arg4121,int arg4122,int arg4123,int arg4124,int arg4125,int arg4126,int arg4127,int arg4128,int arg4129,int arg4130,int arg4131,int arg4132,int arg4133,int arg4134,int arg4135,int arg4136,int arg4137,int arg4138,int arg4139,int arg4140,int arg4141,int arg4142,int arg4143,int arg4144,int arg4145,int arg4146,int arg4147,int arg4148,int arg4149,int arg4150,int arg4151,int arg4152,int arg4153,int arg4154,int arg4155,int arg4156,int arg4157,int arg4158,int arg4159,int arg4160,int arg4161,int arg4162,int arg4163,int arg4164,int arg4165,int arg4166,int arg4167,int arg4168,int arg4169,int arg4170,int arg4171,int arg4172,int arg4173,int arg4174,int arg4175,int arg4176,int arg4177,int arg4178,int arg4179,int arg4180,int arg4181,int arg4182,int arg4183,int arg4184,int arg4185,int arg4186,int arg4187,int arg4188,int arg4189,int arg4190,int arg4191,int arg4192,int arg4193,int arg4194,int arg4195,int arg4196,int arg4197,int arg4198,int arg4199,int arg4200,int arg4201,int arg4202,int arg4203,int arg4204,int arg4205,int arg4206,int arg4207,int arg4208,int arg4209,int arg4210,int arg4211,int arg4212,int arg4213,int arg4214,int arg4215,int arg4216,int arg4217,int arg4218,int arg4219,int arg4220,int arg4221,int arg4222,int arg4223,int arg4224,int arg4225,int arg4226,int arg4227,int arg4228,int arg4229,int arg4230,int arg4231,int arg4232,int arg4233,int arg4234,int arg4235,int arg4236,int arg4237,int arg4238,int arg4239,int arg4240,int arg4241,int arg4242,int arg4243,int arg4244,int arg4245,int arg4246,int arg4247,int arg4248,int arg4249,int arg4250,int arg4251,int arg4252,int arg4253,int arg4254,int arg4255,int arg4256,int arg4257,int arg4258,int arg4259,int arg4260,int arg4261,int arg4262,int arg4263,int arg4264,int arg4265,int arg4266,int arg4267,int arg4268,int arg4269,int arg4270,int arg4271,int arg4272,int arg4273,int arg4274,int arg4275,int arg4276,int arg4277,int arg4278,int arg4279,int arg4280,int arg4281,int arg4282,int arg4283,int arg4284,int arg4285,int arg4286,int arg4287,int arg4288,int arg4289,int arg4290,int arg4291,int arg4292,int arg4293,int arg4294,int arg4295,int arg4296,int arg4297,int arg4298,int arg4299,int arg4300,int arg4301,int arg4302,int arg4303,int arg4304,int arg4305,int arg4306,int arg4307,int arg4308,int arg4309,int arg4310,int arg4311,int arg4312,int arg4313,int arg4314,int arg4315,int arg4316,int arg4317,int arg4318,int arg4319,int arg4320,int arg4321,int arg4322,int arg4323,int arg4324,int arg4325,int arg4326,int arg4327,int arg4328,int arg4329,int arg4330,int arg4331,int arg4332,int arg4333,int arg4334,int arg4335,int arg4336,int arg4337,int arg4338,int arg4339,int arg4340,int arg4341,int arg4342,int arg4343,int arg4344,int arg4345,int arg4346,int arg4347,int arg4348,int arg4349,int arg4350,int arg4351,int arg4352,int arg4353,int arg4354,int arg4355,int arg4356,int arg4357,int arg4358,int arg4359,int arg4360,int arg4361,int arg4362,int arg4363,int arg4364,int arg4365,int arg4366,int arg4367,int arg4368,int arg4369,int arg4370,int arg4371,int arg4372,int arg4373,int arg4374,int arg4375,int arg4376,int arg4377,int arg4378,int arg4379,int arg4380,int arg4381,int arg4382,int arg4383,int arg4384,int arg4385,int arg4386,int arg4387,int arg4388,int arg4389,int arg4390,int arg4391,int arg4392,int arg4393,int arg4394,int arg4395,int arg4396,int arg4397,int arg4398,int arg4399,int arg4400,int arg4401,int arg4402,int arg4403,int arg4404,int arg4405,int arg4406,int arg4407,int arg4408,int arg4409,int arg4410,int arg4411,int arg4412,int arg4413,int arg4414,int arg4415,int arg4416,int arg4417,int arg4418,int arg4419,int arg4420,int arg4421,int arg4422,int arg4423,int arg4424,int arg4425,int arg4426,int arg4427,int arg4428,int arg4429,int arg4430,int arg4431,int arg4432,int arg4433,int arg4434,int arg4435,int arg4436,int arg4437,int arg4438,int arg4439,int arg4440,int arg4441,int arg4442,int arg4443,int arg4444,int arg4445,int arg4446,int arg4447,int arg4448,int arg4449,int arg4450,int arg4451,int arg4452,int arg4453,int arg4454,int arg4455,int arg4456,int arg4457,int arg4458,int arg4459,int arg4460,int arg4461,int arg4462,int arg4463,int arg4464,int arg4465,int arg4466,int arg4467,int arg4468,int arg4469,int arg4470,int arg4471,int arg4472,int arg4473,int arg4474,int arg4475,int arg4476,int arg4477,int arg4478,int arg4479,int arg4480,int arg4481,int arg4482,int arg4483,int arg4484,int arg4485,int arg4486,int arg4487,int arg4488,int arg4489,int arg4490,int arg4491,int arg4492,int arg4493,int arg4494,int arg4495,int arg4496,int arg4497,int arg4498,int arg4499,int arg4500,int arg4501,int arg4502,int arg4503,int arg4504,int arg4505,int arg4506,int arg4507,int arg4508,int arg4509,int arg4510,int arg4511,int arg4512,int arg4513,int arg4514,int arg4515,int arg4516,int arg4517,int arg4518,int arg4519,int arg4520,int arg4521,int arg4522,int arg4523,int arg4524,int arg4525,int arg4526,int arg4527,int arg4528,int arg4529,int arg4530,int arg4531,int arg4532,int arg4533,int arg4534,int arg4535,int arg4536,int arg4537,int arg4538,int arg4539,int arg4540,int arg4541,int arg4542,int arg4543,int arg4544,int arg4545,int arg4546,int arg4547,int arg4548,int arg4549,int arg4550,int arg4551,int arg4552,int arg4553,int arg4554,int arg4555,int arg4556,int arg4557,int arg4558,int arg4559,int arg4560,int arg4561,int arg4562,int arg4563,int arg4564,int arg4565,int arg4566,int arg4567,int arg4568,int arg4569,int arg4570,int arg4571,int arg4572,int arg4573,int arg4574,int arg4575,int arg4576,int arg4577,int arg4578,int arg4579,int arg4580,int arg4581,int arg4582,int arg4583,int arg4584,int arg4585,int arg4586,int arg4587,int arg4588,int arg4589,int arg4590,int arg4591,int arg4592,int arg4593,int arg4594,int arg4595,int arg4596,int arg4597,int arg4598,int arg4599,int arg4600,int arg4601,int arg4602,int arg4603,int arg4604,int arg4605,int arg4606,int arg4607,int arg4608,int arg4609,int arg4610,int arg4611,int arg4612,int arg4613,int arg4614,int arg4615,int arg4616,int arg4617,int arg4618,int arg4619,int arg4620,int arg4621,int arg4622,int arg4623,int arg4624,int arg4625,int arg4626,int arg4627,int arg4628,int arg4629,int arg4630,int arg4631,int arg4632,int arg4633,int arg4634,int arg4635,int arg4636,int arg4637,int arg4638,int arg4639,int arg4640,int arg4641,int arg4642,int arg4643,int arg4644,int arg4645,int arg4646,int arg4647,int arg4648,int arg4649,int arg4650,int arg4651,int arg4652,int arg4653,int arg4654,int arg4655,int arg4656,int arg4657,int arg4658,int arg4659,int arg4660,int arg4661,int arg4662,int arg4663,int arg4664,int arg4665,int arg4666,int arg4667,int arg4668,int arg4669,int arg4670,int arg4671,int arg4672,int arg4673,int arg4674,int arg4675,int arg4676,int arg4677,int arg4678,int arg4679,int arg4680,int arg4681,int arg4682,int arg4683,int arg4684,int arg4685,int arg4686,int arg4687,int arg4688,int arg4689,int arg4690,int arg4691,int arg4692,int arg4693,int arg4694,int arg4695,int arg4696,int arg4697,int arg4698,int arg4699,int arg4700,int arg4701,int arg4702,int arg4703,int arg4704,int arg4705,int arg4706,int arg4707,int arg4708,int arg4709,int arg4710,int arg4711,int arg4712,int arg4713,int arg4714,int arg4715,int arg4716,int arg4717,int arg4718,int arg4719,int arg4720,int arg4721,int arg4722,int arg4723,int arg4724,int arg4725,int arg4726,int arg4727,int arg4728,int arg4729,int arg4730,int arg4731,int arg4732,int arg4733,int arg4734,int arg4735,int arg4736,int arg4737,int arg4738,int arg4739,int arg4740,int arg4741,int arg4742,int arg4743,int arg4744,int arg4745,int arg4746,int arg4747,int arg4748,int arg4749,int arg4750,int arg4751,int arg4752,int arg4753,int arg4754,int arg4755,int arg4756,int arg4757,int arg4758,int arg4759,int arg4760,int arg4761,int arg4762,int arg4763,int arg4764,int arg4765,int arg4766,int arg4767,int arg4768,int arg4769,int arg4770,int arg4771,int arg4772,int arg4773,int arg4774,int arg4775,int arg4776,int arg4777,int arg4778,int arg4779,int arg4780,int arg4781,int arg4782,int arg4783,int arg4784,int arg4785,int arg4786,int arg4787,int arg4788,int arg4789,int arg4790,int arg4791,int arg4792,int arg4793,int arg4794,int arg4795,int arg4796,int arg4797,int arg4798,int arg4799,int arg4800,int arg4801,int arg4802,int arg4803,int arg4804,int arg4805,int arg4806,int arg4807,int arg4808,int arg4809,int arg4810,int arg4811,int arg4812,int arg4813,int arg4814,int arg4815,int arg4816,int arg4817,int arg4818,int arg4819,int arg4820,int arg4821,int arg4822,int arg4823,int arg4824,int arg4825,int arg4826,int arg4827,int arg4828,int arg4829,int arg4830,int arg4831,int arg4832,int arg4833,int arg4834,int arg4835,int arg4836,int arg4837,int arg4838,int arg4839,int arg4840,int arg4841,int arg4842,int arg4843,int arg4844,int arg4845,int arg4846,int arg4847,int arg4848,int arg4849,int arg4850,int arg4851,int arg4852,int arg4853,int arg4854,int arg4855,int arg4856,int arg4857,int arg4858,int arg4859,int arg4860,int arg4861,int arg4862,int arg4863,int arg4864,int arg4865,int arg4866,int arg4867,int arg4868,int arg4869,int arg4870,int arg4871,int arg4872,int arg4873,int arg4874,int arg4875,int arg4876,int arg4877,int arg4878,int arg4879,int arg4880,int arg4881,int arg4882,int arg4883,int arg4884,int arg4885,int arg4886,int arg4887,int arg4888,int arg4889,int arg4890,int arg4891,int arg4892,int arg4893,int arg4894,int arg4895,int arg4896,int arg4897,int arg4898,int arg4899,int arg4900,int arg4901,int arg4902,int arg4903,int arg4904,int arg4905,int arg4906,int arg4907,int arg4908,int arg4909,int arg4910,int arg4911,int arg4912,int arg4913,int arg4914,int arg4915,int arg4916,int arg4917,int arg4918,int arg4919,int arg4920,int arg4921,int arg4922,int arg4923,int arg4924,int arg4925,int arg4926,int arg4927,int arg4928,int arg4929,int arg4930,int arg4931,int arg4932,int arg4933,int arg4934,int arg4935,int arg4936,int arg4937,int arg4938,int arg4939,int arg4940,int arg4941,int arg4942,int arg4943,int arg4944,int arg4945,int arg4946,int arg4947,int arg4948,int arg4949,int arg4950,int arg4951,int arg4952,int arg4953,int arg4954,int arg4955,int arg4956,int arg4957,int arg4958,int arg4959,int arg4960,int arg4961,int arg4962,int arg4963,int arg4964,int arg4965,int arg4966,int arg4967,int arg4968,int arg4969,int arg4970,int arg4971,int arg4972,int arg4973,int arg4974,int arg4975,int arg4976,int arg4977,int arg4978,int arg4979,int arg4980,int arg4981,int arg4982,int arg4983,int arg4984,int arg4985,int arg4986,int arg4987,int arg4988,int arg4989,int arg4990,int arg4991,int arg4992,int arg4993,int arg4994,int arg4995,int arg4996,int arg4997,int arg4998,int arg4999)); +static JSC_DECLARE_NOEXCEPT_JIT_OPERATION_WITHOUT_WTF_INTERNAL(functionWithHellaArguments3, int, (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11, int arg12, int arg13, int arg14, int arg15, int arg16, int arg17, int arg18, int arg19, int arg20, int arg21, int arg22, int arg23, int arg24, int arg25, int arg26, int arg27, int arg28, int arg29, int arg30, int arg31, int arg32, int arg33, int arg34, int arg35, int arg36, int arg37, int arg38, int arg39, int arg40, int arg41, int arg42, int arg43, int arg44, int arg45, int arg46, int arg47, int arg48, int arg49, int arg50, int arg51, int arg52, int arg53, int arg54, int arg55, int arg56, int arg57, int arg58, int arg59, int arg60, int arg61, int arg62, int arg63, int arg64, int arg65, int arg66, int arg67, int arg68, int arg69, int arg70, int arg71, int arg72, int arg73, int arg74, int arg75, int arg76, int arg77, int arg78, int arg79, int arg80, int arg81, int arg82, int arg83, int arg84, int arg85, int arg86, int arg87, int arg88, int arg89, int arg90, int arg91, int arg92, int arg93, int arg94, int arg95, int arg96, int arg97, int arg98, int arg99, int arg100, int arg101, int arg102, int arg103, int arg104, int arg105, int arg106, int arg107, int arg108, int arg109, int arg110, int arg111, int arg112, int arg113, int arg114, int arg115, int arg116, int arg117, int arg118, int arg119, int arg120, int arg121, int arg122, int arg123, int arg124, int arg125, int arg126, int arg127, int arg128, int arg129, int arg130, int arg131, int arg132, int arg133, int arg134, int arg135, int arg136, int arg137, int arg138, int arg139, int arg140, int arg141, int arg142, int arg143, int arg144, int arg145, int arg146, int arg147, int arg148, int arg149, int arg150, int arg151, int arg152, int arg153, int arg154, int arg155, int arg156, int arg157, int arg158, int arg159, int arg160, int arg161, int arg162, int arg163, int arg164, int arg165, int arg166, int arg167, int arg168, int arg169, int arg170, int arg171, int arg172, int arg173, int arg174, int arg175, int arg176, int arg177, int arg178, int arg179, int arg180, int arg181, int arg182, int arg183, int arg184, int arg185, int arg186, int arg187, int arg188, int arg189, int arg190, int arg191, int arg192, int arg193, int arg194, int arg195, int arg196, int arg197, int arg198, int arg199, int arg200, int arg201, int arg202, int arg203, int arg204, int arg205, int arg206, int arg207, int arg208, int arg209, int arg210, int arg211, int arg212, int arg213, int arg214, int arg215, int arg216, int arg217, int arg218, int arg219, int arg220, int arg221, int arg222, int arg223, int arg224, int arg225, int arg226, int arg227, int arg228, int arg229, int arg230, int arg231, int arg232, int arg233, int arg234, int arg235, int arg236, int arg237, int arg238, int arg239, int arg240, int arg241, int arg242, int arg243, int arg244, int arg245, int arg246, int arg247, int arg248, int arg249, int arg250, int arg251, int arg252, int arg253, int arg254, int arg255, int arg256, int arg257, int arg258, int arg259, int arg260, int arg261, int arg262, int arg263, int arg264, int arg265, int arg266, int arg267, int arg268, int arg269, int arg270, int arg271, int arg272, int arg273, int arg274, int arg275, int arg276, int arg277, int arg278, int arg279, int arg280, int arg281, int arg282, int arg283, int arg284, int arg285, int arg286, int arg287, int arg288, int arg289, int arg290, int arg291, int arg292, int arg293, int arg294, int arg295, int arg296, int arg297, int arg298, int arg299, int arg300, int arg301, int arg302, int arg303, int arg304, int arg305, int arg306, int arg307, int arg308, int arg309, int arg310, int arg311, int arg312, int arg313, int arg314, int arg315, int arg316, int arg317, int arg318, int arg319, int arg320, int arg321, int arg322, int arg323, int arg324, int arg325, int arg326, int arg327, int arg328, int arg329, int arg330, int arg331, int arg332, int arg333, int arg334, int arg335, int arg336, int arg337, int arg338, int arg339, int arg340, int arg341, int arg342, int arg343, int arg344, int arg345, int arg346, int arg347, int arg348, int arg349, int arg350, int arg351, int arg352, int arg353, int arg354, int arg355, int arg356, int arg357, int arg358, int arg359, int arg360, int arg361, int arg362, int arg363, int arg364, int arg365, int arg366, int arg367, int arg368, int arg369, int arg370, int arg371, int arg372, int arg373, int arg374, int arg375, int arg376, int arg377, int arg378, int arg379, int arg380, int arg381, int arg382, int arg383, int arg384, int arg385, int arg386, int arg387, int arg388, int arg389, int arg390, int arg391, int arg392, int arg393, int arg394, int arg395, int arg396, int arg397, int arg398, int arg399, int arg400, int arg401, int arg402, int arg403, int arg404, int arg405, int arg406, int arg407, int arg408, int arg409, int arg410, int arg411, int arg412, int arg413, int arg414, int arg415, int arg416, int arg417, int arg418, int arg419, int arg420, int arg421, int arg422, int arg423, int arg424, int arg425, int arg426, int arg427, int arg428, int arg429, int arg430, int arg431, int arg432, int arg433, int arg434, int arg435, int arg436, int arg437, int arg438, int arg439, int arg440, int arg441, int arg442, int arg443, int arg444, int arg445, int arg446, int arg447, int arg448, int arg449, int arg450, int arg451, int arg452, int arg453, int arg454, int arg455, int arg456, int arg457, int arg458, int arg459, int arg460, int arg461, int arg462, int arg463, int arg464, int arg465, int arg466, int arg467, int arg468, int arg469, int arg470, int arg471, int arg472, int arg473, int arg474, int arg475, int arg476, int arg477, int arg478, int arg479, int arg480, int arg481, int arg482, int arg483, int arg484, int arg485, int arg486, int arg487, int arg488, int arg489, int arg490, int arg491, int arg492, int arg493, int arg494, int arg495, int arg496, int arg497, int arg498, int arg499, int arg500, int arg501, int arg502, int arg503, int arg504, int arg505, int arg506, int arg507, int arg508, int arg509, int arg510, int arg511, int arg512, int arg513, int arg514, int arg515, int arg516, int arg517, int arg518, int arg519, int arg520, int arg521, int arg522, int arg523, int arg524, int arg525, int arg526, int arg527, int arg528, int arg529, int arg530, int arg531, int arg532, int arg533, int arg534, int arg535, int arg536, int arg537, int arg538, int arg539, int arg540, int arg541, int arg542, int arg543, int arg544, int arg545, int arg546, int arg547, int arg548, int arg549, int arg550, int arg551, int arg552, int arg553, int arg554, int arg555, int arg556, int arg557, int arg558, int arg559, int arg560, int arg561, int arg562, int arg563, int arg564, int arg565, int arg566, int arg567, int arg568, int arg569, int arg570, int arg571, int arg572, int arg573, int arg574, int arg575, int arg576, int arg577, int arg578, int arg579, int arg580, int arg581, int arg582, int arg583, int arg584, int arg585, int arg586, int arg587, int arg588, int arg589, int arg590, int arg591, int arg592, int arg593, int arg594, int arg595, int arg596, int arg597, int arg598, int arg599, int arg600, int arg601, int arg602, int arg603, int arg604, int arg605, int arg606, int arg607, int arg608, int arg609, int arg610, int arg611, int arg612, int arg613, int arg614, int arg615, int arg616, int arg617, int arg618, int arg619, int arg620, int arg621, int arg622, int arg623, int arg624, int arg625, int arg626, int arg627, int arg628, int arg629, int arg630, int arg631, int arg632, int arg633, int arg634, int arg635, int arg636, int arg637, int arg638, int arg639, int arg640, int arg641, int arg642, int arg643, int arg644, int arg645, int arg646, int arg647, int arg648, int arg649, int arg650, int arg651, int arg652, int arg653, int arg654, int arg655, int arg656, int arg657, int arg658, int arg659, int arg660, int arg661, int arg662, int arg663, int arg664, int arg665, int arg666, int arg667, int arg668, int arg669, int arg670, int arg671, int arg672, int arg673, int arg674, int arg675, int arg676, int arg677, int arg678, int arg679, int arg680, int arg681, int arg682, int arg683, int arg684, int arg685, int arg686, int arg687, int arg688, int arg689, int arg690, int arg691, int arg692, int arg693, int arg694, int arg695, int arg696, int arg697, int arg698, int arg699, int arg700, int arg701, int arg702, int arg703, int arg704, int arg705, int arg706, int arg707, int arg708, int arg709, int arg710, int arg711, int arg712, int arg713, int arg714, int arg715, int arg716, int arg717, int arg718, int arg719, int arg720, int arg721, int arg722, int arg723, int arg724, int arg725, int arg726, int arg727, int arg728, int arg729, int arg730, int arg731, int arg732, int arg733, int arg734, int arg735, int arg736, int arg737, int arg738, int arg739, int arg740, int arg741, int arg742, int arg743, int arg744, int arg745, int arg746, int arg747, int arg748, int arg749, int arg750, int arg751, int arg752, int arg753, int arg754, int arg755, int arg756, int arg757, int arg758, int arg759, int arg760, int arg761, int arg762, int arg763, int arg764, int arg765, int arg766, int arg767, int arg768, int arg769, int arg770, int arg771, int arg772, int arg773, int arg774, int arg775, int arg776, int arg777, int arg778, int arg779, int arg780, int arg781, int arg782, int arg783, int arg784, int arg785, int arg786, int arg787, int arg788, int arg789, int arg790, int arg791, int arg792, int arg793, int arg794, int arg795, int arg796, int arg797, int arg798, int arg799, int arg800, int arg801, int arg802, int arg803, int arg804, int arg805, int arg806, int arg807, int arg808, int arg809, int arg810, int arg811, int arg812, int arg813, int arg814, int arg815, int arg816, int arg817, int arg818, int arg819, int arg820, int arg821, int arg822, int arg823, int arg824, int arg825, int arg826, int arg827, int arg828, int arg829, int arg830, int arg831, int arg832, int arg833, int arg834, int arg835, int arg836, int arg837, int arg838, int arg839, int arg840, int arg841, int arg842, int arg843, int arg844, int arg845, int arg846, int arg847, int arg848, int arg849, int arg850, int arg851, int arg852, int arg853, int arg854, int arg855, int arg856, int arg857, int arg858, int arg859, int arg860, int arg861, int arg862, int arg863, int arg864, int arg865, int arg866, int arg867, int arg868, int arg869, int arg870, int arg871, int arg872, int arg873, int arg874, int arg875, int arg876, int arg877, int arg878, int arg879, int arg880, int arg881, int arg882, int arg883, int arg884, int arg885, int arg886, int arg887, int arg888, int arg889, int arg890, int arg891, int arg892, int arg893, int arg894, int arg895, int arg896, int arg897, int arg898, int arg899, int arg900, int arg901, int arg902, int arg903, int arg904, int arg905, int arg906, int arg907, int arg908, int arg909, int arg910, int arg911, int arg912, int arg913, int arg914, int arg915, int arg916, int arg917, int arg918, int arg919, int arg920, int arg921, int arg922, int arg923, int arg924, int arg925, int arg926, int arg927, int arg928, int arg929, int arg930, int arg931, int arg932, int arg933, int arg934, int arg935, int arg936, int arg937, int arg938, int arg939, int arg940, int arg941, int arg942, int arg943, int arg944, int arg945, int arg946, int arg947, int arg948, int arg949, int arg950, int arg951, int arg952, int arg953, int arg954, int arg955, int arg956, int arg957, int arg958, int arg959, int arg960, int arg961, int arg962, int arg963, int arg964, int arg965, int arg966, int arg967, int arg968, int arg969, int arg970, int arg971, int arg972, int arg973, int arg974, int arg975, int arg976, int arg977, int arg978, int arg979, int arg980, int arg981, int arg982, int arg983, int arg984, int arg985, int arg986, int arg987, int arg988, int arg989, int arg990, int arg991, int arg992, int arg993, int arg994, int arg995, int arg996, int arg997, int arg998, int arg999, int arg1000, int arg1001, int arg1002, int arg1003, int arg1004, int arg1005, int arg1006, int arg1007, int arg1008, int arg1009, int arg1010, int arg1011, int arg1012, int arg1013, int arg1014, int arg1015, int arg1016, int arg1017, int arg1018, int arg1019, int arg1020, int arg1021, int arg1022, int arg1023, int arg1024, int arg1025, int arg1026, int arg1027, int arg1028, int arg1029, int arg1030, int arg1031, int arg1032, int arg1033, int arg1034, int arg1035, int arg1036, int arg1037, int arg1038, int arg1039, int arg1040, int arg1041, int arg1042, int arg1043, int arg1044, int arg1045, int arg1046, int arg1047, int arg1048, int arg1049, int arg1050, int arg1051, int arg1052, int arg1053, int arg1054, int arg1055, int arg1056, int arg1057, int arg1058, int arg1059, int arg1060, int arg1061, int arg1062, int arg1063, int arg1064, int arg1065, int arg1066, int arg1067, int arg1068, int arg1069, int arg1070, int arg1071, int arg1072, int arg1073, int arg1074, int arg1075, int arg1076, int arg1077, int arg1078, int arg1079, int arg1080, int arg1081, int arg1082, int arg1083, int arg1084, int arg1085, int arg1086, int arg1087, int arg1088, int arg1089, int arg1090, int arg1091, int arg1092, int arg1093, int arg1094, int arg1095, int arg1096, int arg1097, int arg1098, int arg1099, int arg1100, int arg1101, int arg1102, int arg1103, int arg1104, int arg1105, int arg1106, int arg1107, int arg1108, int arg1109, int arg1110, int arg1111, int arg1112, int arg1113, int arg1114, int arg1115, int arg1116, int arg1117, int arg1118, int arg1119, int arg1120, int arg1121, int arg1122, int arg1123, int arg1124, int arg1125, int arg1126, int arg1127, int arg1128, int arg1129, int arg1130, int arg1131, int arg1132, int arg1133, int arg1134, int arg1135, int arg1136, int arg1137, int arg1138, int arg1139, int arg1140, int arg1141, int arg1142, int arg1143, int arg1144, int arg1145, int arg1146, int arg1147, int arg1148, int arg1149, int arg1150, int arg1151, int arg1152, int arg1153, int arg1154, int arg1155, int arg1156, int arg1157, int arg1158, int arg1159, int arg1160, int arg1161, int arg1162, int arg1163, int arg1164, int arg1165, int arg1166, int arg1167, int arg1168, int arg1169, int arg1170, int arg1171, int arg1172, int arg1173, int arg1174, int arg1175, int arg1176, int arg1177, int arg1178, int arg1179, int arg1180, int arg1181, int arg1182, int arg1183, int arg1184, int arg1185, int arg1186, int arg1187, int arg1188, int arg1189, int arg1190, int arg1191, int arg1192, int arg1193, int arg1194, int arg1195, int arg1196, int arg1197, int arg1198, int arg1199, int arg1200, int arg1201, int arg1202, int arg1203, int arg1204, int arg1205, int arg1206, int arg1207, int arg1208, int arg1209, int arg1210, int arg1211, int arg1212, int arg1213, int arg1214, int arg1215, int arg1216, int arg1217, int arg1218, int arg1219, int arg1220, int arg1221, int arg1222, int arg1223, int arg1224, int arg1225, int arg1226, int arg1227, int arg1228, int arg1229, int arg1230, int arg1231, int arg1232, int arg1233, int arg1234, int arg1235, int arg1236, int arg1237, int arg1238, int arg1239, int arg1240, int arg1241, int arg1242, int arg1243, int arg1244, int arg1245, int arg1246, int arg1247, int arg1248, int arg1249, int arg1250, int arg1251, int arg1252, int arg1253, int arg1254, int arg1255, int arg1256, int arg1257, int arg1258, int arg1259, int arg1260, int arg1261, int arg1262, int arg1263, int arg1264, int arg1265, int arg1266, int arg1267, int arg1268, int arg1269, int arg1270, int arg1271, int arg1272, int arg1273, int arg1274, int arg1275, int arg1276, int arg1277, int arg1278, int arg1279, int arg1280, int arg1281, int arg1282, int arg1283, int arg1284, int arg1285, int arg1286, int arg1287, int arg1288, int arg1289, int arg1290, int arg1291, int arg1292, int arg1293, int arg1294, int arg1295, int arg1296, int arg1297, int arg1298, int arg1299, int arg1300, int arg1301, int arg1302, int arg1303, int arg1304, int arg1305, int arg1306, int arg1307, int arg1308, int arg1309, int arg1310, int arg1311, int arg1312, int arg1313, int arg1314, int arg1315, int arg1316, int arg1317, int arg1318, int arg1319, int arg1320, int arg1321, int arg1322, int arg1323, int arg1324, int arg1325, int arg1326, int arg1327, int arg1328, int arg1329, int arg1330, int arg1331, int arg1332, int arg1333, int arg1334, int arg1335, int arg1336, int arg1337, int arg1338, int arg1339, int arg1340, int arg1341, int arg1342, int arg1343, int arg1344, int arg1345, int arg1346, int arg1347, int arg1348, int arg1349, int arg1350, int arg1351, int arg1352, int arg1353, int arg1354, int arg1355, int arg1356, int arg1357, int arg1358, int arg1359, int arg1360, int arg1361, int arg1362, int arg1363, int arg1364, int arg1365, int arg1366, int arg1367, int arg1368, int arg1369, int arg1370, int arg1371, int arg1372, int arg1373, int arg1374, int arg1375, int arg1376, int arg1377, int arg1378, int arg1379, int arg1380, int arg1381, int arg1382, int arg1383, int arg1384, int arg1385, int arg1386, int arg1387, int arg1388, int arg1389, int arg1390, int arg1391, int arg1392, int arg1393, int arg1394, int arg1395, int arg1396, int arg1397, int arg1398, int arg1399, int arg1400, int arg1401, int arg1402, int arg1403, int arg1404, int arg1405, int arg1406, int arg1407, int arg1408, int arg1409, int arg1410, int arg1411, int arg1412, int arg1413, int arg1414, int arg1415, int arg1416, int arg1417, int arg1418, int arg1419, int arg1420, int arg1421, int arg1422, int arg1423, int arg1424, int arg1425, int arg1426, int arg1427, int arg1428, int arg1429, int arg1430, int arg1431, int arg1432, int arg1433, int arg1434, int arg1435, int arg1436, int arg1437, int arg1438, int arg1439, int arg1440, int arg1441, int arg1442, int arg1443, int arg1444, int arg1445, int arg1446, int arg1447, int arg1448, int arg1449, int arg1450, int arg1451, int arg1452, int arg1453, int arg1454, int arg1455, int arg1456, int arg1457, int arg1458, int arg1459, int arg1460, int arg1461, int arg1462, int arg1463, int arg1464, int arg1465, int arg1466, int arg1467, int arg1468, int arg1469, int arg1470, int arg1471, int arg1472, int arg1473, int arg1474, int arg1475, int arg1476, int arg1477, int arg1478, int arg1479, int arg1480, int arg1481, int arg1482, int arg1483, int arg1484, int arg1485, int arg1486, int arg1487, int arg1488, int arg1489, int arg1490, int arg1491, int arg1492, int arg1493, int arg1494, int arg1495, int arg1496, int arg1497, int arg1498, int arg1499, int arg1500, int arg1501, int arg1502, int arg1503, int arg1504, int arg1505, int arg1506, int arg1507, int arg1508, int arg1509, int arg1510, int arg1511, int arg1512, int arg1513, int arg1514, int arg1515, int arg1516, int arg1517, int arg1518, int arg1519, int arg1520, int arg1521, int arg1522, int arg1523, int arg1524, int arg1525, int arg1526, int arg1527, int arg1528, int arg1529, int arg1530, int arg1531, int arg1532, int arg1533, int arg1534, int arg1535, int arg1536, int arg1537, int arg1538, int arg1539, int arg1540, int arg1541, int arg1542, int arg1543, int arg1544, int arg1545, int arg1546, int arg1547, int arg1548, int arg1549, int arg1550, int arg1551, int arg1552, int arg1553, int arg1554, int arg1555, int arg1556, int arg1557, int arg1558, int arg1559, int arg1560, int arg1561, int arg1562, int arg1563, int arg1564, int arg1565, int arg1566, int arg1567, int arg1568, int arg1569, int arg1570, int arg1571, int arg1572, int arg1573, int arg1574, int arg1575, int arg1576, int arg1577, int arg1578, int arg1579, int arg1580, int arg1581, int arg1582, int arg1583, int arg1584, int arg1585, int arg1586, int arg1587, int arg1588, int arg1589, int arg1590, int arg1591, int arg1592, int arg1593, int arg1594, int arg1595, int arg1596, int arg1597, int arg1598, int arg1599, int arg1600, int arg1601, int arg1602, int arg1603, int arg1604, int arg1605, int arg1606, int arg1607, int arg1608, int arg1609, int arg1610, int arg1611, int arg1612, int arg1613, int arg1614, int arg1615, int arg1616, int arg1617, int arg1618, int arg1619, int arg1620, int arg1621, int arg1622, int arg1623, int arg1624, int arg1625, int arg1626, int arg1627, int arg1628, int arg1629, int arg1630, int arg1631, int arg1632, int arg1633, int arg1634, int arg1635, int arg1636, int arg1637, int arg1638, int arg1639, int arg1640, int arg1641, int arg1642, int arg1643, int arg1644, int arg1645, int arg1646, int arg1647, int arg1648, int arg1649, int arg1650, int arg1651, int arg1652, int arg1653, int arg1654, int arg1655, int arg1656, int arg1657, int arg1658, int arg1659, int arg1660, int arg1661, int arg1662, int arg1663, int arg1664, int arg1665, int arg1666, int arg1667, int arg1668, int arg1669, int arg1670, int arg1671, int arg1672, int arg1673, int arg1674, int arg1675, int arg1676, int arg1677, int arg1678, int arg1679, int arg1680, int arg1681, int arg1682, int arg1683, int arg1684, int arg1685, int arg1686, int arg1687, int arg1688, int arg1689, int arg1690, int arg1691, int arg1692, int arg1693, int arg1694, int arg1695, int arg1696, int arg1697, int arg1698, int arg1699, int arg1700, int arg1701, int arg1702, int arg1703, int arg1704, int arg1705, int arg1706, int arg1707, int arg1708, int arg1709, int arg1710, int arg1711, int arg1712, int arg1713, int arg1714, int arg1715, int arg1716, int arg1717, int arg1718, int arg1719, int arg1720, int arg1721, int arg1722, int arg1723, int arg1724, int arg1725, int arg1726, int arg1727, int arg1728, int arg1729, int arg1730, int arg1731, int arg1732, int arg1733, int arg1734, int arg1735, int arg1736, int arg1737, int arg1738, int arg1739, int arg1740, int arg1741, int arg1742, int arg1743, int arg1744, int arg1745, int arg1746, int arg1747, int arg1748, int arg1749, int arg1750, int arg1751, int arg1752, int arg1753, int arg1754, int arg1755, int arg1756, int arg1757, int arg1758, int arg1759, int arg1760, int arg1761, int arg1762, int arg1763, int arg1764, int arg1765, int arg1766, int arg1767, int arg1768, int arg1769, int arg1770, int arg1771, int arg1772, int arg1773, int arg1774, int arg1775, int arg1776, int arg1777, int arg1778, int arg1779, int arg1780, int arg1781, int arg1782, int arg1783, int arg1784, int arg1785, int arg1786, int arg1787, int arg1788, int arg1789, int arg1790, int arg1791, int arg1792, int arg1793, int arg1794, int arg1795, int arg1796, int arg1797, int arg1798, int arg1799, int arg1800, int arg1801, int arg1802, int arg1803, int arg1804, int arg1805, int arg1806, int arg1807, int arg1808, int arg1809, int arg1810, int arg1811, int arg1812, int arg1813, int arg1814, int arg1815, int arg1816, int arg1817, int arg1818, int arg1819, int arg1820, int arg1821, int arg1822, int arg1823, int arg1824, int arg1825, int arg1826, int arg1827, int arg1828, int arg1829, int arg1830, int arg1831, int arg1832, int arg1833, int arg1834, int arg1835, int arg1836, int arg1837, int arg1838, int arg1839, int arg1840, int arg1841, int arg1842, int arg1843, int arg1844, int arg1845, int arg1846, int arg1847, int arg1848, int arg1849, int arg1850, int arg1851, int arg1852, int arg1853, int arg1854, int arg1855, int arg1856, int arg1857, int arg1858, int arg1859, int arg1860, int arg1861, int arg1862, int arg1863, int arg1864, int arg1865, int arg1866, int arg1867, int arg1868, int arg1869, int arg1870, int arg1871, int arg1872, int arg1873, int arg1874, int arg1875, int arg1876, int arg1877, int arg1878, int arg1879, int arg1880, int arg1881, int arg1882, int arg1883, int arg1884, int arg1885, int arg1886, int arg1887, int arg1888, int arg1889, int arg1890, int arg1891, int arg1892, int arg1893, int arg1894, int arg1895, int arg1896, int arg1897, int arg1898, int arg1899, int arg1900, int arg1901, int arg1902, int arg1903, int arg1904, int arg1905, int arg1906, int arg1907, int arg1908, int arg1909, int arg1910, int arg1911, int arg1912, int arg1913, int arg1914, int arg1915, int arg1916, int arg1917, int arg1918, int arg1919, int arg1920, int arg1921, int arg1922, int arg1923, int arg1924, int arg1925, int arg1926, int arg1927, int arg1928, int arg1929, int arg1930, int arg1931, int arg1932, int arg1933, int arg1934, int arg1935, int arg1936, int arg1937, int arg1938, int arg1939, int arg1940, int arg1941, int arg1942, int arg1943, int arg1944, int arg1945, int arg1946, int arg1947, int arg1948, int arg1949, int arg1950, int arg1951, int arg1952, int arg1953, int arg1954, int arg1955, int arg1956, int arg1957, int arg1958, int arg1959, int arg1960, int arg1961, int arg1962, int arg1963, int arg1964, int arg1965, int arg1966, int arg1967, int arg1968, int arg1969, int arg1970, int arg1971, int arg1972, int arg1973, int arg1974, int arg1975, int arg1976, int arg1977, int arg1978, int arg1979, int arg1980, int arg1981, int arg1982, int arg1983, int arg1984, int arg1985, int arg1986, int arg1987, int arg1988, int arg1989, int arg1990, int arg1991, int arg1992, int arg1993, int arg1994, int arg1995, int arg1996, int arg1997, int arg1998, int arg1999, int arg2000, int arg2001, int arg2002, int arg2003, int arg2004, int arg2005, int arg2006, int arg2007, int arg2008, int arg2009, int arg2010, int arg2011, int arg2012, int arg2013, int arg2014, int arg2015, int arg2016, int arg2017, int arg2018, int arg2019, int arg2020, int arg2021, int arg2022, int arg2023, int arg2024, int arg2025, int arg2026, int arg2027, int arg2028, int arg2029, int arg2030, int arg2031, int arg2032, int arg2033, int arg2034, int arg2035, int arg2036, int arg2037, int arg2038, int arg2039, int arg2040, int arg2041, int arg2042, int arg2043, int arg2044, int arg2045, int arg2046, int arg2047, int arg2048, int arg2049, int arg2050, int arg2051, int arg2052, int arg2053, int arg2054, int arg2055, int arg2056, int arg2057, int arg2058, int arg2059, int arg2060, int arg2061, int arg2062, int arg2063, int arg2064, int arg2065, int arg2066, int arg2067, int arg2068, int arg2069, int arg2070, int arg2071, int arg2072, int arg2073, int arg2074, int arg2075, int arg2076, int arg2077, int arg2078, int arg2079, int arg2080, int arg2081, int arg2082, int arg2083, int arg2084, int arg2085, int arg2086, int arg2087, int arg2088, int arg2089, int arg2090, int arg2091, int arg2092, int arg2093, int arg2094, int arg2095, int arg2096, int arg2097, int arg2098, int arg2099, int arg2100, int arg2101, int arg2102, int arg2103, int arg2104, int arg2105, int arg2106, int arg2107, int arg2108, int arg2109, int arg2110, int arg2111, int arg2112, int arg2113, int arg2114, int arg2115, int arg2116, int arg2117, int arg2118, int arg2119, int arg2120, int arg2121, int arg2122, int arg2123, int arg2124, int arg2125, int arg2126, int arg2127, int arg2128, int arg2129, int arg2130, int arg2131, int arg2132, int arg2133, int arg2134, int arg2135, int arg2136, int arg2137, int arg2138, int arg2139, int arg2140, int arg2141, int arg2142, int arg2143, int arg2144, int arg2145, int arg2146, int arg2147, int arg2148, int arg2149, int arg2150, int arg2151, int arg2152, int arg2153, int arg2154, int arg2155, int arg2156, int arg2157, int arg2158, int arg2159, int arg2160, int arg2161, int arg2162, int arg2163, int arg2164, int arg2165, int arg2166, int arg2167, int arg2168, int arg2169, int arg2170, int arg2171, int arg2172, int arg2173, int arg2174, int arg2175, int arg2176, int arg2177, int arg2178, int arg2179, int arg2180, int arg2181, int arg2182, int arg2183, int arg2184, int arg2185, int arg2186, int arg2187, int arg2188, int arg2189, int arg2190, int arg2191, int arg2192, int arg2193, int arg2194, int arg2195, int arg2196, int arg2197, int arg2198, int arg2199, int arg2200, int arg2201, int arg2202, int arg2203, int arg2204, int arg2205, int arg2206, int arg2207, int arg2208, int arg2209, int arg2210, int arg2211, int arg2212, int arg2213, int arg2214, int arg2215, int arg2216, int arg2217, int arg2218, int arg2219, int arg2220, int arg2221, int arg2222, int arg2223, int arg2224, int arg2225, int arg2226, int arg2227, int arg2228, int arg2229, int arg2230, int arg2231, int arg2232, int arg2233, int arg2234, int arg2235, int arg2236, int arg2237, int arg2238, int arg2239, int arg2240, int arg2241, int arg2242, int arg2243, int arg2244, int arg2245, int arg2246, int arg2247, int arg2248, int arg2249, int arg2250, int arg2251, int arg2252, int arg2253, int arg2254, int arg2255, int arg2256, int arg2257, int arg2258, int arg2259, int arg2260, int arg2261, int arg2262, int arg2263, int arg2264, int arg2265, int arg2266, int arg2267, int arg2268, int arg2269, int arg2270, int arg2271, int arg2272, int arg2273, int arg2274, int arg2275, int arg2276, int arg2277, int arg2278, int arg2279, int arg2280, int arg2281, int arg2282, int arg2283, int arg2284, int arg2285, int arg2286, int arg2287, int arg2288, int arg2289, int arg2290, int arg2291, int arg2292, int arg2293, int arg2294, int arg2295, int arg2296, int arg2297, int arg2298, int arg2299, int arg2300, int arg2301, int arg2302, int arg2303, int arg2304, int arg2305, int arg2306, int arg2307, int arg2308, int arg2309, int arg2310, int arg2311, int arg2312, int arg2313, int arg2314, int arg2315, int arg2316, int arg2317, int arg2318, int arg2319, int arg2320, int arg2321, int arg2322, int arg2323, int arg2324, int arg2325, int arg2326, int arg2327, int arg2328, int arg2329, int arg2330, int arg2331, int arg2332, int arg2333, int arg2334, int arg2335, int arg2336, int arg2337, int arg2338, int arg2339, int arg2340, int arg2341, int arg2342, int arg2343, int arg2344, int arg2345, int arg2346, int arg2347, int arg2348, int arg2349, int arg2350, int arg2351, int arg2352, int arg2353, int arg2354, int arg2355, int arg2356, int arg2357, int arg2358, int arg2359, int arg2360, int arg2361, int arg2362, int arg2363, int arg2364, int arg2365, int arg2366, int arg2367, int arg2368, int arg2369, int arg2370, int arg2371, int arg2372, int arg2373, int arg2374, int arg2375, int arg2376, int arg2377, int arg2378, int arg2379, int arg2380, int arg2381, int arg2382, int arg2383, int arg2384, int arg2385, int arg2386, int arg2387, int arg2388, int arg2389, int arg2390, int arg2391, int arg2392, int arg2393, int arg2394, int arg2395, int arg2396, int arg2397, int arg2398, int arg2399, int arg2400, int arg2401, int arg2402, int arg2403, int arg2404, int arg2405, int arg2406, int arg2407, int arg2408, int arg2409, int arg2410, int arg2411, int arg2412, int arg2413, int arg2414, int arg2415, int arg2416, int arg2417, int arg2418, int arg2419, int arg2420, int arg2421, int arg2422, int arg2423, int arg2424, int arg2425, int arg2426, int arg2427, int arg2428, int arg2429, int arg2430, int arg2431, int arg2432, int arg2433, int arg2434, int arg2435, int arg2436, int arg2437, int arg2438, int arg2439, int arg2440, int arg2441, int arg2442, int arg2443, int arg2444, int arg2445, int arg2446, int arg2447, int arg2448, int arg2449, int arg2450, int arg2451, int arg2452, int arg2453, int arg2454, int arg2455, int arg2456, int arg2457, int arg2458, int arg2459, int arg2460, int arg2461, int arg2462, int arg2463, int arg2464, int arg2465, int arg2466, int arg2467, int arg2468, int arg2469, int arg2470, int arg2471, int arg2472, int arg2473, int arg2474, int arg2475, int arg2476, int arg2477, int arg2478, int arg2479, int arg2480, int arg2481, int arg2482, int arg2483, int arg2484, int arg2485, int arg2486, int arg2487, int arg2488, int arg2489, int arg2490, int arg2491, int arg2492, int arg2493, int arg2494, int arg2495, int arg2496, int arg2497, int arg2498, int arg2499, int arg2500, int arg2501, int arg2502, int arg2503, int arg2504, int arg2505, int arg2506, int arg2507, int arg2508, int arg2509, int arg2510, int arg2511, int arg2512, int arg2513, int arg2514, int arg2515, int arg2516, int arg2517, int arg2518, int arg2519, int arg2520, int arg2521, int arg2522, int arg2523, int arg2524, int arg2525, int arg2526, int arg2527, int arg2528, int arg2529, int arg2530, int arg2531, int arg2532, int arg2533, int arg2534, int arg2535, int arg2536, int arg2537, int arg2538, int arg2539, int arg2540, int arg2541, int arg2542, int arg2543, int arg2544, int arg2545, int arg2546, int arg2547, int arg2548, int arg2549, int arg2550, int arg2551, int arg2552, int arg2553, int arg2554, int arg2555, int arg2556, int arg2557, int arg2558, int arg2559, int arg2560, int arg2561, int arg2562, int arg2563, int arg2564, int arg2565, int arg2566, int arg2567, int arg2568, int arg2569, int arg2570, int arg2571, int arg2572, int arg2573, int arg2574, int arg2575, int arg2576, int arg2577, int arg2578, int arg2579, int arg2580, int arg2581, int arg2582, int arg2583, int arg2584, int arg2585, int arg2586, int arg2587, int arg2588, int arg2589, int arg2590, int arg2591, int arg2592, int arg2593, int arg2594, int arg2595, int arg2596, int arg2597, int arg2598, int arg2599, int arg2600, int arg2601, int arg2602, int arg2603, int arg2604, int arg2605, int arg2606, int arg2607, int arg2608, int arg2609, int arg2610, int arg2611, int arg2612, int arg2613, int arg2614, int arg2615, int arg2616, int arg2617, int arg2618, int arg2619, int arg2620, int arg2621, int arg2622, int arg2623, int arg2624, int arg2625, int arg2626, int arg2627, int arg2628, int arg2629, int arg2630, int arg2631, int arg2632, int arg2633, int arg2634, int arg2635, int arg2636, int arg2637, int arg2638, int arg2639, int arg2640, int arg2641, int arg2642, int arg2643, int arg2644, int arg2645, int arg2646, int arg2647, int arg2648, int arg2649, int arg2650, int arg2651, int arg2652, int arg2653, int arg2654, int arg2655, int arg2656, int arg2657, int arg2658, int arg2659, int arg2660, int arg2661, int arg2662, int arg2663, int arg2664, int arg2665, int arg2666, int arg2667, int arg2668, int arg2669, int arg2670, int arg2671, int arg2672, int arg2673, int arg2674, int arg2675, int arg2676, int arg2677, int arg2678, int arg2679, int arg2680, int arg2681, int arg2682, int arg2683, int arg2684, int arg2685, int arg2686, int arg2687, int arg2688, int arg2689, int arg2690, int arg2691, int arg2692, int arg2693, int arg2694, int arg2695, int arg2696, int arg2697, int arg2698, int arg2699, int arg2700, int arg2701, int arg2702, int arg2703, int arg2704, int arg2705, int arg2706, int arg2707, int arg2708, int arg2709, int arg2710, int arg2711, int arg2712, int arg2713, int arg2714, int arg2715, int arg2716, int arg2717, int arg2718, int arg2719, int arg2720, int arg2721, int arg2722, int arg2723, int arg2724, int arg2725, int arg2726, int arg2727, int arg2728, int arg2729, int arg2730, int arg2731, int arg2732, int arg2733, int arg2734, int arg2735, int arg2736, int arg2737, int arg2738, int arg2739, int arg2740, int arg2741, int arg2742, int arg2743, int arg2744, int arg2745, int arg2746, int arg2747, int arg2748, int arg2749, int arg2750, int arg2751, int arg2752, int arg2753, int arg2754, int arg2755, int arg2756, int arg2757, int arg2758, int arg2759, int arg2760, int arg2761, int arg2762, int arg2763, int arg2764, int arg2765, int arg2766, int arg2767, int arg2768, int arg2769, int arg2770, int arg2771, int arg2772, int arg2773, int arg2774, int arg2775, int arg2776, int arg2777, int arg2778, int arg2779, int arg2780, int arg2781, int arg2782, int arg2783, int arg2784, int arg2785, int arg2786, int arg2787, int arg2788, int arg2789, int arg2790, int arg2791, int arg2792, int arg2793, int arg2794, int arg2795, int arg2796, int arg2797, int arg2798, int arg2799, int arg2800, int arg2801, int arg2802, int arg2803, int arg2804, int arg2805, int arg2806, int arg2807, int arg2808, int arg2809, int arg2810, int arg2811, int arg2812, int arg2813, int arg2814, int arg2815, int arg2816, int arg2817, int arg2818, int arg2819, int arg2820, int arg2821, int arg2822, int arg2823, int arg2824, int arg2825, int arg2826, int arg2827, int arg2828, int arg2829, int arg2830, int arg2831, int arg2832, int arg2833, int arg2834, int arg2835, int arg2836, int arg2837, int arg2838, int arg2839, int arg2840, int arg2841, int arg2842, int arg2843, int arg2844, int arg2845, int arg2846, int arg2847, int arg2848, int arg2849, int arg2850, int arg2851, int arg2852, int arg2853, int arg2854, int arg2855, int arg2856, int arg2857, int arg2858, int arg2859, int arg2860, int arg2861, int arg2862, int arg2863, int arg2864, int arg2865, int arg2866, int arg2867, int arg2868, int arg2869, int arg2870, int arg2871, int arg2872, int arg2873, int arg2874, int arg2875, int arg2876, int arg2877, int arg2878, int arg2879, int arg2880, int arg2881, int arg2882, int arg2883, int arg2884, int arg2885, int arg2886, int arg2887, int arg2888, int arg2889, int arg2890, int arg2891, int arg2892, int arg2893, int arg2894, int arg2895, int arg2896, int arg2897, int arg2898, int arg2899, int arg2900, int arg2901, int arg2902, int arg2903, int arg2904, int arg2905, int arg2906, int arg2907, int arg2908, int arg2909, int arg2910, int arg2911, int arg2912, int arg2913, int arg2914, int arg2915, int arg2916, int arg2917, int arg2918, int arg2919, int arg2920, int arg2921, int arg2922, int arg2923, int arg2924, int arg2925, int arg2926, int arg2927, int arg2928, int arg2929, int arg2930, int arg2931, int arg2932, int arg2933, int arg2934, int arg2935, int arg2936, int arg2937, int arg2938, int arg2939, int arg2940, int arg2941, int arg2942, int arg2943, int arg2944, int arg2945, int arg2946, int arg2947, int arg2948, int arg2949, int arg2950, int arg2951, int arg2952, int arg2953, int arg2954, int arg2955, int arg2956, int arg2957, int arg2958, int arg2959, int arg2960, int arg2961, int arg2962, int arg2963, int arg2964, int arg2965, int arg2966, int arg2967, int arg2968, int arg2969, int arg2970, int arg2971, int arg2972, int arg2973, int arg2974, int arg2975, int arg2976, int arg2977, int arg2978, int arg2979, int arg2980, int arg2981, int arg2982, int arg2983, int arg2984, int arg2985, int arg2986, int arg2987, int arg2988, int arg2989, int arg2990, int arg2991, int arg2992, int arg2993, int arg2994, int arg2995, int arg2996, int arg2997, int arg2998, int arg2999, int arg3000, int arg3001, int arg3002, int arg3003, int arg3004, int arg3005, int arg3006, int arg3007, int arg3008, int arg3009, int arg3010, int arg3011, int arg3012, int arg3013, int arg3014, int arg3015, int arg3016, int arg3017, int arg3018, int arg3019, int arg3020, int arg3021, int arg3022, int arg3023, int arg3024, int arg3025, int arg3026, int arg3027, int arg3028, int arg3029, int arg3030, int arg3031, int arg3032, int arg3033, int arg3034, int arg3035, int arg3036, int arg3037, int arg3038, int arg3039, int arg3040, int arg3041, int arg3042, int arg3043, int arg3044, int arg3045, int arg3046, int arg3047, int arg3048, int arg3049, int arg3050, int arg3051, int arg3052, int arg3053, int arg3054, int arg3055, int arg3056, int arg3057, int arg3058, int arg3059, int arg3060, int arg3061, int arg3062, int arg3063, int arg3064, int arg3065, int arg3066, int arg3067, int arg3068, int arg3069, int arg3070, int arg3071, int arg3072, int arg3073, int arg3074, int arg3075, int arg3076, int arg3077, int arg3078, int arg3079, int arg3080, int arg3081, int arg3082, int arg3083, int arg3084, int arg3085, int arg3086, int arg3087, int arg3088, int arg3089, int arg3090, int arg3091, int arg3092, int arg3093, int arg3094, int arg3095, int arg3096, int arg3097, int arg3098, int arg3099, int arg3100, int arg3101, int arg3102, int arg3103, int arg3104, int arg3105, int arg3106, int arg3107, int arg3108, int arg3109, int arg3110, int arg3111, int arg3112, int arg3113, int arg3114, int arg3115, int arg3116, int arg3117, int arg3118, int arg3119, int arg3120, int arg3121, int arg3122, int arg3123, int arg3124, int arg3125, int arg3126, int arg3127, int arg3128, int arg3129, int arg3130, int arg3131, int arg3132, int arg3133, int arg3134, int arg3135, int arg3136, int arg3137, int arg3138, int arg3139, int arg3140, int arg3141, int arg3142, int arg3143, int arg3144, int arg3145, int arg3146, int arg3147, int arg3148, int arg3149, int arg3150, int arg3151, int arg3152, int arg3153, int arg3154, int arg3155, int arg3156, int arg3157, int arg3158, int arg3159, int arg3160, int arg3161, int arg3162, int arg3163, int arg3164, int arg3165, int arg3166, int arg3167, int arg3168, int arg3169, int arg3170, int arg3171, int arg3172, int arg3173, int arg3174, int arg3175, int arg3176, int arg3177, int arg3178, int arg3179, int arg3180, int arg3181, int arg3182, int arg3183, int arg3184, int arg3185, int arg3186, int arg3187, int arg3188, int arg3189, int arg3190, int arg3191, int arg3192, int arg3193, int arg3194, int arg3195, int arg3196, int arg3197, int arg3198, int arg3199, int arg3200, int arg3201, int arg3202, int arg3203, int arg3204, int arg3205, int arg3206, int arg3207, int arg3208, int arg3209, int arg3210, int arg3211, int arg3212, int arg3213, int arg3214, int arg3215, int arg3216, int arg3217, int arg3218, int arg3219, int arg3220, int arg3221, int arg3222, int arg3223, int arg3224, int arg3225, int arg3226, int arg3227, int arg3228, int arg3229, int arg3230, int arg3231, int arg3232, int arg3233, int arg3234, int arg3235, int arg3236, int arg3237, int arg3238, int arg3239, int arg3240, int arg3241, int arg3242, int arg3243, int arg3244, int arg3245, int arg3246, int arg3247, int arg3248, int arg3249, int arg3250, int arg3251, int arg3252, int arg3253, int arg3254, int arg3255, int arg3256, int arg3257, int arg3258, int arg3259, int arg3260, int arg3261, int arg3262, int arg3263, int arg3264, int arg3265, int arg3266, int arg3267, int arg3268, int arg3269, int arg3270, int arg3271, int arg3272, int arg3273, int arg3274, int arg3275, int arg3276, int arg3277, int arg3278, int arg3279, int arg3280, int arg3281, int arg3282, int arg3283, int arg3284, int arg3285, int arg3286, int arg3287, int arg3288, int arg3289, int arg3290, int arg3291, int arg3292, int arg3293, int arg3294, int arg3295, int arg3296, int arg3297, int arg3298, int arg3299, int arg3300, int arg3301, int arg3302, int arg3303, int arg3304, int arg3305, int arg3306, int arg3307, int arg3308, int arg3309, int arg3310, int arg3311, int arg3312, int arg3313, int arg3314, int arg3315, int arg3316, int arg3317, int arg3318, int arg3319, int arg3320, int arg3321, int arg3322, int arg3323, int arg3324, int arg3325, int arg3326, int arg3327, int arg3328, int arg3329, int arg3330, int arg3331, int arg3332, int arg3333, int arg3334, int arg3335, int arg3336, int arg3337, int arg3338, int arg3339, int arg3340, int arg3341, int arg3342, int arg3343, int arg3344, int arg3345, int arg3346, int arg3347, int arg3348, int arg3349, int arg3350, int arg3351, int arg3352, int arg3353, int arg3354, int arg3355, int arg3356, int arg3357, int arg3358, int arg3359, int arg3360, int arg3361, int arg3362, int arg3363, int arg3364, int arg3365, int arg3366, int arg3367, int arg3368, int arg3369, int arg3370, int arg3371, int arg3372, int arg3373, int arg3374, int arg3375, int arg3376, int arg3377, int arg3378, int arg3379, int arg3380, int arg3381, int arg3382, int arg3383, int arg3384, int arg3385, int arg3386, int arg3387, int arg3388, int arg3389, int arg3390, int arg3391, int arg3392, int arg3393, int arg3394, int arg3395, int arg3396, int arg3397, int arg3398, int arg3399, int arg3400, int arg3401, int arg3402, int arg3403, int arg3404, int arg3405, int arg3406, int arg3407, int arg3408, int arg3409, int arg3410, int arg3411, int arg3412, int arg3413, int arg3414, int arg3415, int arg3416, int arg3417, int arg3418, int arg3419, int arg3420, int arg3421, int arg3422, int arg3423, int arg3424, int arg3425, int arg3426, int arg3427, int arg3428, int arg3429, int arg3430, int arg3431, int arg3432, int arg3433, int arg3434, int arg3435, int arg3436, int arg3437, int arg3438, int arg3439, int arg3440, int arg3441, int arg3442, int arg3443, int arg3444, int arg3445, int arg3446, int arg3447, int arg3448, int arg3449, int arg3450, int arg3451, int arg3452, int arg3453, int arg3454, int arg3455, int arg3456, int arg3457, int arg3458, int arg3459, int arg3460, int arg3461, int arg3462, int arg3463, int arg3464, int arg3465, int arg3466, int arg3467, int arg3468, int arg3469, int arg3470, int arg3471, int arg3472, int arg3473, int arg3474, int arg3475, int arg3476, int arg3477, int arg3478, int arg3479, int arg3480, int arg3481, int arg3482, int arg3483, int arg3484, int arg3485, int arg3486, int arg3487, int arg3488, int arg3489, int arg3490, int arg3491, int arg3492, int arg3493, int arg3494, int arg3495, int arg3496, int arg3497, int arg3498, int arg3499, int arg3500, int arg3501, int arg3502, int arg3503, int arg3504, int arg3505, int arg3506, int arg3507, int arg3508, int arg3509, int arg3510, int arg3511, int arg3512, int arg3513, int arg3514, int arg3515, int arg3516, int arg3517, int arg3518, int arg3519, int arg3520, int arg3521, int arg3522, int arg3523, int arg3524, int arg3525, int arg3526, int arg3527, int arg3528, int arg3529, int arg3530, int arg3531, int arg3532, int arg3533, int arg3534, int arg3535, int arg3536, int arg3537, int arg3538, int arg3539, int arg3540, int arg3541, int arg3542, int arg3543, int arg3544, int arg3545, int arg3546, int arg3547, int arg3548, int arg3549, int arg3550, int arg3551, int arg3552, int arg3553, int arg3554, int arg3555, int arg3556, int arg3557, int arg3558, int arg3559, int arg3560, int arg3561, int arg3562, int arg3563, int arg3564, int arg3565, int arg3566, int arg3567, int arg3568, int arg3569, int arg3570, int arg3571, int arg3572, int arg3573, int arg3574, int arg3575, int arg3576, int arg3577, int arg3578, int arg3579, int arg3580, int arg3581, int arg3582, int arg3583, int arg3584, int arg3585, int arg3586, int arg3587, int arg3588, int arg3589, int arg3590, int arg3591, int arg3592, int arg3593, int arg3594, int arg3595, int arg3596, int arg3597, int arg3598, int arg3599, int arg3600, int arg3601, int arg3602, int arg3603, int arg3604, int arg3605, int arg3606, int arg3607, int arg3608, int arg3609, int arg3610, int arg3611, int arg3612, int arg3613, int arg3614, int arg3615, int arg3616, int arg3617, int arg3618, int arg3619, int arg3620, int arg3621, int arg3622, int arg3623, int arg3624, int arg3625, int arg3626, int arg3627, int arg3628, int arg3629, int arg3630, int arg3631, int arg3632, int arg3633, int arg3634, int arg3635, int arg3636, int arg3637, int arg3638, int arg3639, int arg3640, int arg3641, int arg3642, int arg3643, int arg3644, int arg3645, int arg3646, int arg3647, int arg3648, int arg3649, int arg3650, int arg3651, int arg3652, int arg3653, int arg3654, int arg3655, int arg3656, int arg3657, int arg3658, int arg3659, int arg3660, int arg3661, int arg3662, int arg3663, int arg3664, int arg3665, int arg3666, int arg3667, int arg3668, int arg3669, int arg3670, int arg3671, int arg3672, int arg3673, int arg3674, int arg3675, int arg3676, int arg3677, int arg3678, int arg3679, int arg3680, int arg3681, int arg3682, int arg3683, int arg3684, int arg3685, int arg3686, int arg3687, int arg3688, int arg3689, int arg3690, int arg3691, int arg3692, int arg3693, int arg3694, int arg3695, int arg3696, int arg3697, int arg3698, int arg3699, int arg3700, int arg3701, int arg3702, int arg3703, int arg3704, int arg3705, int arg3706, int arg3707, int arg3708, int arg3709, int arg3710, int arg3711, int arg3712, int arg3713, int arg3714, int arg3715, int arg3716, int arg3717, int arg3718, int arg3719, int arg3720, int arg3721, int arg3722, int arg3723, int arg3724, int arg3725, int arg3726, int arg3727, int arg3728, int arg3729, int arg3730, int arg3731, int arg3732, int arg3733, int arg3734, int arg3735, int arg3736, int arg3737, int arg3738, int arg3739, int arg3740, int arg3741, int arg3742, int arg3743, int arg3744, int arg3745, int arg3746, int arg3747, int arg3748, int arg3749, int arg3750, int arg3751, int arg3752, int arg3753, int arg3754, int arg3755, int arg3756, int arg3757, int arg3758, int arg3759, int arg3760, int arg3761, int arg3762, int arg3763, int arg3764, int arg3765, int arg3766, int arg3767, int arg3768, int arg3769, int arg3770, int arg3771, int arg3772, int arg3773, int arg3774, int arg3775, int arg3776, int arg3777, int arg3778, int arg3779, int arg3780, int arg3781, int arg3782, int arg3783, int arg3784, int arg3785, int arg3786, int arg3787, int arg3788, int arg3789, int arg3790, int arg3791, int arg3792, int arg3793, int arg3794, int arg3795, int arg3796, int arg3797, int arg3798, int arg3799, int arg3800, int arg3801, int arg3802, int arg3803, int arg3804, int arg3805, int arg3806, int arg3807, int arg3808, int arg3809, int arg3810, int arg3811, int arg3812, int arg3813, int arg3814, int arg3815, int arg3816, int arg3817, int arg3818, int arg3819, int arg3820, int arg3821, int arg3822, int arg3823, int arg3824, int arg3825, int arg3826, int arg3827, int arg3828, int arg3829, int arg3830, int arg3831, int arg3832, int arg3833, int arg3834, int arg3835, int arg3836, int arg3837, int arg3838, int arg3839, int arg3840, int arg3841, int arg3842, int arg3843, int arg3844, int arg3845, int arg3846, int arg3847, int arg3848, int arg3849, int arg3850, int arg3851, int arg3852, int arg3853, int arg3854, int arg3855, int arg3856, int arg3857, int arg3858, int arg3859, int arg3860, int arg3861, int arg3862, int arg3863, int arg3864, int arg3865, int arg3866, int arg3867, int arg3868, int arg3869, int arg3870, int arg3871, int arg3872, int arg3873, int arg3874, int arg3875, int arg3876, int arg3877, int arg3878, int arg3879, int arg3880, int arg3881, int arg3882, int arg3883, int arg3884, int arg3885, int arg3886, int arg3887, int arg3888, int arg3889, int arg3890, int arg3891, int arg3892, int arg3893, int arg3894, int arg3895, int arg3896, int arg3897, int arg3898, int arg3899, int arg3900, int arg3901, int arg3902, int arg3903, int arg3904, int arg3905, int arg3906, int arg3907, int arg3908, int arg3909, int arg3910, int arg3911, int arg3912, int arg3913, int arg3914, int arg3915, int arg3916, int arg3917, int arg3918, int arg3919, int arg3920, int arg3921, int arg3922, int arg3923, int arg3924, int arg3925, int arg3926, int arg3927, int arg3928, int arg3929, int arg3930, int arg3931, int arg3932, int arg3933, int arg3934, int arg3935, int arg3936, int arg3937, int arg3938, int arg3939, int arg3940, int arg3941, int arg3942, int arg3943, int arg3944, int arg3945, int arg3946, int arg3947, int arg3948, int arg3949, int arg3950, int arg3951, int arg3952, int arg3953, int arg3954, int arg3955, int arg3956, int arg3957, int arg3958, int arg3959, int arg3960, int arg3961, int arg3962, int arg3963, int arg3964, int arg3965, int arg3966, int arg3967, int arg3968, int arg3969, int arg3970, int arg3971, int arg3972, int arg3973, int arg3974, int arg3975, int arg3976, int arg3977, int arg3978, int arg3979, int arg3980, int arg3981, int arg3982, int arg3983, int arg3984, int arg3985, int arg3986, int arg3987, int arg3988, int arg3989, int arg3990, int arg3991, int arg3992, int arg3993, int arg3994, int arg3995, int arg3996, int arg3997, int arg3998, int arg3999, int arg4000, int arg4001, int arg4002, int arg4003, int arg4004, int arg4005, int arg4006, int arg4007, int arg4008, int arg4009, int arg4010, int arg4011, int arg4012, int arg4013, int arg4014, int arg4015, int arg4016, int arg4017, int arg4018, int arg4019, int arg4020, int arg4021, int arg4022, int arg4023, int arg4024, int arg4025, int arg4026, int arg4027, int arg4028, int arg4029, int arg4030, int arg4031, int arg4032, int arg4033, int arg4034, int arg4035, int arg4036, int arg4037, int arg4038, int arg4039, int arg4040, int arg4041, int arg4042, int arg4043, int arg4044, int arg4045, int arg4046, int arg4047, int arg4048, int arg4049, int arg4050, int arg4051, int arg4052, int arg4053, int arg4054, int arg4055, int arg4056, int arg4057, int arg4058, int arg4059, int arg4060, int arg4061, int arg4062, int arg4063, int arg4064, int arg4065, int arg4066, int arg4067, int arg4068, int arg4069, int arg4070, int arg4071, int arg4072, int arg4073, int arg4074, int arg4075, int arg4076, int arg4077, int arg4078, int arg4079, int arg4080, int arg4081, int arg4082, int arg4083, int arg4084, int arg4085, int arg4086, int arg4087, int arg4088, int arg4089, int arg4090, int arg4091, int arg4092, int arg4093, int arg4094, int arg4095, int arg4096, int arg4097, int arg4098, int arg4099, int arg4100, int arg4101, int arg4102, int arg4103, int arg4104, int arg4105, int arg4106, int arg4107, int arg4108, int arg4109, int arg4110, int arg4111, int arg4112, int arg4113, int arg4114, int arg4115, int arg4116, int arg4117, int arg4118, int arg4119, int arg4120, int arg4121, int arg4122, int arg4123, int arg4124, int arg4125, int arg4126, int arg4127, int arg4128, int arg4129, int arg4130, int arg4131, int arg4132, int arg4133, int arg4134, int arg4135, int arg4136, int arg4137, int arg4138, int arg4139, int arg4140, int arg4141, int arg4142, int arg4143, int arg4144, int arg4145, int arg4146, int arg4147, int arg4148, int arg4149, int arg4150, int arg4151, int arg4152, int arg4153, int arg4154, int arg4155, int arg4156, int arg4157, int arg4158, int arg4159, int arg4160, int arg4161, int arg4162, int arg4163, int arg4164, int arg4165, int arg4166, int arg4167, int arg4168, int arg4169, int arg4170, int arg4171, int arg4172, int arg4173, int arg4174, int arg4175, int arg4176, int arg4177, int arg4178, int arg4179, int arg4180, int arg4181, int arg4182, int arg4183, int arg4184, int arg4185, int arg4186, int arg4187, int arg4188, int arg4189, int arg4190, int arg4191, int arg4192, int arg4193, int arg4194, int arg4195, int arg4196, int arg4197, int arg4198, int arg4199, int arg4200, int arg4201, int arg4202, int arg4203, int arg4204, int arg4205, int arg4206, int arg4207, int arg4208, int arg4209, int arg4210, int arg4211, int arg4212, int arg4213, int arg4214, int arg4215, int arg4216, int arg4217, int arg4218, int arg4219, int arg4220, int arg4221, int arg4222, int arg4223, int arg4224, int arg4225, int arg4226, int arg4227, int arg4228, int arg4229, int arg4230, int arg4231, int arg4232, int arg4233, int arg4234, int arg4235, int arg4236, int arg4237, int arg4238, int arg4239, int arg4240, int arg4241, int arg4242, int arg4243, int arg4244, int arg4245, int arg4246, int arg4247, int arg4248, int arg4249, int arg4250, int arg4251, int arg4252, int arg4253, int arg4254, int arg4255, int arg4256, int arg4257, int arg4258, int arg4259, int arg4260, int arg4261, int arg4262, int arg4263, int arg4264, int arg4265, int arg4266, int arg4267, int arg4268, int arg4269, int arg4270, int arg4271, int arg4272, int arg4273, int arg4274, int arg4275, int arg4276, int arg4277, int arg4278, int arg4279, int arg4280, int arg4281, int arg4282, int arg4283, int arg4284, int arg4285, int arg4286, int arg4287, int arg4288, int arg4289, int arg4290, int arg4291, int arg4292, int arg4293, int arg4294, int arg4295, int arg4296, int arg4297, int arg4298, int arg4299, int arg4300, int arg4301, int arg4302, int arg4303, int arg4304, int arg4305, int arg4306, int arg4307, int arg4308, int arg4309, int arg4310, int arg4311, int arg4312, int arg4313, int arg4314, int arg4315, int arg4316, int arg4317, int arg4318, int arg4319, int arg4320, int arg4321, int arg4322, int arg4323, int arg4324, int arg4325, int arg4326, int arg4327, int arg4328, int arg4329, int arg4330, int arg4331, int arg4332, int arg4333, int arg4334, int arg4335, int arg4336, int arg4337, int arg4338, int arg4339, int arg4340, int arg4341, int arg4342, int arg4343, int arg4344, int arg4345, int arg4346, int arg4347, int arg4348, int arg4349, int arg4350, int arg4351, int arg4352, int arg4353, int arg4354, int arg4355, int arg4356, int arg4357, int arg4358, int arg4359, int arg4360, int arg4361, int arg4362, int arg4363, int arg4364, int arg4365, int arg4366, int arg4367, int arg4368, int arg4369, int arg4370, int arg4371, int arg4372, int arg4373, int arg4374, int arg4375, int arg4376, int arg4377, int arg4378, int arg4379, int arg4380, int arg4381, int arg4382, int arg4383, int arg4384, int arg4385, int arg4386, int arg4387, int arg4388, int arg4389, int arg4390, int arg4391, int arg4392, int arg4393, int arg4394, int arg4395, int arg4396, int arg4397, int arg4398, int arg4399, int arg4400, int arg4401, int arg4402, int arg4403, int arg4404, int arg4405, int arg4406, int arg4407, int arg4408, int arg4409, int arg4410, int arg4411, int arg4412, int arg4413, int arg4414, int arg4415, int arg4416, int arg4417, int arg4418, int arg4419, int arg4420, int arg4421, int arg4422, int arg4423, int arg4424, int arg4425, int arg4426, int arg4427, int arg4428, int arg4429, int arg4430, int arg4431, int arg4432, int arg4433, int arg4434, int arg4435, int arg4436, int arg4437, int arg4438, int arg4439, int arg4440, int arg4441, int arg4442, int arg4443, int arg4444, int arg4445, int arg4446, int arg4447, int arg4448, int arg4449, int arg4450, int arg4451, int arg4452, int arg4453, int arg4454, int arg4455, int arg4456, int arg4457, int arg4458, int arg4459, int arg4460, int arg4461, int arg4462, int arg4463, int arg4464, int arg4465, int arg4466, int arg4467, int arg4468, int arg4469, int arg4470, int arg4471, int arg4472, int arg4473, int arg4474, int arg4475, int arg4476, int arg4477, int arg4478, int arg4479, int arg4480, int arg4481, int arg4482, int arg4483, int arg4484, int arg4485, int arg4486, int arg4487, int arg4488, int arg4489, int arg4490, int arg4491, int arg4492, int arg4493, int arg4494, int arg4495, int arg4496, int arg4497, int arg4498, int arg4499, int arg4500, int arg4501, int arg4502, int arg4503, int arg4504, int arg4505, int arg4506, int arg4507, int arg4508, int arg4509, int arg4510, int arg4511, int arg4512, int arg4513, int arg4514, int arg4515, int arg4516, int arg4517, int arg4518, int arg4519, int arg4520, int arg4521, int arg4522, int arg4523, int arg4524, int arg4525, int arg4526, int arg4527, int arg4528, int arg4529, int arg4530, int arg4531, int arg4532, int arg4533, int arg4534, int arg4535, int arg4536, int arg4537, int arg4538, int arg4539, int arg4540, int arg4541, int arg4542, int arg4543, int arg4544, int arg4545, int arg4546, int arg4547, int arg4548, int arg4549, int arg4550, int arg4551, int arg4552, int arg4553, int arg4554, int arg4555, int arg4556, int arg4557, int arg4558, int arg4559, int arg4560, int arg4561, int arg4562, int arg4563, int arg4564, int arg4565, int arg4566, int arg4567, int arg4568, int arg4569, int arg4570, int arg4571, int arg4572, int arg4573, int arg4574, int arg4575, int arg4576, int arg4577, int arg4578, int arg4579, int arg4580, int arg4581, int arg4582, int arg4583, int arg4584, int arg4585, int arg4586, int arg4587, int arg4588, int arg4589, int arg4590, int arg4591, int arg4592, int arg4593, int arg4594, int arg4595, int arg4596, int arg4597, int arg4598, int arg4599, int arg4600, int arg4601, int arg4602, int arg4603, int arg4604, int arg4605, int arg4606, int arg4607, int arg4608, int arg4609, int arg4610, int arg4611, int arg4612, int arg4613, int arg4614, int arg4615, int arg4616, int arg4617, int arg4618, int arg4619, int arg4620, int arg4621, int arg4622, int arg4623, int arg4624, int arg4625, int arg4626, int arg4627, int arg4628, int arg4629, int arg4630, int arg4631, int arg4632, int arg4633, int arg4634, int arg4635, int arg4636, int arg4637, int arg4638, int arg4639, int arg4640, int arg4641, int arg4642, int arg4643, int arg4644, int arg4645, int arg4646, int arg4647, int arg4648, int arg4649, int arg4650, int arg4651, int arg4652, int arg4653, int arg4654, int arg4655, int arg4656, int arg4657, int arg4658, int arg4659, int arg4660, int arg4661, int arg4662, int arg4663, int arg4664, int arg4665, int arg4666, int arg4667, int arg4668, int arg4669, int arg4670, int arg4671, int arg4672, int arg4673, int arg4674, int arg4675, int arg4676, int arg4677, int arg4678, int arg4679, int arg4680, int arg4681, int arg4682, int arg4683, int arg4684, int arg4685, int arg4686, int arg4687, int arg4688, int arg4689, int arg4690, int arg4691, int arg4692, int arg4693, int arg4694, int arg4695, int arg4696, int arg4697, int arg4698, int arg4699, int arg4700, int arg4701, int arg4702, int arg4703, int arg4704, int arg4705, int arg4706, int arg4707, int arg4708, int arg4709, int arg4710, int arg4711, int arg4712, int arg4713, int arg4714, int arg4715, int arg4716, int arg4717, int arg4718, int arg4719, int arg4720, int arg4721, int arg4722, int arg4723, int arg4724, int arg4725, int arg4726, int arg4727, int arg4728, int arg4729, int arg4730, int arg4731, int arg4732, int arg4733, int arg4734, int arg4735, int arg4736, int arg4737, int arg4738, int arg4739, int arg4740, int arg4741, int arg4742, int arg4743, int arg4744, int arg4745, int arg4746, int arg4747, int arg4748, int arg4749, int arg4750, int arg4751, int arg4752, int arg4753, int arg4754, int arg4755, int arg4756, int arg4757, int arg4758, int arg4759, int arg4760, int arg4761, int arg4762, int arg4763, int arg4764, int arg4765, int arg4766, int arg4767, int arg4768, int arg4769, int arg4770, int arg4771, int arg4772, int arg4773, int arg4774, int arg4775, int arg4776, int arg4777, int arg4778, int arg4779, int arg4780, int arg4781, int arg4782, int arg4783, int arg4784, int arg4785, int arg4786, int arg4787, int arg4788, int arg4789, int arg4790, int arg4791, int arg4792, int arg4793, int arg4794, int arg4795, int arg4796, int arg4797, int arg4798, int arg4799, int arg4800, int arg4801, int arg4802, int arg4803, int arg4804, int arg4805, int arg4806, int arg4807, int arg4808, int arg4809, int arg4810, int arg4811, int arg4812, int arg4813, int arg4814, int arg4815, int arg4816, int arg4817, int arg4818, int arg4819, int arg4820, int arg4821, int arg4822, int arg4823, int arg4824, int arg4825, int arg4826, int arg4827, int arg4828, int arg4829, int arg4830, int arg4831, int arg4832, int arg4833, int arg4834, int arg4835, int arg4836, int arg4837, int arg4838, int arg4839, int arg4840, int arg4841, int arg4842, int arg4843, int arg4844, int arg4845, int arg4846, int arg4847, int arg4848, int arg4849, int arg4850, int arg4851, int arg4852, int arg4853, int arg4854, int arg4855, int arg4856, int arg4857, int arg4858, int arg4859, int arg4860, int arg4861, int arg4862, int arg4863, int arg4864, int arg4865, int arg4866, int arg4867, int arg4868, int arg4869, int arg4870, int arg4871, int arg4872, int arg4873, int arg4874, int arg4875, int arg4876, int arg4877, int arg4878, int arg4879, int arg4880, int arg4881, int arg4882, int arg4883, int arg4884, int arg4885, int arg4886, int arg4887, int arg4888, int arg4889, int arg4890, int arg4891, int arg4892, int arg4893, int arg4894, int arg4895, int arg4896, int arg4897, int arg4898, int arg4899, int arg4900, int arg4901, int arg4902, int arg4903, int arg4904, int arg4905, int arg4906, int arg4907, int arg4908, int arg4909, int arg4910, int arg4911, int arg4912, int arg4913, int arg4914, int arg4915, int arg4916, int arg4917, int arg4918, int arg4919, int arg4920, int arg4921, int arg4922, int arg4923, int arg4924, int arg4925, int arg4926, int arg4927, int arg4928, int arg4929, int arg4930, int arg4931, int arg4932, int arg4933, int arg4934, int arg4935, int arg4936, int arg4937, int arg4938, int arg4939, int arg4940, int arg4941, int arg4942, int arg4943, int arg4944, int arg4945, int arg4946, int arg4947, int arg4948, int arg4949, int arg4950, int arg4951, int arg4952, int arg4953, int arg4954, int arg4955, int arg4956, int arg4957, int arg4958, int arg4959, int arg4960, int arg4961, int arg4962, int arg4963, int arg4964, int arg4965, int arg4966, int arg4967, int arg4968, int arg4969, int arg4970, int arg4971, int arg4972, int arg4973, int arg4974, int arg4975, int arg4976, int arg4977, int arg4978, int arg4979, int arg4980, int arg4981, int arg4982, int arg4983, int arg4984, int arg4985, int arg4986, int arg4987, int arg4988, int arg4989, int arg4990, int arg4991, int arg4992, int arg4993, int arg4994, int arg4995, int arg4996, int arg4997, int arg4998, int arg4999, int arg5000, int arg5001, int arg5002, int arg5003, int arg5004, int arg5005, int arg5006, int arg5007, int arg5008, int arg5009, int arg5010, int arg5011, int arg5012, int arg5013, int arg5014, int arg5015, int arg5016, int arg5017, int arg5018, int arg5019, int arg5020, int arg5021, int arg5022, int arg5023, int arg5024, int arg5025, int arg5026, int arg5027, int arg5028, int arg5029, int arg5030, int arg5031, int arg5032, int arg5033, int arg5034, int arg5035, int arg5036, int arg5037, int arg5038, int arg5039)); } // extern "C" -JSC_DEFINE_NOEXCEPT_JIT_OPERATION(functionWithHellaArguments3, int, (int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25,int arg26,int arg27,int arg28,int arg29,int arg30,int arg31,int arg32,int arg33,int arg34,int arg35,int arg36,int arg37,int arg38,int arg39,int arg40,int arg41,int arg42,int arg43,int arg44,int arg45,int arg46,int arg47,int arg48,int arg49,int arg50,int arg51,int arg52,int arg53,int arg54,int arg55,int arg56,int arg57,int arg58,int arg59,int arg60,int arg61,int arg62,int arg63,int arg64,int arg65,int arg66,int arg67,int arg68,int arg69,int arg70,int arg71,int arg72,int arg73,int arg74,int arg75,int arg76,int arg77,int arg78,int arg79,int arg80,int arg81,int arg82,int arg83,int arg84,int arg85,int arg86,int arg87,int arg88,int arg89,int arg90,int arg91,int arg92,int arg93,int arg94,int arg95,int arg96,int arg97,int arg98,int arg99,int arg100,int arg101,int arg102,int arg103,int arg104,int arg105,int arg106,int arg107,int arg108,int arg109,int arg110,int arg111,int arg112,int arg113,int arg114,int arg115,int arg116,int arg117,int arg118,int arg119,int arg120,int arg121,int arg122,int arg123,int arg124,int arg125,int arg126,int arg127,int arg128,int arg129,int arg130,int arg131,int arg132,int arg133,int arg134,int arg135,int arg136,int arg137,int arg138,int arg139,int arg140,int arg141,int arg142,int arg143,int arg144,int arg145,int arg146,int arg147,int arg148,int arg149,int arg150,int arg151,int arg152,int arg153,int arg154,int arg155,int arg156,int arg157,int arg158,int arg159,int arg160,int arg161,int arg162,int arg163,int arg164,int arg165,int arg166,int arg167,int arg168,int arg169,int arg170,int arg171,int arg172,int arg173,int arg174,int arg175,int arg176,int arg177,int arg178,int arg179,int arg180,int arg181,int arg182,int arg183,int arg184,int arg185,int arg186,int arg187,int arg188,int arg189,int arg190,int arg191,int arg192,int arg193,int arg194,int arg195,int arg196,int arg197,int arg198,int arg199,int arg200,int arg201,int arg202,int arg203,int arg204,int arg205,int arg206,int arg207,int arg208,int arg209,int arg210,int arg211,int arg212,int arg213,int arg214,int arg215,int arg216,int arg217,int arg218,int arg219,int arg220,int arg221,int arg222,int arg223,int arg224,int arg225,int arg226,int arg227,int arg228,int arg229,int arg230,int arg231,int arg232,int arg233,int arg234,int arg235,int arg236,int arg237,int arg238,int arg239,int arg240,int arg241,int arg242,int arg243,int arg244,int arg245,int arg246,int arg247,int arg248,int arg249,int arg250,int arg251,int arg252,int arg253,int arg254,int arg255,int arg256,int arg257,int arg258,int arg259,int arg260,int arg261,int arg262,int arg263,int arg264,int arg265,int arg266,int arg267,int arg268,int arg269,int arg270,int arg271,int arg272,int arg273,int arg274,int arg275,int arg276,int arg277,int arg278,int arg279,int arg280,int arg281,int arg282,int arg283,int arg284,int arg285,int arg286,int arg287,int arg288,int arg289,int arg290,int arg291,int arg292,int arg293,int arg294,int arg295,int arg296,int arg297,int arg298,int arg299,int arg300,int arg301,int arg302,int arg303,int arg304,int arg305,int arg306,int arg307,int arg308,int arg309,int arg310,int arg311,int arg312,int arg313,int arg314,int arg315,int arg316,int arg317,int arg318,int arg319,int arg320,int arg321,int arg322,int arg323,int arg324,int arg325,int arg326,int arg327,int arg328,int arg329,int arg330,int arg331,int arg332,int arg333,int arg334,int arg335,int arg336,int arg337,int arg338,int arg339,int arg340,int arg341,int arg342,int arg343,int arg344,int arg345,int arg346,int arg347,int arg348,int arg349,int arg350,int arg351,int arg352,int arg353,int arg354,int arg355,int arg356,int arg357,int arg358,int arg359,int arg360,int arg361,int arg362,int arg363,int arg364,int arg365,int arg366,int arg367,int arg368,int arg369,int arg370,int arg371,int arg372,int arg373,int arg374,int arg375,int arg376,int arg377,int arg378,int arg379,int arg380,int arg381,int arg382,int arg383,int arg384,int arg385,int arg386,int arg387,int arg388,int arg389,int arg390,int arg391,int arg392,int arg393,int arg394,int arg395,int arg396,int arg397,int arg398,int arg399,int arg400,int arg401,int arg402,int arg403,int arg404,int arg405,int arg406,int arg407,int arg408,int arg409,int arg410,int arg411,int arg412,int arg413,int arg414,int arg415,int arg416,int arg417,int arg418,int arg419,int arg420,int arg421,int arg422,int arg423,int arg424,int arg425,int arg426,int arg427,int arg428,int arg429,int arg430,int arg431,int arg432,int arg433,int arg434,int arg435,int arg436,int arg437,int arg438,int arg439,int arg440,int arg441,int arg442,int arg443,int arg444,int arg445,int arg446,int arg447,int arg448,int arg449,int arg450,int arg451,int arg452,int arg453,int arg454,int arg455,int arg456,int arg457,int arg458,int arg459,int arg460,int arg461,int arg462,int arg463,int arg464,int arg465,int arg466,int arg467,int arg468,int arg469,int arg470,int arg471,int arg472,int arg473,int arg474,int arg475,int arg476,int arg477,int arg478,int arg479,int arg480,int arg481,int arg482,int arg483,int arg484,int arg485,int arg486,int arg487,int arg488,int arg489,int arg490,int arg491,int arg492,int arg493,int arg494,int arg495,int arg496,int arg497,int arg498,int arg499,int arg500,int arg501,int arg502,int arg503,int arg504,int arg505,int arg506,int arg507,int arg508,int arg509,int arg510,int arg511,int arg512,int arg513,int arg514,int arg515,int arg516,int arg517,int arg518,int arg519,int arg520,int arg521,int arg522,int arg523,int arg524,int arg525,int arg526,int arg527,int arg528,int arg529,int arg530,int arg531,int arg532,int arg533,int arg534,int arg535,int arg536,int arg537,int arg538,int arg539,int arg540,int arg541,int arg542,int arg543,int arg544,int arg545,int arg546,int arg547,int arg548,int arg549,int arg550,int arg551,int arg552,int arg553,int arg554,int arg555,int arg556,int arg557,int arg558,int arg559,int arg560,int arg561,int arg562,int arg563,int arg564,int arg565,int arg566,int arg567,int arg568,int arg569,int arg570,int arg571,int arg572,int arg573,int arg574,int arg575,int arg576,int arg577,int arg578,int arg579,int arg580,int arg581,int arg582,int arg583,int arg584,int arg585,int arg586,int arg587,int arg588,int arg589,int arg590,int arg591,int arg592,int arg593,int arg594,int arg595,int arg596,int arg597,int arg598,int arg599,int arg600,int arg601,int arg602,int arg603,int arg604,int arg605,int arg606,int arg607,int arg608,int arg609,int arg610,int arg611,int arg612,int arg613,int arg614,int arg615,int arg616,int arg617,int arg618,int arg619,int arg620,int arg621,int arg622,int arg623,int arg624,int arg625,int arg626,int arg627,int arg628,int arg629,int arg630,int arg631,int arg632,int arg633,int arg634,int arg635,int arg636,int arg637,int arg638,int arg639,int arg640,int arg641,int arg642,int arg643,int arg644,int arg645,int arg646,int arg647,int arg648,int arg649,int arg650,int arg651,int arg652,int arg653,int arg654,int arg655,int arg656,int arg657,int arg658,int arg659,int arg660,int arg661,int arg662,int arg663,int arg664,int arg665,int arg666,int arg667,int arg668,int arg669,int arg670,int arg671,int arg672,int arg673,int arg674,int arg675,int arg676,int arg677,int arg678,int arg679,int arg680,int arg681,int arg682,int arg683,int arg684,int arg685,int arg686,int arg687,int arg688,int arg689,int arg690,int arg691,int arg692,int arg693,int arg694,int arg695,int arg696,int arg697,int arg698,int arg699,int arg700,int arg701,int arg702,int arg703,int arg704,int arg705,int arg706,int arg707,int arg708,int arg709,int arg710,int arg711,int arg712,int arg713,int arg714,int arg715,int arg716,int arg717,int arg718,int arg719,int arg720,int arg721,int arg722,int arg723,int arg724,int arg725,int arg726,int arg727,int arg728,int arg729,int arg730,int arg731,int arg732,int arg733,int arg734,int arg735,int arg736,int arg737,int arg738,int arg739,int arg740,int arg741,int arg742,int arg743,int arg744,int arg745,int arg746,int arg747,int arg748,int arg749,int arg750,int arg751,int arg752,int arg753,int arg754,int arg755,int arg756,int arg757,int arg758,int arg759,int arg760,int arg761,int arg762,int arg763,int arg764,int arg765,int arg766,int arg767,int arg768,int arg769,int arg770,int arg771,int arg772,int arg773,int arg774,int arg775,int arg776,int arg777,int arg778,int arg779,int arg780,int arg781,int arg782,int arg783,int arg784,int arg785,int arg786,int arg787,int arg788,int arg789,int arg790,int arg791,int arg792,int arg793,int arg794,int arg795,int arg796,int arg797,int arg798,int arg799,int arg800,int arg801,int arg802,int arg803,int arg804,int arg805,int arg806,int arg807,int arg808,int arg809,int arg810,int arg811,int arg812,int arg813,int arg814,int arg815,int arg816,int arg817,int arg818,int arg819,int arg820,int arg821,int arg822,int arg823,int arg824,int arg825,int arg826,int arg827,int arg828,int arg829,int arg830,int arg831,int arg832,int arg833,int arg834,int arg835,int arg836,int arg837,int arg838,int arg839,int arg840,int arg841,int arg842,int arg843,int arg844,int arg845,int arg846,int arg847,int arg848,int arg849,int arg850,int arg851,int arg852,int arg853,int arg854,int arg855,int arg856,int arg857,int arg858,int arg859,int arg860,int arg861,int arg862,int arg863,int arg864,int arg865,int arg866,int arg867,int arg868,int arg869,int arg870,int arg871,int arg872,int arg873,int arg874,int arg875,int arg876,int arg877,int arg878,int arg879,int arg880,int arg881,int arg882,int arg883,int arg884,int arg885,int arg886,int arg887,int arg888,int arg889,int arg890,int arg891,int arg892,int arg893,int arg894,int arg895,int arg896,int arg897,int arg898,int arg899,int arg900,int arg901,int arg902,int arg903,int arg904,int arg905,int arg906,int arg907,int arg908,int arg909,int arg910,int arg911,int arg912,int arg913,int arg914,int arg915,int arg916,int arg917,int arg918,int arg919,int arg920,int arg921,int arg922,int arg923,int arg924,int arg925,int arg926,int arg927,int arg928,int arg929,int arg930,int arg931,int arg932,int arg933,int arg934,int arg935,int arg936,int arg937,int arg938,int arg939,int arg940,int arg941,int arg942,int arg943,int arg944,int arg945,int arg946,int arg947,int arg948,int arg949,int arg950,int arg951,int arg952,int arg953,int arg954,int arg955,int arg956,int arg957,int arg958,int arg959,int arg960,int arg961,int arg962,int arg963,int arg964,int arg965,int arg966,int arg967,int arg968,int arg969,int arg970,int arg971,int arg972,int arg973,int arg974,int arg975,int arg976,int arg977,int arg978,int arg979,int arg980,int arg981,int arg982,int arg983,int arg984,int arg985,int arg986,int arg987,int arg988,int arg989,int arg990,int arg991,int arg992,int arg993,int arg994,int arg995,int arg996,int arg997,int arg998,int arg999,int arg1000,int arg1001,int arg1002,int arg1003,int arg1004,int arg1005,int arg1006,int arg1007,int arg1008,int arg1009,int arg1010,int arg1011,int arg1012,int arg1013,int arg1014,int arg1015,int arg1016,int arg1017,int arg1018,int arg1019,int arg1020,int arg1021,int arg1022,int arg1023,int arg1024,int arg1025,int arg1026,int arg1027,int arg1028,int arg1029,int arg1030,int arg1031,int arg1032,int arg1033,int arg1034,int arg1035,int arg1036,int arg1037,int arg1038,int arg1039,int arg1040,int arg1041,int arg1042,int arg1043,int arg1044,int arg1045,int arg1046,int arg1047,int arg1048,int arg1049,int arg1050,int arg1051,int arg1052,int arg1053,int arg1054,int arg1055,int arg1056,int arg1057,int arg1058,int arg1059,int arg1060,int arg1061,int arg1062,int arg1063,int arg1064,int arg1065,int arg1066,int arg1067,int arg1068,int arg1069,int arg1070,int arg1071,int arg1072,int arg1073,int arg1074,int arg1075,int arg1076,int arg1077,int arg1078,int arg1079,int arg1080,int arg1081,int arg1082,int arg1083,int arg1084,int arg1085,int arg1086,int arg1087,int arg1088,int arg1089,int arg1090,int arg1091,int arg1092,int arg1093,int arg1094,int arg1095,int arg1096,int arg1097,int arg1098,int arg1099,int arg1100,int arg1101,int arg1102,int arg1103,int arg1104,int arg1105,int arg1106,int arg1107,int arg1108,int arg1109,int arg1110,int arg1111,int arg1112,int arg1113,int arg1114,int arg1115,int arg1116,int arg1117,int arg1118,int arg1119,int arg1120,int arg1121,int arg1122,int arg1123,int arg1124,int arg1125,int arg1126,int arg1127,int arg1128,int arg1129,int arg1130,int arg1131,int arg1132,int arg1133,int arg1134,int arg1135,int arg1136,int arg1137,int arg1138,int arg1139,int arg1140,int arg1141,int arg1142,int arg1143,int arg1144,int arg1145,int arg1146,int arg1147,int arg1148,int arg1149,int arg1150,int arg1151,int arg1152,int arg1153,int arg1154,int arg1155,int arg1156,int arg1157,int arg1158,int arg1159,int arg1160,int arg1161,int arg1162,int arg1163,int arg1164,int arg1165,int arg1166,int arg1167,int arg1168,int arg1169,int arg1170,int arg1171,int arg1172,int arg1173,int arg1174,int arg1175,int arg1176,int arg1177,int arg1178,int arg1179,int arg1180,int arg1181,int arg1182,int arg1183,int arg1184,int arg1185,int arg1186,int arg1187,int arg1188,int arg1189,int arg1190,int arg1191,int arg1192,int arg1193,int arg1194,int arg1195,int arg1196,int arg1197,int arg1198,int arg1199,int arg1200,int arg1201,int arg1202,int arg1203,int arg1204,int arg1205,int arg1206,int arg1207,int arg1208,int arg1209,int arg1210,int arg1211,int arg1212,int arg1213,int arg1214,int arg1215,int arg1216,int arg1217,int arg1218,int arg1219,int arg1220,int arg1221,int arg1222,int arg1223,int arg1224,int arg1225,int arg1226,int arg1227,int arg1228,int arg1229,int arg1230,int arg1231,int arg1232,int arg1233,int arg1234,int arg1235,int arg1236,int arg1237,int arg1238,int arg1239,int arg1240,int arg1241,int arg1242,int arg1243,int arg1244,int arg1245,int arg1246,int arg1247,int arg1248,int arg1249,int arg1250,int arg1251,int arg1252,int arg1253,int arg1254,int arg1255,int arg1256,int arg1257,int arg1258,int arg1259,int arg1260,int arg1261,int arg1262,int arg1263,int arg1264,int arg1265,int arg1266,int arg1267,int arg1268,int arg1269,int arg1270,int arg1271,int arg1272,int arg1273,int arg1274,int arg1275,int arg1276,int arg1277,int arg1278,int arg1279,int arg1280,int arg1281,int arg1282,int arg1283,int arg1284,int arg1285,int arg1286,int arg1287,int arg1288,int arg1289,int arg1290,int arg1291,int arg1292,int arg1293,int arg1294,int arg1295,int arg1296,int arg1297,int arg1298,int arg1299,int arg1300,int arg1301,int arg1302,int arg1303,int arg1304,int arg1305,int arg1306,int arg1307,int arg1308,int arg1309,int arg1310,int arg1311,int arg1312,int arg1313,int arg1314,int arg1315,int arg1316,int arg1317,int arg1318,int arg1319,int arg1320,int arg1321,int arg1322,int arg1323,int arg1324,int arg1325,int arg1326,int arg1327,int arg1328,int arg1329,int arg1330,int arg1331,int arg1332,int arg1333,int arg1334,int arg1335,int arg1336,int arg1337,int arg1338,int arg1339,int arg1340,int arg1341,int arg1342,int arg1343,int arg1344,int arg1345,int arg1346,int arg1347,int arg1348,int arg1349,int arg1350,int arg1351,int arg1352,int arg1353,int arg1354,int arg1355,int arg1356,int arg1357,int arg1358,int arg1359,int arg1360,int arg1361,int arg1362,int arg1363,int arg1364,int arg1365,int arg1366,int arg1367,int arg1368,int arg1369,int arg1370,int arg1371,int arg1372,int arg1373,int arg1374,int arg1375,int arg1376,int arg1377,int arg1378,int arg1379,int arg1380,int arg1381,int arg1382,int arg1383,int arg1384,int arg1385,int arg1386,int arg1387,int arg1388,int arg1389,int arg1390,int arg1391,int arg1392,int arg1393,int arg1394,int arg1395,int arg1396,int arg1397,int arg1398,int arg1399,int arg1400,int arg1401,int arg1402,int arg1403,int arg1404,int arg1405,int arg1406,int arg1407,int arg1408,int arg1409,int arg1410,int arg1411,int arg1412,int arg1413,int arg1414,int arg1415,int arg1416,int arg1417,int arg1418,int arg1419,int arg1420,int arg1421,int arg1422,int arg1423,int arg1424,int arg1425,int arg1426,int arg1427,int arg1428,int arg1429,int arg1430,int arg1431,int arg1432,int arg1433,int arg1434,int arg1435,int arg1436,int arg1437,int arg1438,int arg1439,int arg1440,int arg1441,int arg1442,int arg1443,int arg1444,int arg1445,int arg1446,int arg1447,int arg1448,int arg1449,int arg1450,int arg1451,int arg1452,int arg1453,int arg1454,int arg1455,int arg1456,int arg1457,int arg1458,int arg1459,int arg1460,int arg1461,int arg1462,int arg1463,int arg1464,int arg1465,int arg1466,int arg1467,int arg1468,int arg1469,int arg1470,int arg1471,int arg1472,int arg1473,int arg1474,int arg1475,int arg1476,int arg1477,int arg1478,int arg1479,int arg1480,int arg1481,int arg1482,int arg1483,int arg1484,int arg1485,int arg1486,int arg1487,int arg1488,int arg1489,int arg1490,int arg1491,int arg1492,int arg1493,int arg1494,int arg1495,int arg1496,int arg1497,int arg1498,int arg1499,int arg1500,int arg1501,int arg1502,int arg1503,int arg1504,int arg1505,int arg1506,int arg1507,int arg1508,int arg1509,int arg1510,int arg1511,int arg1512,int arg1513,int arg1514,int arg1515,int arg1516,int arg1517,int arg1518,int arg1519,int arg1520,int arg1521,int arg1522,int arg1523,int arg1524,int arg1525,int arg1526,int arg1527,int arg1528,int arg1529,int arg1530,int arg1531,int arg1532,int arg1533,int arg1534,int arg1535,int arg1536,int arg1537,int arg1538,int arg1539,int arg1540,int arg1541,int arg1542,int arg1543,int arg1544,int arg1545,int arg1546,int arg1547,int arg1548,int arg1549,int arg1550,int arg1551,int arg1552,int arg1553,int arg1554,int arg1555,int arg1556,int arg1557,int arg1558,int arg1559,int arg1560,int arg1561,int arg1562,int arg1563,int arg1564,int arg1565,int arg1566,int arg1567,int arg1568,int arg1569,int arg1570,int arg1571,int arg1572,int arg1573,int arg1574,int arg1575,int arg1576,int arg1577,int arg1578,int arg1579,int arg1580,int arg1581,int arg1582,int arg1583,int arg1584,int arg1585,int arg1586,int arg1587,int arg1588,int arg1589,int arg1590,int arg1591,int arg1592,int arg1593,int arg1594,int arg1595,int arg1596,int arg1597,int arg1598,int arg1599,int arg1600,int arg1601,int arg1602,int arg1603,int arg1604,int arg1605,int arg1606,int arg1607,int arg1608,int arg1609,int arg1610,int arg1611,int arg1612,int arg1613,int arg1614,int arg1615,int arg1616,int arg1617,int arg1618,int arg1619,int arg1620,int arg1621,int arg1622,int arg1623,int arg1624,int arg1625,int arg1626,int arg1627,int arg1628,int arg1629,int arg1630,int arg1631,int arg1632,int arg1633,int arg1634,int arg1635,int arg1636,int arg1637,int arg1638,int arg1639,int arg1640,int arg1641,int arg1642,int arg1643,int arg1644,int arg1645,int arg1646,int arg1647,int arg1648,int arg1649,int arg1650,int arg1651,int arg1652,int arg1653,int arg1654,int arg1655,int arg1656,int arg1657,int arg1658,int arg1659,int arg1660,int arg1661,int arg1662,int arg1663,int arg1664,int arg1665,int arg1666,int arg1667,int arg1668,int arg1669,int arg1670,int arg1671,int arg1672,int arg1673,int arg1674,int arg1675,int arg1676,int arg1677,int arg1678,int arg1679,int arg1680,int arg1681,int arg1682,int arg1683,int arg1684,int arg1685,int arg1686,int arg1687,int arg1688,int arg1689,int arg1690,int arg1691,int arg1692,int arg1693,int arg1694,int arg1695,int arg1696,int arg1697,int arg1698,int arg1699,int arg1700,int arg1701,int arg1702,int arg1703,int arg1704,int arg1705,int arg1706,int arg1707,int arg1708,int arg1709,int arg1710,int arg1711,int arg1712,int arg1713,int arg1714,int arg1715,int arg1716,int arg1717,int arg1718,int arg1719,int arg1720,int arg1721,int arg1722,int arg1723,int arg1724,int arg1725,int arg1726,int arg1727,int arg1728,int arg1729,int arg1730,int arg1731,int arg1732,int arg1733,int arg1734,int arg1735,int arg1736,int arg1737,int arg1738,int arg1739,int arg1740,int arg1741,int arg1742,int arg1743,int arg1744,int arg1745,int arg1746,int arg1747,int arg1748,int arg1749,int arg1750,int arg1751,int arg1752,int arg1753,int arg1754,int arg1755,int arg1756,int arg1757,int arg1758,int arg1759,int arg1760,int arg1761,int arg1762,int arg1763,int arg1764,int arg1765,int arg1766,int arg1767,int arg1768,int arg1769,int arg1770,int arg1771,int arg1772,int arg1773,int arg1774,int arg1775,int arg1776,int arg1777,int arg1778,int arg1779,int arg1780,int arg1781,int arg1782,int arg1783,int arg1784,int arg1785,int arg1786,int arg1787,int arg1788,int arg1789,int arg1790,int arg1791,int arg1792,int arg1793,int arg1794,int arg1795,int arg1796,int arg1797,int arg1798,int arg1799,int arg1800,int arg1801,int arg1802,int arg1803,int arg1804,int arg1805,int arg1806,int arg1807,int arg1808,int arg1809,int arg1810,int arg1811,int arg1812,int arg1813,int arg1814,int arg1815,int arg1816,int arg1817,int arg1818,int arg1819,int arg1820,int arg1821,int arg1822,int arg1823,int arg1824,int arg1825,int arg1826,int arg1827,int arg1828,int arg1829,int arg1830,int arg1831,int arg1832,int arg1833,int arg1834,int arg1835,int arg1836,int arg1837,int arg1838,int arg1839,int arg1840,int arg1841,int arg1842,int arg1843,int arg1844,int arg1845,int arg1846,int arg1847,int arg1848,int arg1849,int arg1850,int arg1851,int arg1852,int arg1853,int arg1854,int arg1855,int arg1856,int arg1857,int arg1858,int arg1859,int arg1860,int arg1861,int arg1862,int arg1863,int arg1864,int arg1865,int arg1866,int arg1867,int arg1868,int arg1869,int arg1870,int arg1871,int arg1872,int arg1873,int arg1874,int arg1875,int arg1876,int arg1877,int arg1878,int arg1879,int arg1880,int arg1881,int arg1882,int arg1883,int arg1884,int arg1885,int arg1886,int arg1887,int arg1888,int arg1889,int arg1890,int arg1891,int arg1892,int arg1893,int arg1894,int arg1895,int arg1896,int arg1897,int arg1898,int arg1899,int arg1900,int arg1901,int arg1902,int arg1903,int arg1904,int arg1905,int arg1906,int arg1907,int arg1908,int arg1909,int arg1910,int arg1911,int arg1912,int arg1913,int arg1914,int arg1915,int arg1916,int arg1917,int arg1918,int arg1919,int arg1920,int arg1921,int arg1922,int arg1923,int arg1924,int arg1925,int arg1926,int arg1927,int arg1928,int arg1929,int arg1930,int arg1931,int arg1932,int arg1933,int arg1934,int arg1935,int arg1936,int arg1937,int arg1938,int arg1939,int arg1940,int arg1941,int arg1942,int arg1943,int arg1944,int arg1945,int arg1946,int arg1947,int arg1948,int arg1949,int arg1950,int arg1951,int arg1952,int arg1953,int arg1954,int arg1955,int arg1956,int arg1957,int arg1958,int arg1959,int arg1960,int arg1961,int arg1962,int arg1963,int arg1964,int arg1965,int arg1966,int arg1967,int arg1968,int arg1969,int arg1970,int arg1971,int arg1972,int arg1973,int arg1974,int arg1975,int arg1976,int arg1977,int arg1978,int arg1979,int arg1980,int arg1981,int arg1982,int arg1983,int arg1984,int arg1985,int arg1986,int arg1987,int arg1988,int arg1989,int arg1990,int arg1991,int arg1992,int arg1993,int arg1994,int arg1995,int arg1996,int arg1997,int arg1998,int arg1999,int arg2000,int arg2001,int arg2002,int arg2003,int arg2004,int arg2005,int arg2006,int arg2007,int arg2008,int arg2009,int arg2010,int arg2011,int arg2012,int arg2013,int arg2014,int arg2015,int arg2016,int arg2017,int arg2018,int arg2019,int arg2020,int arg2021,int arg2022,int arg2023,int arg2024,int arg2025,int arg2026,int arg2027,int arg2028,int arg2029,int arg2030,int arg2031,int arg2032,int arg2033,int arg2034,int arg2035,int arg2036,int arg2037,int arg2038,int arg2039,int arg2040,int arg2041,int arg2042,int arg2043,int arg2044,int arg2045,int arg2046,int arg2047,int arg2048,int arg2049,int arg2050,int arg2051,int arg2052,int arg2053,int arg2054,int arg2055,int arg2056,int arg2057,int arg2058,int arg2059,int arg2060,int arg2061,int arg2062,int arg2063,int arg2064,int arg2065,int arg2066,int arg2067,int arg2068,int arg2069,int arg2070,int arg2071,int arg2072,int arg2073,int arg2074,int arg2075,int arg2076,int arg2077,int arg2078,int arg2079,int arg2080,int arg2081,int arg2082,int arg2083,int arg2084,int arg2085,int arg2086,int arg2087,int arg2088,int arg2089,int arg2090,int arg2091,int arg2092,int arg2093,int arg2094,int arg2095,int arg2096,int arg2097,int arg2098,int arg2099,int arg2100,int arg2101,int arg2102,int arg2103,int arg2104,int arg2105,int arg2106,int arg2107,int arg2108,int arg2109,int arg2110,int arg2111,int arg2112,int arg2113,int arg2114,int arg2115,int arg2116,int arg2117,int arg2118,int arg2119,int arg2120,int arg2121,int arg2122,int arg2123,int arg2124,int arg2125,int arg2126,int arg2127,int arg2128,int arg2129,int arg2130,int arg2131,int arg2132,int arg2133,int arg2134,int arg2135,int arg2136,int arg2137,int arg2138,int arg2139,int arg2140,int arg2141,int arg2142,int arg2143,int arg2144,int arg2145,int arg2146,int arg2147,int arg2148,int arg2149,int arg2150,int arg2151,int arg2152,int arg2153,int arg2154,int arg2155,int arg2156,int arg2157,int arg2158,int arg2159,int arg2160,int arg2161,int arg2162,int arg2163,int arg2164,int arg2165,int arg2166,int arg2167,int arg2168,int arg2169,int arg2170,int arg2171,int arg2172,int arg2173,int arg2174,int arg2175,int arg2176,int arg2177,int arg2178,int arg2179,int arg2180,int arg2181,int arg2182,int arg2183,int arg2184,int arg2185,int arg2186,int arg2187,int arg2188,int arg2189,int arg2190,int arg2191,int arg2192,int arg2193,int arg2194,int arg2195,int arg2196,int arg2197,int arg2198,int arg2199,int arg2200,int arg2201,int arg2202,int arg2203,int arg2204,int arg2205,int arg2206,int arg2207,int arg2208,int arg2209,int arg2210,int arg2211,int arg2212,int arg2213,int arg2214,int arg2215,int arg2216,int arg2217,int arg2218,int arg2219,int arg2220,int arg2221,int arg2222,int arg2223,int arg2224,int arg2225,int arg2226,int arg2227,int arg2228,int arg2229,int arg2230,int arg2231,int arg2232,int arg2233,int arg2234,int arg2235,int arg2236,int arg2237,int arg2238,int arg2239,int arg2240,int arg2241,int arg2242,int arg2243,int arg2244,int arg2245,int arg2246,int arg2247,int arg2248,int arg2249,int arg2250,int arg2251,int arg2252,int arg2253,int arg2254,int arg2255,int arg2256,int arg2257,int arg2258,int arg2259,int arg2260,int arg2261,int arg2262,int arg2263,int arg2264,int arg2265,int arg2266,int arg2267,int arg2268,int arg2269,int arg2270,int arg2271,int arg2272,int arg2273,int arg2274,int arg2275,int arg2276,int arg2277,int arg2278,int arg2279,int arg2280,int arg2281,int arg2282,int arg2283,int arg2284,int arg2285,int arg2286,int arg2287,int arg2288,int arg2289,int arg2290,int arg2291,int arg2292,int arg2293,int arg2294,int arg2295,int arg2296,int arg2297,int arg2298,int arg2299,int arg2300,int arg2301,int arg2302,int arg2303,int arg2304,int arg2305,int arg2306,int arg2307,int arg2308,int arg2309,int arg2310,int arg2311,int arg2312,int arg2313,int arg2314,int arg2315,int arg2316,int arg2317,int arg2318,int arg2319,int arg2320,int arg2321,int arg2322,int arg2323,int arg2324,int arg2325,int arg2326,int arg2327,int arg2328,int arg2329,int arg2330,int arg2331,int arg2332,int arg2333,int arg2334,int arg2335,int arg2336,int arg2337,int arg2338,int arg2339,int arg2340,int arg2341,int arg2342,int arg2343,int arg2344,int arg2345,int arg2346,int arg2347,int arg2348,int arg2349,int arg2350,int arg2351,int arg2352,int arg2353,int arg2354,int arg2355,int arg2356,int arg2357,int arg2358,int arg2359,int arg2360,int arg2361,int arg2362,int arg2363,int arg2364,int arg2365,int arg2366,int arg2367,int arg2368,int arg2369,int arg2370,int arg2371,int arg2372,int arg2373,int arg2374,int arg2375,int arg2376,int arg2377,int arg2378,int arg2379,int arg2380,int arg2381,int arg2382,int arg2383,int arg2384,int arg2385,int arg2386,int arg2387,int arg2388,int arg2389,int arg2390,int arg2391,int arg2392,int arg2393,int arg2394,int arg2395,int arg2396,int arg2397,int arg2398,int arg2399,int arg2400,int arg2401,int arg2402,int arg2403,int arg2404,int arg2405,int arg2406,int arg2407,int arg2408,int arg2409,int arg2410,int arg2411,int arg2412,int arg2413,int arg2414,int arg2415,int arg2416,int arg2417,int arg2418,int arg2419,int arg2420,int arg2421,int arg2422,int arg2423,int arg2424,int arg2425,int arg2426,int arg2427,int arg2428,int arg2429,int arg2430,int arg2431,int arg2432,int arg2433,int arg2434,int arg2435,int arg2436,int arg2437,int arg2438,int arg2439,int arg2440,int arg2441,int arg2442,int arg2443,int arg2444,int arg2445,int arg2446,int arg2447,int arg2448,int arg2449,int arg2450,int arg2451,int arg2452,int arg2453,int arg2454,int arg2455,int arg2456,int arg2457,int arg2458,int arg2459,int arg2460,int arg2461,int arg2462,int arg2463,int arg2464,int arg2465,int arg2466,int arg2467,int arg2468,int arg2469,int arg2470,int arg2471,int arg2472,int arg2473,int arg2474,int arg2475,int arg2476,int arg2477,int arg2478,int arg2479,int arg2480,int arg2481,int arg2482,int arg2483,int arg2484,int arg2485,int arg2486,int arg2487,int arg2488,int arg2489,int arg2490,int arg2491,int arg2492,int arg2493,int arg2494,int arg2495,int arg2496,int arg2497,int arg2498,int arg2499,int arg2500,int arg2501,int arg2502,int arg2503,int arg2504,int arg2505,int arg2506,int arg2507,int arg2508,int arg2509,int arg2510,int arg2511,int arg2512,int arg2513,int arg2514,int arg2515,int arg2516,int arg2517,int arg2518,int arg2519,int arg2520,int arg2521,int arg2522,int arg2523,int arg2524,int arg2525,int arg2526,int arg2527,int arg2528,int arg2529,int arg2530,int arg2531,int arg2532,int arg2533,int arg2534,int arg2535,int arg2536,int arg2537,int arg2538,int arg2539,int arg2540,int arg2541,int arg2542,int arg2543,int arg2544,int arg2545,int arg2546,int arg2547,int arg2548,int arg2549,int arg2550,int arg2551,int arg2552,int arg2553,int arg2554,int arg2555,int arg2556,int arg2557,int arg2558,int arg2559,int arg2560,int arg2561,int arg2562,int arg2563,int arg2564,int arg2565,int arg2566,int arg2567,int arg2568,int arg2569,int arg2570,int arg2571,int arg2572,int arg2573,int arg2574,int arg2575,int arg2576,int arg2577,int arg2578,int arg2579,int arg2580,int arg2581,int arg2582,int arg2583,int arg2584,int arg2585,int arg2586,int arg2587,int arg2588,int arg2589,int arg2590,int arg2591,int arg2592,int arg2593,int arg2594,int arg2595,int arg2596,int arg2597,int arg2598,int arg2599,int arg2600,int arg2601,int arg2602,int arg2603,int arg2604,int arg2605,int arg2606,int arg2607,int arg2608,int arg2609,int arg2610,int arg2611,int arg2612,int arg2613,int arg2614,int arg2615,int arg2616,int arg2617,int arg2618,int arg2619,int arg2620,int arg2621,int arg2622,int arg2623,int arg2624,int arg2625,int arg2626,int arg2627,int arg2628,int arg2629,int arg2630,int arg2631,int arg2632,int arg2633,int arg2634,int arg2635,int arg2636,int arg2637,int arg2638,int arg2639,int arg2640,int arg2641,int arg2642,int arg2643,int arg2644,int arg2645,int arg2646,int arg2647,int arg2648,int arg2649,int arg2650,int arg2651,int arg2652,int arg2653,int arg2654,int arg2655,int arg2656,int arg2657,int arg2658,int arg2659,int arg2660,int arg2661,int arg2662,int arg2663,int arg2664,int arg2665,int arg2666,int arg2667,int arg2668,int arg2669,int arg2670,int arg2671,int arg2672,int arg2673,int arg2674,int arg2675,int arg2676,int arg2677,int arg2678,int arg2679,int arg2680,int arg2681,int arg2682,int arg2683,int arg2684,int arg2685,int arg2686,int arg2687,int arg2688,int arg2689,int arg2690,int arg2691,int arg2692,int arg2693,int arg2694,int arg2695,int arg2696,int arg2697,int arg2698,int arg2699,int arg2700,int arg2701,int arg2702,int arg2703,int arg2704,int arg2705,int arg2706,int arg2707,int arg2708,int arg2709,int arg2710,int arg2711,int arg2712,int arg2713,int arg2714,int arg2715,int arg2716,int arg2717,int arg2718,int arg2719,int arg2720,int arg2721,int arg2722,int arg2723,int arg2724,int arg2725,int arg2726,int arg2727,int arg2728,int arg2729,int arg2730,int arg2731,int arg2732,int arg2733,int arg2734,int arg2735,int arg2736,int arg2737,int arg2738,int arg2739,int arg2740,int arg2741,int arg2742,int arg2743,int arg2744,int arg2745,int arg2746,int arg2747,int arg2748,int arg2749,int arg2750,int arg2751,int arg2752,int arg2753,int arg2754,int arg2755,int arg2756,int arg2757,int arg2758,int arg2759,int arg2760,int arg2761,int arg2762,int arg2763,int arg2764,int arg2765,int arg2766,int arg2767,int arg2768,int arg2769,int arg2770,int arg2771,int arg2772,int arg2773,int arg2774,int arg2775,int arg2776,int arg2777,int arg2778,int arg2779,int arg2780,int arg2781,int arg2782,int arg2783,int arg2784,int arg2785,int arg2786,int arg2787,int arg2788,int arg2789,int arg2790,int arg2791,int arg2792,int arg2793,int arg2794,int arg2795,int arg2796,int arg2797,int arg2798,int arg2799,int arg2800,int arg2801,int arg2802,int arg2803,int arg2804,int arg2805,int arg2806,int arg2807,int arg2808,int arg2809,int arg2810,int arg2811,int arg2812,int arg2813,int arg2814,int arg2815,int arg2816,int arg2817,int arg2818,int arg2819,int arg2820,int arg2821,int arg2822,int arg2823,int arg2824,int arg2825,int arg2826,int arg2827,int arg2828,int arg2829,int arg2830,int arg2831,int arg2832,int arg2833,int arg2834,int arg2835,int arg2836,int arg2837,int arg2838,int arg2839,int arg2840,int arg2841,int arg2842,int arg2843,int arg2844,int arg2845,int arg2846,int arg2847,int arg2848,int arg2849,int arg2850,int arg2851,int arg2852,int arg2853,int arg2854,int arg2855,int arg2856,int arg2857,int arg2858,int arg2859,int arg2860,int arg2861,int arg2862,int arg2863,int arg2864,int arg2865,int arg2866,int arg2867,int arg2868,int arg2869,int arg2870,int arg2871,int arg2872,int arg2873,int arg2874,int arg2875,int arg2876,int arg2877,int arg2878,int arg2879,int arg2880,int arg2881,int arg2882,int arg2883,int arg2884,int arg2885,int arg2886,int arg2887,int arg2888,int arg2889,int arg2890,int arg2891,int arg2892,int arg2893,int arg2894,int arg2895,int arg2896,int arg2897,int arg2898,int arg2899,int arg2900,int arg2901,int arg2902,int arg2903,int arg2904,int arg2905,int arg2906,int arg2907,int arg2908,int arg2909,int arg2910,int arg2911,int arg2912,int arg2913,int arg2914,int arg2915,int arg2916,int arg2917,int arg2918,int arg2919,int arg2920,int arg2921,int arg2922,int arg2923,int arg2924,int arg2925,int arg2926,int arg2927,int arg2928,int arg2929,int arg2930,int arg2931,int arg2932,int arg2933,int arg2934,int arg2935,int arg2936,int arg2937,int arg2938,int arg2939,int arg2940,int arg2941,int arg2942,int arg2943,int arg2944,int arg2945,int arg2946,int arg2947,int arg2948,int arg2949,int arg2950,int arg2951,int arg2952,int arg2953,int arg2954,int arg2955,int arg2956,int arg2957,int arg2958,int arg2959,int arg2960,int arg2961,int arg2962,int arg2963,int arg2964,int arg2965,int arg2966,int arg2967,int arg2968,int arg2969,int arg2970,int arg2971,int arg2972,int arg2973,int arg2974,int arg2975,int arg2976,int arg2977,int arg2978,int arg2979,int arg2980,int arg2981,int arg2982,int arg2983,int arg2984,int arg2985,int arg2986,int arg2987,int arg2988,int arg2989,int arg2990,int arg2991,int arg2992,int arg2993,int arg2994,int arg2995,int arg2996,int arg2997,int arg2998,int arg2999,int arg3000,int arg3001,int arg3002,int arg3003,int arg3004,int arg3005,int arg3006,int arg3007,int arg3008,int arg3009,int arg3010,int arg3011,int arg3012,int arg3013,int arg3014,int arg3015,int arg3016,int arg3017,int arg3018,int arg3019,int arg3020,int arg3021,int arg3022,int arg3023,int arg3024,int arg3025,int arg3026,int arg3027,int arg3028,int arg3029,int arg3030,int arg3031,int arg3032,int arg3033,int arg3034,int arg3035,int arg3036,int arg3037,int arg3038,int arg3039,int arg3040,int arg3041,int arg3042,int arg3043,int arg3044,int arg3045,int arg3046,int arg3047,int arg3048,int arg3049,int arg3050,int arg3051,int arg3052,int arg3053,int arg3054,int arg3055,int arg3056,int arg3057,int arg3058,int arg3059,int arg3060,int arg3061,int arg3062,int arg3063,int arg3064,int arg3065,int arg3066,int arg3067,int arg3068,int arg3069,int arg3070,int arg3071,int arg3072,int arg3073,int arg3074,int arg3075,int arg3076,int arg3077,int arg3078,int arg3079,int arg3080,int arg3081,int arg3082,int arg3083,int arg3084,int arg3085,int arg3086,int arg3087,int arg3088,int arg3089,int arg3090,int arg3091,int arg3092,int arg3093,int arg3094,int arg3095,int arg3096,int arg3097,int arg3098,int arg3099,int arg3100,int arg3101,int arg3102,int arg3103,int arg3104,int arg3105,int arg3106,int arg3107,int arg3108,int arg3109,int arg3110,int arg3111,int arg3112,int arg3113,int arg3114,int arg3115,int arg3116,int arg3117,int arg3118,int arg3119,int arg3120,int arg3121,int arg3122,int arg3123,int arg3124,int arg3125,int arg3126,int arg3127,int arg3128,int arg3129,int arg3130,int arg3131,int arg3132,int arg3133,int arg3134,int arg3135,int arg3136,int arg3137,int arg3138,int arg3139,int arg3140,int arg3141,int arg3142,int arg3143,int arg3144,int arg3145,int arg3146,int arg3147,int arg3148,int arg3149,int arg3150,int arg3151,int arg3152,int arg3153,int arg3154,int arg3155,int arg3156,int arg3157,int arg3158,int arg3159,int arg3160,int arg3161,int arg3162,int arg3163,int arg3164,int arg3165,int arg3166,int arg3167,int arg3168,int arg3169,int arg3170,int arg3171,int arg3172,int arg3173,int arg3174,int arg3175,int arg3176,int arg3177,int arg3178,int arg3179,int arg3180,int arg3181,int arg3182,int arg3183,int arg3184,int arg3185,int arg3186,int arg3187,int arg3188,int arg3189,int arg3190,int arg3191,int arg3192,int arg3193,int arg3194,int arg3195,int arg3196,int arg3197,int arg3198,int arg3199,int arg3200,int arg3201,int arg3202,int arg3203,int arg3204,int arg3205,int arg3206,int arg3207,int arg3208,int arg3209,int arg3210,int arg3211,int arg3212,int arg3213,int arg3214,int arg3215,int arg3216,int arg3217,int arg3218,int arg3219,int arg3220,int arg3221,int arg3222,int arg3223,int arg3224,int arg3225,int arg3226,int arg3227,int arg3228,int arg3229,int arg3230,int arg3231,int arg3232,int arg3233,int arg3234,int arg3235,int arg3236,int arg3237,int arg3238,int arg3239,int arg3240,int arg3241,int arg3242,int arg3243,int arg3244,int arg3245,int arg3246,int arg3247,int arg3248,int arg3249,int arg3250,int arg3251,int arg3252,int arg3253,int arg3254,int arg3255,int arg3256,int arg3257,int arg3258,int arg3259,int arg3260,int arg3261,int arg3262,int arg3263,int arg3264,int arg3265,int arg3266,int arg3267,int arg3268,int arg3269,int arg3270,int arg3271,int arg3272,int arg3273,int arg3274,int arg3275,int arg3276,int arg3277,int arg3278,int arg3279,int arg3280,int arg3281,int arg3282,int arg3283,int arg3284,int arg3285,int arg3286,int arg3287,int arg3288,int arg3289,int arg3290,int arg3291,int arg3292,int arg3293,int arg3294,int arg3295,int arg3296,int arg3297,int arg3298,int arg3299,int arg3300,int arg3301,int arg3302,int arg3303,int arg3304,int arg3305,int arg3306,int arg3307,int arg3308,int arg3309,int arg3310,int arg3311,int arg3312,int arg3313,int arg3314,int arg3315,int arg3316,int arg3317,int arg3318,int arg3319,int arg3320,int arg3321,int arg3322,int arg3323,int arg3324,int arg3325,int arg3326,int arg3327,int arg3328,int arg3329,int arg3330,int arg3331,int arg3332,int arg3333,int arg3334,int arg3335,int arg3336,int arg3337,int arg3338,int arg3339,int arg3340,int arg3341,int arg3342,int arg3343,int arg3344,int arg3345,int arg3346,int arg3347,int arg3348,int arg3349,int arg3350,int arg3351,int arg3352,int arg3353,int arg3354,int arg3355,int arg3356,int arg3357,int arg3358,int arg3359,int arg3360,int arg3361,int arg3362,int arg3363,int arg3364,int arg3365,int arg3366,int arg3367,int arg3368,int arg3369,int arg3370,int arg3371,int arg3372,int arg3373,int arg3374,int arg3375,int arg3376,int arg3377,int arg3378,int arg3379,int arg3380,int arg3381,int arg3382,int arg3383,int arg3384,int arg3385,int arg3386,int arg3387,int arg3388,int arg3389,int arg3390,int arg3391,int arg3392,int arg3393,int arg3394,int arg3395,int arg3396,int arg3397,int arg3398,int arg3399,int arg3400,int arg3401,int arg3402,int arg3403,int arg3404,int arg3405,int arg3406,int arg3407,int arg3408,int arg3409,int arg3410,int arg3411,int arg3412,int arg3413,int arg3414,int arg3415,int arg3416,int arg3417,int arg3418,int arg3419,int arg3420,int arg3421,int arg3422,int arg3423,int arg3424,int arg3425,int arg3426,int arg3427,int arg3428,int arg3429,int arg3430,int arg3431,int arg3432,int arg3433,int arg3434,int arg3435,int arg3436,int arg3437,int arg3438,int arg3439,int arg3440,int arg3441,int arg3442,int arg3443,int arg3444,int arg3445,int arg3446,int arg3447,int arg3448,int arg3449,int arg3450,int arg3451,int arg3452,int arg3453,int arg3454,int arg3455,int arg3456,int arg3457,int arg3458,int arg3459,int arg3460,int arg3461,int arg3462,int arg3463,int arg3464,int arg3465,int arg3466,int arg3467,int arg3468,int arg3469,int arg3470,int arg3471,int arg3472,int arg3473,int arg3474,int arg3475,int arg3476,int arg3477,int arg3478,int arg3479,int arg3480,int arg3481,int arg3482,int arg3483,int arg3484,int arg3485,int arg3486,int arg3487,int arg3488,int arg3489,int arg3490,int arg3491,int arg3492,int arg3493,int arg3494,int arg3495,int arg3496,int arg3497,int arg3498,int arg3499,int arg3500,int arg3501,int arg3502,int arg3503,int arg3504,int arg3505,int arg3506,int arg3507,int arg3508,int arg3509,int arg3510,int arg3511,int arg3512,int arg3513,int arg3514,int arg3515,int arg3516,int arg3517,int arg3518,int arg3519,int arg3520,int arg3521,int arg3522,int arg3523,int arg3524,int arg3525,int arg3526,int arg3527,int arg3528,int arg3529,int arg3530,int arg3531,int arg3532,int arg3533,int arg3534,int arg3535,int arg3536,int arg3537,int arg3538,int arg3539,int arg3540,int arg3541,int arg3542,int arg3543,int arg3544,int arg3545,int arg3546,int arg3547,int arg3548,int arg3549,int arg3550,int arg3551,int arg3552,int arg3553,int arg3554,int arg3555,int arg3556,int arg3557,int arg3558,int arg3559,int arg3560,int arg3561,int arg3562,int arg3563,int arg3564,int arg3565,int arg3566,int arg3567,int arg3568,int arg3569,int arg3570,int arg3571,int arg3572,int arg3573,int arg3574,int arg3575,int arg3576,int arg3577,int arg3578,int arg3579,int arg3580,int arg3581,int arg3582,int arg3583,int arg3584,int arg3585,int arg3586,int arg3587,int arg3588,int arg3589,int arg3590,int arg3591,int arg3592,int arg3593,int arg3594,int arg3595,int arg3596,int arg3597,int arg3598,int arg3599,int arg3600,int arg3601,int arg3602,int arg3603,int arg3604,int arg3605,int arg3606,int arg3607,int arg3608,int arg3609,int arg3610,int arg3611,int arg3612,int arg3613,int arg3614,int arg3615,int arg3616,int arg3617,int arg3618,int arg3619,int arg3620,int arg3621,int arg3622,int arg3623,int arg3624,int arg3625,int arg3626,int arg3627,int arg3628,int arg3629,int arg3630,int arg3631,int arg3632,int arg3633,int arg3634,int arg3635,int arg3636,int arg3637,int arg3638,int arg3639,int arg3640,int arg3641,int arg3642,int arg3643,int arg3644,int arg3645,int arg3646,int arg3647,int arg3648,int arg3649,int arg3650,int arg3651,int arg3652,int arg3653,int arg3654,int arg3655,int arg3656,int arg3657,int arg3658,int arg3659,int arg3660,int arg3661,int arg3662,int arg3663,int arg3664,int arg3665,int arg3666,int arg3667,int arg3668,int arg3669,int arg3670,int arg3671,int arg3672,int arg3673,int arg3674,int arg3675,int arg3676,int arg3677,int arg3678,int arg3679,int arg3680,int arg3681,int arg3682,int arg3683,int arg3684,int arg3685,int arg3686,int arg3687,int arg3688,int arg3689,int arg3690,int arg3691,int arg3692,int arg3693,int arg3694,int arg3695,int arg3696,int arg3697,int arg3698,int arg3699,int arg3700,int arg3701,int arg3702,int arg3703,int arg3704,int arg3705,int arg3706,int arg3707,int arg3708,int arg3709,int arg3710,int arg3711,int arg3712,int arg3713,int arg3714,int arg3715,int arg3716,int arg3717,int arg3718,int arg3719,int arg3720,int arg3721,int arg3722,int arg3723,int arg3724,int arg3725,int arg3726,int arg3727,int arg3728,int arg3729,int arg3730,int arg3731,int arg3732,int arg3733,int arg3734,int arg3735,int arg3736,int arg3737,int arg3738,int arg3739,int arg3740,int arg3741,int arg3742,int arg3743,int arg3744,int arg3745,int arg3746,int arg3747,int arg3748,int arg3749,int arg3750,int arg3751,int arg3752,int arg3753,int arg3754,int arg3755,int arg3756,int arg3757,int arg3758,int arg3759,int arg3760,int arg3761,int arg3762,int arg3763,int arg3764,int arg3765,int arg3766,int arg3767,int arg3768,int arg3769,int arg3770,int arg3771,int arg3772,int arg3773,int arg3774,int arg3775,int arg3776,int arg3777,int arg3778,int arg3779,int arg3780,int arg3781,int arg3782,int arg3783,int arg3784,int arg3785,int arg3786,int arg3787,int arg3788,int arg3789,int arg3790,int arg3791,int arg3792,int arg3793,int arg3794,int arg3795,int arg3796,int arg3797,int arg3798,int arg3799,int arg3800,int arg3801,int arg3802,int arg3803,int arg3804,int arg3805,int arg3806,int arg3807,int arg3808,int arg3809,int arg3810,int arg3811,int arg3812,int arg3813,int arg3814,int arg3815,int arg3816,int arg3817,int arg3818,int arg3819,int arg3820,int arg3821,int arg3822,int arg3823,int arg3824,int arg3825,int arg3826,int arg3827,int arg3828,int arg3829,int arg3830,int arg3831,int arg3832,int arg3833,int arg3834,int arg3835,int arg3836,int arg3837,int arg3838,int arg3839,int arg3840,int arg3841,int arg3842,int arg3843,int arg3844,int arg3845,int arg3846,int arg3847,int arg3848,int arg3849,int arg3850,int arg3851,int arg3852,int arg3853,int arg3854,int arg3855,int arg3856,int arg3857,int arg3858,int arg3859,int arg3860,int arg3861,int arg3862,int arg3863,int arg3864,int arg3865,int arg3866,int arg3867,int arg3868,int arg3869,int arg3870,int arg3871,int arg3872,int arg3873,int arg3874,int arg3875,int arg3876,int arg3877,int arg3878,int arg3879,int arg3880,int arg3881,int arg3882,int arg3883,int arg3884,int arg3885,int arg3886,int arg3887,int arg3888,int arg3889,int arg3890,int arg3891,int arg3892,int arg3893,int arg3894,int arg3895,int arg3896,int arg3897,int arg3898,int arg3899,int arg3900,int arg3901,int arg3902,int arg3903,int arg3904,int arg3905,int arg3906,int arg3907,int arg3908,int arg3909,int arg3910,int arg3911,int arg3912,int arg3913,int arg3914,int arg3915,int arg3916,int arg3917,int arg3918,int arg3919,int arg3920,int arg3921,int arg3922,int arg3923,int arg3924,int arg3925,int arg3926,int arg3927,int arg3928,int arg3929,int arg3930,int arg3931,int arg3932,int arg3933,int arg3934,int arg3935,int arg3936,int arg3937,int arg3938,int arg3939,int arg3940,int arg3941,int arg3942,int arg3943,int arg3944,int arg3945,int arg3946,int arg3947,int arg3948,int arg3949,int arg3950,int arg3951,int arg3952,int arg3953,int arg3954,int arg3955,int arg3956,int arg3957,int arg3958,int arg3959,int arg3960,int arg3961,int arg3962,int arg3963,int arg3964,int arg3965,int arg3966,int arg3967,int arg3968,int arg3969,int arg3970,int arg3971,int arg3972,int arg3973,int arg3974,int arg3975,int arg3976,int arg3977,int arg3978,int arg3979,int arg3980,int arg3981,int arg3982,int arg3983,int arg3984,int arg3985,int arg3986,int arg3987,int arg3988,int arg3989,int arg3990,int arg3991,int arg3992,int arg3993,int arg3994,int arg3995,int arg3996,int arg3997,int arg3998,int arg3999,int arg4000,int arg4001,int arg4002,int arg4003,int arg4004,int arg4005,int arg4006,int arg4007,int arg4008,int arg4009,int arg4010,int arg4011,int arg4012,int arg4013,int arg4014,int arg4015,int arg4016,int arg4017,int arg4018,int arg4019,int arg4020,int arg4021,int arg4022,int arg4023,int arg4024,int arg4025,int arg4026,int arg4027,int arg4028,int arg4029,int arg4030,int arg4031,int arg4032,int arg4033,int arg4034,int arg4035,int arg4036,int arg4037,int arg4038,int arg4039,int arg4040,int arg4041,int arg4042,int arg4043,int arg4044,int arg4045,int arg4046,int arg4047,int arg4048,int arg4049,int arg4050,int arg4051,int arg4052,int arg4053,int arg4054,int arg4055,int arg4056,int arg4057,int arg4058,int arg4059,int arg4060,int arg4061,int arg4062,int arg4063,int arg4064,int arg4065,int arg4066,int arg4067,int arg4068,int arg4069,int arg4070,int arg4071,int arg4072,int arg4073,int arg4074,int arg4075,int arg4076,int arg4077,int arg4078,int arg4079,int arg4080,int arg4081,int arg4082,int arg4083,int arg4084,int arg4085,int arg4086,int arg4087,int arg4088,int arg4089,int arg4090,int arg4091,int arg4092,int arg4093,int arg4094,int arg4095,int arg4096,int arg4097,int arg4098,int arg4099,int arg4100,int arg4101,int arg4102,int arg4103,int arg4104,int arg4105,int arg4106,int arg4107,int arg4108,int arg4109,int arg4110,int arg4111,int arg4112,int arg4113,int arg4114,int arg4115,int arg4116,int arg4117,int arg4118,int arg4119,int arg4120,int arg4121,int arg4122,int arg4123,int arg4124,int arg4125,int arg4126,int arg4127,int arg4128,int arg4129,int arg4130,int arg4131,int arg4132,int arg4133,int arg4134,int arg4135,int arg4136,int arg4137,int arg4138,int arg4139,int arg4140,int arg4141,int arg4142,int arg4143,int arg4144,int arg4145,int arg4146,int arg4147,int arg4148,int arg4149,int arg4150,int arg4151,int arg4152,int arg4153,int arg4154,int arg4155,int arg4156,int arg4157,int arg4158,int arg4159,int arg4160,int arg4161,int arg4162,int arg4163,int arg4164,int arg4165,int arg4166,int arg4167,int arg4168,int arg4169,int arg4170,int arg4171,int arg4172,int arg4173,int arg4174,int arg4175,int arg4176,int arg4177,int arg4178,int arg4179,int arg4180,int arg4181,int arg4182,int arg4183,int arg4184,int arg4185,int arg4186,int arg4187,int arg4188,int arg4189,int arg4190,int arg4191,int arg4192,int arg4193,int arg4194,int arg4195,int arg4196,int arg4197,int arg4198,int arg4199,int arg4200,int arg4201,int arg4202,int arg4203,int arg4204,int arg4205,int arg4206,int arg4207,int arg4208,int arg4209,int arg4210,int arg4211,int arg4212,int arg4213,int arg4214,int arg4215,int arg4216,int arg4217,int arg4218,int arg4219,int arg4220,int arg4221,int arg4222,int arg4223,int arg4224,int arg4225,int arg4226,int arg4227,int arg4228,int arg4229,int arg4230,int arg4231,int arg4232,int arg4233,int arg4234,int arg4235,int arg4236,int arg4237,int arg4238,int arg4239,int arg4240,int arg4241,int arg4242,int arg4243,int arg4244,int arg4245,int arg4246,int arg4247,int arg4248,int arg4249,int arg4250,int arg4251,int arg4252,int arg4253,int arg4254,int arg4255,int arg4256,int arg4257,int arg4258,int arg4259,int arg4260,int arg4261,int arg4262,int arg4263,int arg4264,int arg4265,int arg4266,int arg4267,int arg4268,int arg4269,int arg4270,int arg4271,int arg4272,int arg4273,int arg4274,int arg4275,int arg4276,int arg4277,int arg4278,int arg4279,int arg4280,int arg4281,int arg4282,int arg4283,int arg4284,int arg4285,int arg4286,int arg4287,int arg4288,int arg4289,int arg4290,int arg4291,int arg4292,int arg4293,int arg4294,int arg4295,int arg4296,int arg4297,int arg4298,int arg4299,int arg4300,int arg4301,int arg4302,int arg4303,int arg4304,int arg4305,int arg4306,int arg4307,int arg4308,int arg4309,int arg4310,int arg4311,int arg4312,int arg4313,int arg4314,int arg4315,int arg4316,int arg4317,int arg4318,int arg4319,int arg4320,int arg4321,int arg4322,int arg4323,int arg4324,int arg4325,int arg4326,int arg4327,int arg4328,int arg4329,int arg4330,int arg4331,int arg4332,int arg4333,int arg4334,int arg4335,int arg4336,int arg4337,int arg4338,int arg4339,int arg4340,int arg4341,int arg4342,int arg4343,int arg4344,int arg4345,int arg4346,int arg4347,int arg4348,int arg4349,int arg4350,int arg4351,int arg4352,int arg4353,int arg4354,int arg4355,int arg4356,int arg4357,int arg4358,int arg4359,int arg4360,int arg4361,int arg4362,int arg4363,int arg4364,int arg4365,int arg4366,int arg4367,int arg4368,int arg4369,int arg4370,int arg4371,int arg4372,int arg4373,int arg4374,int arg4375,int arg4376,int arg4377,int arg4378,int arg4379,int arg4380,int arg4381,int arg4382,int arg4383,int arg4384,int arg4385,int arg4386,int arg4387,int arg4388,int arg4389,int arg4390,int arg4391,int arg4392,int arg4393,int arg4394,int arg4395,int arg4396,int arg4397,int arg4398,int arg4399,int arg4400,int arg4401,int arg4402,int arg4403,int arg4404,int arg4405,int arg4406,int arg4407,int arg4408,int arg4409,int arg4410,int arg4411,int arg4412,int arg4413,int arg4414,int arg4415,int arg4416,int arg4417,int arg4418,int arg4419,int arg4420,int arg4421,int arg4422,int arg4423,int arg4424,int arg4425,int arg4426,int arg4427,int arg4428,int arg4429,int arg4430,int arg4431,int arg4432,int arg4433,int arg4434,int arg4435,int arg4436,int arg4437,int arg4438,int arg4439,int arg4440,int arg4441,int arg4442,int arg4443,int arg4444,int arg4445,int arg4446,int arg4447,int arg4448,int arg4449,int arg4450,int arg4451,int arg4452,int arg4453,int arg4454,int arg4455,int arg4456,int arg4457,int arg4458,int arg4459,int arg4460,int arg4461,int arg4462,int arg4463,int arg4464,int arg4465,int arg4466,int arg4467,int arg4468,int arg4469,int arg4470,int arg4471,int arg4472,int arg4473,int arg4474,int arg4475,int arg4476,int arg4477,int arg4478,int arg4479,int arg4480,int arg4481,int arg4482,int arg4483,int arg4484,int arg4485,int arg4486,int arg4487,int arg4488,int arg4489,int arg4490,int arg4491,int arg4492,int arg4493,int arg4494,int arg4495,int arg4496,int arg4497,int arg4498,int arg4499,int arg4500,int arg4501,int arg4502,int arg4503,int arg4504,int arg4505,int arg4506,int arg4507,int arg4508,int arg4509,int arg4510,int arg4511,int arg4512,int arg4513,int arg4514,int arg4515,int arg4516,int arg4517,int arg4518,int arg4519,int arg4520,int arg4521,int arg4522,int arg4523,int arg4524,int arg4525,int arg4526,int arg4527,int arg4528,int arg4529,int arg4530,int arg4531,int arg4532,int arg4533,int arg4534,int arg4535,int arg4536,int arg4537,int arg4538,int arg4539,int arg4540,int arg4541,int arg4542,int arg4543,int arg4544,int arg4545,int arg4546,int arg4547,int arg4548,int arg4549,int arg4550,int arg4551,int arg4552,int arg4553,int arg4554,int arg4555,int arg4556,int arg4557,int arg4558,int arg4559,int arg4560,int arg4561,int arg4562,int arg4563,int arg4564,int arg4565,int arg4566,int arg4567,int arg4568,int arg4569,int arg4570,int arg4571,int arg4572,int arg4573,int arg4574,int arg4575,int arg4576,int arg4577,int arg4578,int arg4579,int arg4580,int arg4581,int arg4582,int arg4583,int arg4584,int arg4585,int arg4586,int arg4587,int arg4588,int arg4589,int arg4590,int arg4591,int arg4592,int arg4593,int arg4594,int arg4595,int arg4596,int arg4597,int arg4598,int arg4599,int arg4600,int arg4601,int arg4602,int arg4603,int arg4604,int arg4605,int arg4606,int arg4607,int arg4608,int arg4609,int arg4610,int arg4611,int arg4612,int arg4613,int arg4614,int arg4615,int arg4616,int arg4617,int arg4618,int arg4619,int arg4620,int arg4621,int arg4622,int arg4623,int arg4624,int arg4625,int arg4626,int arg4627,int arg4628,int arg4629,int arg4630,int arg4631,int arg4632,int arg4633,int arg4634,int arg4635,int arg4636,int arg4637,int arg4638,int arg4639,int arg4640,int arg4641,int arg4642,int arg4643,int arg4644,int arg4645,int arg4646,int arg4647,int arg4648,int arg4649,int arg4650,int arg4651,int arg4652,int arg4653,int arg4654,int arg4655,int arg4656,int arg4657,int arg4658,int arg4659,int arg4660,int arg4661,int arg4662,int arg4663,int arg4664,int arg4665,int arg4666,int arg4667,int arg4668,int arg4669,int arg4670,int arg4671,int arg4672,int arg4673,int arg4674,int arg4675,int arg4676,int arg4677,int arg4678,int arg4679,int arg4680,int arg4681,int arg4682,int arg4683,int arg4684,int arg4685,int arg4686,int arg4687,int arg4688,int arg4689,int arg4690,int arg4691,int arg4692,int arg4693,int arg4694,int arg4695,int arg4696,int arg4697,int arg4698,int arg4699,int arg4700,int arg4701,int arg4702,int arg4703,int arg4704,int arg4705,int arg4706,int arg4707,int arg4708,int arg4709,int arg4710,int arg4711,int arg4712,int arg4713,int arg4714,int arg4715,int arg4716,int arg4717,int arg4718,int arg4719,int arg4720,int arg4721,int arg4722,int arg4723,int arg4724,int arg4725,int arg4726,int arg4727,int arg4728,int arg4729,int arg4730,int arg4731,int arg4732,int arg4733,int arg4734,int arg4735,int arg4736,int arg4737,int arg4738,int arg4739,int arg4740,int arg4741,int arg4742,int arg4743,int arg4744,int arg4745,int arg4746,int arg4747,int arg4748,int arg4749,int arg4750,int arg4751,int arg4752,int arg4753,int arg4754,int arg4755,int arg4756,int arg4757,int arg4758,int arg4759,int arg4760,int arg4761,int arg4762,int arg4763,int arg4764,int arg4765,int arg4766,int arg4767,int arg4768,int arg4769,int arg4770,int arg4771,int arg4772,int arg4773,int arg4774,int arg4775,int arg4776,int arg4777,int arg4778,int arg4779,int arg4780,int arg4781,int arg4782,int arg4783,int arg4784,int arg4785,int arg4786,int arg4787,int arg4788,int arg4789,int arg4790,int arg4791,int arg4792,int arg4793,int arg4794,int arg4795,int arg4796,int arg4797,int arg4798,int arg4799,int arg4800,int arg4801,int arg4802,int arg4803,int arg4804,int arg4805,int arg4806,int arg4807,int arg4808,int arg4809,int arg4810,int arg4811,int arg4812,int arg4813,int arg4814,int arg4815,int arg4816,int arg4817,int arg4818,int arg4819,int arg4820,int arg4821,int arg4822,int arg4823,int arg4824,int arg4825,int arg4826,int arg4827,int arg4828,int arg4829,int arg4830,int arg4831,int arg4832,int arg4833,int arg4834,int arg4835,int arg4836,int arg4837,int arg4838,int arg4839,int arg4840,int arg4841,int arg4842,int arg4843,int arg4844,int arg4845,int arg4846,int arg4847,int arg4848,int arg4849,int arg4850,int arg4851,int arg4852,int arg4853,int arg4854,int arg4855,int arg4856,int arg4857,int arg4858,int arg4859,int arg4860,int arg4861,int arg4862,int arg4863,int arg4864,int arg4865,int arg4866,int arg4867,int arg4868,int arg4869,int arg4870,int arg4871,int arg4872,int arg4873,int arg4874,int arg4875,int arg4876,int arg4877,int arg4878,int arg4879,int arg4880,int arg4881,int arg4882,int arg4883,int arg4884,int arg4885,int arg4886,int arg4887,int arg4888,int arg4889,int arg4890,int arg4891,int arg4892,int arg4893,int arg4894,int arg4895,int arg4896,int arg4897,int arg4898,int arg4899,int arg4900,int arg4901,int arg4902,int arg4903,int arg4904,int arg4905,int arg4906,int arg4907,int arg4908,int arg4909,int arg4910,int arg4911,int arg4912,int arg4913,int arg4914,int arg4915,int arg4916,int arg4917,int arg4918,int arg4919,int arg4920,int arg4921,int arg4922,int arg4923,int arg4924,int arg4925,int arg4926,int arg4927,int arg4928,int arg4929,int arg4930,int arg4931,int arg4932,int arg4933,int arg4934,int arg4935,int arg4936,int arg4937,int arg4938,int arg4939,int arg4940,int arg4941,int arg4942,int arg4943,int arg4944,int arg4945,int arg4946,int arg4947,int arg4948,int arg4949,int arg4950,int arg4951,int arg4952,int arg4953,int arg4954,int arg4955,int arg4956,int arg4957,int arg4958,int arg4959,int arg4960,int arg4961,int arg4962,int arg4963,int arg4964,int arg4965,int arg4966,int arg4967,int arg4968,int arg4969,int arg4970,int arg4971,int arg4972,int arg4973,int arg4974,int arg4975,int arg4976,int arg4977,int arg4978,int arg4979,int arg4980,int arg4981,int arg4982,int arg4983,int arg4984,int arg4985,int arg4986,int arg4987,int arg4988,int arg4989,int arg4990,int arg4991,int arg4992,int arg4993,int arg4994,int arg4995,int arg4996,int arg4997,int arg4998,int arg4999)) -{ return arg0+arg1+arg2+arg3+arg4+arg5+arg6+arg7+arg8+arg9+arg10+arg11+arg12+arg13+arg14+arg15+arg16+arg17+arg18+arg19+arg20+arg21+arg22+arg23+arg24+arg25+arg26+arg27+arg28+arg29+arg30+arg31+arg32+arg33+arg34+arg35+arg36+arg37+arg38+arg39+arg40+arg41+arg42+arg43+arg44+arg45+arg46+arg47+arg48+arg49+arg50+arg51+arg52+arg53+arg54+arg55+arg56+arg57+arg58+arg59+arg60+arg61+arg62+arg63+arg64+arg65+arg66+arg67+arg68+arg69+arg70+arg71+arg72+arg73+arg74+arg75+arg76+arg77+arg78+arg79+arg80+arg81+arg82+arg83+arg84+arg85+arg86+arg87+arg88+arg89+arg90+arg91+arg92+arg93+arg94+arg95+arg96+arg97+arg98+arg99+arg100+arg101+arg102+arg103+arg104+arg105+arg106+arg107+arg108+arg109+arg110+arg111+arg112+arg113+arg114+arg115+arg116+arg117+arg118+arg119+arg120+arg121+arg122+arg123+arg124+arg125+arg126+arg127+arg128+arg129+arg130+arg131+arg132+arg133+arg134+arg135+arg136+arg137+arg138+arg139+arg140+arg141+arg142+arg143+arg144+arg145+arg146+arg147+arg148+arg149+arg150+arg151+arg152+arg153+arg154+arg155+arg156+arg157+arg158+arg159+arg160+arg161+arg162+arg163+arg164+arg165+arg166+arg167+arg168+arg169+arg170+arg171+arg172+arg173+arg174+arg175+arg176+arg177+arg178+arg179+arg180+arg181+arg182+arg183+arg184+arg185+arg186+arg187+arg188+arg189+arg190+arg191+arg192+arg193+arg194+arg195+arg196+arg197+arg198+arg199+arg200+arg201+arg202+arg203+arg204+arg205+arg206+arg207+arg208+arg209+arg210+arg211+arg212+arg213+arg214+arg215+arg216+arg217+arg218+arg219+arg220+arg221+arg222+arg223+arg224+arg225+arg226+arg227+arg228+arg229+arg230+arg231+arg232+arg233+arg234+arg235+arg236+arg237+arg238+arg239+arg240+arg241+arg242+arg243+arg244+arg245+arg246+arg247+arg248+arg249+arg250+arg251+arg252+arg253+arg254+arg255+arg256+arg257+arg258+arg259+arg260+arg261+arg262+arg263+arg264+arg265+arg266+arg267+arg268+arg269+arg270+arg271+arg272+arg273+arg274+arg275+arg276+arg277+arg278+arg279+arg280+arg281+arg282+arg283+arg284+arg285+arg286+arg287+arg288+arg289+arg290+arg291+arg292+arg293+arg294+arg295+arg296+arg297+arg298+arg299+arg300+arg301+arg302+arg303+arg304+arg305+arg306+arg307+arg308+arg309+arg310+arg311+arg312+arg313+arg314+arg315+arg316+arg317+arg318+arg319+arg320+arg321+arg322+arg323+arg324+arg325+arg326+arg327+arg328+arg329+arg330+arg331+arg332+arg333+arg334+arg335+arg336+arg337+arg338+arg339+arg340+arg341+arg342+arg343+arg344+arg345+arg346+arg347+arg348+arg349+arg350+arg351+arg352+arg353+arg354+arg355+arg356+arg357+arg358+arg359+arg360+arg361+arg362+arg363+arg364+arg365+arg366+arg367+arg368+arg369+arg370+arg371+arg372+arg373+arg374+arg375+arg376+arg377+arg378+arg379+arg380+arg381+arg382+arg383+arg384+arg385+arg386+arg387+arg388+arg389+arg390+arg391+arg392+arg393+arg394+arg395+arg396+arg397+arg398+arg399+arg400+arg401+arg402+arg403+arg404+arg405+arg406+arg407+arg408+arg409+arg410+arg411+arg412+arg413+arg414+arg415+arg416+arg417+arg418+arg419+arg420+arg421+arg422+arg423+arg424+arg425+arg426+arg427+arg428+arg429+arg430+arg431+arg432+arg433+arg434+arg435+arg436+arg437+arg438+arg439+arg440+arg441+arg442+arg443+arg444+arg445+arg446+arg447+arg448+arg449+arg450+arg451+arg452+arg453+arg454+arg455+arg456+arg457+arg458+arg459+arg460+arg461+arg462+arg463+arg464+arg465+arg466+arg467+arg468+arg469+arg470+arg471+arg472+arg473+arg474+arg475+arg476+arg477+arg478+arg479+arg480+arg481+arg482+arg483+arg484+arg485+arg486+arg487+arg488+arg489+arg490+arg491+arg492+arg493+arg494+arg495+arg496+arg497+arg498+arg499+arg500+arg501+arg502+arg503+arg504+arg505+arg506+arg507+arg508+arg509+arg510+arg511+arg512+arg513+arg514+arg515+arg516+arg517+arg518+arg519+arg520+arg521+arg522+arg523+arg524+arg525+arg526+arg527+arg528+arg529+arg530+arg531+arg532+arg533+arg534+arg535+arg536+arg537+arg538+arg539+arg540+arg541+arg542+arg543+arg544+arg545+arg546+arg547+arg548+arg549+arg550+arg551+arg552+arg553+arg554+arg555+arg556+arg557+arg558+arg559+arg560+arg561+arg562+arg563+arg564+arg565+arg566+arg567+arg568+arg569+arg570+arg571+arg572+arg573+arg574+arg575+arg576+arg577+arg578+arg579+arg580+arg581+arg582+arg583+arg584+arg585+arg586+arg587+arg588+arg589+arg590+arg591+arg592+arg593+arg594+arg595+arg596+arg597+arg598+arg599+arg600+arg601+arg602+arg603+arg604+arg605+arg606+arg607+arg608+arg609+arg610+arg611+arg612+arg613+arg614+arg615+arg616+arg617+arg618+arg619+arg620+arg621+arg622+arg623+arg624+arg625+arg626+arg627+arg628+arg629+arg630+arg631+arg632+arg633+arg634+arg635+arg636+arg637+arg638+arg639+arg640+arg641+arg642+arg643+arg644+arg645+arg646+arg647+arg648+arg649+arg650+arg651+arg652+arg653+arg654+arg655+arg656+arg657+arg658+arg659+arg660+arg661+arg662+arg663+arg664+arg665+arg666+arg667+arg668+arg669+arg670+arg671+arg672+arg673+arg674+arg675+arg676+arg677+arg678+arg679+arg680+arg681+arg682+arg683+arg684+arg685+arg686+arg687+arg688+arg689+arg690+arg691+arg692+arg693+arg694+arg695+arg696+arg697+arg698+arg699+arg700+arg701+arg702+arg703+arg704+arg705+arg706+arg707+arg708+arg709+arg710+arg711+arg712+arg713+arg714+arg715+arg716+arg717+arg718+arg719+arg720+arg721+arg722+arg723+arg724+arg725+arg726+arg727+arg728+arg729+arg730+arg731+arg732+arg733+arg734+arg735+arg736+arg737+arg738+arg739+arg740+arg741+arg742+arg743+arg744+arg745+arg746+arg747+arg748+arg749+arg750+arg751+arg752+arg753+arg754+arg755+arg756+arg757+arg758+arg759+arg760+arg761+arg762+arg763+arg764+arg765+arg766+arg767+arg768+arg769+arg770+arg771+arg772+arg773+arg774+arg775+arg776+arg777+arg778+arg779+arg780+arg781+arg782+arg783+arg784+arg785+arg786+arg787+arg788+arg789+arg790+arg791+arg792+arg793+arg794+arg795+arg796+arg797+arg798+arg799+arg800+arg801+arg802+arg803+arg804+arg805+arg806+arg807+arg808+arg809+arg810+arg811+arg812+arg813+arg814+arg815+arg816+arg817+arg818+arg819+arg820+arg821+arg822+arg823+arg824+arg825+arg826+arg827+arg828+arg829+arg830+arg831+arg832+arg833+arg834+arg835+arg836+arg837+arg838+arg839+arg840+arg841+arg842+arg843+arg844+arg845+arg846+arg847+arg848+arg849+arg850+arg851+arg852+arg853+arg854+arg855+arg856+arg857+arg858+arg859+arg860+arg861+arg862+arg863+arg864+arg865+arg866+arg867+arg868+arg869+arg870+arg871+arg872+arg873+arg874+arg875+arg876+arg877+arg878+arg879+arg880+arg881+arg882+arg883+arg884+arg885+arg886+arg887+arg888+arg889+arg890+arg891+arg892+arg893+arg894+arg895+arg896+arg897+arg898+arg899+arg900+arg901+arg902+arg903+arg904+arg905+arg906+arg907+arg908+arg909+arg910+arg911+arg912+arg913+arg914+arg915+arg916+arg917+arg918+arg919+arg920+arg921+arg922+arg923+arg924+arg925+arg926+arg927+arg928+arg929+arg930+arg931+arg932+arg933+arg934+arg935+arg936+arg937+arg938+arg939+arg940+arg941+arg942+arg943+arg944+arg945+arg946+arg947+arg948+arg949+arg950+arg951+arg952+arg953+arg954+arg955+arg956+arg957+arg958+arg959+arg960+arg961+arg962+arg963+arg964+arg965+arg966+arg967+arg968+arg969+arg970+arg971+arg972+arg973+arg974+arg975+arg976+arg977+arg978+arg979+arg980+arg981+arg982+arg983+arg984+arg985+arg986+arg987+arg988+arg989+arg990+arg991+arg992+arg993+arg994+arg995+arg996+arg997+arg998+arg999+arg1000+arg1001+arg1002+arg1003+arg1004+arg1005+arg1006+arg1007+arg1008+arg1009+arg1010+arg1011+arg1012+arg1013+arg1014+arg1015+arg1016+arg1017+arg1018+arg1019+arg1020+arg1021+arg1022+arg1023+arg1024+arg1025+arg1026+arg1027+arg1028+arg1029+arg1030+arg1031+arg1032+arg1033+arg1034+arg1035+arg1036+arg1037+arg1038+arg1039+arg1040+arg1041+arg1042+arg1043+arg1044+arg1045+arg1046+arg1047+arg1048+arg1049+arg1050+arg1051+arg1052+arg1053+arg1054+arg1055+arg1056+arg1057+arg1058+arg1059+arg1060+arg1061+arg1062+arg1063+arg1064+arg1065+arg1066+arg1067+arg1068+arg1069+arg1070+arg1071+arg1072+arg1073+arg1074+arg1075+arg1076+arg1077+arg1078+arg1079+arg1080+arg1081+arg1082+arg1083+arg1084+arg1085+arg1086+arg1087+arg1088+arg1089+arg1090+arg1091+arg1092+arg1093+arg1094+arg1095+arg1096+arg1097+arg1098+arg1099+arg1100+arg1101+arg1102+arg1103+arg1104+arg1105+arg1106+arg1107+arg1108+arg1109+arg1110+arg1111+arg1112+arg1113+arg1114+arg1115+arg1116+arg1117+arg1118+arg1119+arg1120+arg1121+arg1122+arg1123+arg1124+arg1125+arg1126+arg1127+arg1128+arg1129+arg1130+arg1131+arg1132+arg1133+arg1134+arg1135+arg1136+arg1137+arg1138+arg1139+arg1140+arg1141+arg1142+arg1143+arg1144+arg1145+arg1146+arg1147+arg1148+arg1149+arg1150+arg1151+arg1152+arg1153+arg1154+arg1155+arg1156+arg1157+arg1158+arg1159+arg1160+arg1161+arg1162+arg1163+arg1164+arg1165+arg1166+arg1167+arg1168+arg1169+arg1170+arg1171+arg1172+arg1173+arg1174+arg1175+arg1176+arg1177+arg1178+arg1179+arg1180+arg1181+arg1182+arg1183+arg1184+arg1185+arg1186+arg1187+arg1188+arg1189+arg1190+arg1191+arg1192+arg1193+arg1194+arg1195+arg1196+arg1197+arg1198+arg1199+arg1200+arg1201+arg1202+arg1203+arg1204+arg1205+arg1206+arg1207+arg1208+arg1209+arg1210+arg1211+arg1212+arg1213+arg1214+arg1215+arg1216+arg1217+arg1218+arg1219+arg1220+arg1221+arg1222+arg1223+arg1224+arg1225+arg1226+arg1227+arg1228+arg1229+arg1230+arg1231+arg1232+arg1233+arg1234+arg1235+arg1236+arg1237+arg1238+arg1239+arg1240+arg1241+arg1242+arg1243+arg1244+arg1245+arg1246+arg1247+arg1248+arg1249+arg1250+arg1251+arg1252+arg1253+arg1254+arg1255+arg1256+arg1257+arg1258+arg1259+arg1260+arg1261+arg1262+arg1263+arg1264+arg1265+arg1266+arg1267+arg1268+arg1269+arg1270+arg1271+arg1272+arg1273+arg1274+arg1275+arg1276+arg1277+arg1278+arg1279+arg1280+arg1281+arg1282+arg1283+arg1284+arg1285+arg1286+arg1287+arg1288+arg1289+arg1290+arg1291+arg1292+arg1293+arg1294+arg1295+arg1296+arg1297+arg1298+arg1299+arg1300+arg1301+arg1302+arg1303+arg1304+arg1305+arg1306+arg1307+arg1308+arg1309+arg1310+arg1311+arg1312+arg1313+arg1314+arg1315+arg1316+arg1317+arg1318+arg1319+arg1320+arg1321+arg1322+arg1323+arg1324+arg1325+arg1326+arg1327+arg1328+arg1329+arg1330+arg1331+arg1332+arg1333+arg1334+arg1335+arg1336+arg1337+arg1338+arg1339+arg1340+arg1341+arg1342+arg1343+arg1344+arg1345+arg1346+arg1347+arg1348+arg1349+arg1350+arg1351+arg1352+arg1353+arg1354+arg1355+arg1356+arg1357+arg1358+arg1359+arg1360+arg1361+arg1362+arg1363+arg1364+arg1365+arg1366+arg1367+arg1368+arg1369+arg1370+arg1371+arg1372+arg1373+arg1374+arg1375+arg1376+arg1377+arg1378+arg1379+arg1380+arg1381+arg1382+arg1383+arg1384+arg1385+arg1386+arg1387+arg1388+arg1389+arg1390+arg1391+arg1392+arg1393+arg1394+arg1395+arg1396+arg1397+arg1398+arg1399+arg1400+arg1401+arg1402+arg1403+arg1404+arg1405+arg1406+arg1407+arg1408+arg1409+arg1410+arg1411+arg1412+arg1413+arg1414+arg1415+arg1416+arg1417+arg1418+arg1419+arg1420+arg1421+arg1422+arg1423+arg1424+arg1425+arg1426+arg1427+arg1428+arg1429+arg1430+arg1431+arg1432+arg1433+arg1434+arg1435+arg1436+arg1437+arg1438+arg1439+arg1440+arg1441+arg1442+arg1443+arg1444+arg1445+arg1446+arg1447+arg1448+arg1449+arg1450+arg1451+arg1452+arg1453+arg1454+arg1455+arg1456+arg1457+arg1458+arg1459+arg1460+arg1461+arg1462+arg1463+arg1464+arg1465+arg1466+arg1467+arg1468+arg1469+arg1470+arg1471+arg1472+arg1473+arg1474+arg1475+arg1476+arg1477+arg1478+arg1479+arg1480+arg1481+arg1482+arg1483+arg1484+arg1485+arg1486+arg1487+arg1488+arg1489+arg1490+arg1491+arg1492+arg1493+arg1494+arg1495+arg1496+arg1497+arg1498+arg1499+arg1500+arg1501+arg1502+arg1503+arg1504+arg1505+arg1506+arg1507+arg1508+arg1509+arg1510+arg1511+arg1512+arg1513+arg1514+arg1515+arg1516+arg1517+arg1518+arg1519+arg1520+arg1521+arg1522+arg1523+arg1524+arg1525+arg1526+arg1527+arg1528+arg1529+arg1530+arg1531+arg1532+arg1533+arg1534+arg1535+arg1536+arg1537+arg1538+arg1539+arg1540+arg1541+arg1542+arg1543+arg1544+arg1545+arg1546+arg1547+arg1548+arg1549+arg1550+arg1551+arg1552+arg1553+arg1554+arg1555+arg1556+arg1557+arg1558+arg1559+arg1560+arg1561+arg1562+arg1563+arg1564+arg1565+arg1566+arg1567+arg1568+arg1569+arg1570+arg1571+arg1572+arg1573+arg1574+arg1575+arg1576+arg1577+arg1578+arg1579+arg1580+arg1581+arg1582+arg1583+arg1584+arg1585+arg1586+arg1587+arg1588+arg1589+arg1590+arg1591+arg1592+arg1593+arg1594+arg1595+arg1596+arg1597+arg1598+arg1599+arg1600+arg1601+arg1602+arg1603+arg1604+arg1605+arg1606+arg1607+arg1608+arg1609+arg1610+arg1611+arg1612+arg1613+arg1614+arg1615+arg1616+arg1617+arg1618+arg1619+arg1620+arg1621+arg1622+arg1623+arg1624+arg1625+arg1626+arg1627+arg1628+arg1629+arg1630+arg1631+arg1632+arg1633+arg1634+arg1635+arg1636+arg1637+arg1638+arg1639+arg1640+arg1641+arg1642+arg1643+arg1644+arg1645+arg1646+arg1647+arg1648+arg1649+arg1650+arg1651+arg1652+arg1653+arg1654+arg1655+arg1656+arg1657+arg1658+arg1659+arg1660+arg1661+arg1662+arg1663+arg1664+arg1665+arg1666+arg1667+arg1668+arg1669+arg1670+arg1671+arg1672+arg1673+arg1674+arg1675+arg1676+arg1677+arg1678+arg1679+arg1680+arg1681+arg1682+arg1683+arg1684+arg1685+arg1686+arg1687+arg1688+arg1689+arg1690+arg1691+arg1692+arg1693+arg1694+arg1695+arg1696+arg1697+arg1698+arg1699+arg1700+arg1701+arg1702+arg1703+arg1704+arg1705+arg1706+arg1707+arg1708+arg1709+arg1710+arg1711+arg1712+arg1713+arg1714+arg1715+arg1716+arg1717+arg1718+arg1719+arg1720+arg1721+arg1722+arg1723+arg1724+arg1725+arg1726+arg1727+arg1728+arg1729+arg1730+arg1731+arg1732+arg1733+arg1734+arg1735+arg1736+arg1737+arg1738+arg1739+arg1740+arg1741+arg1742+arg1743+arg1744+arg1745+arg1746+arg1747+arg1748+arg1749+arg1750+arg1751+arg1752+arg1753+arg1754+arg1755+arg1756+arg1757+arg1758+arg1759+arg1760+arg1761+arg1762+arg1763+arg1764+arg1765+arg1766+arg1767+arg1768+arg1769+arg1770+arg1771+arg1772+arg1773+arg1774+arg1775+arg1776+arg1777+arg1778+arg1779+arg1780+arg1781+arg1782+arg1783+arg1784+arg1785+arg1786+arg1787+arg1788+arg1789+arg1790+arg1791+arg1792+arg1793+arg1794+arg1795+arg1796+arg1797+arg1798+arg1799+arg1800+arg1801+arg1802+arg1803+arg1804+arg1805+arg1806+arg1807+arg1808+arg1809+arg1810+arg1811+arg1812+arg1813+arg1814+arg1815+arg1816+arg1817+arg1818+arg1819+arg1820+arg1821+arg1822+arg1823+arg1824+arg1825+arg1826+arg1827+arg1828+arg1829+arg1830+arg1831+arg1832+arg1833+arg1834+arg1835+arg1836+arg1837+arg1838+arg1839+arg1840+arg1841+arg1842+arg1843+arg1844+arg1845+arg1846+arg1847+arg1848+arg1849+arg1850+arg1851+arg1852+arg1853+arg1854+arg1855+arg1856+arg1857+arg1858+arg1859+arg1860+arg1861+arg1862+arg1863+arg1864+arg1865+arg1866+arg1867+arg1868+arg1869+arg1870+arg1871+arg1872+arg1873+arg1874+arg1875+arg1876+arg1877+arg1878+arg1879+arg1880+arg1881+arg1882+arg1883+arg1884+arg1885+arg1886+arg1887+arg1888+arg1889+arg1890+arg1891+arg1892+arg1893+arg1894+arg1895+arg1896+arg1897+arg1898+arg1899+arg1900+arg1901+arg1902+arg1903+arg1904+arg1905+arg1906+arg1907+arg1908+arg1909+arg1910+arg1911+arg1912+arg1913+arg1914+arg1915+arg1916+arg1917+arg1918+arg1919+arg1920+arg1921+arg1922+arg1923+arg1924+arg1925+arg1926+arg1927+arg1928+arg1929+arg1930+arg1931+arg1932+arg1933+arg1934+arg1935+arg1936+arg1937+arg1938+arg1939+arg1940+arg1941+arg1942+arg1943+arg1944+arg1945+arg1946+arg1947+arg1948+arg1949+arg1950+arg1951+arg1952+arg1953+arg1954+arg1955+arg1956+arg1957+arg1958+arg1959+arg1960+arg1961+arg1962+arg1963+arg1964+arg1965+arg1966+arg1967+arg1968+arg1969+arg1970+arg1971+arg1972+arg1973+arg1974+arg1975+arg1976+arg1977+arg1978+arg1979+arg1980+arg1981+arg1982+arg1983+arg1984+arg1985+arg1986+arg1987+arg1988+arg1989+arg1990+arg1991+arg1992+arg1993+arg1994+arg1995+arg1996+arg1997+arg1998+arg1999+arg2000+arg2001+arg2002+arg2003+arg2004+arg2005+arg2006+arg2007+arg2008+arg2009+arg2010+arg2011+arg2012+arg2013+arg2014+arg2015+arg2016+arg2017+arg2018+arg2019+arg2020+arg2021+arg2022+arg2023+arg2024+arg2025+arg2026+arg2027+arg2028+arg2029+arg2030+arg2031+arg2032+arg2033+arg2034+arg2035+arg2036+arg2037+arg2038+arg2039+arg2040+arg2041+arg2042+arg2043+arg2044+arg2045+arg2046+arg2047+arg2048+arg2049+arg2050+arg2051+arg2052+arg2053+arg2054+arg2055+arg2056+arg2057+arg2058+arg2059+arg2060+arg2061+arg2062+arg2063+arg2064+arg2065+arg2066+arg2067+arg2068+arg2069+arg2070+arg2071+arg2072+arg2073+arg2074+arg2075+arg2076+arg2077+arg2078+arg2079+arg2080+arg2081+arg2082+arg2083+arg2084+arg2085+arg2086+arg2087+arg2088+arg2089+arg2090+arg2091+arg2092+arg2093+arg2094+arg2095+arg2096+arg2097+arg2098+arg2099+arg2100+arg2101+arg2102+arg2103+arg2104+arg2105+arg2106+arg2107+arg2108+arg2109+arg2110+arg2111+arg2112+arg2113+arg2114+arg2115+arg2116+arg2117+arg2118+arg2119+arg2120+arg2121+arg2122+arg2123+arg2124+arg2125+arg2126+arg2127+arg2128+arg2129+arg2130+arg2131+arg2132+arg2133+arg2134+arg2135+arg2136+arg2137+arg2138+arg2139+arg2140+arg2141+arg2142+arg2143+arg2144+arg2145+arg2146+arg2147+arg2148+arg2149+arg2150+arg2151+arg2152+arg2153+arg2154+arg2155+arg2156+arg2157+arg2158+arg2159+arg2160+arg2161+arg2162+arg2163+arg2164+arg2165+arg2166+arg2167+arg2168+arg2169+arg2170+arg2171+arg2172+arg2173+arg2174+arg2175+arg2176+arg2177+arg2178+arg2179+arg2180+arg2181+arg2182+arg2183+arg2184+arg2185+arg2186+arg2187+arg2188+arg2189+arg2190+arg2191+arg2192+arg2193+arg2194+arg2195+arg2196+arg2197+arg2198+arg2199+arg2200+arg2201+arg2202+arg2203+arg2204+arg2205+arg2206+arg2207+arg2208+arg2209+arg2210+arg2211+arg2212+arg2213+arg2214+arg2215+arg2216+arg2217+arg2218+arg2219+arg2220+arg2221+arg2222+arg2223+arg2224+arg2225+arg2226+arg2227+arg2228+arg2229+arg2230+arg2231+arg2232+arg2233+arg2234+arg2235+arg2236+arg2237+arg2238+arg2239+arg2240+arg2241+arg2242+arg2243+arg2244+arg2245+arg2246+arg2247+arg2248+arg2249+arg2250+arg2251+arg2252+arg2253+arg2254+arg2255+arg2256+arg2257+arg2258+arg2259+arg2260+arg2261+arg2262+arg2263+arg2264+arg2265+arg2266+arg2267+arg2268+arg2269+arg2270+arg2271+arg2272+arg2273+arg2274+arg2275+arg2276+arg2277+arg2278+arg2279+arg2280+arg2281+arg2282+arg2283+arg2284+arg2285+arg2286+arg2287+arg2288+arg2289+arg2290+arg2291+arg2292+arg2293+arg2294+arg2295+arg2296+arg2297+arg2298+arg2299+arg2300+arg2301+arg2302+arg2303+arg2304+arg2305+arg2306+arg2307+arg2308+arg2309+arg2310+arg2311+arg2312+arg2313+arg2314+arg2315+arg2316+arg2317+arg2318+arg2319+arg2320+arg2321+arg2322+arg2323+arg2324+arg2325+arg2326+arg2327+arg2328+arg2329+arg2330+arg2331+arg2332+arg2333+arg2334+arg2335+arg2336+arg2337+arg2338+arg2339+arg2340+arg2341+arg2342+arg2343+arg2344+arg2345+arg2346+arg2347+arg2348+arg2349+arg2350+arg2351+arg2352+arg2353+arg2354+arg2355+arg2356+arg2357+arg2358+arg2359+arg2360+arg2361+arg2362+arg2363+arg2364+arg2365+arg2366+arg2367+arg2368+arg2369+arg2370+arg2371+arg2372+arg2373+arg2374+arg2375+arg2376+arg2377+arg2378+arg2379+arg2380+arg2381+arg2382+arg2383+arg2384+arg2385+arg2386+arg2387+arg2388+arg2389+arg2390+arg2391+arg2392+arg2393+arg2394+arg2395+arg2396+arg2397+arg2398+arg2399+arg2400+arg2401+arg2402+arg2403+arg2404+arg2405+arg2406+arg2407+arg2408+arg2409+arg2410+arg2411+arg2412+arg2413+arg2414+arg2415+arg2416+arg2417+arg2418+arg2419+arg2420+arg2421+arg2422+arg2423+arg2424+arg2425+arg2426+arg2427+arg2428+arg2429+arg2430+arg2431+arg2432+arg2433+arg2434+arg2435+arg2436+arg2437+arg2438+arg2439+arg2440+arg2441+arg2442+arg2443+arg2444+arg2445+arg2446+arg2447+arg2448+arg2449+arg2450+arg2451+arg2452+arg2453+arg2454+arg2455+arg2456+arg2457+arg2458+arg2459+arg2460+arg2461+arg2462+arg2463+arg2464+arg2465+arg2466+arg2467+arg2468+arg2469+arg2470+arg2471+arg2472+arg2473+arg2474+arg2475+arg2476+arg2477+arg2478+arg2479+arg2480+arg2481+arg2482+arg2483+arg2484+arg2485+arg2486+arg2487+arg2488+arg2489+arg2490+arg2491+arg2492+arg2493+arg2494+arg2495+arg2496+arg2497+arg2498+arg2499+arg2500+arg2501+arg2502+arg2503+arg2504+arg2505+arg2506+arg2507+arg2508+arg2509+arg2510+arg2511+arg2512+arg2513+arg2514+arg2515+arg2516+arg2517+arg2518+arg2519+arg2520+arg2521+arg2522+arg2523+arg2524+arg2525+arg2526+arg2527+arg2528+arg2529+arg2530+arg2531+arg2532+arg2533+arg2534+arg2535+arg2536+arg2537+arg2538+arg2539+arg2540+arg2541+arg2542+arg2543+arg2544+arg2545+arg2546+arg2547+arg2548+arg2549+arg2550+arg2551+arg2552+arg2553+arg2554+arg2555+arg2556+arg2557+arg2558+arg2559+arg2560+arg2561+arg2562+arg2563+arg2564+arg2565+arg2566+arg2567+arg2568+arg2569+arg2570+arg2571+arg2572+arg2573+arg2574+arg2575+arg2576+arg2577+arg2578+arg2579+arg2580+arg2581+arg2582+arg2583+arg2584+arg2585+arg2586+arg2587+arg2588+arg2589+arg2590+arg2591+arg2592+arg2593+arg2594+arg2595+arg2596+arg2597+arg2598+arg2599+arg2600+arg2601+arg2602+arg2603+arg2604+arg2605+arg2606+arg2607+arg2608+arg2609+arg2610+arg2611+arg2612+arg2613+arg2614+arg2615+arg2616+arg2617+arg2618+arg2619+arg2620+arg2621+arg2622+arg2623+arg2624+arg2625+arg2626+arg2627+arg2628+arg2629+arg2630+arg2631+arg2632+arg2633+arg2634+arg2635+arg2636+arg2637+arg2638+arg2639+arg2640+arg2641+arg2642+arg2643+arg2644+arg2645+arg2646+arg2647+arg2648+arg2649+arg2650+arg2651+arg2652+arg2653+arg2654+arg2655+arg2656+arg2657+arg2658+arg2659+arg2660+arg2661+arg2662+arg2663+arg2664+arg2665+arg2666+arg2667+arg2668+arg2669+arg2670+arg2671+arg2672+arg2673+arg2674+arg2675+arg2676+arg2677+arg2678+arg2679+arg2680+arg2681+arg2682+arg2683+arg2684+arg2685+arg2686+arg2687+arg2688+arg2689+arg2690+arg2691+arg2692+arg2693+arg2694+arg2695+arg2696+arg2697+arg2698+arg2699+arg2700+arg2701+arg2702+arg2703+arg2704+arg2705+arg2706+arg2707+arg2708+arg2709+arg2710+arg2711+arg2712+arg2713+arg2714+arg2715+arg2716+arg2717+arg2718+arg2719+arg2720+arg2721+arg2722+arg2723+arg2724+arg2725+arg2726+arg2727+arg2728+arg2729+arg2730+arg2731+arg2732+arg2733+arg2734+arg2735+arg2736+arg2737+arg2738+arg2739+arg2740+arg2741+arg2742+arg2743+arg2744+arg2745+arg2746+arg2747+arg2748+arg2749+arg2750+arg2751+arg2752+arg2753+arg2754+arg2755+arg2756+arg2757+arg2758+arg2759+arg2760+arg2761+arg2762+arg2763+arg2764+arg2765+arg2766+arg2767+arg2768+arg2769+arg2770+arg2771+arg2772+arg2773+arg2774+arg2775+arg2776+arg2777+arg2778+arg2779+arg2780+arg2781+arg2782+arg2783+arg2784+arg2785+arg2786+arg2787+arg2788+arg2789+arg2790+arg2791+arg2792+arg2793+arg2794+arg2795+arg2796+arg2797+arg2798+arg2799+arg2800+arg2801+arg2802+arg2803+arg2804+arg2805+arg2806+arg2807+arg2808+arg2809+arg2810+arg2811+arg2812+arg2813+arg2814+arg2815+arg2816+arg2817+arg2818+arg2819+arg2820+arg2821+arg2822+arg2823+arg2824+arg2825+arg2826+arg2827+arg2828+arg2829+arg2830+arg2831+arg2832+arg2833+arg2834+arg2835+arg2836+arg2837+arg2838+arg2839+arg2840+arg2841+arg2842+arg2843+arg2844+arg2845+arg2846+arg2847+arg2848+arg2849+arg2850+arg2851+arg2852+arg2853+arg2854+arg2855+arg2856+arg2857+arg2858+arg2859+arg2860+arg2861+arg2862+arg2863+arg2864+arg2865+arg2866+arg2867+arg2868+arg2869+arg2870+arg2871+arg2872+arg2873+arg2874+arg2875+arg2876+arg2877+arg2878+arg2879+arg2880+arg2881+arg2882+arg2883+arg2884+arg2885+arg2886+arg2887+arg2888+arg2889+arg2890+arg2891+arg2892+arg2893+arg2894+arg2895+arg2896+arg2897+arg2898+arg2899+arg2900+arg2901+arg2902+arg2903+arg2904+arg2905+arg2906+arg2907+arg2908+arg2909+arg2910+arg2911+arg2912+arg2913+arg2914+arg2915+arg2916+arg2917+arg2918+arg2919+arg2920+arg2921+arg2922+arg2923+arg2924+arg2925+arg2926+arg2927+arg2928+arg2929+arg2930+arg2931+arg2932+arg2933+arg2934+arg2935+arg2936+arg2937+arg2938+arg2939+arg2940+arg2941+arg2942+arg2943+arg2944+arg2945+arg2946+arg2947+arg2948+arg2949+arg2950+arg2951+arg2952+arg2953+arg2954+arg2955+arg2956+arg2957+arg2958+arg2959+arg2960+arg2961+arg2962+arg2963+arg2964+arg2965+arg2966+arg2967+arg2968+arg2969+arg2970+arg2971+arg2972+arg2973+arg2974+arg2975+arg2976+arg2977+arg2978+arg2979+arg2980+arg2981+arg2982+arg2983+arg2984+arg2985+arg2986+arg2987+arg2988+arg2989+arg2990+arg2991+arg2992+arg2993+arg2994+arg2995+arg2996+arg2997+arg2998+arg2999+arg3000+arg3001+arg3002+arg3003+arg3004+arg3005+arg3006+arg3007+arg3008+arg3009+arg3010+arg3011+arg3012+arg3013+arg3014+arg3015+arg3016+arg3017+arg3018+arg3019+arg3020+arg3021+arg3022+arg3023+arg3024+arg3025+arg3026+arg3027+arg3028+arg3029+arg3030+arg3031+arg3032+arg3033+arg3034+arg3035+arg3036+arg3037+arg3038+arg3039+arg3040+arg3041+arg3042+arg3043+arg3044+arg3045+arg3046+arg3047+arg3048+arg3049+arg3050+arg3051+arg3052+arg3053+arg3054+arg3055+arg3056+arg3057+arg3058+arg3059+arg3060+arg3061+arg3062+arg3063+arg3064+arg3065+arg3066+arg3067+arg3068+arg3069+arg3070+arg3071+arg3072+arg3073+arg3074+arg3075+arg3076+arg3077+arg3078+arg3079+arg3080+arg3081+arg3082+arg3083+arg3084+arg3085+arg3086+arg3087+arg3088+arg3089+arg3090+arg3091+arg3092+arg3093+arg3094+arg3095+arg3096+arg3097+arg3098+arg3099+arg3100+arg3101+arg3102+arg3103+arg3104+arg3105+arg3106+arg3107+arg3108+arg3109+arg3110+arg3111+arg3112+arg3113+arg3114+arg3115+arg3116+arg3117+arg3118+arg3119+arg3120+arg3121+arg3122+arg3123+arg3124+arg3125+arg3126+arg3127+arg3128+arg3129+arg3130+arg3131+arg3132+arg3133+arg3134+arg3135+arg3136+arg3137+arg3138+arg3139+arg3140+arg3141+arg3142+arg3143+arg3144+arg3145+arg3146+arg3147+arg3148+arg3149+arg3150+arg3151+arg3152+arg3153+arg3154+arg3155+arg3156+arg3157+arg3158+arg3159+arg3160+arg3161+arg3162+arg3163+arg3164+arg3165+arg3166+arg3167+arg3168+arg3169+arg3170+arg3171+arg3172+arg3173+arg3174+arg3175+arg3176+arg3177+arg3178+arg3179+arg3180+arg3181+arg3182+arg3183+arg3184+arg3185+arg3186+arg3187+arg3188+arg3189+arg3190+arg3191+arg3192+arg3193+arg3194+arg3195+arg3196+arg3197+arg3198+arg3199+arg3200+arg3201+arg3202+arg3203+arg3204+arg3205+arg3206+arg3207+arg3208+arg3209+arg3210+arg3211+arg3212+arg3213+arg3214+arg3215+arg3216+arg3217+arg3218+arg3219+arg3220+arg3221+arg3222+arg3223+arg3224+arg3225+arg3226+arg3227+arg3228+arg3229+arg3230+arg3231+arg3232+arg3233+arg3234+arg3235+arg3236+arg3237+arg3238+arg3239+arg3240+arg3241+arg3242+arg3243+arg3244+arg3245+arg3246+arg3247+arg3248+arg3249+arg3250+arg3251+arg3252+arg3253+arg3254+arg3255+arg3256+arg3257+arg3258+arg3259+arg3260+arg3261+arg3262+arg3263+arg3264+arg3265+arg3266+arg3267+arg3268+arg3269+arg3270+arg3271+arg3272+arg3273+arg3274+arg3275+arg3276+arg3277+arg3278+arg3279+arg3280+arg3281+arg3282+arg3283+arg3284+arg3285+arg3286+arg3287+arg3288+arg3289+arg3290+arg3291+arg3292+arg3293+arg3294+arg3295+arg3296+arg3297+arg3298+arg3299+arg3300+arg3301+arg3302+arg3303+arg3304+arg3305+arg3306+arg3307+arg3308+arg3309+arg3310+arg3311+arg3312+arg3313+arg3314+arg3315+arg3316+arg3317+arg3318+arg3319+arg3320+arg3321+arg3322+arg3323+arg3324+arg3325+arg3326+arg3327+arg3328+arg3329+arg3330+arg3331+arg3332+arg3333+arg3334+arg3335+arg3336+arg3337+arg3338+arg3339+arg3340+arg3341+arg3342+arg3343+arg3344+arg3345+arg3346+arg3347+arg3348+arg3349+arg3350+arg3351+arg3352+arg3353+arg3354+arg3355+arg3356+arg3357+arg3358+arg3359+arg3360+arg3361+arg3362+arg3363+arg3364+arg3365+arg3366+arg3367+arg3368+arg3369+arg3370+arg3371+arg3372+arg3373+arg3374+arg3375+arg3376+arg3377+arg3378+arg3379+arg3380+arg3381+arg3382+arg3383+arg3384+arg3385+arg3386+arg3387+arg3388+arg3389+arg3390+arg3391+arg3392+arg3393+arg3394+arg3395+arg3396+arg3397+arg3398+arg3399+arg3400+arg3401+arg3402+arg3403+arg3404+arg3405+arg3406+arg3407+arg3408+arg3409+arg3410+arg3411+arg3412+arg3413+arg3414+arg3415+arg3416+arg3417+arg3418+arg3419+arg3420+arg3421+arg3422+arg3423+arg3424+arg3425+arg3426+arg3427+arg3428+arg3429+arg3430+arg3431+arg3432+arg3433+arg3434+arg3435+arg3436+arg3437+arg3438+arg3439+arg3440+arg3441+arg3442+arg3443+arg3444+arg3445+arg3446+arg3447+arg3448+arg3449+arg3450+arg3451+arg3452+arg3453+arg3454+arg3455+arg3456+arg3457+arg3458+arg3459+arg3460+arg3461+arg3462+arg3463+arg3464+arg3465+arg3466+arg3467+arg3468+arg3469+arg3470+arg3471+arg3472+arg3473+arg3474+arg3475+arg3476+arg3477+arg3478+arg3479+arg3480+arg3481+arg3482+arg3483+arg3484+arg3485+arg3486+arg3487+arg3488+arg3489+arg3490+arg3491+arg3492+arg3493+arg3494+arg3495+arg3496+arg3497+arg3498+arg3499+arg3500+arg3501+arg3502+arg3503+arg3504+arg3505+arg3506+arg3507+arg3508+arg3509+arg3510+arg3511+arg3512+arg3513+arg3514+arg3515+arg3516+arg3517+arg3518+arg3519+arg3520+arg3521+arg3522+arg3523+arg3524+arg3525+arg3526+arg3527+arg3528+arg3529+arg3530+arg3531+arg3532+arg3533+arg3534+arg3535+arg3536+arg3537+arg3538+arg3539+arg3540+arg3541+arg3542+arg3543+arg3544+arg3545+arg3546+arg3547+arg3548+arg3549+arg3550+arg3551+arg3552+arg3553+arg3554+arg3555+arg3556+arg3557+arg3558+arg3559+arg3560+arg3561+arg3562+arg3563+arg3564+arg3565+arg3566+arg3567+arg3568+arg3569+arg3570+arg3571+arg3572+arg3573+arg3574+arg3575+arg3576+arg3577+arg3578+arg3579+arg3580+arg3581+arg3582+arg3583+arg3584+arg3585+arg3586+arg3587+arg3588+arg3589+arg3590+arg3591+arg3592+arg3593+arg3594+arg3595+arg3596+arg3597+arg3598+arg3599+arg3600+arg3601+arg3602+arg3603+arg3604+arg3605+arg3606+arg3607+arg3608+arg3609+arg3610+arg3611+arg3612+arg3613+arg3614+arg3615+arg3616+arg3617+arg3618+arg3619+arg3620+arg3621+arg3622+arg3623+arg3624+arg3625+arg3626+arg3627+arg3628+arg3629+arg3630+arg3631+arg3632+arg3633+arg3634+arg3635+arg3636+arg3637+arg3638+arg3639+arg3640+arg3641+arg3642+arg3643+arg3644+arg3645+arg3646+arg3647+arg3648+arg3649+arg3650+arg3651+arg3652+arg3653+arg3654+arg3655+arg3656+arg3657+arg3658+arg3659+arg3660+arg3661+arg3662+arg3663+arg3664+arg3665+arg3666+arg3667+arg3668+arg3669+arg3670+arg3671+arg3672+arg3673+arg3674+arg3675+arg3676+arg3677+arg3678+arg3679+arg3680+arg3681+arg3682+arg3683+arg3684+arg3685+arg3686+arg3687+arg3688+arg3689+arg3690+arg3691+arg3692+arg3693+arg3694+arg3695+arg3696+arg3697+arg3698+arg3699+arg3700+arg3701+arg3702+arg3703+arg3704+arg3705+arg3706+arg3707+arg3708+arg3709+arg3710+arg3711+arg3712+arg3713+arg3714+arg3715+arg3716+arg3717+arg3718+arg3719+arg3720+arg3721+arg3722+arg3723+arg3724+arg3725+arg3726+arg3727+arg3728+arg3729+arg3730+arg3731+arg3732+arg3733+arg3734+arg3735+arg3736+arg3737+arg3738+arg3739+arg3740+arg3741+arg3742+arg3743+arg3744+arg3745+arg3746+arg3747+arg3748+arg3749+arg3750+arg3751+arg3752+arg3753+arg3754+arg3755+arg3756+arg3757+arg3758+arg3759+arg3760+arg3761+arg3762+arg3763+arg3764+arg3765+arg3766+arg3767+arg3768+arg3769+arg3770+arg3771+arg3772+arg3773+arg3774+arg3775+arg3776+arg3777+arg3778+arg3779+arg3780+arg3781+arg3782+arg3783+arg3784+arg3785+arg3786+arg3787+arg3788+arg3789+arg3790+arg3791+arg3792+arg3793+arg3794+arg3795+arg3796+arg3797+arg3798+arg3799+arg3800+arg3801+arg3802+arg3803+arg3804+arg3805+arg3806+arg3807+arg3808+arg3809+arg3810+arg3811+arg3812+arg3813+arg3814+arg3815+arg3816+arg3817+arg3818+arg3819+arg3820+arg3821+arg3822+arg3823+arg3824+arg3825+arg3826+arg3827+arg3828+arg3829+arg3830+arg3831+arg3832+arg3833+arg3834+arg3835+arg3836+arg3837+arg3838+arg3839+arg3840+arg3841+arg3842+arg3843+arg3844+arg3845+arg3846+arg3847+arg3848+arg3849+arg3850+arg3851+arg3852+arg3853+arg3854+arg3855+arg3856+arg3857+arg3858+arg3859+arg3860+arg3861+arg3862+arg3863+arg3864+arg3865+arg3866+arg3867+arg3868+arg3869+arg3870+arg3871+arg3872+arg3873+arg3874+arg3875+arg3876+arg3877+arg3878+arg3879+arg3880+arg3881+arg3882+arg3883+arg3884+arg3885+arg3886+arg3887+arg3888+arg3889+arg3890+arg3891+arg3892+arg3893+arg3894+arg3895+arg3896+arg3897+arg3898+arg3899+arg3900+arg3901+arg3902+arg3903+arg3904+arg3905+arg3906+arg3907+arg3908+arg3909+arg3910+arg3911+arg3912+arg3913+arg3914+arg3915+arg3916+arg3917+arg3918+arg3919+arg3920+arg3921+arg3922+arg3923+arg3924+arg3925+arg3926+arg3927+arg3928+arg3929+arg3930+arg3931+arg3932+arg3933+arg3934+arg3935+arg3936+arg3937+arg3938+arg3939+arg3940+arg3941+arg3942+arg3943+arg3944+arg3945+arg3946+arg3947+arg3948+arg3949+arg3950+arg3951+arg3952+arg3953+arg3954+arg3955+arg3956+arg3957+arg3958+arg3959+arg3960+arg3961+arg3962+arg3963+arg3964+arg3965+arg3966+arg3967+arg3968+arg3969+arg3970+arg3971+arg3972+arg3973+arg3974+arg3975+arg3976+arg3977+arg3978+arg3979+arg3980+arg3981+arg3982+arg3983+arg3984+arg3985+arg3986+arg3987+arg3988+arg3989+arg3990+arg3991+arg3992+arg3993+arg3994+arg3995+arg3996+arg3997+arg3998+arg3999+arg4000+arg4001+arg4002+arg4003+arg4004+arg4005+arg4006+arg4007+arg4008+arg4009+arg4010+arg4011+arg4012+arg4013+arg4014+arg4015+arg4016+arg4017+arg4018+arg4019+arg4020+arg4021+arg4022+arg4023+arg4024+arg4025+arg4026+arg4027+arg4028+arg4029+arg4030+arg4031+arg4032+arg4033+arg4034+arg4035+arg4036+arg4037+arg4038+arg4039+arg4040+arg4041+arg4042+arg4043+arg4044+arg4045+arg4046+arg4047+arg4048+arg4049+arg4050+arg4051+arg4052+arg4053+arg4054+arg4055+arg4056+arg4057+arg4058+arg4059+arg4060+arg4061+arg4062+arg4063+arg4064+arg4065+arg4066+arg4067+arg4068+arg4069+arg4070+arg4071+arg4072+arg4073+arg4074+arg4075+arg4076+arg4077+arg4078+arg4079+arg4080+arg4081+arg4082+arg4083+arg4084+arg4085+arg4086+arg4087+arg4088+arg4089+arg4090+arg4091+arg4092+arg4093+arg4094+arg4095+arg4096+arg4097+arg4098+arg4099+arg4100+arg4101+arg4102+arg4103+arg4104+arg4105+arg4106+arg4107+arg4108+arg4109+arg4110+arg4111+arg4112+arg4113+arg4114+arg4115+arg4116+arg4117+arg4118+arg4119+arg4120+arg4121+arg4122+arg4123+arg4124+arg4125+arg4126+arg4127+arg4128+arg4129+arg4130+arg4131+arg4132+arg4133+arg4134+arg4135+arg4136+arg4137+arg4138+arg4139+arg4140+arg4141+arg4142+arg4143+arg4144+arg4145+arg4146+arg4147+arg4148+arg4149+arg4150+arg4151+arg4152+arg4153+arg4154+arg4155+arg4156+arg4157+arg4158+arg4159+arg4160+arg4161+arg4162+arg4163+arg4164+arg4165+arg4166+arg4167+arg4168+arg4169+arg4170+arg4171+arg4172+arg4173+arg4174+arg4175+arg4176+arg4177+arg4178+arg4179+arg4180+arg4181+arg4182+arg4183+arg4184+arg4185+arg4186+arg4187+arg4188+arg4189+arg4190+arg4191+arg4192+arg4193+arg4194+arg4195+arg4196+arg4197+arg4198+arg4199+arg4200+arg4201+arg4202+arg4203+arg4204+arg4205+arg4206+arg4207+arg4208+arg4209+arg4210+arg4211+arg4212+arg4213+arg4214+arg4215+arg4216+arg4217+arg4218+arg4219+arg4220+arg4221+arg4222+arg4223+arg4224+arg4225+arg4226+arg4227+arg4228+arg4229+arg4230+arg4231+arg4232+arg4233+arg4234+arg4235+arg4236+arg4237+arg4238+arg4239+arg4240+arg4241+arg4242+arg4243+arg4244+arg4245+arg4246+arg4247+arg4248+arg4249+arg4250+arg4251+arg4252+arg4253+arg4254+arg4255+arg4256+arg4257+arg4258+arg4259+arg4260+arg4261+arg4262+arg4263+arg4264+arg4265+arg4266+arg4267+arg4268+arg4269+arg4270+arg4271+arg4272+arg4273+arg4274+arg4275+arg4276+arg4277+arg4278+arg4279+arg4280+arg4281+arg4282+arg4283+arg4284+arg4285+arg4286+arg4287+arg4288+arg4289+arg4290+arg4291+arg4292+arg4293+arg4294+arg4295+arg4296+arg4297+arg4298+arg4299+arg4300+arg4301+arg4302+arg4303+arg4304+arg4305+arg4306+arg4307+arg4308+arg4309+arg4310+arg4311+arg4312+arg4313+arg4314+arg4315+arg4316+arg4317+arg4318+arg4319+arg4320+arg4321+arg4322+arg4323+arg4324+arg4325+arg4326+arg4327+arg4328+arg4329+arg4330+arg4331+arg4332+arg4333+arg4334+arg4335+arg4336+arg4337+arg4338+arg4339+arg4340+arg4341+arg4342+arg4343+arg4344+arg4345+arg4346+arg4347+arg4348+arg4349+arg4350+arg4351+arg4352+arg4353+arg4354+arg4355+arg4356+arg4357+arg4358+arg4359+arg4360+arg4361+arg4362+arg4363+arg4364+arg4365+arg4366+arg4367+arg4368+arg4369+arg4370+arg4371+arg4372+arg4373+arg4374+arg4375+arg4376+arg4377+arg4378+arg4379+arg4380+arg4381+arg4382+arg4383+arg4384+arg4385+arg4386+arg4387+arg4388+arg4389+arg4390+arg4391+arg4392+arg4393+arg4394+arg4395+arg4396+arg4397+arg4398+arg4399+arg4400+arg4401+arg4402+arg4403+arg4404+arg4405+arg4406+arg4407+arg4408+arg4409+arg4410+arg4411+arg4412+arg4413+arg4414+arg4415+arg4416+arg4417+arg4418+arg4419+arg4420+arg4421+arg4422+arg4423+arg4424+arg4425+arg4426+arg4427+arg4428+arg4429+arg4430+arg4431+arg4432+arg4433+arg4434+arg4435+arg4436+arg4437+arg4438+arg4439+arg4440+arg4441+arg4442+arg4443+arg4444+arg4445+arg4446+arg4447+arg4448+arg4449+arg4450+arg4451+arg4452+arg4453+arg4454+arg4455+arg4456+arg4457+arg4458+arg4459+arg4460+arg4461+arg4462+arg4463+arg4464+arg4465+arg4466+arg4467+arg4468+arg4469+arg4470+arg4471+arg4472+arg4473+arg4474+arg4475+arg4476+arg4477+arg4478+arg4479+arg4480+arg4481+arg4482+arg4483+arg4484+arg4485+arg4486+arg4487+arg4488+arg4489+arg4490+arg4491+arg4492+arg4493+arg4494+arg4495+arg4496+arg4497+arg4498+arg4499+arg4500+arg4501+arg4502+arg4503+arg4504+arg4505+arg4506+arg4507+arg4508+arg4509+arg4510+arg4511+arg4512+arg4513+arg4514+arg4515+arg4516+arg4517+arg4518+arg4519+arg4520+arg4521+arg4522+arg4523+arg4524+arg4525+arg4526+arg4527+arg4528+arg4529+arg4530+arg4531+arg4532+arg4533+arg4534+arg4535+arg4536+arg4537+arg4538+arg4539+arg4540+arg4541+arg4542+arg4543+arg4544+arg4545+arg4546+arg4547+arg4548+arg4549+arg4550+arg4551+arg4552+arg4553+arg4554+arg4555+arg4556+arg4557+arg4558+arg4559+arg4560+arg4561+arg4562+arg4563+arg4564+arg4565+arg4566+arg4567+arg4568+arg4569+arg4570+arg4571+arg4572+arg4573+arg4574+arg4575+arg4576+arg4577+arg4578+arg4579+arg4580+arg4581+arg4582+arg4583+arg4584+arg4585+arg4586+arg4587+arg4588+arg4589+arg4590+arg4591+arg4592+arg4593+arg4594+arg4595+arg4596+arg4597+arg4598+arg4599+arg4600+arg4601+arg4602+arg4603+arg4604+arg4605+arg4606+arg4607+arg4608+arg4609+arg4610+arg4611+arg4612+arg4613+arg4614+arg4615+arg4616+arg4617+arg4618+arg4619+arg4620+arg4621+arg4622+arg4623+arg4624+arg4625+arg4626+arg4627+arg4628+arg4629+arg4630+arg4631+arg4632+arg4633+arg4634+arg4635+arg4636+arg4637+arg4638+arg4639+arg4640+arg4641+arg4642+arg4643+arg4644+arg4645+arg4646+arg4647+arg4648+arg4649+arg4650+arg4651+arg4652+arg4653+arg4654+arg4655+arg4656+arg4657+arg4658+arg4659+arg4660+arg4661+arg4662+arg4663+arg4664+arg4665+arg4666+arg4667+arg4668+arg4669+arg4670+arg4671+arg4672+arg4673+arg4674+arg4675+arg4676+arg4677+arg4678+arg4679+arg4680+arg4681+arg4682+arg4683+arg4684+arg4685+arg4686+arg4687+arg4688+arg4689+arg4690+arg4691+arg4692+arg4693+arg4694+arg4695+arg4696+arg4697+arg4698+arg4699+arg4700+arg4701+arg4702+arg4703+arg4704+arg4705+arg4706+arg4707+arg4708+arg4709+arg4710+arg4711+arg4712+arg4713+arg4714+arg4715+arg4716+arg4717+arg4718+arg4719+arg4720+arg4721+arg4722+arg4723+arg4724+arg4725+arg4726+arg4727+arg4728+arg4729+arg4730+arg4731+arg4732+arg4733+arg4734+arg4735+arg4736+arg4737+arg4738+arg4739+arg4740+arg4741+arg4742+arg4743+arg4744+arg4745+arg4746+arg4747+arg4748+arg4749+arg4750+arg4751+arg4752+arg4753+arg4754+arg4755+arg4756+arg4757+arg4758+arg4759+arg4760+arg4761+arg4762+arg4763+arg4764+arg4765+arg4766+arg4767+arg4768+arg4769+arg4770+arg4771+arg4772+arg4773+arg4774+arg4775+arg4776+arg4777+arg4778+arg4779+arg4780+arg4781+arg4782+arg4783+arg4784+arg4785+arg4786+arg4787+arg4788+arg4789+arg4790+arg4791+arg4792+arg4793+arg4794+arg4795+arg4796+arg4797+arg4798+arg4799+arg4800+arg4801+arg4802+arg4803+arg4804+arg4805+arg4806+arg4807+arg4808+arg4809+arg4810+arg4811+arg4812+arg4813+arg4814+arg4815+arg4816+arg4817+arg4818+arg4819+arg4820+arg4821+arg4822+arg4823+arg4824+arg4825+arg4826+arg4827+arg4828+arg4829+arg4830+arg4831+arg4832+arg4833+arg4834+arg4835+arg4836+arg4837+arg4838+arg4839+arg4840+arg4841+arg4842+arg4843+arg4844+arg4845+arg4846+arg4847+arg4848+arg4849+arg4850+arg4851+arg4852+arg4853+arg4854+arg4855+arg4856+arg4857+arg4858+arg4859+arg4860+arg4861+arg4862+arg4863+arg4864+arg4865+arg4866+arg4867+arg4868+arg4869+arg4870+arg4871+arg4872+arg4873+arg4874+arg4875+arg4876+arg4877+arg4878+arg4879+arg4880+arg4881+arg4882+arg4883+arg4884+arg4885+arg4886+arg4887+arg4888+arg4889+arg4890+arg4891+arg4892+arg4893+arg4894+arg4895+arg4896+arg4897+arg4898+arg4899+arg4900+arg4901+arg4902+arg4903+arg4904+arg4905+arg4906+arg4907+arg4908+arg4909+arg4910+arg4911+arg4912+arg4913+arg4914+arg4915+arg4916+arg4917+arg4918+arg4919+arg4920+arg4921+arg4922+arg4923+arg4924+arg4925+arg4926+arg4927+arg4928+arg4929+arg4930+arg4931+arg4932+arg4933+arg4934+arg4935+arg4936+arg4937+arg4938+arg4939+arg4940+arg4941+arg4942+arg4943+arg4944+arg4945+arg4946+arg4947+arg4948+arg4949+arg4950+arg4951+arg4952+arg4953+arg4954+arg4955+arg4956+arg4957+arg4958+arg4959+arg4960+arg4961+arg4962+arg4963+arg4964+arg4965+arg4966+arg4967+arg4968+arg4969+arg4970+arg4971+arg4972+arg4973+arg4974+arg4975+arg4976+arg4977+arg4978+arg4979+arg4980+arg4981+arg4982+arg4983+arg4984+arg4985+arg4986+arg4987+arg4988+arg4989+arg4990+arg4991+arg4992+arg4993+arg4994+arg4995+arg4996+arg4997+arg4998+arg4999;} +JSC_DEFINE_NOEXCEPT_JIT_OPERATION(functionWithHellaArguments3, int, (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11, int arg12, int arg13, int arg14, int arg15, int arg16, int arg17, int arg18, int arg19, int arg20, int arg21, int arg22, int arg23, int arg24, int arg25, int arg26, int arg27, int arg28, int arg29, int arg30, int arg31, int arg32, int arg33, int arg34, int arg35, int arg36, int arg37, int arg38, int arg39, int arg40, int arg41, int arg42, int arg43, int arg44, int arg45, int arg46, int arg47, int arg48, int arg49, int arg50, int arg51, int arg52, int arg53, int arg54, int arg55, int arg56, int arg57, int arg58, int arg59, int arg60, int arg61, int arg62, int arg63, int arg64, int arg65, int arg66, int arg67, int arg68, int arg69, int arg70, int arg71, int arg72, int arg73, int arg74, int arg75, int arg76, int arg77, int arg78, int arg79, int arg80, int arg81, int arg82, int arg83, int arg84, int arg85, int arg86, int arg87, int arg88, int arg89, int arg90, int arg91, int arg92, int arg93, int arg94, int arg95, int arg96, int arg97, int arg98, int arg99, int arg100, int arg101, int arg102, int arg103, int arg104, int arg105, int arg106, int arg107, int arg108, int arg109, int arg110, int arg111, int arg112, int arg113, int arg114, int arg115, int arg116, int arg117, int arg118, int arg119, int arg120, int arg121, int arg122, int arg123, int arg124, int arg125, int arg126, int arg127, int arg128, int arg129, int arg130, int arg131, int arg132, int arg133, int arg134, int arg135, int arg136, int arg137, int arg138, int arg139, int arg140, int arg141, int arg142, int arg143, int arg144, int arg145, int arg146, int arg147, int arg148, int arg149, int arg150, int arg151, int arg152, int arg153, int arg154, int arg155, int arg156, int arg157, int arg158, int arg159, int arg160, int arg161, int arg162, int arg163, int arg164, int arg165, int arg166, int arg167, int arg168, int arg169, int arg170, int arg171, int arg172, int arg173, int arg174, int arg175, int arg176, int arg177, int arg178, int arg179, int arg180, int arg181, int arg182, int arg183, int arg184, int arg185, int arg186, int arg187, int arg188, int arg189, int arg190, int arg191, int arg192, int arg193, int arg194, int arg195, int arg196, int arg197, int arg198, int arg199, int arg200, int arg201, int arg202, int arg203, int arg204, int arg205, int arg206, int arg207, int arg208, int arg209, int arg210, int arg211, int arg212, int arg213, int arg214, int arg215, int arg216, int arg217, int arg218, int arg219, int arg220, int arg221, int arg222, int arg223, int arg224, int arg225, int arg226, int arg227, int arg228, int arg229, int arg230, int arg231, int arg232, int arg233, int arg234, int arg235, int arg236, int arg237, int arg238, int arg239, int arg240, int arg241, int arg242, int arg243, int arg244, int arg245, int arg246, int arg247, int arg248, int arg249, int arg250, int arg251, int arg252, int arg253, int arg254, int arg255, int arg256, int arg257, int arg258, int arg259, int arg260, int arg261, int arg262, int arg263, int arg264, int arg265, int arg266, int arg267, int arg268, int arg269, int arg270, int arg271, int arg272, int arg273, int arg274, int arg275, int arg276, int arg277, int arg278, int arg279, int arg280, int arg281, int arg282, int arg283, int arg284, int arg285, int arg286, int arg287, int arg288, int arg289, int arg290, int arg291, int arg292, int arg293, int arg294, int arg295, int arg296, int arg297, int arg298, int arg299, int arg300, int arg301, int arg302, int arg303, int arg304, int arg305, int arg306, int arg307, int arg308, int arg309, int arg310, int arg311, int arg312, int arg313, int arg314, int arg315, int arg316, int arg317, int arg318, int arg319, int arg320, int arg321, int arg322, int arg323, int arg324, int arg325, int arg326, int arg327, int arg328, int arg329, int arg330, int arg331, int arg332, int arg333, int arg334, int arg335, int arg336, int arg337, int arg338, int arg339, int arg340, int arg341, int arg342, int arg343, int arg344, int arg345, int arg346, int arg347, int arg348, int arg349, int arg350, int arg351, int arg352, int arg353, int arg354, int arg355, int arg356, int arg357, int arg358, int arg359, int arg360, int arg361, int arg362, int arg363, int arg364, int arg365, int arg366, int arg367, int arg368, int arg369, int arg370, int arg371, int arg372, int arg373, int arg374, int arg375, int arg376, int arg377, int arg378, int arg379, int arg380, int arg381, int arg382, int arg383, int arg384, int arg385, int arg386, int arg387, int arg388, int arg389, int arg390, int arg391, int arg392, int arg393, int arg394, int arg395, int arg396, int arg397, int arg398, int arg399, int arg400, int arg401, int arg402, int arg403, int arg404, int arg405, int arg406, int arg407, int arg408, int arg409, int arg410, int arg411, int arg412, int arg413, int arg414, int arg415, int arg416, int arg417, int arg418, int arg419, int arg420, int arg421, int arg422, int arg423, int arg424, int arg425, int arg426, int arg427, int arg428, int arg429, int arg430, int arg431, int arg432, int arg433, int arg434, int arg435, int arg436, int arg437, int arg438, int arg439, int arg440, int arg441, int arg442, int arg443, int arg444, int arg445, int arg446, int arg447, int arg448, int arg449, int arg450, int arg451, int arg452, int arg453, int arg454, int arg455, int arg456, int arg457, int arg458, int arg459, int arg460, int arg461, int arg462, int arg463, int arg464, int arg465, int arg466, int arg467, int arg468, int arg469, int arg470, int arg471, int arg472, int arg473, int arg474, int arg475, int arg476, int arg477, int arg478, int arg479, int arg480, int arg481, int arg482, int arg483, int arg484, int arg485, int arg486, int arg487, int arg488, int arg489, int arg490, int arg491, int arg492, int arg493, int arg494, int arg495, int arg496, int arg497, int arg498, int arg499, int arg500, int arg501, int arg502, int arg503, int arg504, int arg505, int arg506, int arg507, int arg508, int arg509, int arg510, int arg511, int arg512, int arg513, int arg514, int arg515, int arg516, int arg517, int arg518, int arg519, int arg520, int arg521, int arg522, int arg523, int arg524, int arg525, int arg526, int arg527, int arg528, int arg529, int arg530, int arg531, int arg532, int arg533, int arg534, int arg535, int arg536, int arg537, int arg538, int arg539, int arg540, int arg541, int arg542, int arg543, int arg544, int arg545, int arg546, int arg547, int arg548, int arg549, int arg550, int arg551, int arg552, int arg553, int arg554, int arg555, int arg556, int arg557, int arg558, int arg559, int arg560, int arg561, int arg562, int arg563, int arg564, int arg565, int arg566, int arg567, int arg568, int arg569, int arg570, int arg571, int arg572, int arg573, int arg574, int arg575, int arg576, int arg577, int arg578, int arg579, int arg580, int arg581, int arg582, int arg583, int arg584, int arg585, int arg586, int arg587, int arg588, int arg589, int arg590, int arg591, int arg592, int arg593, int arg594, int arg595, int arg596, int arg597, int arg598, int arg599, int arg600, int arg601, int arg602, int arg603, int arg604, int arg605, int arg606, int arg607, int arg608, int arg609, int arg610, int arg611, int arg612, int arg613, int arg614, int arg615, int arg616, int arg617, int arg618, int arg619, int arg620, int arg621, int arg622, int arg623, int arg624, int arg625, int arg626, int arg627, int arg628, int arg629, int arg630, int arg631, int arg632, int arg633, int arg634, int arg635, int arg636, int arg637, int arg638, int arg639, int arg640, int arg641, int arg642, int arg643, int arg644, int arg645, int arg646, int arg647, int arg648, int arg649, int arg650, int arg651, int arg652, int arg653, int arg654, int arg655, int arg656, int arg657, int arg658, int arg659, int arg660, int arg661, int arg662, int arg663, int arg664, int arg665, int arg666, int arg667, int arg668, int arg669, int arg670, int arg671, int arg672, int arg673, int arg674, int arg675, int arg676, int arg677, int arg678, int arg679, int arg680, int arg681, int arg682, int arg683, int arg684, int arg685, int arg686, int arg687, int arg688, int arg689, int arg690, int arg691, int arg692, int arg693, int arg694, int arg695, int arg696, int arg697, int arg698, int arg699, int arg700, int arg701, int arg702, int arg703, int arg704, int arg705, int arg706, int arg707, int arg708, int arg709, int arg710, int arg711, int arg712, int arg713, int arg714, int arg715, int arg716, int arg717, int arg718, int arg719, int arg720, int arg721, int arg722, int arg723, int arg724, int arg725, int arg726, int arg727, int arg728, int arg729, int arg730, int arg731, int arg732, int arg733, int arg734, int arg735, int arg736, int arg737, int arg738, int arg739, int arg740, int arg741, int arg742, int arg743, int arg744, int arg745, int arg746, int arg747, int arg748, int arg749, int arg750, int arg751, int arg752, int arg753, int arg754, int arg755, int arg756, int arg757, int arg758, int arg759, int arg760, int arg761, int arg762, int arg763, int arg764, int arg765, int arg766, int arg767, int arg768, int arg769, int arg770, int arg771, int arg772, int arg773, int arg774, int arg775, int arg776, int arg777, int arg778, int arg779, int arg780, int arg781, int arg782, int arg783, int arg784, int arg785, int arg786, int arg787, int arg788, int arg789, int arg790, int arg791, int arg792, int arg793, int arg794, int arg795, int arg796, int arg797, int arg798, int arg799, int arg800, int arg801, int arg802, int arg803, int arg804, int arg805, int arg806, int arg807, int arg808, int arg809, int arg810, int arg811, int arg812, int arg813, int arg814, int arg815, int arg816, int arg817, int arg818, int arg819, int arg820, int arg821, int arg822, int arg823, int arg824, int arg825, int arg826, int arg827, int arg828, int arg829, int arg830, int arg831, int arg832, int arg833, int arg834, int arg835, int arg836, int arg837, int arg838, int arg839, int arg840, int arg841, int arg842, int arg843, int arg844, int arg845, int arg846, int arg847, int arg848, int arg849, int arg850, int arg851, int arg852, int arg853, int arg854, int arg855, int arg856, int arg857, int arg858, int arg859, int arg860, int arg861, int arg862, int arg863, int arg864, int arg865, int arg866, int arg867, int arg868, int arg869, int arg870, int arg871, int arg872, int arg873, int arg874, int arg875, int arg876, int arg877, int arg878, int arg879, int arg880, int arg881, int arg882, int arg883, int arg884, int arg885, int arg886, int arg887, int arg888, int arg889, int arg890, int arg891, int arg892, int arg893, int arg894, int arg895, int arg896, int arg897, int arg898, int arg899, int arg900, int arg901, int arg902, int arg903, int arg904, int arg905, int arg906, int arg907, int arg908, int arg909, int arg910, int arg911, int arg912, int arg913, int arg914, int arg915, int arg916, int arg917, int arg918, int arg919, int arg920, int arg921, int arg922, int arg923, int arg924, int arg925, int arg926, int arg927, int arg928, int arg929, int arg930, int arg931, int arg932, int arg933, int arg934, int arg935, int arg936, int arg937, int arg938, int arg939, int arg940, int arg941, int arg942, int arg943, int arg944, int arg945, int arg946, int arg947, int arg948, int arg949, int arg950, int arg951, int arg952, int arg953, int arg954, int arg955, int arg956, int arg957, int arg958, int arg959, int arg960, int arg961, int arg962, int arg963, int arg964, int arg965, int arg966, int arg967, int arg968, int arg969, int arg970, int arg971, int arg972, int arg973, int arg974, int arg975, int arg976, int arg977, int arg978, int arg979, int arg980, int arg981, int arg982, int arg983, int arg984, int arg985, int arg986, int arg987, int arg988, int arg989, int arg990, int arg991, int arg992, int arg993, int arg994, int arg995, int arg996, int arg997, int arg998, int arg999, int arg1000, int arg1001, int arg1002, int arg1003, int arg1004, int arg1005, int arg1006, int arg1007, int arg1008, int arg1009, int arg1010, int arg1011, int arg1012, int arg1013, int arg1014, int arg1015, int arg1016, int arg1017, int arg1018, int arg1019, int arg1020, int arg1021, int arg1022, int arg1023, int arg1024, int arg1025, int arg1026, int arg1027, int arg1028, int arg1029, int arg1030, int arg1031, int arg1032, int arg1033, int arg1034, int arg1035, int arg1036, int arg1037, int arg1038, int arg1039, int arg1040, int arg1041, int arg1042, int arg1043, int arg1044, int arg1045, int arg1046, int arg1047, int arg1048, int arg1049, int arg1050, int arg1051, int arg1052, int arg1053, int arg1054, int arg1055, int arg1056, int arg1057, int arg1058, int arg1059, int arg1060, int arg1061, int arg1062, int arg1063, int arg1064, int arg1065, int arg1066, int arg1067, int arg1068, int arg1069, int arg1070, int arg1071, int arg1072, int arg1073, int arg1074, int arg1075, int arg1076, int arg1077, int arg1078, int arg1079, int arg1080, int arg1081, int arg1082, int arg1083, int arg1084, int arg1085, int arg1086, int arg1087, int arg1088, int arg1089, int arg1090, int arg1091, int arg1092, int arg1093, int arg1094, int arg1095, int arg1096, int arg1097, int arg1098, int arg1099, int arg1100, int arg1101, int arg1102, int arg1103, int arg1104, int arg1105, int arg1106, int arg1107, int arg1108, int arg1109, int arg1110, int arg1111, int arg1112, int arg1113, int arg1114, int arg1115, int arg1116, int arg1117, int arg1118, int arg1119, int arg1120, int arg1121, int arg1122, int arg1123, int arg1124, int arg1125, int arg1126, int arg1127, int arg1128, int arg1129, int arg1130, int arg1131, int arg1132, int arg1133, int arg1134, int arg1135, int arg1136, int arg1137, int arg1138, int arg1139, int arg1140, int arg1141, int arg1142, int arg1143, int arg1144, int arg1145, int arg1146, int arg1147, int arg1148, int arg1149, int arg1150, int arg1151, int arg1152, int arg1153, int arg1154, int arg1155, int arg1156, int arg1157, int arg1158, int arg1159, int arg1160, int arg1161, int arg1162, int arg1163, int arg1164, int arg1165, int arg1166, int arg1167, int arg1168, int arg1169, int arg1170, int arg1171, int arg1172, int arg1173, int arg1174, int arg1175, int arg1176, int arg1177, int arg1178, int arg1179, int arg1180, int arg1181, int arg1182, int arg1183, int arg1184, int arg1185, int arg1186, int arg1187, int arg1188, int arg1189, int arg1190, int arg1191, int arg1192, int arg1193, int arg1194, int arg1195, int arg1196, int arg1197, int arg1198, int arg1199, int arg1200, int arg1201, int arg1202, int arg1203, int arg1204, int arg1205, int arg1206, int arg1207, int arg1208, int arg1209, int arg1210, int arg1211, int arg1212, int arg1213, int arg1214, int arg1215, int arg1216, int arg1217, int arg1218, int arg1219, int arg1220, int arg1221, int arg1222, int arg1223, int arg1224, int arg1225, int arg1226, int arg1227, int arg1228, int arg1229, int arg1230, int arg1231, int arg1232, int arg1233, int arg1234, int arg1235, int arg1236, int arg1237, int arg1238, int arg1239, int arg1240, int arg1241, int arg1242, int arg1243, int arg1244, int arg1245, int arg1246, int arg1247, int arg1248, int arg1249, int arg1250, int arg1251, int arg1252, int arg1253, int arg1254, int arg1255, int arg1256, int arg1257, int arg1258, int arg1259, int arg1260, int arg1261, int arg1262, int arg1263, int arg1264, int arg1265, int arg1266, int arg1267, int arg1268, int arg1269, int arg1270, int arg1271, int arg1272, int arg1273, int arg1274, int arg1275, int arg1276, int arg1277, int arg1278, int arg1279, int arg1280, int arg1281, int arg1282, int arg1283, int arg1284, int arg1285, int arg1286, int arg1287, int arg1288, int arg1289, int arg1290, int arg1291, int arg1292, int arg1293, int arg1294, int arg1295, int arg1296, int arg1297, int arg1298, int arg1299, int arg1300, int arg1301, int arg1302, int arg1303, int arg1304, int arg1305, int arg1306, int arg1307, int arg1308, int arg1309, int arg1310, int arg1311, int arg1312, int arg1313, int arg1314, int arg1315, int arg1316, int arg1317, int arg1318, int arg1319, int arg1320, int arg1321, int arg1322, int arg1323, int arg1324, int arg1325, int arg1326, int arg1327, int arg1328, int arg1329, int arg1330, int arg1331, int arg1332, int arg1333, int arg1334, int arg1335, int arg1336, int arg1337, int arg1338, int arg1339, int arg1340, int arg1341, int arg1342, int arg1343, int arg1344, int arg1345, int arg1346, int arg1347, int arg1348, int arg1349, int arg1350, int arg1351, int arg1352, int arg1353, int arg1354, int arg1355, int arg1356, int arg1357, int arg1358, int arg1359, int arg1360, int arg1361, int arg1362, int arg1363, int arg1364, int arg1365, int arg1366, int arg1367, int arg1368, int arg1369, int arg1370, int arg1371, int arg1372, int arg1373, int arg1374, int arg1375, int arg1376, int arg1377, int arg1378, int arg1379, int arg1380, int arg1381, int arg1382, int arg1383, int arg1384, int arg1385, int arg1386, int arg1387, int arg1388, int arg1389, int arg1390, int arg1391, int arg1392, int arg1393, int arg1394, int arg1395, int arg1396, int arg1397, int arg1398, int arg1399, int arg1400, int arg1401, int arg1402, int arg1403, int arg1404, int arg1405, int arg1406, int arg1407, int arg1408, int arg1409, int arg1410, int arg1411, int arg1412, int arg1413, int arg1414, int arg1415, int arg1416, int arg1417, int arg1418, int arg1419, int arg1420, int arg1421, int arg1422, int arg1423, int arg1424, int arg1425, int arg1426, int arg1427, int arg1428, int arg1429, int arg1430, int arg1431, int arg1432, int arg1433, int arg1434, int arg1435, int arg1436, int arg1437, int arg1438, int arg1439, int arg1440, int arg1441, int arg1442, int arg1443, int arg1444, int arg1445, int arg1446, int arg1447, int arg1448, int arg1449, int arg1450, int arg1451, int arg1452, int arg1453, int arg1454, int arg1455, int arg1456, int arg1457, int arg1458, int arg1459, int arg1460, int arg1461, int arg1462, int arg1463, int arg1464, int arg1465, int arg1466, int arg1467, int arg1468, int arg1469, int arg1470, int arg1471, int arg1472, int arg1473, int arg1474, int arg1475, int arg1476, int arg1477, int arg1478, int arg1479, int arg1480, int arg1481, int arg1482, int arg1483, int arg1484, int arg1485, int arg1486, int arg1487, int arg1488, int arg1489, int arg1490, int arg1491, int arg1492, int arg1493, int arg1494, int arg1495, int arg1496, int arg1497, int arg1498, int arg1499, int arg1500, int arg1501, int arg1502, int arg1503, int arg1504, int arg1505, int arg1506, int arg1507, int arg1508, int arg1509, int arg1510, int arg1511, int arg1512, int arg1513, int arg1514, int arg1515, int arg1516, int arg1517, int arg1518, int arg1519, int arg1520, int arg1521, int arg1522, int arg1523, int arg1524, int arg1525, int arg1526, int arg1527, int arg1528, int arg1529, int arg1530, int arg1531, int arg1532, int arg1533, int arg1534, int arg1535, int arg1536, int arg1537, int arg1538, int arg1539, int arg1540, int arg1541, int arg1542, int arg1543, int arg1544, int arg1545, int arg1546, int arg1547, int arg1548, int arg1549, int arg1550, int arg1551, int arg1552, int arg1553, int arg1554, int arg1555, int arg1556, int arg1557, int arg1558, int arg1559, int arg1560, int arg1561, int arg1562, int arg1563, int arg1564, int arg1565, int arg1566, int arg1567, int arg1568, int arg1569, int arg1570, int arg1571, int arg1572, int arg1573, int arg1574, int arg1575, int arg1576, int arg1577, int arg1578, int arg1579, int arg1580, int arg1581, int arg1582, int arg1583, int arg1584, int arg1585, int arg1586, int arg1587, int arg1588, int arg1589, int arg1590, int arg1591, int arg1592, int arg1593, int arg1594, int arg1595, int arg1596, int arg1597, int arg1598, int arg1599, int arg1600, int arg1601, int arg1602, int arg1603, int arg1604, int arg1605, int arg1606, int arg1607, int arg1608, int arg1609, int arg1610, int arg1611, int arg1612, int arg1613, int arg1614, int arg1615, int arg1616, int arg1617, int arg1618, int arg1619, int arg1620, int arg1621, int arg1622, int arg1623, int arg1624, int arg1625, int arg1626, int arg1627, int arg1628, int arg1629, int arg1630, int arg1631, int arg1632, int arg1633, int arg1634, int arg1635, int arg1636, int arg1637, int arg1638, int arg1639, int arg1640, int arg1641, int arg1642, int arg1643, int arg1644, int arg1645, int arg1646, int arg1647, int arg1648, int arg1649, int arg1650, int arg1651, int arg1652, int arg1653, int arg1654, int arg1655, int arg1656, int arg1657, int arg1658, int arg1659, int arg1660, int arg1661, int arg1662, int arg1663, int arg1664, int arg1665, int arg1666, int arg1667, int arg1668, int arg1669, int arg1670, int arg1671, int arg1672, int arg1673, int arg1674, int arg1675, int arg1676, int arg1677, int arg1678, int arg1679, int arg1680, int arg1681, int arg1682, int arg1683, int arg1684, int arg1685, int arg1686, int arg1687, int arg1688, int arg1689, int arg1690, int arg1691, int arg1692, int arg1693, int arg1694, int arg1695, int arg1696, int arg1697, int arg1698, int arg1699, int arg1700, int arg1701, int arg1702, int arg1703, int arg1704, int arg1705, int arg1706, int arg1707, int arg1708, int arg1709, int arg1710, int arg1711, int arg1712, int arg1713, int arg1714, int arg1715, int arg1716, int arg1717, int arg1718, int arg1719, int arg1720, int arg1721, int arg1722, int arg1723, int arg1724, int arg1725, int arg1726, int arg1727, int arg1728, int arg1729, int arg1730, int arg1731, int arg1732, int arg1733, int arg1734, int arg1735, int arg1736, int arg1737, int arg1738, int arg1739, int arg1740, int arg1741, int arg1742, int arg1743, int arg1744, int arg1745, int arg1746, int arg1747, int arg1748, int arg1749, int arg1750, int arg1751, int arg1752, int arg1753, int arg1754, int arg1755, int arg1756, int arg1757, int arg1758, int arg1759, int arg1760, int arg1761, int arg1762, int arg1763, int arg1764, int arg1765, int arg1766, int arg1767, int arg1768, int arg1769, int arg1770, int arg1771, int arg1772, int arg1773, int arg1774, int arg1775, int arg1776, int arg1777, int arg1778, int arg1779, int arg1780, int arg1781, int arg1782, int arg1783, int arg1784, int arg1785, int arg1786, int arg1787, int arg1788, int arg1789, int arg1790, int arg1791, int arg1792, int arg1793, int arg1794, int arg1795, int arg1796, int arg1797, int arg1798, int arg1799, int arg1800, int arg1801, int arg1802, int arg1803, int arg1804, int arg1805, int arg1806, int arg1807, int arg1808, int arg1809, int arg1810, int arg1811, int arg1812, int arg1813, int arg1814, int arg1815, int arg1816, int arg1817, int arg1818, int arg1819, int arg1820, int arg1821, int arg1822, int arg1823, int arg1824, int arg1825, int arg1826, int arg1827, int arg1828, int arg1829, int arg1830, int arg1831, int arg1832, int arg1833, int arg1834, int arg1835, int arg1836, int arg1837, int arg1838, int arg1839, int arg1840, int arg1841, int arg1842, int arg1843, int arg1844, int arg1845, int arg1846, int arg1847, int arg1848, int arg1849, int arg1850, int arg1851, int arg1852, int arg1853, int arg1854, int arg1855, int arg1856, int arg1857, int arg1858, int arg1859, int arg1860, int arg1861, int arg1862, int arg1863, int arg1864, int arg1865, int arg1866, int arg1867, int arg1868, int arg1869, int arg1870, int arg1871, int arg1872, int arg1873, int arg1874, int arg1875, int arg1876, int arg1877, int arg1878, int arg1879, int arg1880, int arg1881, int arg1882, int arg1883, int arg1884, int arg1885, int arg1886, int arg1887, int arg1888, int arg1889, int arg1890, int arg1891, int arg1892, int arg1893, int arg1894, int arg1895, int arg1896, int arg1897, int arg1898, int arg1899, int arg1900, int arg1901, int arg1902, int arg1903, int arg1904, int arg1905, int arg1906, int arg1907, int arg1908, int arg1909, int arg1910, int arg1911, int arg1912, int arg1913, int arg1914, int arg1915, int arg1916, int arg1917, int arg1918, int arg1919, int arg1920, int arg1921, int arg1922, int arg1923, int arg1924, int arg1925, int arg1926, int arg1927, int arg1928, int arg1929, int arg1930, int arg1931, int arg1932, int arg1933, int arg1934, int arg1935, int arg1936, int arg1937, int arg1938, int arg1939, int arg1940, int arg1941, int arg1942, int arg1943, int arg1944, int arg1945, int arg1946, int arg1947, int arg1948, int arg1949, int arg1950, int arg1951, int arg1952, int arg1953, int arg1954, int arg1955, int arg1956, int arg1957, int arg1958, int arg1959, int arg1960, int arg1961, int arg1962, int arg1963, int arg1964, int arg1965, int arg1966, int arg1967, int arg1968, int arg1969, int arg1970, int arg1971, int arg1972, int arg1973, int arg1974, int arg1975, int arg1976, int arg1977, int arg1978, int arg1979, int arg1980, int arg1981, int arg1982, int arg1983, int arg1984, int arg1985, int arg1986, int arg1987, int arg1988, int arg1989, int arg1990, int arg1991, int arg1992, int arg1993, int arg1994, int arg1995, int arg1996, int arg1997, int arg1998, int arg1999, int arg2000, int arg2001, int arg2002, int arg2003, int arg2004, int arg2005, int arg2006, int arg2007, int arg2008, int arg2009, int arg2010, int arg2011, int arg2012, int arg2013, int arg2014, int arg2015, int arg2016, int arg2017, int arg2018, int arg2019, int arg2020, int arg2021, int arg2022, int arg2023, int arg2024, int arg2025, int arg2026, int arg2027, int arg2028, int arg2029, int arg2030, int arg2031, int arg2032, int arg2033, int arg2034, int arg2035, int arg2036, int arg2037, int arg2038, int arg2039, int arg2040, int arg2041, int arg2042, int arg2043, int arg2044, int arg2045, int arg2046, int arg2047, int arg2048, int arg2049, int arg2050, int arg2051, int arg2052, int arg2053, int arg2054, int arg2055, int arg2056, int arg2057, int arg2058, int arg2059, int arg2060, int arg2061, int arg2062, int arg2063, int arg2064, int arg2065, int arg2066, int arg2067, int arg2068, int arg2069, int arg2070, int arg2071, int arg2072, int arg2073, int arg2074, int arg2075, int arg2076, int arg2077, int arg2078, int arg2079, int arg2080, int arg2081, int arg2082, int arg2083, int arg2084, int arg2085, int arg2086, int arg2087, int arg2088, int arg2089, int arg2090, int arg2091, int arg2092, int arg2093, int arg2094, int arg2095, int arg2096, int arg2097, int arg2098, int arg2099, int arg2100, int arg2101, int arg2102, int arg2103, int arg2104, int arg2105, int arg2106, int arg2107, int arg2108, int arg2109, int arg2110, int arg2111, int arg2112, int arg2113, int arg2114, int arg2115, int arg2116, int arg2117, int arg2118, int arg2119, int arg2120, int arg2121, int arg2122, int arg2123, int arg2124, int arg2125, int arg2126, int arg2127, int arg2128, int arg2129, int arg2130, int arg2131, int arg2132, int arg2133, int arg2134, int arg2135, int arg2136, int arg2137, int arg2138, int arg2139, int arg2140, int arg2141, int arg2142, int arg2143, int arg2144, int arg2145, int arg2146, int arg2147, int arg2148, int arg2149, int arg2150, int arg2151, int arg2152, int arg2153, int arg2154, int arg2155, int arg2156, int arg2157, int arg2158, int arg2159, int arg2160, int arg2161, int arg2162, int arg2163, int arg2164, int arg2165, int arg2166, int arg2167, int arg2168, int arg2169, int arg2170, int arg2171, int arg2172, int arg2173, int arg2174, int arg2175, int arg2176, int arg2177, int arg2178, int arg2179, int arg2180, int arg2181, int arg2182, int arg2183, int arg2184, int arg2185, int arg2186, int arg2187, int arg2188, int arg2189, int arg2190, int arg2191, int arg2192, int arg2193, int arg2194, int arg2195, int arg2196, int arg2197, int arg2198, int arg2199, int arg2200, int arg2201, int arg2202, int arg2203, int arg2204, int arg2205, int arg2206, int arg2207, int arg2208, int arg2209, int arg2210, int arg2211, int arg2212, int arg2213, int arg2214, int arg2215, int arg2216, int arg2217, int arg2218, int arg2219, int arg2220, int arg2221, int arg2222, int arg2223, int arg2224, int arg2225, int arg2226, int arg2227, int arg2228, int arg2229, int arg2230, int arg2231, int arg2232, int arg2233, int arg2234, int arg2235, int arg2236, int arg2237, int arg2238, int arg2239, int arg2240, int arg2241, int arg2242, int arg2243, int arg2244, int arg2245, int arg2246, int arg2247, int arg2248, int arg2249, int arg2250, int arg2251, int arg2252, int arg2253, int arg2254, int arg2255, int arg2256, int arg2257, int arg2258, int arg2259, int arg2260, int arg2261, int arg2262, int arg2263, int arg2264, int arg2265, int arg2266, int arg2267, int arg2268, int arg2269, int arg2270, int arg2271, int arg2272, int arg2273, int arg2274, int arg2275, int arg2276, int arg2277, int arg2278, int arg2279, int arg2280, int arg2281, int arg2282, int arg2283, int arg2284, int arg2285, int arg2286, int arg2287, int arg2288, int arg2289, int arg2290, int arg2291, int arg2292, int arg2293, int arg2294, int arg2295, int arg2296, int arg2297, int arg2298, int arg2299, int arg2300, int arg2301, int arg2302, int arg2303, int arg2304, int arg2305, int arg2306, int arg2307, int arg2308, int arg2309, int arg2310, int arg2311, int arg2312, int arg2313, int arg2314, int arg2315, int arg2316, int arg2317, int arg2318, int arg2319, int arg2320, int arg2321, int arg2322, int arg2323, int arg2324, int arg2325, int arg2326, int arg2327, int arg2328, int arg2329, int arg2330, int arg2331, int arg2332, int arg2333, int arg2334, int arg2335, int arg2336, int arg2337, int arg2338, int arg2339, int arg2340, int arg2341, int arg2342, int arg2343, int arg2344, int arg2345, int arg2346, int arg2347, int arg2348, int arg2349, int arg2350, int arg2351, int arg2352, int arg2353, int arg2354, int arg2355, int arg2356, int arg2357, int arg2358, int arg2359, int arg2360, int arg2361, int arg2362, int arg2363, int arg2364, int arg2365, int arg2366, int arg2367, int arg2368, int arg2369, int arg2370, int arg2371, int arg2372, int arg2373, int arg2374, int arg2375, int arg2376, int arg2377, int arg2378, int arg2379, int arg2380, int arg2381, int arg2382, int arg2383, int arg2384, int arg2385, int arg2386, int arg2387, int arg2388, int arg2389, int arg2390, int arg2391, int arg2392, int arg2393, int arg2394, int arg2395, int arg2396, int arg2397, int arg2398, int arg2399, int arg2400, int arg2401, int arg2402, int arg2403, int arg2404, int arg2405, int arg2406, int arg2407, int arg2408, int arg2409, int arg2410, int arg2411, int arg2412, int arg2413, int arg2414, int arg2415, int arg2416, int arg2417, int arg2418, int arg2419, int arg2420, int arg2421, int arg2422, int arg2423, int arg2424, int arg2425, int arg2426, int arg2427, int arg2428, int arg2429, int arg2430, int arg2431, int arg2432, int arg2433, int arg2434, int arg2435, int arg2436, int arg2437, int arg2438, int arg2439, int arg2440, int arg2441, int arg2442, int arg2443, int arg2444, int arg2445, int arg2446, int arg2447, int arg2448, int arg2449, int arg2450, int arg2451, int arg2452, int arg2453, int arg2454, int arg2455, int arg2456, int arg2457, int arg2458, int arg2459, int arg2460, int arg2461, int arg2462, int arg2463, int arg2464, int arg2465, int arg2466, int arg2467, int arg2468, int arg2469, int arg2470, int arg2471, int arg2472, int arg2473, int arg2474, int arg2475, int arg2476, int arg2477, int arg2478, int arg2479, int arg2480, int arg2481, int arg2482, int arg2483, int arg2484, int arg2485, int arg2486, int arg2487, int arg2488, int arg2489, int arg2490, int arg2491, int arg2492, int arg2493, int arg2494, int arg2495, int arg2496, int arg2497, int arg2498, int arg2499, int arg2500, int arg2501, int arg2502, int arg2503, int arg2504, int arg2505, int arg2506, int arg2507, int arg2508, int arg2509, int arg2510, int arg2511, int arg2512, int arg2513, int arg2514, int arg2515, int arg2516, int arg2517, int arg2518, int arg2519, int arg2520, int arg2521, int arg2522, int arg2523, int arg2524, int arg2525, int arg2526, int arg2527, int arg2528, int arg2529, int arg2530, int arg2531, int arg2532, int arg2533, int arg2534, int arg2535, int arg2536, int arg2537, int arg2538, int arg2539, int arg2540, int arg2541, int arg2542, int arg2543, int arg2544, int arg2545, int arg2546, int arg2547, int arg2548, int arg2549, int arg2550, int arg2551, int arg2552, int arg2553, int arg2554, int arg2555, int arg2556, int arg2557, int arg2558, int arg2559, int arg2560, int arg2561, int arg2562, int arg2563, int arg2564, int arg2565, int arg2566, int arg2567, int arg2568, int arg2569, int arg2570, int arg2571, int arg2572, int arg2573, int arg2574, int arg2575, int arg2576, int arg2577, int arg2578, int arg2579, int arg2580, int arg2581, int arg2582, int arg2583, int arg2584, int arg2585, int arg2586, int arg2587, int arg2588, int arg2589, int arg2590, int arg2591, int arg2592, int arg2593, int arg2594, int arg2595, int arg2596, int arg2597, int arg2598, int arg2599, int arg2600, int arg2601, int arg2602, int arg2603, int arg2604, int arg2605, int arg2606, int arg2607, int arg2608, int arg2609, int arg2610, int arg2611, int arg2612, int arg2613, int arg2614, int arg2615, int arg2616, int arg2617, int arg2618, int arg2619, int arg2620, int arg2621, int arg2622, int arg2623, int arg2624, int arg2625, int arg2626, int arg2627, int arg2628, int arg2629, int arg2630, int arg2631, int arg2632, int arg2633, int arg2634, int arg2635, int arg2636, int arg2637, int arg2638, int arg2639, int arg2640, int arg2641, int arg2642, int arg2643, int arg2644, int arg2645, int arg2646, int arg2647, int arg2648, int arg2649, int arg2650, int arg2651, int arg2652, int arg2653, int arg2654, int arg2655, int arg2656, int arg2657, int arg2658, int arg2659, int arg2660, int arg2661, int arg2662, int arg2663, int arg2664, int arg2665, int arg2666, int arg2667, int arg2668, int arg2669, int arg2670, int arg2671, int arg2672, int arg2673, int arg2674, int arg2675, int arg2676, int arg2677, int arg2678, int arg2679, int arg2680, int arg2681, int arg2682, int arg2683, int arg2684, int arg2685, int arg2686, int arg2687, int arg2688, int arg2689, int arg2690, int arg2691, int arg2692, int arg2693, int arg2694, int arg2695, int arg2696, int arg2697, int arg2698, int arg2699, int arg2700, int arg2701, int arg2702, int arg2703, int arg2704, int arg2705, int arg2706, int arg2707, int arg2708, int arg2709, int arg2710, int arg2711, int arg2712, int arg2713, int arg2714, int arg2715, int arg2716, int arg2717, int arg2718, int arg2719, int arg2720, int arg2721, int arg2722, int arg2723, int arg2724, int arg2725, int arg2726, int arg2727, int arg2728, int arg2729, int arg2730, int arg2731, int arg2732, int arg2733, int arg2734, int arg2735, int arg2736, int arg2737, int arg2738, int arg2739, int arg2740, int arg2741, int arg2742, int arg2743, int arg2744, int arg2745, int arg2746, int arg2747, int arg2748, int arg2749, int arg2750, int arg2751, int arg2752, int arg2753, int arg2754, int arg2755, int arg2756, int arg2757, int arg2758, int arg2759, int arg2760, int arg2761, int arg2762, int arg2763, int arg2764, int arg2765, int arg2766, int arg2767, int arg2768, int arg2769, int arg2770, int arg2771, int arg2772, int arg2773, int arg2774, int arg2775, int arg2776, int arg2777, int arg2778, int arg2779, int arg2780, int arg2781, int arg2782, int arg2783, int arg2784, int arg2785, int arg2786, int arg2787, int arg2788, int arg2789, int arg2790, int arg2791, int arg2792, int arg2793, int arg2794, int arg2795, int arg2796, int arg2797, int arg2798, int arg2799, int arg2800, int arg2801, int arg2802, int arg2803, int arg2804, int arg2805, int arg2806, int arg2807, int arg2808, int arg2809, int arg2810, int arg2811, int arg2812, int arg2813, int arg2814, int arg2815, int arg2816, int arg2817, int arg2818, int arg2819, int arg2820, int arg2821, int arg2822, int arg2823, int arg2824, int arg2825, int arg2826, int arg2827, int arg2828, int arg2829, int arg2830, int arg2831, int arg2832, int arg2833, int arg2834, int arg2835, int arg2836, int arg2837, int arg2838, int arg2839, int arg2840, int arg2841, int arg2842, int arg2843, int arg2844, int arg2845, int arg2846, int arg2847, int arg2848, int arg2849, int arg2850, int arg2851, int arg2852, int arg2853, int arg2854, int arg2855, int arg2856, int arg2857, int arg2858, int arg2859, int arg2860, int arg2861, int arg2862, int arg2863, int arg2864, int arg2865, int arg2866, int arg2867, int arg2868, int arg2869, int arg2870, int arg2871, int arg2872, int arg2873, int arg2874, int arg2875, int arg2876, int arg2877, int arg2878, int arg2879, int arg2880, int arg2881, int arg2882, int arg2883, int arg2884, int arg2885, int arg2886, int arg2887, int arg2888, int arg2889, int arg2890, int arg2891, int arg2892, int arg2893, int arg2894, int arg2895, int arg2896, int arg2897, int arg2898, int arg2899, int arg2900, int arg2901, int arg2902, int arg2903, int arg2904, int arg2905, int arg2906, int arg2907, int arg2908, int arg2909, int arg2910, int arg2911, int arg2912, int arg2913, int arg2914, int arg2915, int arg2916, int arg2917, int arg2918, int arg2919, int arg2920, int arg2921, int arg2922, int arg2923, int arg2924, int arg2925, int arg2926, int arg2927, int arg2928, int arg2929, int arg2930, int arg2931, int arg2932, int arg2933, int arg2934, int arg2935, int arg2936, int arg2937, int arg2938, int arg2939, int arg2940, int arg2941, int arg2942, int arg2943, int arg2944, int arg2945, int arg2946, int arg2947, int arg2948, int arg2949, int arg2950, int arg2951, int arg2952, int arg2953, int arg2954, int arg2955, int arg2956, int arg2957, int arg2958, int arg2959, int arg2960, int arg2961, int arg2962, int arg2963, int arg2964, int arg2965, int arg2966, int arg2967, int arg2968, int arg2969, int arg2970, int arg2971, int arg2972, int arg2973, int arg2974, int arg2975, int arg2976, int arg2977, int arg2978, int arg2979, int arg2980, int arg2981, int arg2982, int arg2983, int arg2984, int arg2985, int arg2986, int arg2987, int arg2988, int arg2989, int arg2990, int arg2991, int arg2992, int arg2993, int arg2994, int arg2995, int arg2996, int arg2997, int arg2998, int arg2999, int arg3000, int arg3001, int arg3002, int arg3003, int arg3004, int arg3005, int arg3006, int arg3007, int arg3008, int arg3009, int arg3010, int arg3011, int arg3012, int arg3013, int arg3014, int arg3015, int arg3016, int arg3017, int arg3018, int arg3019, int arg3020, int arg3021, int arg3022, int arg3023, int arg3024, int arg3025, int arg3026, int arg3027, int arg3028, int arg3029, int arg3030, int arg3031, int arg3032, int arg3033, int arg3034, int arg3035, int arg3036, int arg3037, int arg3038, int arg3039, int arg3040, int arg3041, int arg3042, int arg3043, int arg3044, int arg3045, int arg3046, int arg3047, int arg3048, int arg3049, int arg3050, int arg3051, int arg3052, int arg3053, int arg3054, int arg3055, int arg3056, int arg3057, int arg3058, int arg3059, int arg3060, int arg3061, int arg3062, int arg3063, int arg3064, int arg3065, int arg3066, int arg3067, int arg3068, int arg3069, int arg3070, int arg3071, int arg3072, int arg3073, int arg3074, int arg3075, int arg3076, int arg3077, int arg3078, int arg3079, int arg3080, int arg3081, int arg3082, int arg3083, int arg3084, int arg3085, int arg3086, int arg3087, int arg3088, int arg3089, int arg3090, int arg3091, int arg3092, int arg3093, int arg3094, int arg3095, int arg3096, int arg3097, int arg3098, int arg3099, int arg3100, int arg3101, int arg3102, int arg3103, int arg3104, int arg3105, int arg3106, int arg3107, int arg3108, int arg3109, int arg3110, int arg3111, int arg3112, int arg3113, int arg3114, int arg3115, int arg3116, int arg3117, int arg3118, int arg3119, int arg3120, int arg3121, int arg3122, int arg3123, int arg3124, int arg3125, int arg3126, int arg3127, int arg3128, int arg3129, int arg3130, int arg3131, int arg3132, int arg3133, int arg3134, int arg3135, int arg3136, int arg3137, int arg3138, int arg3139, int arg3140, int arg3141, int arg3142, int arg3143, int arg3144, int arg3145, int arg3146, int arg3147, int arg3148, int arg3149, int arg3150, int arg3151, int arg3152, int arg3153, int arg3154, int arg3155, int arg3156, int arg3157, int arg3158, int arg3159, int arg3160, int arg3161, int arg3162, int arg3163, int arg3164, int arg3165, int arg3166, int arg3167, int arg3168, int arg3169, int arg3170, int arg3171, int arg3172, int arg3173, int arg3174, int arg3175, int arg3176, int arg3177, int arg3178, int arg3179, int arg3180, int arg3181, int arg3182, int arg3183, int arg3184, int arg3185, int arg3186, int arg3187, int arg3188, int arg3189, int arg3190, int arg3191, int arg3192, int arg3193, int arg3194, int arg3195, int arg3196, int arg3197, int arg3198, int arg3199, int arg3200, int arg3201, int arg3202, int arg3203, int arg3204, int arg3205, int arg3206, int arg3207, int arg3208, int arg3209, int arg3210, int arg3211, int arg3212, int arg3213, int arg3214, int arg3215, int arg3216, int arg3217, int arg3218, int arg3219, int arg3220, int arg3221, int arg3222, int arg3223, int arg3224, int arg3225, int arg3226, int arg3227, int arg3228, int arg3229, int arg3230, int arg3231, int arg3232, int arg3233, int arg3234, int arg3235, int arg3236, int arg3237, int arg3238, int arg3239, int arg3240, int arg3241, int arg3242, int arg3243, int arg3244, int arg3245, int arg3246, int arg3247, int arg3248, int arg3249, int arg3250, int arg3251, int arg3252, int arg3253, int arg3254, int arg3255, int arg3256, int arg3257, int arg3258, int arg3259, int arg3260, int arg3261, int arg3262, int arg3263, int arg3264, int arg3265, int arg3266, int arg3267, int arg3268, int arg3269, int arg3270, int arg3271, int arg3272, int arg3273, int arg3274, int arg3275, int arg3276, int arg3277, int arg3278, int arg3279, int arg3280, int arg3281, int arg3282, int arg3283, int arg3284, int arg3285, int arg3286, int arg3287, int arg3288, int arg3289, int arg3290, int arg3291, int arg3292, int arg3293, int arg3294, int arg3295, int arg3296, int arg3297, int arg3298, int arg3299, int arg3300, int arg3301, int arg3302, int arg3303, int arg3304, int arg3305, int arg3306, int arg3307, int arg3308, int arg3309, int arg3310, int arg3311, int arg3312, int arg3313, int arg3314, int arg3315, int arg3316, int arg3317, int arg3318, int arg3319, int arg3320, int arg3321, int arg3322, int arg3323, int arg3324, int arg3325, int arg3326, int arg3327, int arg3328, int arg3329, int arg3330, int arg3331, int arg3332, int arg3333, int arg3334, int arg3335, int arg3336, int arg3337, int arg3338, int arg3339, int arg3340, int arg3341, int arg3342, int arg3343, int arg3344, int arg3345, int arg3346, int arg3347, int arg3348, int arg3349, int arg3350, int arg3351, int arg3352, int arg3353, int arg3354, int arg3355, int arg3356, int arg3357, int arg3358, int arg3359, int arg3360, int arg3361, int arg3362, int arg3363, int arg3364, int arg3365, int arg3366, int arg3367, int arg3368, int arg3369, int arg3370, int arg3371, int arg3372, int arg3373, int arg3374, int arg3375, int arg3376, int arg3377, int arg3378, int arg3379, int arg3380, int arg3381, int arg3382, int arg3383, int arg3384, int arg3385, int arg3386, int arg3387, int arg3388, int arg3389, int arg3390, int arg3391, int arg3392, int arg3393, int arg3394, int arg3395, int arg3396, int arg3397, int arg3398, int arg3399, int arg3400, int arg3401, int arg3402, int arg3403, int arg3404, int arg3405, int arg3406, int arg3407, int arg3408, int arg3409, int arg3410, int arg3411, int arg3412, int arg3413, int arg3414, int arg3415, int arg3416, int arg3417, int arg3418, int arg3419, int arg3420, int arg3421, int arg3422, int arg3423, int arg3424, int arg3425, int arg3426, int arg3427, int arg3428, int arg3429, int arg3430, int arg3431, int arg3432, int arg3433, int arg3434, int arg3435, int arg3436, int arg3437, int arg3438, int arg3439, int arg3440, int arg3441, int arg3442, int arg3443, int arg3444, int arg3445, int arg3446, int arg3447, int arg3448, int arg3449, int arg3450, int arg3451, int arg3452, int arg3453, int arg3454, int arg3455, int arg3456, int arg3457, int arg3458, int arg3459, int arg3460, int arg3461, int arg3462, int arg3463, int arg3464, int arg3465, int arg3466, int arg3467, int arg3468, int arg3469, int arg3470, int arg3471, int arg3472, int arg3473, int arg3474, int arg3475, int arg3476, int arg3477, int arg3478, int arg3479, int arg3480, int arg3481, int arg3482, int arg3483, int arg3484, int arg3485, int arg3486, int arg3487, int arg3488, int arg3489, int arg3490, int arg3491, int arg3492, int arg3493, int arg3494, int arg3495, int arg3496, int arg3497, int arg3498, int arg3499, int arg3500, int arg3501, int arg3502, int arg3503, int arg3504, int arg3505, int arg3506, int arg3507, int arg3508, int arg3509, int arg3510, int arg3511, int arg3512, int arg3513, int arg3514, int arg3515, int arg3516, int arg3517, int arg3518, int arg3519, int arg3520, int arg3521, int arg3522, int arg3523, int arg3524, int arg3525, int arg3526, int arg3527, int arg3528, int arg3529, int arg3530, int arg3531, int arg3532, int arg3533, int arg3534, int arg3535, int arg3536, int arg3537, int arg3538, int arg3539, int arg3540, int arg3541, int arg3542, int arg3543, int arg3544, int arg3545, int arg3546, int arg3547, int arg3548, int arg3549, int arg3550, int arg3551, int arg3552, int arg3553, int arg3554, int arg3555, int arg3556, int arg3557, int arg3558, int arg3559, int arg3560, int arg3561, int arg3562, int arg3563, int arg3564, int arg3565, int arg3566, int arg3567, int arg3568, int arg3569, int arg3570, int arg3571, int arg3572, int arg3573, int arg3574, int arg3575, int arg3576, int arg3577, int arg3578, int arg3579, int arg3580, int arg3581, int arg3582, int arg3583, int arg3584, int arg3585, int arg3586, int arg3587, int arg3588, int arg3589, int arg3590, int arg3591, int arg3592, int arg3593, int arg3594, int arg3595, int arg3596, int arg3597, int arg3598, int arg3599, int arg3600, int arg3601, int arg3602, int arg3603, int arg3604, int arg3605, int arg3606, int arg3607, int arg3608, int arg3609, int arg3610, int arg3611, int arg3612, int arg3613, int arg3614, int arg3615, int arg3616, int arg3617, int arg3618, int arg3619, int arg3620, int arg3621, int arg3622, int arg3623, int arg3624, int arg3625, int arg3626, int arg3627, int arg3628, int arg3629, int arg3630, int arg3631, int arg3632, int arg3633, int arg3634, int arg3635, int arg3636, int arg3637, int arg3638, int arg3639, int arg3640, int arg3641, int arg3642, int arg3643, int arg3644, int arg3645, int arg3646, int arg3647, int arg3648, int arg3649, int arg3650, int arg3651, int arg3652, int arg3653, int arg3654, int arg3655, int arg3656, int arg3657, int arg3658, int arg3659, int arg3660, int arg3661, int arg3662, int arg3663, int arg3664, int arg3665, int arg3666, int arg3667, int arg3668, int arg3669, int arg3670, int arg3671, int arg3672, int arg3673, int arg3674, int arg3675, int arg3676, int arg3677, int arg3678, int arg3679, int arg3680, int arg3681, int arg3682, int arg3683, int arg3684, int arg3685, int arg3686, int arg3687, int arg3688, int arg3689, int arg3690, int arg3691, int arg3692, int arg3693, int arg3694, int arg3695, int arg3696, int arg3697, int arg3698, int arg3699, int arg3700, int arg3701, int arg3702, int arg3703, int arg3704, int arg3705, int arg3706, int arg3707, int arg3708, int arg3709, int arg3710, int arg3711, int arg3712, int arg3713, int arg3714, int arg3715, int arg3716, int arg3717, int arg3718, int arg3719, int arg3720, int arg3721, int arg3722, int arg3723, int arg3724, int arg3725, int arg3726, int arg3727, int arg3728, int arg3729, int arg3730, int arg3731, int arg3732, int arg3733, int arg3734, int arg3735, int arg3736, int arg3737, int arg3738, int arg3739, int arg3740, int arg3741, int arg3742, int arg3743, int arg3744, int arg3745, int arg3746, int arg3747, int arg3748, int arg3749, int arg3750, int arg3751, int arg3752, int arg3753, int arg3754, int arg3755, int arg3756, int arg3757, int arg3758, int arg3759, int arg3760, int arg3761, int arg3762, int arg3763, int arg3764, int arg3765, int arg3766, int arg3767, int arg3768, int arg3769, int arg3770, int arg3771, int arg3772, int arg3773, int arg3774, int arg3775, int arg3776, int arg3777, int arg3778, int arg3779, int arg3780, int arg3781, int arg3782, int arg3783, int arg3784, int arg3785, int arg3786, int arg3787, int arg3788, int arg3789, int arg3790, int arg3791, int arg3792, int arg3793, int arg3794, int arg3795, int arg3796, int arg3797, int arg3798, int arg3799, int arg3800, int arg3801, int arg3802, int arg3803, int arg3804, int arg3805, int arg3806, int arg3807, int arg3808, int arg3809, int arg3810, int arg3811, int arg3812, int arg3813, int arg3814, int arg3815, int arg3816, int arg3817, int arg3818, int arg3819, int arg3820, int arg3821, int arg3822, int arg3823, int arg3824, int arg3825, int arg3826, int arg3827, int arg3828, int arg3829, int arg3830, int arg3831, int arg3832, int arg3833, int arg3834, int arg3835, int arg3836, int arg3837, int arg3838, int arg3839, int arg3840, int arg3841, int arg3842, int arg3843, int arg3844, int arg3845, int arg3846, int arg3847, int arg3848, int arg3849, int arg3850, int arg3851, int arg3852, int arg3853, int arg3854, int arg3855, int arg3856, int arg3857, int arg3858, int arg3859, int arg3860, int arg3861, int arg3862, int arg3863, int arg3864, int arg3865, int arg3866, int arg3867, int arg3868, int arg3869, int arg3870, int arg3871, int arg3872, int arg3873, int arg3874, int arg3875, int arg3876, int arg3877, int arg3878, int arg3879, int arg3880, int arg3881, int arg3882, int arg3883, int arg3884, int arg3885, int arg3886, int arg3887, int arg3888, int arg3889, int arg3890, int arg3891, int arg3892, int arg3893, int arg3894, int arg3895, int arg3896, int arg3897, int arg3898, int arg3899, int arg3900, int arg3901, int arg3902, int arg3903, int arg3904, int arg3905, int arg3906, int arg3907, int arg3908, int arg3909, int arg3910, int arg3911, int arg3912, int arg3913, int arg3914, int arg3915, int arg3916, int arg3917, int arg3918, int arg3919, int arg3920, int arg3921, int arg3922, int arg3923, int arg3924, int arg3925, int arg3926, int arg3927, int arg3928, int arg3929, int arg3930, int arg3931, int arg3932, int arg3933, int arg3934, int arg3935, int arg3936, int arg3937, int arg3938, int arg3939, int arg3940, int arg3941, int arg3942, int arg3943, int arg3944, int arg3945, int arg3946, int arg3947, int arg3948, int arg3949, int arg3950, int arg3951, int arg3952, int arg3953, int arg3954, int arg3955, int arg3956, int arg3957, int arg3958, int arg3959, int arg3960, int arg3961, int arg3962, int arg3963, int arg3964, int arg3965, int arg3966, int arg3967, int arg3968, int arg3969, int arg3970, int arg3971, int arg3972, int arg3973, int arg3974, int arg3975, int arg3976, int arg3977, int arg3978, int arg3979, int arg3980, int arg3981, int arg3982, int arg3983, int arg3984, int arg3985, int arg3986, int arg3987, int arg3988, int arg3989, int arg3990, int arg3991, int arg3992, int arg3993, int arg3994, int arg3995, int arg3996, int arg3997, int arg3998, int arg3999, int arg4000, int arg4001, int arg4002, int arg4003, int arg4004, int arg4005, int arg4006, int arg4007, int arg4008, int arg4009, int arg4010, int arg4011, int arg4012, int arg4013, int arg4014, int arg4015, int arg4016, int arg4017, int arg4018, int arg4019, int arg4020, int arg4021, int arg4022, int arg4023, int arg4024, int arg4025, int arg4026, int arg4027, int arg4028, int arg4029, int arg4030, int arg4031, int arg4032, int arg4033, int arg4034, int arg4035, int arg4036, int arg4037, int arg4038, int arg4039, int arg4040, int arg4041, int arg4042, int arg4043, int arg4044, int arg4045, int arg4046, int arg4047, int arg4048, int arg4049, int arg4050, int arg4051, int arg4052, int arg4053, int arg4054, int arg4055, int arg4056, int arg4057, int arg4058, int arg4059, int arg4060, int arg4061, int arg4062, int arg4063, int arg4064, int arg4065, int arg4066, int arg4067, int arg4068, int arg4069, int arg4070, int arg4071, int arg4072, int arg4073, int arg4074, int arg4075, int arg4076, int arg4077, int arg4078, int arg4079, int arg4080, int arg4081, int arg4082, int arg4083, int arg4084, int arg4085, int arg4086, int arg4087, int arg4088, int arg4089, int arg4090, int arg4091, int arg4092, int arg4093, int arg4094, int arg4095, int arg4096, int arg4097, int arg4098, int arg4099, int arg4100, int arg4101, int arg4102, int arg4103, int arg4104, int arg4105, int arg4106, int arg4107, int arg4108, int arg4109, int arg4110, int arg4111, int arg4112, int arg4113, int arg4114, int arg4115, int arg4116, int arg4117, int arg4118, int arg4119, int arg4120, int arg4121, int arg4122, int arg4123, int arg4124, int arg4125, int arg4126, int arg4127, int arg4128, int arg4129, int arg4130, int arg4131, int arg4132, int arg4133, int arg4134, int arg4135, int arg4136, int arg4137, int arg4138, int arg4139, int arg4140, int arg4141, int arg4142, int arg4143, int arg4144, int arg4145, int arg4146, int arg4147, int arg4148, int arg4149, int arg4150, int arg4151, int arg4152, int arg4153, int arg4154, int arg4155, int arg4156, int arg4157, int arg4158, int arg4159, int arg4160, int arg4161, int arg4162, int arg4163, int arg4164, int arg4165, int arg4166, int arg4167, int arg4168, int arg4169, int arg4170, int arg4171, int arg4172, int arg4173, int arg4174, int arg4175, int arg4176, int arg4177, int arg4178, int arg4179, int arg4180, int arg4181, int arg4182, int arg4183, int arg4184, int arg4185, int arg4186, int arg4187, int arg4188, int arg4189, int arg4190, int arg4191, int arg4192, int arg4193, int arg4194, int arg4195, int arg4196, int arg4197, int arg4198, int arg4199, int arg4200, int arg4201, int arg4202, int arg4203, int arg4204, int arg4205, int arg4206, int arg4207, int arg4208, int arg4209, int arg4210, int arg4211, int arg4212, int arg4213, int arg4214, int arg4215, int arg4216, int arg4217, int arg4218, int arg4219, int arg4220, int arg4221, int arg4222, int arg4223, int arg4224, int arg4225, int arg4226, int arg4227, int arg4228, int arg4229, int arg4230, int arg4231, int arg4232, int arg4233, int arg4234, int arg4235, int arg4236, int arg4237, int arg4238, int arg4239, int arg4240, int arg4241, int arg4242, int arg4243, int arg4244, int arg4245, int arg4246, int arg4247, int arg4248, int arg4249, int arg4250, int arg4251, int arg4252, int arg4253, int arg4254, int arg4255, int arg4256, int arg4257, int arg4258, int arg4259, int arg4260, int arg4261, int arg4262, int arg4263, int arg4264, int arg4265, int arg4266, int arg4267, int arg4268, int arg4269, int arg4270, int arg4271, int arg4272, int arg4273, int arg4274, int arg4275, int arg4276, int arg4277, int arg4278, int arg4279, int arg4280, int arg4281, int arg4282, int arg4283, int arg4284, int arg4285, int arg4286, int arg4287, int arg4288, int arg4289, int arg4290, int arg4291, int arg4292, int arg4293, int arg4294, int arg4295, int arg4296, int arg4297, int arg4298, int arg4299, int arg4300, int arg4301, int arg4302, int arg4303, int arg4304, int arg4305, int arg4306, int arg4307, int arg4308, int arg4309, int arg4310, int arg4311, int arg4312, int arg4313, int arg4314, int arg4315, int arg4316, int arg4317, int arg4318, int arg4319, int arg4320, int arg4321, int arg4322, int arg4323, int arg4324, int arg4325, int arg4326, int arg4327, int arg4328, int arg4329, int arg4330, int arg4331, int arg4332, int arg4333, int arg4334, int arg4335, int arg4336, int arg4337, int arg4338, int arg4339, int arg4340, int arg4341, int arg4342, int arg4343, int arg4344, int arg4345, int arg4346, int arg4347, int arg4348, int arg4349, int arg4350, int arg4351, int arg4352, int arg4353, int arg4354, int arg4355, int arg4356, int arg4357, int arg4358, int arg4359, int arg4360, int arg4361, int arg4362, int arg4363, int arg4364, int arg4365, int arg4366, int arg4367, int arg4368, int arg4369, int arg4370, int arg4371, int arg4372, int arg4373, int arg4374, int arg4375, int arg4376, int arg4377, int arg4378, int arg4379, int arg4380, int arg4381, int arg4382, int arg4383, int arg4384, int arg4385, int arg4386, int arg4387, int arg4388, int arg4389, int arg4390, int arg4391, int arg4392, int arg4393, int arg4394, int arg4395, int arg4396, int arg4397, int arg4398, int arg4399, int arg4400, int arg4401, int arg4402, int arg4403, int arg4404, int arg4405, int arg4406, int arg4407, int arg4408, int arg4409, int arg4410, int arg4411, int arg4412, int arg4413, int arg4414, int arg4415, int arg4416, int arg4417, int arg4418, int arg4419, int arg4420, int arg4421, int arg4422, int arg4423, int arg4424, int arg4425, int arg4426, int arg4427, int arg4428, int arg4429, int arg4430, int arg4431, int arg4432, int arg4433, int arg4434, int arg4435, int arg4436, int arg4437, int arg4438, int arg4439, int arg4440, int arg4441, int arg4442, int arg4443, int arg4444, int arg4445, int arg4446, int arg4447, int arg4448, int arg4449, int arg4450, int arg4451, int arg4452, int arg4453, int arg4454, int arg4455, int arg4456, int arg4457, int arg4458, int arg4459, int arg4460, int arg4461, int arg4462, int arg4463, int arg4464, int arg4465, int arg4466, int arg4467, int arg4468, int arg4469, int arg4470, int arg4471, int arg4472, int arg4473, int arg4474, int arg4475, int arg4476, int arg4477, int arg4478, int arg4479, int arg4480, int arg4481, int arg4482, int arg4483, int arg4484, int arg4485, int arg4486, int arg4487, int arg4488, int arg4489, int arg4490, int arg4491, int arg4492, int arg4493, int arg4494, int arg4495, int arg4496, int arg4497, int arg4498, int arg4499, int arg4500, int arg4501, int arg4502, int arg4503, int arg4504, int arg4505, int arg4506, int arg4507, int arg4508, int arg4509, int arg4510, int arg4511, int arg4512, int arg4513, int arg4514, int arg4515, int arg4516, int arg4517, int arg4518, int arg4519, int arg4520, int arg4521, int arg4522, int arg4523, int arg4524, int arg4525, int arg4526, int arg4527, int arg4528, int arg4529, int arg4530, int arg4531, int arg4532, int arg4533, int arg4534, int arg4535, int arg4536, int arg4537, int arg4538, int arg4539, int arg4540, int arg4541, int arg4542, int arg4543, int arg4544, int arg4545, int arg4546, int arg4547, int arg4548, int arg4549, int arg4550, int arg4551, int arg4552, int arg4553, int arg4554, int arg4555, int arg4556, int arg4557, int arg4558, int arg4559, int arg4560, int arg4561, int arg4562, int arg4563, int arg4564, int arg4565, int arg4566, int arg4567, int arg4568, int arg4569, int arg4570, int arg4571, int arg4572, int arg4573, int arg4574, int arg4575, int arg4576, int arg4577, int arg4578, int arg4579, int arg4580, int arg4581, int arg4582, int arg4583, int arg4584, int arg4585, int arg4586, int arg4587, int arg4588, int arg4589, int arg4590, int arg4591, int arg4592, int arg4593, int arg4594, int arg4595, int arg4596, int arg4597, int arg4598, int arg4599, int arg4600, int arg4601, int arg4602, int arg4603, int arg4604, int arg4605, int arg4606, int arg4607, int arg4608, int arg4609, int arg4610, int arg4611, int arg4612, int arg4613, int arg4614, int arg4615, int arg4616, int arg4617, int arg4618, int arg4619, int arg4620, int arg4621, int arg4622, int arg4623, int arg4624, int arg4625, int arg4626, int arg4627, int arg4628, int arg4629, int arg4630, int arg4631, int arg4632, int arg4633, int arg4634, int arg4635, int arg4636, int arg4637, int arg4638, int arg4639, int arg4640, int arg4641, int arg4642, int arg4643, int arg4644, int arg4645, int arg4646, int arg4647, int arg4648, int arg4649, int arg4650, int arg4651, int arg4652, int arg4653, int arg4654, int arg4655, int arg4656, int arg4657, int arg4658, int arg4659, int arg4660, int arg4661, int arg4662, int arg4663, int arg4664, int arg4665, int arg4666, int arg4667, int arg4668, int arg4669, int arg4670, int arg4671, int arg4672, int arg4673, int arg4674, int arg4675, int arg4676, int arg4677, int arg4678, int arg4679, int arg4680, int arg4681, int arg4682, int arg4683, int arg4684, int arg4685, int arg4686, int arg4687, int arg4688, int arg4689, int arg4690, int arg4691, int arg4692, int arg4693, int arg4694, int arg4695, int arg4696, int arg4697, int arg4698, int arg4699, int arg4700, int arg4701, int arg4702, int arg4703, int arg4704, int arg4705, int arg4706, int arg4707, int arg4708, int arg4709, int arg4710, int arg4711, int arg4712, int arg4713, int arg4714, int arg4715, int arg4716, int arg4717, int arg4718, int arg4719, int arg4720, int arg4721, int arg4722, int arg4723, int arg4724, int arg4725, int arg4726, int arg4727, int arg4728, int arg4729, int arg4730, int arg4731, int arg4732, int arg4733, int arg4734, int arg4735, int arg4736, int arg4737, int arg4738, int arg4739, int arg4740, int arg4741, int arg4742, int arg4743, int arg4744, int arg4745, int arg4746, int arg4747, int arg4748, int arg4749, int arg4750, int arg4751, int arg4752, int arg4753, int arg4754, int arg4755, int arg4756, int arg4757, int arg4758, int arg4759, int arg4760, int arg4761, int arg4762, int arg4763, int arg4764, int arg4765, int arg4766, int arg4767, int arg4768, int arg4769, int arg4770, int arg4771, int arg4772, int arg4773, int arg4774, int arg4775, int arg4776, int arg4777, int arg4778, int arg4779, int arg4780, int arg4781, int arg4782, int arg4783, int arg4784, int arg4785, int arg4786, int arg4787, int arg4788, int arg4789, int arg4790, int arg4791, int arg4792, int arg4793, int arg4794, int arg4795, int arg4796, int arg4797, int arg4798, int arg4799, int arg4800, int arg4801, int arg4802, int arg4803, int arg4804, int arg4805, int arg4806, int arg4807, int arg4808, int arg4809, int arg4810, int arg4811, int arg4812, int arg4813, int arg4814, int arg4815, int arg4816, int arg4817, int arg4818, int arg4819, int arg4820, int arg4821, int arg4822, int arg4823, int arg4824, int arg4825, int arg4826, int arg4827, int arg4828, int arg4829, int arg4830, int arg4831, int arg4832, int arg4833, int arg4834, int arg4835, int arg4836, int arg4837, int arg4838, int arg4839, int arg4840, int arg4841, int arg4842, int arg4843, int arg4844, int arg4845, int arg4846, int arg4847, int arg4848, int arg4849, int arg4850, int arg4851, int arg4852, int arg4853, int arg4854, int arg4855, int arg4856, int arg4857, int arg4858, int arg4859, int arg4860, int arg4861, int arg4862, int arg4863, int arg4864, int arg4865, int arg4866, int arg4867, int arg4868, int arg4869, int arg4870, int arg4871, int arg4872, int arg4873, int arg4874, int arg4875, int arg4876, int arg4877, int arg4878, int arg4879, int arg4880, int arg4881, int arg4882, int arg4883, int arg4884, int arg4885, int arg4886, int arg4887, int arg4888, int arg4889, int arg4890, int arg4891, int arg4892, int arg4893, int arg4894, int arg4895, int arg4896, int arg4897, int arg4898, int arg4899, int arg4900, int arg4901, int arg4902, int arg4903, int arg4904, int arg4905, int arg4906, int arg4907, int arg4908, int arg4909, int arg4910, int arg4911, int arg4912, int arg4913, int arg4914, int arg4915, int arg4916, int arg4917, int arg4918, int arg4919, int arg4920, int arg4921, int arg4922, int arg4923, int arg4924, int arg4925, int arg4926, int arg4927, int arg4928, int arg4929, int arg4930, int arg4931, int arg4932, int arg4933, int arg4934, int arg4935, int arg4936, int arg4937, int arg4938, int arg4939, int arg4940, int arg4941, int arg4942, int arg4943, int arg4944, int arg4945, int arg4946, int arg4947, int arg4948, int arg4949, int arg4950, int arg4951, int arg4952, int arg4953, int arg4954, int arg4955, int arg4956, int arg4957, int arg4958, int arg4959, int arg4960, int arg4961, int arg4962, int arg4963, int arg4964, int arg4965, int arg4966, int arg4967, int arg4968, int arg4969, int arg4970, int arg4971, int arg4972, int arg4973, int arg4974, int arg4975, int arg4976, int arg4977, int arg4978, int arg4979, int arg4980, int arg4981, int arg4982, int arg4983, int arg4984, int arg4985, int arg4986, int arg4987, int arg4988, int arg4989, int arg4990, int arg4991, int arg4992, int arg4993, int arg4994, int arg4995, int arg4996, int arg4997, int arg4998, int arg4999, int arg5000, int arg5001, int arg5002, int arg5003, int arg5004, int arg5005, int arg5006, int arg5007, int arg5008, int arg5009, int arg5010, int arg5011, int arg5012, int arg5013, int arg5014, int arg5015, int arg5016, int arg5017, int arg5018, int arg5019, int arg5020, int arg5021, int arg5022, int arg5023, int arg5024, int arg5025, int arg5026, int arg5027, int arg5028, int arg5029, int arg5030, int arg5031, int arg5032, int arg5033, int arg5034, int arg5035, int arg5036, int arg5037, int arg5038, int arg5039)) +{ return arg0+arg1+arg2+arg3+arg4+arg5+arg6+arg7+arg8+arg9+arg10+arg11+arg12+arg13+arg14+arg15+arg16+arg17+arg18+arg19+arg20+arg21+arg22+arg23+arg24+arg25+arg26+arg27+arg28+arg29+arg30+arg31+arg32+arg33+arg34+arg35+arg36+arg37+arg38+arg39+arg40+arg41+arg42+arg43+arg44+arg45+arg46+arg47+arg48+arg49+arg50+arg51+arg52+arg53+arg54+arg55+arg56+arg57+arg58+arg59+arg60+arg61+arg62+arg63+arg64+arg65+arg66+arg67+arg68+arg69+arg70+arg71+arg72+arg73+arg74+arg75+arg76+arg77+arg78+arg79+arg80+arg81+arg82+arg83+arg84+arg85+arg86+arg87+arg88+arg89+arg90+arg91+arg92+arg93+arg94+arg95+arg96+arg97+arg98+arg99+arg100+arg101+arg102+arg103+arg104+arg105+arg106+arg107+arg108+arg109+arg110+arg111+arg112+arg113+arg114+arg115+arg116+arg117+arg118+arg119+arg120+arg121+arg122+arg123+arg124+arg125+arg126+arg127+arg128+arg129+arg130+arg131+arg132+arg133+arg134+arg135+arg136+arg137+arg138+arg139+arg140+arg141+arg142+arg143+arg144+arg145+arg146+arg147+arg148+arg149+arg150+arg151+arg152+arg153+arg154+arg155+arg156+arg157+arg158+arg159+arg160+arg161+arg162+arg163+arg164+arg165+arg166+arg167+arg168+arg169+arg170+arg171+arg172+arg173+arg174+arg175+arg176+arg177+arg178+arg179+arg180+arg181+arg182+arg183+arg184+arg185+arg186+arg187+arg188+arg189+arg190+arg191+arg192+arg193+arg194+arg195+arg196+arg197+arg198+arg199+arg200+arg201+arg202+arg203+arg204+arg205+arg206+arg207+arg208+arg209+arg210+arg211+arg212+arg213+arg214+arg215+arg216+arg217+arg218+arg219+arg220+arg221+arg222+arg223+arg224+arg225+arg226+arg227+arg228+arg229+arg230+arg231+arg232+arg233+arg234+arg235+arg236+arg237+arg238+arg239+arg240+arg241+arg242+arg243+arg244+arg245+arg246+arg247+arg248+arg249+arg250+arg251+arg252+arg253+arg254+arg255+arg256+arg257+arg258+arg259+arg260+arg261+arg262+arg263+arg264+arg265+arg266+arg267+arg268+arg269+arg270+arg271+arg272+arg273+arg274+arg275+arg276+arg277+arg278+arg279+arg280+arg281+arg282+arg283+arg284+arg285+arg286+arg287+arg288+arg289+arg290+arg291+arg292+arg293+arg294+arg295+arg296+arg297+arg298+arg299+arg300+arg301+arg302+arg303+arg304+arg305+arg306+arg307+arg308+arg309+arg310+arg311+arg312+arg313+arg314+arg315+arg316+arg317+arg318+arg319+arg320+arg321+arg322+arg323+arg324+arg325+arg326+arg327+arg328+arg329+arg330+arg331+arg332+arg333+arg334+arg335+arg336+arg337+arg338+arg339+arg340+arg341+arg342+arg343+arg344+arg345+arg346+arg347+arg348+arg349+arg350+arg351+arg352+arg353+arg354+arg355+arg356+arg357+arg358+arg359+arg360+arg361+arg362+arg363+arg364+arg365+arg366+arg367+arg368+arg369+arg370+arg371+arg372+arg373+arg374+arg375+arg376+arg377+arg378+arg379+arg380+arg381+arg382+arg383+arg384+arg385+arg386+arg387+arg388+arg389+arg390+arg391+arg392+arg393+arg394+arg395+arg396+arg397+arg398+arg399+arg400+arg401+arg402+arg403+arg404+arg405+arg406+arg407+arg408+arg409+arg410+arg411+arg412+arg413+arg414+arg415+arg416+arg417+arg418+arg419+arg420+arg421+arg422+arg423+arg424+arg425+arg426+arg427+arg428+arg429+arg430+arg431+arg432+arg433+arg434+arg435+arg436+arg437+arg438+arg439+arg440+arg441+arg442+arg443+arg444+arg445+arg446+arg447+arg448+arg449+arg450+arg451+arg452+arg453+arg454+arg455+arg456+arg457+arg458+arg459+arg460+arg461+arg462+arg463+arg464+arg465+arg466+arg467+arg468+arg469+arg470+arg471+arg472+arg473+arg474+arg475+arg476+arg477+arg478+arg479+arg480+arg481+arg482+arg483+arg484+arg485+arg486+arg487+arg488+arg489+arg490+arg491+arg492+arg493+arg494+arg495+arg496+arg497+arg498+arg499+arg500+arg501+arg502+arg503+arg504+arg505+arg506+arg507+arg508+arg509+arg510+arg511+arg512+arg513+arg514+arg515+arg516+arg517+arg518+arg519+arg520+arg521+arg522+arg523+arg524+arg525+arg526+arg527+arg528+arg529+arg530+arg531+arg532+arg533+arg534+arg535+arg536+arg537+arg538+arg539+arg540+arg541+arg542+arg543+arg544+arg545+arg546+arg547+arg548+arg549+arg550+arg551+arg552+arg553+arg554+arg555+arg556+arg557+arg558+arg559+arg560+arg561+arg562+arg563+arg564+arg565+arg566+arg567+arg568+arg569+arg570+arg571+arg572+arg573+arg574+arg575+arg576+arg577+arg578+arg579+arg580+arg581+arg582+arg583+arg584+arg585+arg586+arg587+arg588+arg589+arg590+arg591+arg592+arg593+arg594+arg595+arg596+arg597+arg598+arg599+arg600+arg601+arg602+arg603+arg604+arg605+arg606+arg607+arg608+arg609+arg610+arg611+arg612+arg613+arg614+arg615+arg616+arg617+arg618+arg619+arg620+arg621+arg622+arg623+arg624+arg625+arg626+arg627+arg628+arg629+arg630+arg631+arg632+arg633+arg634+arg635+arg636+arg637+arg638+arg639+arg640+arg641+arg642+arg643+arg644+arg645+arg646+arg647+arg648+arg649+arg650+arg651+arg652+arg653+arg654+arg655+arg656+arg657+arg658+arg659+arg660+arg661+arg662+arg663+arg664+arg665+arg666+arg667+arg668+arg669+arg670+arg671+arg672+arg673+arg674+arg675+arg676+arg677+arg678+arg679+arg680+arg681+arg682+arg683+arg684+arg685+arg686+arg687+arg688+arg689+arg690+arg691+arg692+arg693+arg694+arg695+arg696+arg697+arg698+arg699+arg700+arg701+arg702+arg703+arg704+arg705+arg706+arg707+arg708+arg709+arg710+arg711+arg712+arg713+arg714+arg715+arg716+arg717+arg718+arg719+arg720+arg721+arg722+arg723+arg724+arg725+arg726+arg727+arg728+arg729+arg730+arg731+arg732+arg733+arg734+arg735+arg736+arg737+arg738+arg739+arg740+arg741+arg742+arg743+arg744+arg745+arg746+arg747+arg748+arg749+arg750+arg751+arg752+arg753+arg754+arg755+arg756+arg757+arg758+arg759+arg760+arg761+arg762+arg763+arg764+arg765+arg766+arg767+arg768+arg769+arg770+arg771+arg772+arg773+arg774+arg775+arg776+arg777+arg778+arg779+arg780+arg781+arg782+arg783+arg784+arg785+arg786+arg787+arg788+arg789+arg790+arg791+arg792+arg793+arg794+arg795+arg796+arg797+arg798+arg799+arg800+arg801+arg802+arg803+arg804+arg805+arg806+arg807+arg808+arg809+arg810+arg811+arg812+arg813+arg814+arg815+arg816+arg817+arg818+arg819+arg820+arg821+arg822+arg823+arg824+arg825+arg826+arg827+arg828+arg829+arg830+arg831+arg832+arg833+arg834+arg835+arg836+arg837+arg838+arg839+arg840+arg841+arg842+arg843+arg844+arg845+arg846+arg847+arg848+arg849+arg850+arg851+arg852+arg853+arg854+arg855+arg856+arg857+arg858+arg859+arg860+arg861+arg862+arg863+arg864+arg865+arg866+arg867+arg868+arg869+arg870+arg871+arg872+arg873+arg874+arg875+arg876+arg877+arg878+arg879+arg880+arg881+arg882+arg883+arg884+arg885+arg886+arg887+arg888+arg889+arg890+arg891+arg892+arg893+arg894+arg895+arg896+arg897+arg898+arg899+arg900+arg901+arg902+arg903+arg904+arg905+arg906+arg907+arg908+arg909+arg910+arg911+arg912+arg913+arg914+arg915+arg916+arg917+arg918+arg919+arg920+arg921+arg922+arg923+arg924+arg925+arg926+arg927+arg928+arg929+arg930+arg931+arg932+arg933+arg934+arg935+arg936+arg937+arg938+arg939+arg940+arg941+arg942+arg943+arg944+arg945+arg946+arg947+arg948+arg949+arg950+arg951+arg952+arg953+arg954+arg955+arg956+arg957+arg958+arg959+arg960+arg961+arg962+arg963+arg964+arg965+arg966+arg967+arg968+arg969+arg970+arg971+arg972+arg973+arg974+arg975+arg976+arg977+arg978+arg979+arg980+arg981+arg982+arg983+arg984+arg985+arg986+arg987+arg988+arg989+arg990+arg991+arg992+arg993+arg994+arg995+arg996+arg997+arg998+arg999+arg1000+arg1001+arg1002+arg1003+arg1004+arg1005+arg1006+arg1007+arg1008+arg1009+arg1010+arg1011+arg1012+arg1013+arg1014+arg1015+arg1016+arg1017+arg1018+arg1019+arg1020+arg1021+arg1022+arg1023+arg1024+arg1025+arg1026+arg1027+arg1028+arg1029+arg1030+arg1031+arg1032+arg1033+arg1034+arg1035+arg1036+arg1037+arg1038+arg1039+arg1040+arg1041+arg1042+arg1043+arg1044+arg1045+arg1046+arg1047+arg1048+arg1049+arg1050+arg1051+arg1052+arg1053+arg1054+arg1055+arg1056+arg1057+arg1058+arg1059+arg1060+arg1061+arg1062+arg1063+arg1064+arg1065+arg1066+arg1067+arg1068+arg1069+arg1070+arg1071+arg1072+arg1073+arg1074+arg1075+arg1076+arg1077+arg1078+arg1079+arg1080+arg1081+arg1082+arg1083+arg1084+arg1085+arg1086+arg1087+arg1088+arg1089+arg1090+arg1091+arg1092+arg1093+arg1094+arg1095+arg1096+arg1097+arg1098+arg1099+arg1100+arg1101+arg1102+arg1103+arg1104+arg1105+arg1106+arg1107+arg1108+arg1109+arg1110+arg1111+arg1112+arg1113+arg1114+arg1115+arg1116+arg1117+arg1118+arg1119+arg1120+arg1121+arg1122+arg1123+arg1124+arg1125+arg1126+arg1127+arg1128+arg1129+arg1130+arg1131+arg1132+arg1133+arg1134+arg1135+arg1136+arg1137+arg1138+arg1139+arg1140+arg1141+arg1142+arg1143+arg1144+arg1145+arg1146+arg1147+arg1148+arg1149+arg1150+arg1151+arg1152+arg1153+arg1154+arg1155+arg1156+arg1157+arg1158+arg1159+arg1160+arg1161+arg1162+arg1163+arg1164+arg1165+arg1166+arg1167+arg1168+arg1169+arg1170+arg1171+arg1172+arg1173+arg1174+arg1175+arg1176+arg1177+arg1178+arg1179+arg1180+arg1181+arg1182+arg1183+arg1184+arg1185+arg1186+arg1187+arg1188+arg1189+arg1190+arg1191+arg1192+arg1193+arg1194+arg1195+arg1196+arg1197+arg1198+arg1199+arg1200+arg1201+arg1202+arg1203+arg1204+arg1205+arg1206+arg1207+arg1208+arg1209+arg1210+arg1211+arg1212+arg1213+arg1214+arg1215+arg1216+arg1217+arg1218+arg1219+arg1220+arg1221+arg1222+arg1223+arg1224+arg1225+arg1226+arg1227+arg1228+arg1229+arg1230+arg1231+arg1232+arg1233+arg1234+arg1235+arg1236+arg1237+arg1238+arg1239+arg1240+arg1241+arg1242+arg1243+arg1244+arg1245+arg1246+arg1247+arg1248+arg1249+arg1250+arg1251+arg1252+arg1253+arg1254+arg1255+arg1256+arg1257+arg1258+arg1259+arg1260+arg1261+arg1262+arg1263+arg1264+arg1265+arg1266+arg1267+arg1268+arg1269+arg1270+arg1271+arg1272+arg1273+arg1274+arg1275+arg1276+arg1277+arg1278+arg1279+arg1280+arg1281+arg1282+arg1283+arg1284+arg1285+arg1286+arg1287+arg1288+arg1289+arg1290+arg1291+arg1292+arg1293+arg1294+arg1295+arg1296+arg1297+arg1298+arg1299+arg1300+arg1301+arg1302+arg1303+arg1304+arg1305+arg1306+arg1307+arg1308+arg1309+arg1310+arg1311+arg1312+arg1313+arg1314+arg1315+arg1316+arg1317+arg1318+arg1319+arg1320+arg1321+arg1322+arg1323+arg1324+arg1325+arg1326+arg1327+arg1328+arg1329+arg1330+arg1331+arg1332+arg1333+arg1334+arg1335+arg1336+arg1337+arg1338+arg1339+arg1340+arg1341+arg1342+arg1343+arg1344+arg1345+arg1346+arg1347+arg1348+arg1349+arg1350+arg1351+arg1352+arg1353+arg1354+arg1355+arg1356+arg1357+arg1358+arg1359+arg1360+arg1361+arg1362+arg1363+arg1364+arg1365+arg1366+arg1367+arg1368+arg1369+arg1370+arg1371+arg1372+arg1373+arg1374+arg1375+arg1376+arg1377+arg1378+arg1379+arg1380+arg1381+arg1382+arg1383+arg1384+arg1385+arg1386+arg1387+arg1388+arg1389+arg1390+arg1391+arg1392+arg1393+arg1394+arg1395+arg1396+arg1397+arg1398+arg1399+arg1400+arg1401+arg1402+arg1403+arg1404+arg1405+arg1406+arg1407+arg1408+arg1409+arg1410+arg1411+arg1412+arg1413+arg1414+arg1415+arg1416+arg1417+arg1418+arg1419+arg1420+arg1421+arg1422+arg1423+arg1424+arg1425+arg1426+arg1427+arg1428+arg1429+arg1430+arg1431+arg1432+arg1433+arg1434+arg1435+arg1436+arg1437+arg1438+arg1439+arg1440+arg1441+arg1442+arg1443+arg1444+arg1445+arg1446+arg1447+arg1448+arg1449+arg1450+arg1451+arg1452+arg1453+arg1454+arg1455+arg1456+arg1457+arg1458+arg1459+arg1460+arg1461+arg1462+arg1463+arg1464+arg1465+arg1466+arg1467+arg1468+arg1469+arg1470+arg1471+arg1472+arg1473+arg1474+arg1475+arg1476+arg1477+arg1478+arg1479+arg1480+arg1481+arg1482+arg1483+arg1484+arg1485+arg1486+arg1487+arg1488+arg1489+arg1490+arg1491+arg1492+arg1493+arg1494+arg1495+arg1496+arg1497+arg1498+arg1499+arg1500+arg1501+arg1502+arg1503+arg1504+arg1505+arg1506+arg1507+arg1508+arg1509+arg1510+arg1511+arg1512+arg1513+arg1514+arg1515+arg1516+arg1517+arg1518+arg1519+arg1520+arg1521+arg1522+arg1523+arg1524+arg1525+arg1526+arg1527+arg1528+arg1529+arg1530+arg1531+arg1532+arg1533+arg1534+arg1535+arg1536+arg1537+arg1538+arg1539+arg1540+arg1541+arg1542+arg1543+arg1544+arg1545+arg1546+arg1547+arg1548+arg1549+arg1550+arg1551+arg1552+arg1553+arg1554+arg1555+arg1556+arg1557+arg1558+arg1559+arg1560+arg1561+arg1562+arg1563+arg1564+arg1565+arg1566+arg1567+arg1568+arg1569+arg1570+arg1571+arg1572+arg1573+arg1574+arg1575+arg1576+arg1577+arg1578+arg1579+arg1580+arg1581+arg1582+arg1583+arg1584+arg1585+arg1586+arg1587+arg1588+arg1589+arg1590+arg1591+arg1592+arg1593+arg1594+arg1595+arg1596+arg1597+arg1598+arg1599+arg1600+arg1601+arg1602+arg1603+arg1604+arg1605+arg1606+arg1607+arg1608+arg1609+arg1610+arg1611+arg1612+arg1613+arg1614+arg1615+arg1616+arg1617+arg1618+arg1619+arg1620+arg1621+arg1622+arg1623+arg1624+arg1625+arg1626+arg1627+arg1628+arg1629+arg1630+arg1631+arg1632+arg1633+arg1634+arg1635+arg1636+arg1637+arg1638+arg1639+arg1640+arg1641+arg1642+arg1643+arg1644+arg1645+arg1646+arg1647+arg1648+arg1649+arg1650+arg1651+arg1652+arg1653+arg1654+arg1655+arg1656+arg1657+arg1658+arg1659+arg1660+arg1661+arg1662+arg1663+arg1664+arg1665+arg1666+arg1667+arg1668+arg1669+arg1670+arg1671+arg1672+arg1673+arg1674+arg1675+arg1676+arg1677+arg1678+arg1679+arg1680+arg1681+arg1682+arg1683+arg1684+arg1685+arg1686+arg1687+arg1688+arg1689+arg1690+arg1691+arg1692+arg1693+arg1694+arg1695+arg1696+arg1697+arg1698+arg1699+arg1700+arg1701+arg1702+arg1703+arg1704+arg1705+arg1706+arg1707+arg1708+arg1709+arg1710+arg1711+arg1712+arg1713+arg1714+arg1715+arg1716+arg1717+arg1718+arg1719+arg1720+arg1721+arg1722+arg1723+arg1724+arg1725+arg1726+arg1727+arg1728+arg1729+arg1730+arg1731+arg1732+arg1733+arg1734+arg1735+arg1736+arg1737+arg1738+arg1739+arg1740+arg1741+arg1742+arg1743+arg1744+arg1745+arg1746+arg1747+arg1748+arg1749+arg1750+arg1751+arg1752+arg1753+arg1754+arg1755+arg1756+arg1757+arg1758+arg1759+arg1760+arg1761+arg1762+arg1763+arg1764+arg1765+arg1766+arg1767+arg1768+arg1769+arg1770+arg1771+arg1772+arg1773+arg1774+arg1775+arg1776+arg1777+arg1778+arg1779+arg1780+arg1781+arg1782+arg1783+arg1784+arg1785+arg1786+arg1787+arg1788+arg1789+arg1790+arg1791+arg1792+arg1793+arg1794+arg1795+arg1796+arg1797+arg1798+arg1799+arg1800+arg1801+arg1802+arg1803+arg1804+arg1805+arg1806+arg1807+arg1808+arg1809+arg1810+arg1811+arg1812+arg1813+arg1814+arg1815+arg1816+arg1817+arg1818+arg1819+arg1820+arg1821+arg1822+arg1823+arg1824+arg1825+arg1826+arg1827+arg1828+arg1829+arg1830+arg1831+arg1832+arg1833+arg1834+arg1835+arg1836+arg1837+arg1838+arg1839+arg1840+arg1841+arg1842+arg1843+arg1844+arg1845+arg1846+arg1847+arg1848+arg1849+arg1850+arg1851+arg1852+arg1853+arg1854+arg1855+arg1856+arg1857+arg1858+arg1859+arg1860+arg1861+arg1862+arg1863+arg1864+arg1865+arg1866+arg1867+arg1868+arg1869+arg1870+arg1871+arg1872+arg1873+arg1874+arg1875+arg1876+arg1877+arg1878+arg1879+arg1880+arg1881+arg1882+arg1883+arg1884+arg1885+arg1886+arg1887+arg1888+arg1889+arg1890+arg1891+arg1892+arg1893+arg1894+arg1895+arg1896+arg1897+arg1898+arg1899+arg1900+arg1901+arg1902+arg1903+arg1904+arg1905+arg1906+arg1907+arg1908+arg1909+arg1910+arg1911+arg1912+arg1913+arg1914+arg1915+arg1916+arg1917+arg1918+arg1919+arg1920+arg1921+arg1922+arg1923+arg1924+arg1925+arg1926+arg1927+arg1928+arg1929+arg1930+arg1931+arg1932+arg1933+arg1934+arg1935+arg1936+arg1937+arg1938+arg1939+arg1940+arg1941+arg1942+arg1943+arg1944+arg1945+arg1946+arg1947+arg1948+arg1949+arg1950+arg1951+arg1952+arg1953+arg1954+arg1955+arg1956+arg1957+arg1958+arg1959+arg1960+arg1961+arg1962+arg1963+arg1964+arg1965+arg1966+arg1967+arg1968+arg1969+arg1970+arg1971+arg1972+arg1973+arg1974+arg1975+arg1976+arg1977+arg1978+arg1979+arg1980+arg1981+arg1982+arg1983+arg1984+arg1985+arg1986+arg1987+arg1988+arg1989+arg1990+arg1991+arg1992+arg1993+arg1994+arg1995+arg1996+arg1997+arg1998+arg1999+arg2000+arg2001+arg2002+arg2003+arg2004+arg2005+arg2006+arg2007+arg2008+arg2009+arg2010+arg2011+arg2012+arg2013+arg2014+arg2015+arg2016+arg2017+arg2018+arg2019+arg2020+arg2021+arg2022+arg2023+arg2024+arg2025+arg2026+arg2027+arg2028+arg2029+arg2030+arg2031+arg2032+arg2033+arg2034+arg2035+arg2036+arg2037+arg2038+arg2039+arg2040+arg2041+arg2042+arg2043+arg2044+arg2045+arg2046+arg2047+arg2048+arg2049+arg2050+arg2051+arg2052+arg2053+arg2054+arg2055+arg2056+arg2057+arg2058+arg2059+arg2060+arg2061+arg2062+arg2063+arg2064+arg2065+arg2066+arg2067+arg2068+arg2069+arg2070+arg2071+arg2072+arg2073+arg2074+arg2075+arg2076+arg2077+arg2078+arg2079+arg2080+arg2081+arg2082+arg2083+arg2084+arg2085+arg2086+arg2087+arg2088+arg2089+arg2090+arg2091+arg2092+arg2093+arg2094+arg2095+arg2096+arg2097+arg2098+arg2099+arg2100+arg2101+arg2102+arg2103+arg2104+arg2105+arg2106+arg2107+arg2108+arg2109+arg2110+arg2111+arg2112+arg2113+arg2114+arg2115+arg2116+arg2117+arg2118+arg2119+arg2120+arg2121+arg2122+arg2123+arg2124+arg2125+arg2126+arg2127+arg2128+arg2129+arg2130+arg2131+arg2132+arg2133+arg2134+arg2135+arg2136+arg2137+arg2138+arg2139+arg2140+arg2141+arg2142+arg2143+arg2144+arg2145+arg2146+arg2147+arg2148+arg2149+arg2150+arg2151+arg2152+arg2153+arg2154+arg2155+arg2156+arg2157+arg2158+arg2159+arg2160+arg2161+arg2162+arg2163+arg2164+arg2165+arg2166+arg2167+arg2168+arg2169+arg2170+arg2171+arg2172+arg2173+arg2174+arg2175+arg2176+arg2177+arg2178+arg2179+arg2180+arg2181+arg2182+arg2183+arg2184+arg2185+arg2186+arg2187+arg2188+arg2189+arg2190+arg2191+arg2192+arg2193+arg2194+arg2195+arg2196+arg2197+arg2198+arg2199+arg2200+arg2201+arg2202+arg2203+arg2204+arg2205+arg2206+arg2207+arg2208+arg2209+arg2210+arg2211+arg2212+arg2213+arg2214+arg2215+arg2216+arg2217+arg2218+arg2219+arg2220+arg2221+arg2222+arg2223+arg2224+arg2225+arg2226+arg2227+arg2228+arg2229+arg2230+arg2231+arg2232+arg2233+arg2234+arg2235+arg2236+arg2237+arg2238+arg2239+arg2240+arg2241+arg2242+arg2243+arg2244+arg2245+arg2246+arg2247+arg2248+arg2249+arg2250+arg2251+arg2252+arg2253+arg2254+arg2255+arg2256+arg2257+arg2258+arg2259+arg2260+arg2261+arg2262+arg2263+arg2264+arg2265+arg2266+arg2267+arg2268+arg2269+arg2270+arg2271+arg2272+arg2273+arg2274+arg2275+arg2276+arg2277+arg2278+arg2279+arg2280+arg2281+arg2282+arg2283+arg2284+arg2285+arg2286+arg2287+arg2288+arg2289+arg2290+arg2291+arg2292+arg2293+arg2294+arg2295+arg2296+arg2297+arg2298+arg2299+arg2300+arg2301+arg2302+arg2303+arg2304+arg2305+arg2306+arg2307+arg2308+arg2309+arg2310+arg2311+arg2312+arg2313+arg2314+arg2315+arg2316+arg2317+arg2318+arg2319+arg2320+arg2321+arg2322+arg2323+arg2324+arg2325+arg2326+arg2327+arg2328+arg2329+arg2330+arg2331+arg2332+arg2333+arg2334+arg2335+arg2336+arg2337+arg2338+arg2339+arg2340+arg2341+arg2342+arg2343+arg2344+arg2345+arg2346+arg2347+arg2348+arg2349+arg2350+arg2351+arg2352+arg2353+arg2354+arg2355+arg2356+arg2357+arg2358+arg2359+arg2360+arg2361+arg2362+arg2363+arg2364+arg2365+arg2366+arg2367+arg2368+arg2369+arg2370+arg2371+arg2372+arg2373+arg2374+arg2375+arg2376+arg2377+arg2378+arg2379+arg2380+arg2381+arg2382+arg2383+arg2384+arg2385+arg2386+arg2387+arg2388+arg2389+arg2390+arg2391+arg2392+arg2393+arg2394+arg2395+arg2396+arg2397+arg2398+arg2399+arg2400+arg2401+arg2402+arg2403+arg2404+arg2405+arg2406+arg2407+arg2408+arg2409+arg2410+arg2411+arg2412+arg2413+arg2414+arg2415+arg2416+arg2417+arg2418+arg2419+arg2420+arg2421+arg2422+arg2423+arg2424+arg2425+arg2426+arg2427+arg2428+arg2429+arg2430+arg2431+arg2432+arg2433+arg2434+arg2435+arg2436+arg2437+arg2438+arg2439+arg2440+arg2441+arg2442+arg2443+arg2444+arg2445+arg2446+arg2447+arg2448+arg2449+arg2450+arg2451+arg2452+arg2453+arg2454+arg2455+arg2456+arg2457+arg2458+arg2459+arg2460+arg2461+arg2462+arg2463+arg2464+arg2465+arg2466+arg2467+arg2468+arg2469+arg2470+arg2471+arg2472+arg2473+arg2474+arg2475+arg2476+arg2477+arg2478+arg2479+arg2480+arg2481+arg2482+arg2483+arg2484+arg2485+arg2486+arg2487+arg2488+arg2489+arg2490+arg2491+arg2492+arg2493+arg2494+arg2495+arg2496+arg2497+arg2498+arg2499+arg2500+arg2501+arg2502+arg2503+arg2504+arg2505+arg2506+arg2507+arg2508+arg2509+arg2510+arg2511+arg2512+arg2513+arg2514+arg2515+arg2516+arg2517+arg2518+arg2519+arg2520+arg2521+arg2522+arg2523+arg2524+arg2525+arg2526+arg2527+arg2528+arg2529+arg2530+arg2531+arg2532+arg2533+arg2534+arg2535+arg2536+arg2537+arg2538+arg2539+arg2540+arg2541+arg2542+arg2543+arg2544+arg2545+arg2546+arg2547+arg2548+arg2549+arg2550+arg2551+arg2552+arg2553+arg2554+arg2555+arg2556+arg2557+arg2558+arg2559+arg2560+arg2561+arg2562+arg2563+arg2564+arg2565+arg2566+arg2567+arg2568+arg2569+arg2570+arg2571+arg2572+arg2573+arg2574+arg2575+arg2576+arg2577+arg2578+arg2579+arg2580+arg2581+arg2582+arg2583+arg2584+arg2585+arg2586+arg2587+arg2588+arg2589+arg2590+arg2591+arg2592+arg2593+arg2594+arg2595+arg2596+arg2597+arg2598+arg2599+arg2600+arg2601+arg2602+arg2603+arg2604+arg2605+arg2606+arg2607+arg2608+arg2609+arg2610+arg2611+arg2612+arg2613+arg2614+arg2615+arg2616+arg2617+arg2618+arg2619+arg2620+arg2621+arg2622+arg2623+arg2624+arg2625+arg2626+arg2627+arg2628+arg2629+arg2630+arg2631+arg2632+arg2633+arg2634+arg2635+arg2636+arg2637+arg2638+arg2639+arg2640+arg2641+arg2642+arg2643+arg2644+arg2645+arg2646+arg2647+arg2648+arg2649+arg2650+arg2651+arg2652+arg2653+arg2654+arg2655+arg2656+arg2657+arg2658+arg2659+arg2660+arg2661+arg2662+arg2663+arg2664+arg2665+arg2666+arg2667+arg2668+arg2669+arg2670+arg2671+arg2672+arg2673+arg2674+arg2675+arg2676+arg2677+arg2678+arg2679+arg2680+arg2681+arg2682+arg2683+arg2684+arg2685+arg2686+arg2687+arg2688+arg2689+arg2690+arg2691+arg2692+arg2693+arg2694+arg2695+arg2696+arg2697+arg2698+arg2699+arg2700+arg2701+arg2702+arg2703+arg2704+arg2705+arg2706+arg2707+arg2708+arg2709+arg2710+arg2711+arg2712+arg2713+arg2714+arg2715+arg2716+arg2717+arg2718+arg2719+arg2720+arg2721+arg2722+arg2723+arg2724+arg2725+arg2726+arg2727+arg2728+arg2729+arg2730+arg2731+arg2732+arg2733+arg2734+arg2735+arg2736+arg2737+arg2738+arg2739+arg2740+arg2741+arg2742+arg2743+arg2744+arg2745+arg2746+arg2747+arg2748+arg2749+arg2750+arg2751+arg2752+arg2753+arg2754+arg2755+arg2756+arg2757+arg2758+arg2759+arg2760+arg2761+arg2762+arg2763+arg2764+arg2765+arg2766+arg2767+arg2768+arg2769+arg2770+arg2771+arg2772+arg2773+arg2774+arg2775+arg2776+arg2777+arg2778+arg2779+arg2780+arg2781+arg2782+arg2783+arg2784+arg2785+arg2786+arg2787+arg2788+arg2789+arg2790+arg2791+arg2792+arg2793+arg2794+arg2795+arg2796+arg2797+arg2798+arg2799+arg2800+arg2801+arg2802+arg2803+arg2804+arg2805+arg2806+arg2807+arg2808+arg2809+arg2810+arg2811+arg2812+arg2813+arg2814+arg2815+arg2816+arg2817+arg2818+arg2819+arg2820+arg2821+arg2822+arg2823+arg2824+arg2825+arg2826+arg2827+arg2828+arg2829+arg2830+arg2831+arg2832+arg2833+arg2834+arg2835+arg2836+arg2837+arg2838+arg2839+arg2840+arg2841+arg2842+arg2843+arg2844+arg2845+arg2846+arg2847+arg2848+arg2849+arg2850+arg2851+arg2852+arg2853+arg2854+arg2855+arg2856+arg2857+arg2858+arg2859+arg2860+arg2861+arg2862+arg2863+arg2864+arg2865+arg2866+arg2867+arg2868+arg2869+arg2870+arg2871+arg2872+arg2873+arg2874+arg2875+arg2876+arg2877+arg2878+arg2879+arg2880+arg2881+arg2882+arg2883+arg2884+arg2885+arg2886+arg2887+arg2888+arg2889+arg2890+arg2891+arg2892+arg2893+arg2894+arg2895+arg2896+arg2897+arg2898+arg2899+arg2900+arg2901+arg2902+arg2903+arg2904+arg2905+arg2906+arg2907+arg2908+arg2909+arg2910+arg2911+arg2912+arg2913+arg2914+arg2915+arg2916+arg2917+arg2918+arg2919+arg2920+arg2921+arg2922+arg2923+arg2924+arg2925+arg2926+arg2927+arg2928+arg2929+arg2930+arg2931+arg2932+arg2933+arg2934+arg2935+arg2936+arg2937+arg2938+arg2939+arg2940+arg2941+arg2942+arg2943+arg2944+arg2945+arg2946+arg2947+arg2948+arg2949+arg2950+arg2951+arg2952+arg2953+arg2954+arg2955+arg2956+arg2957+arg2958+arg2959+arg2960+arg2961+arg2962+arg2963+arg2964+arg2965+arg2966+arg2967+arg2968+arg2969+arg2970+arg2971+arg2972+arg2973+arg2974+arg2975+arg2976+arg2977+arg2978+arg2979+arg2980+arg2981+arg2982+arg2983+arg2984+arg2985+arg2986+arg2987+arg2988+arg2989+arg2990+arg2991+arg2992+arg2993+arg2994+arg2995+arg2996+arg2997+arg2998+arg2999+arg3000+arg3001+arg3002+arg3003+arg3004+arg3005+arg3006+arg3007+arg3008+arg3009+arg3010+arg3011+arg3012+arg3013+arg3014+arg3015+arg3016+arg3017+arg3018+arg3019+arg3020+arg3021+arg3022+arg3023+arg3024+arg3025+arg3026+arg3027+arg3028+arg3029+arg3030+arg3031+arg3032+arg3033+arg3034+arg3035+arg3036+arg3037+arg3038+arg3039+arg3040+arg3041+arg3042+arg3043+arg3044+arg3045+arg3046+arg3047+arg3048+arg3049+arg3050+arg3051+arg3052+arg3053+arg3054+arg3055+arg3056+arg3057+arg3058+arg3059+arg3060+arg3061+arg3062+arg3063+arg3064+arg3065+arg3066+arg3067+arg3068+arg3069+arg3070+arg3071+arg3072+arg3073+arg3074+arg3075+arg3076+arg3077+arg3078+arg3079+arg3080+arg3081+arg3082+arg3083+arg3084+arg3085+arg3086+arg3087+arg3088+arg3089+arg3090+arg3091+arg3092+arg3093+arg3094+arg3095+arg3096+arg3097+arg3098+arg3099+arg3100+arg3101+arg3102+arg3103+arg3104+arg3105+arg3106+arg3107+arg3108+arg3109+arg3110+arg3111+arg3112+arg3113+arg3114+arg3115+arg3116+arg3117+arg3118+arg3119+arg3120+arg3121+arg3122+arg3123+arg3124+arg3125+arg3126+arg3127+arg3128+arg3129+arg3130+arg3131+arg3132+arg3133+arg3134+arg3135+arg3136+arg3137+arg3138+arg3139+arg3140+arg3141+arg3142+arg3143+arg3144+arg3145+arg3146+arg3147+arg3148+arg3149+arg3150+arg3151+arg3152+arg3153+arg3154+arg3155+arg3156+arg3157+arg3158+arg3159+arg3160+arg3161+arg3162+arg3163+arg3164+arg3165+arg3166+arg3167+arg3168+arg3169+arg3170+arg3171+arg3172+arg3173+arg3174+arg3175+arg3176+arg3177+arg3178+arg3179+arg3180+arg3181+arg3182+arg3183+arg3184+arg3185+arg3186+arg3187+arg3188+arg3189+arg3190+arg3191+arg3192+arg3193+arg3194+arg3195+arg3196+arg3197+arg3198+arg3199+arg3200+arg3201+arg3202+arg3203+arg3204+arg3205+arg3206+arg3207+arg3208+arg3209+arg3210+arg3211+arg3212+arg3213+arg3214+arg3215+arg3216+arg3217+arg3218+arg3219+arg3220+arg3221+arg3222+arg3223+arg3224+arg3225+arg3226+arg3227+arg3228+arg3229+arg3230+arg3231+arg3232+arg3233+arg3234+arg3235+arg3236+arg3237+arg3238+arg3239+arg3240+arg3241+arg3242+arg3243+arg3244+arg3245+arg3246+arg3247+arg3248+arg3249+arg3250+arg3251+arg3252+arg3253+arg3254+arg3255+arg3256+arg3257+arg3258+arg3259+arg3260+arg3261+arg3262+arg3263+arg3264+arg3265+arg3266+arg3267+arg3268+arg3269+arg3270+arg3271+arg3272+arg3273+arg3274+arg3275+arg3276+arg3277+arg3278+arg3279+arg3280+arg3281+arg3282+arg3283+arg3284+arg3285+arg3286+arg3287+arg3288+arg3289+arg3290+arg3291+arg3292+arg3293+arg3294+arg3295+arg3296+arg3297+arg3298+arg3299+arg3300+arg3301+arg3302+arg3303+arg3304+arg3305+arg3306+arg3307+arg3308+arg3309+arg3310+arg3311+arg3312+arg3313+arg3314+arg3315+arg3316+arg3317+arg3318+arg3319+arg3320+arg3321+arg3322+arg3323+arg3324+arg3325+arg3326+arg3327+arg3328+arg3329+arg3330+arg3331+arg3332+arg3333+arg3334+arg3335+arg3336+arg3337+arg3338+arg3339+arg3340+arg3341+arg3342+arg3343+arg3344+arg3345+arg3346+arg3347+arg3348+arg3349+arg3350+arg3351+arg3352+arg3353+arg3354+arg3355+arg3356+arg3357+arg3358+arg3359+arg3360+arg3361+arg3362+arg3363+arg3364+arg3365+arg3366+arg3367+arg3368+arg3369+arg3370+arg3371+arg3372+arg3373+arg3374+arg3375+arg3376+arg3377+arg3378+arg3379+arg3380+arg3381+arg3382+arg3383+arg3384+arg3385+arg3386+arg3387+arg3388+arg3389+arg3390+arg3391+arg3392+arg3393+arg3394+arg3395+arg3396+arg3397+arg3398+arg3399+arg3400+arg3401+arg3402+arg3403+arg3404+arg3405+arg3406+arg3407+arg3408+arg3409+arg3410+arg3411+arg3412+arg3413+arg3414+arg3415+arg3416+arg3417+arg3418+arg3419+arg3420+arg3421+arg3422+arg3423+arg3424+arg3425+arg3426+arg3427+arg3428+arg3429+arg3430+arg3431+arg3432+arg3433+arg3434+arg3435+arg3436+arg3437+arg3438+arg3439+arg3440+arg3441+arg3442+arg3443+arg3444+arg3445+arg3446+arg3447+arg3448+arg3449+arg3450+arg3451+arg3452+arg3453+arg3454+arg3455+arg3456+arg3457+arg3458+arg3459+arg3460+arg3461+arg3462+arg3463+arg3464+arg3465+arg3466+arg3467+arg3468+arg3469+arg3470+arg3471+arg3472+arg3473+arg3474+arg3475+arg3476+arg3477+arg3478+arg3479+arg3480+arg3481+arg3482+arg3483+arg3484+arg3485+arg3486+arg3487+arg3488+arg3489+arg3490+arg3491+arg3492+arg3493+arg3494+arg3495+arg3496+arg3497+arg3498+arg3499+arg3500+arg3501+arg3502+arg3503+arg3504+arg3505+arg3506+arg3507+arg3508+arg3509+arg3510+arg3511+arg3512+arg3513+arg3514+arg3515+arg3516+arg3517+arg3518+arg3519+arg3520+arg3521+arg3522+arg3523+arg3524+arg3525+arg3526+arg3527+arg3528+arg3529+arg3530+arg3531+arg3532+arg3533+arg3534+arg3535+arg3536+arg3537+arg3538+arg3539+arg3540+arg3541+arg3542+arg3543+arg3544+arg3545+arg3546+arg3547+arg3548+arg3549+arg3550+arg3551+arg3552+arg3553+arg3554+arg3555+arg3556+arg3557+arg3558+arg3559+arg3560+arg3561+arg3562+arg3563+arg3564+arg3565+arg3566+arg3567+arg3568+arg3569+arg3570+arg3571+arg3572+arg3573+arg3574+arg3575+arg3576+arg3577+arg3578+arg3579+arg3580+arg3581+arg3582+arg3583+arg3584+arg3585+arg3586+arg3587+arg3588+arg3589+arg3590+arg3591+arg3592+arg3593+arg3594+arg3595+arg3596+arg3597+arg3598+arg3599+arg3600+arg3601+arg3602+arg3603+arg3604+arg3605+arg3606+arg3607+arg3608+arg3609+arg3610+arg3611+arg3612+arg3613+arg3614+arg3615+arg3616+arg3617+arg3618+arg3619+arg3620+arg3621+arg3622+arg3623+arg3624+arg3625+arg3626+arg3627+arg3628+arg3629+arg3630+arg3631+arg3632+arg3633+arg3634+arg3635+arg3636+arg3637+arg3638+arg3639+arg3640+arg3641+arg3642+arg3643+arg3644+arg3645+arg3646+arg3647+arg3648+arg3649+arg3650+arg3651+arg3652+arg3653+arg3654+arg3655+arg3656+arg3657+arg3658+arg3659+arg3660+arg3661+arg3662+arg3663+arg3664+arg3665+arg3666+arg3667+arg3668+arg3669+arg3670+arg3671+arg3672+arg3673+arg3674+arg3675+arg3676+arg3677+arg3678+arg3679+arg3680+arg3681+arg3682+arg3683+arg3684+arg3685+arg3686+arg3687+arg3688+arg3689+arg3690+arg3691+arg3692+arg3693+arg3694+arg3695+arg3696+arg3697+arg3698+arg3699+arg3700+arg3701+arg3702+arg3703+arg3704+arg3705+arg3706+arg3707+arg3708+arg3709+arg3710+arg3711+arg3712+arg3713+arg3714+arg3715+arg3716+arg3717+arg3718+arg3719+arg3720+arg3721+arg3722+arg3723+arg3724+arg3725+arg3726+arg3727+arg3728+arg3729+arg3730+arg3731+arg3732+arg3733+arg3734+arg3735+arg3736+arg3737+arg3738+arg3739+arg3740+arg3741+arg3742+arg3743+arg3744+arg3745+arg3746+arg3747+arg3748+arg3749+arg3750+arg3751+arg3752+arg3753+arg3754+arg3755+arg3756+arg3757+arg3758+arg3759+arg3760+arg3761+arg3762+arg3763+arg3764+arg3765+arg3766+arg3767+arg3768+arg3769+arg3770+arg3771+arg3772+arg3773+arg3774+arg3775+arg3776+arg3777+arg3778+arg3779+arg3780+arg3781+arg3782+arg3783+arg3784+arg3785+arg3786+arg3787+arg3788+arg3789+arg3790+arg3791+arg3792+arg3793+arg3794+arg3795+arg3796+arg3797+arg3798+arg3799+arg3800+arg3801+arg3802+arg3803+arg3804+arg3805+arg3806+arg3807+arg3808+arg3809+arg3810+arg3811+arg3812+arg3813+arg3814+arg3815+arg3816+arg3817+arg3818+arg3819+arg3820+arg3821+arg3822+arg3823+arg3824+arg3825+arg3826+arg3827+arg3828+arg3829+arg3830+arg3831+arg3832+arg3833+arg3834+arg3835+arg3836+arg3837+arg3838+arg3839+arg3840+arg3841+arg3842+arg3843+arg3844+arg3845+arg3846+arg3847+arg3848+arg3849+arg3850+arg3851+arg3852+arg3853+arg3854+arg3855+arg3856+arg3857+arg3858+arg3859+arg3860+arg3861+arg3862+arg3863+arg3864+arg3865+arg3866+arg3867+arg3868+arg3869+arg3870+arg3871+arg3872+arg3873+arg3874+arg3875+arg3876+arg3877+arg3878+arg3879+arg3880+arg3881+arg3882+arg3883+arg3884+arg3885+arg3886+arg3887+arg3888+arg3889+arg3890+arg3891+arg3892+arg3893+arg3894+arg3895+arg3896+arg3897+arg3898+arg3899+arg3900+arg3901+arg3902+arg3903+arg3904+arg3905+arg3906+arg3907+arg3908+arg3909+arg3910+arg3911+arg3912+arg3913+arg3914+arg3915+arg3916+arg3917+arg3918+arg3919+arg3920+arg3921+arg3922+arg3923+arg3924+arg3925+arg3926+arg3927+arg3928+arg3929+arg3930+arg3931+arg3932+arg3933+arg3934+arg3935+arg3936+arg3937+arg3938+arg3939+arg3940+arg3941+arg3942+arg3943+arg3944+arg3945+arg3946+arg3947+arg3948+arg3949+arg3950+arg3951+arg3952+arg3953+arg3954+arg3955+arg3956+arg3957+arg3958+arg3959+arg3960+arg3961+arg3962+arg3963+arg3964+arg3965+arg3966+arg3967+arg3968+arg3969+arg3970+arg3971+arg3972+arg3973+arg3974+arg3975+arg3976+arg3977+arg3978+arg3979+arg3980+arg3981+arg3982+arg3983+arg3984+arg3985+arg3986+arg3987+arg3988+arg3989+arg3990+arg3991+arg3992+arg3993+arg3994+arg3995+arg3996+arg3997+arg3998+arg3999+arg4000+arg4001+arg4002+arg4003+arg4004+arg4005+arg4006+arg4007+arg4008+arg4009+arg4010+arg4011+arg4012+arg4013+arg4014+arg4015+arg4016+arg4017+arg4018+arg4019+arg4020+arg4021+arg4022+arg4023+arg4024+arg4025+arg4026+arg4027+arg4028+arg4029+arg4030+arg4031+arg4032+arg4033+arg4034+arg4035+arg4036+arg4037+arg4038+arg4039+arg4040+arg4041+arg4042+arg4043+arg4044+arg4045+arg4046+arg4047+arg4048+arg4049+arg4050+arg4051+arg4052+arg4053+arg4054+arg4055+arg4056+arg4057+arg4058+arg4059+arg4060+arg4061+arg4062+arg4063+arg4064+arg4065+arg4066+arg4067+arg4068+arg4069+arg4070+arg4071+arg4072+arg4073+arg4074+arg4075+arg4076+arg4077+arg4078+arg4079+arg4080+arg4081+arg4082+arg4083+arg4084+arg4085+arg4086+arg4087+arg4088+arg4089+arg4090+arg4091+arg4092+arg4093+arg4094+arg4095+arg4096+arg4097+arg4098+arg4099+arg4100+arg4101+arg4102+arg4103+arg4104+arg4105+arg4106+arg4107+arg4108+arg4109+arg4110+arg4111+arg4112+arg4113+arg4114+arg4115+arg4116+arg4117+arg4118+arg4119+arg4120+arg4121+arg4122+arg4123+arg4124+arg4125+arg4126+arg4127+arg4128+arg4129+arg4130+arg4131+arg4132+arg4133+arg4134+arg4135+arg4136+arg4137+arg4138+arg4139+arg4140+arg4141+arg4142+arg4143+arg4144+arg4145+arg4146+arg4147+arg4148+arg4149+arg4150+arg4151+arg4152+arg4153+arg4154+arg4155+arg4156+arg4157+arg4158+arg4159+arg4160+arg4161+arg4162+arg4163+arg4164+arg4165+arg4166+arg4167+arg4168+arg4169+arg4170+arg4171+arg4172+arg4173+arg4174+arg4175+arg4176+arg4177+arg4178+arg4179+arg4180+arg4181+arg4182+arg4183+arg4184+arg4185+arg4186+arg4187+arg4188+arg4189+arg4190+arg4191+arg4192+arg4193+arg4194+arg4195+arg4196+arg4197+arg4198+arg4199+arg4200+arg4201+arg4202+arg4203+arg4204+arg4205+arg4206+arg4207+arg4208+arg4209+arg4210+arg4211+arg4212+arg4213+arg4214+arg4215+arg4216+arg4217+arg4218+arg4219+arg4220+arg4221+arg4222+arg4223+arg4224+arg4225+arg4226+arg4227+arg4228+arg4229+arg4230+arg4231+arg4232+arg4233+arg4234+arg4235+arg4236+arg4237+arg4238+arg4239+arg4240+arg4241+arg4242+arg4243+arg4244+arg4245+arg4246+arg4247+arg4248+arg4249+arg4250+arg4251+arg4252+arg4253+arg4254+arg4255+arg4256+arg4257+arg4258+arg4259+arg4260+arg4261+arg4262+arg4263+arg4264+arg4265+arg4266+arg4267+arg4268+arg4269+arg4270+arg4271+arg4272+arg4273+arg4274+arg4275+arg4276+arg4277+arg4278+arg4279+arg4280+arg4281+arg4282+arg4283+arg4284+arg4285+arg4286+arg4287+arg4288+arg4289+arg4290+arg4291+arg4292+arg4293+arg4294+arg4295+arg4296+arg4297+arg4298+arg4299+arg4300+arg4301+arg4302+arg4303+arg4304+arg4305+arg4306+arg4307+arg4308+arg4309+arg4310+arg4311+arg4312+arg4313+arg4314+arg4315+arg4316+arg4317+arg4318+arg4319+arg4320+arg4321+arg4322+arg4323+arg4324+arg4325+arg4326+arg4327+arg4328+arg4329+arg4330+arg4331+arg4332+arg4333+arg4334+arg4335+arg4336+arg4337+arg4338+arg4339+arg4340+arg4341+arg4342+arg4343+arg4344+arg4345+arg4346+arg4347+arg4348+arg4349+arg4350+arg4351+arg4352+arg4353+arg4354+arg4355+arg4356+arg4357+arg4358+arg4359+arg4360+arg4361+arg4362+arg4363+arg4364+arg4365+arg4366+arg4367+arg4368+arg4369+arg4370+arg4371+arg4372+arg4373+arg4374+arg4375+arg4376+arg4377+arg4378+arg4379+arg4380+arg4381+arg4382+arg4383+arg4384+arg4385+arg4386+arg4387+arg4388+arg4389+arg4390+arg4391+arg4392+arg4393+arg4394+arg4395+arg4396+arg4397+arg4398+arg4399+arg4400+arg4401+arg4402+arg4403+arg4404+arg4405+arg4406+arg4407+arg4408+arg4409+arg4410+arg4411+arg4412+arg4413+arg4414+arg4415+arg4416+arg4417+arg4418+arg4419+arg4420+arg4421+arg4422+arg4423+arg4424+arg4425+arg4426+arg4427+arg4428+arg4429+arg4430+arg4431+arg4432+arg4433+arg4434+arg4435+arg4436+arg4437+arg4438+arg4439+arg4440+arg4441+arg4442+arg4443+arg4444+arg4445+arg4446+arg4447+arg4448+arg4449+arg4450+arg4451+arg4452+arg4453+arg4454+arg4455+arg4456+arg4457+arg4458+arg4459+arg4460+arg4461+arg4462+arg4463+arg4464+arg4465+arg4466+arg4467+arg4468+arg4469+arg4470+arg4471+arg4472+arg4473+arg4474+arg4475+arg4476+arg4477+arg4478+arg4479+arg4480+arg4481+arg4482+arg4483+arg4484+arg4485+arg4486+arg4487+arg4488+arg4489+arg4490+arg4491+arg4492+arg4493+arg4494+arg4495+arg4496+arg4497+arg4498+arg4499+arg4500+arg4501+arg4502+arg4503+arg4504+arg4505+arg4506+arg4507+arg4508+arg4509+arg4510+arg4511+arg4512+arg4513+arg4514+arg4515+arg4516+arg4517+arg4518+arg4519+arg4520+arg4521+arg4522+arg4523+arg4524+arg4525+arg4526+arg4527+arg4528+arg4529+arg4530+arg4531+arg4532+arg4533+arg4534+arg4535+arg4536+arg4537+arg4538+arg4539+arg4540+arg4541+arg4542+arg4543+arg4544+arg4545+arg4546+arg4547+arg4548+arg4549+arg4550+arg4551+arg4552+arg4553+arg4554+arg4555+arg4556+arg4557+arg4558+arg4559+arg4560+arg4561+arg4562+arg4563+arg4564+arg4565+arg4566+arg4567+arg4568+arg4569+arg4570+arg4571+arg4572+arg4573+arg4574+arg4575+arg4576+arg4577+arg4578+arg4579+arg4580+arg4581+arg4582+arg4583+arg4584+arg4585+arg4586+arg4587+arg4588+arg4589+arg4590+arg4591+arg4592+arg4593+arg4594+arg4595+arg4596+arg4597+arg4598+arg4599+arg4600+arg4601+arg4602+arg4603+arg4604+arg4605+arg4606+arg4607+arg4608+arg4609+arg4610+arg4611+arg4612+arg4613+arg4614+arg4615+arg4616+arg4617+arg4618+arg4619+arg4620+arg4621+arg4622+arg4623+arg4624+arg4625+arg4626+arg4627+arg4628+arg4629+arg4630+arg4631+arg4632+arg4633+arg4634+arg4635+arg4636+arg4637+arg4638+arg4639+arg4640+arg4641+arg4642+arg4643+arg4644+arg4645+arg4646+arg4647+arg4648+arg4649+arg4650+arg4651+arg4652+arg4653+arg4654+arg4655+arg4656+arg4657+arg4658+arg4659+arg4660+arg4661+arg4662+arg4663+arg4664+arg4665+arg4666+arg4667+arg4668+arg4669+arg4670+arg4671+arg4672+arg4673+arg4674+arg4675+arg4676+arg4677+arg4678+arg4679+arg4680+arg4681+arg4682+arg4683+arg4684+arg4685+arg4686+arg4687+arg4688+arg4689+arg4690+arg4691+arg4692+arg4693+arg4694+arg4695+arg4696+arg4697+arg4698+arg4699+arg4700+arg4701+arg4702+arg4703+arg4704+arg4705+arg4706+arg4707+arg4708+arg4709+arg4710+arg4711+arg4712+arg4713+arg4714+arg4715+arg4716+arg4717+arg4718+arg4719+arg4720+arg4721+arg4722+arg4723+arg4724+arg4725+arg4726+arg4727+arg4728+arg4729+arg4730+arg4731+arg4732+arg4733+arg4734+arg4735+arg4736+arg4737+arg4738+arg4739+arg4740+arg4741+arg4742+arg4743+arg4744+arg4745+arg4746+arg4747+arg4748+arg4749+arg4750+arg4751+arg4752+arg4753+arg4754+arg4755+arg4756+arg4757+arg4758+arg4759+arg4760+arg4761+arg4762+arg4763+arg4764+arg4765+arg4766+arg4767+arg4768+arg4769+arg4770+arg4771+arg4772+arg4773+arg4774+arg4775+arg4776+arg4777+arg4778+arg4779+arg4780+arg4781+arg4782+arg4783+arg4784+arg4785+arg4786+arg4787+arg4788+arg4789+arg4790+arg4791+arg4792+arg4793+arg4794+arg4795+arg4796+arg4797+arg4798+arg4799+arg4800+arg4801+arg4802+arg4803+arg4804+arg4805+arg4806+arg4807+arg4808+arg4809+arg4810+arg4811+arg4812+arg4813+arg4814+arg4815+arg4816+arg4817+arg4818+arg4819+arg4820+arg4821+arg4822+arg4823+arg4824+arg4825+arg4826+arg4827+arg4828+arg4829+arg4830+arg4831+arg4832+arg4833+arg4834+arg4835+arg4836+arg4837+arg4838+arg4839+arg4840+arg4841+arg4842+arg4843+arg4844+arg4845+arg4846+arg4847+arg4848+arg4849+arg4850+arg4851+arg4852+arg4853+arg4854+arg4855+arg4856+arg4857+arg4858+arg4859+arg4860+arg4861+arg4862+arg4863+arg4864+arg4865+arg4866+arg4867+arg4868+arg4869+arg4870+arg4871+arg4872+arg4873+arg4874+arg4875+arg4876+arg4877+arg4878+arg4879+arg4880+arg4881+arg4882+arg4883+arg4884+arg4885+arg4886+arg4887+arg4888+arg4889+arg4890+arg4891+arg4892+arg4893+arg4894+arg4895+arg4896+arg4897+arg4898+arg4899+arg4900+arg4901+arg4902+arg4903+arg4904+arg4905+arg4906+arg4907+arg4908+arg4909+arg4910+arg4911+arg4912+arg4913+arg4914+arg4915+arg4916+arg4917+arg4918+arg4919+arg4920+arg4921+arg4922+arg4923+arg4924+arg4925+arg4926+arg4927+arg4928+arg4929+arg4930+arg4931+arg4932+arg4933+arg4934+arg4935+arg4936+arg4937+arg4938+arg4939+arg4940+arg4941+arg4942+arg4943+arg4944+arg4945+arg4946+arg4947+arg4948+arg4949+arg4950+arg4951+arg4952+arg4953+arg4954+arg4955+arg4956+arg4957+arg4958+arg4959+arg4960+arg4961+arg4962+arg4963+arg4964+arg4965+arg4966+arg4967+arg4968+arg4969+arg4970+arg4971+arg4972+arg4973+arg4974+arg4975+arg4976+arg4977+arg4978+arg4979+arg4980+arg4981+arg4982+arg4983+arg4984+arg4985+arg4986+arg4987+arg4988+arg4989+arg4990+arg4991+arg4992+arg4993+arg4994+arg4995+arg4996+arg4997+arg4998+arg4999+arg5000+arg5001+arg5002+arg5003+arg5004+arg5005+arg5006+arg5007+arg5008+arg5009+arg5010+arg5011+arg5012+arg5013+arg5014+arg5015+arg5016+arg5017+arg5018+arg5019+arg5020+arg5021+arg5022+arg5023+arg5024+arg5025+arg5026+arg5027+arg5028+arg5029+arg5030+arg5031+arg5032+arg5033+arg5034+arg5035+arg5036+arg5037+arg5038+arg5039; } void testCallFunctionWithHellaArguments3() { Procedure proc; BasicBlock* root = proc.addBlock(); Vector args; - for (unsigned i = 0; i < 5000; ++i) + for (unsigned i = 0; i < 5040; ++i) args.append(root->appendNew(proc, Origin(), 4095 - 5000 + i - 1)); CCallValue* call = root->appendNew( @@ -2226,13 +2226,13 @@ void testCallFunctionWithHellaArguments3() std::unique_ptr compilation = compileProc(proc); CHECK_EQ(invoke(*compilation), invoke(*compilation)); - CHECK_EQ(invoke(*compilation), 7967500); + CHECK_EQ(invoke(*compilation), 8132040); CHECK_EQ(invoke(*compilation), invoke(*compilation)); - CHECK_EQ(invoke(*compilation), 7967500); + CHECK_EQ(invoke(*compilation), 8132040); CHECK_EQ(invoke(*compilation), invoke(*compilation)); - CHECK_EQ(invoke(*compilation), 7967500); + CHECK_EQ(invoke(*compilation), 8132040); CHECK_EQ(invoke(*compilation), invoke(*compilation)); - CHECK_EQ(invoke(*compilation), 7967500); + CHECK_EQ(invoke(*compilation), 8132040); } struct IntPtrPair { From b1eedb37b086ebae010e777317e517ff8fcef0ee Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Thu, 27 Feb 2025 03:42:21 -0800 Subject: [PATCH 05/54] [JSC][armv7] Fix BBQJIT::F64CopySign on armv7 https://bugs.webkit.org/show_bug.cgi?id=288081 Reviewed by Yusuke Suzuki and Justin Michaud. Properly allocate a scratch FPR instead of a GPR pair for a scratch float value. * Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp: (JSC::Wasm::BBQJITImpl::BBQJIT::addF64Copysign): Canonical link: https://commits.webkit.org/291216@main (cherry picked from commit 667960fc04252cb7397532b7fdf04c9be52ee482) --- Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp index 2dda9962e276..5e9e5f734792 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp @@ -2706,8 +2706,8 @@ PartialResult WARN_UNUSED_RETURN BBQJIT::addF64Copysign(Value lhs, Value rhs, Va F64CopysignHelper(lhsLocation, rhsLocation, resultLocation); ), BLOCK( - ImmHelpers::immLocation(lhsLocation, rhsLocation) = Location::fromGPR2(wasmScratchGPR, wasmScratchGPR2); - emitMoveConst(ImmHelpers::imm(lhs, rhs), Location::fromGPR2(wasmScratchGPR, wasmScratchGPR2)); + ImmHelpers::immLocation(lhsLocation, rhsLocation) = Location::fromFPR(wasmScratchFPR); + emitMoveConst(ImmHelpers::imm(lhs, rhs), Location::fromFPR(wasmScratchFPR)); F64CopysignHelper(lhsLocation, rhsLocation, resultLocation); ) ) From d06a7ff2f5be517db8cdabac0d0390a64b4960cc Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Thu, 27 Feb 2025 13:35:16 -0800 Subject: [PATCH 06/54] [ARMv7] Build-webkit should support --32-bit on ARM64 https://bugs.webkit.org/show_bug.cgi?id=288574 Reviewed by Michael Catanzaro. This change was tested with a JSCOnly build in an armhf webkit-container-sdk container on an ARM64 Thelio Astra workstation. * Source/cmake/WebKitCommon.cmake: * Tools/Scripts/webkitdirs.pm: (generateBuildSystemFromCMakeProject): Canonical link: https://commits.webkit.org/291253@main (cherry picked from commit 4a09da23668aae5a6a0a56f613a59b512f787087) --- Source/cmake/WebKitCommon.cmake | 6 +++++- Tools/Scripts/webkitdirs.pm | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Source/cmake/WebKitCommon.cmake b/Source/cmake/WebKitCommon.cmake index 38ac0c471add..1df3084c8b1a 100644 --- a/Source/cmake/WebKitCommon.cmake +++ b/Source/cmake/WebKitCommon.cmake @@ -100,7 +100,11 @@ if (NOT HAS_RUN_WEBKIT_COMMON) string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} LOWERCASE_CMAKE_SYSTEM_PROCESSOR) endif () if (LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64|^arm64|^cortex-?[am][2-7][2-8])") - set(WTF_CPU_ARM64 1) + if (FORCE_32BIT) + set(WTF_CPU_ARM 1) + else () + set(WTF_CPU_ARM64 1) + endif () elseif (LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(^arm|^cortex)") set(WTF_CPU_ARM 1) elseif (LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "^mips64") diff --git a/Tools/Scripts/webkitdirs.pm b/Tools/Scripts/webkitdirs.pm index 8535e72996c8..1f159b9d831c 100755 --- a/Tools/Scripts/webkitdirs.pm +++ b/Tools/Scripts/webkitdirs.pm @@ -2843,6 +2843,16 @@ sub generateBuildSystemFromCMakeProject $ENV{"CXXFLAGS"} = "-m32" . ($ENV{"CXXFLAGS"} || ""); $ENV{"LDFLAGS"} = "-m32" . ($ENV{"LDFLAGS"} || ""); } + if (architecture() eq "arm64" && shouldBuild32Bit()) { + # CMAKE_LIBRARY_ARCHITECTURE is needed to get the right .pc + # files in Debian-based systems, for the others + # CMAKE_PREFIX_PATH will get us /usr/lib, which should be the + # right path for 32bit. See FindPkgConfig.cmake. + push @cmakeArgs, '-DFORCE_32BIT=ON -DCMAKE_PREFIX_PATH="/usr" -DCMAKE_LIBRARY_ARCHITECTURE=armv7-a+fp'; + $ENV{"CFLAGS"} = "-m32 -march=armv7-a+fp" . ($ENV{"CFLAGS"} || ""); + $ENV{"CXXFLAGS"} = "-m32 -march=armv7-a+fp" . ($ENV{"CXXFLAGS"} || ""); + $ENV{"LDFLAGS"} = "-m32 -march=armv7-a+fp" . ($ENV{"LDFLAGS"} || ""); + } push @args, @cmakeArgs if @cmakeArgs; my $cmakeSourceDir = isCygwin() ? windowsSourceDir() : sourceDir(); From f162d84195d379c3aa8ee381fb1334d9eeeab660 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Mon, 10 Mar 2025 03:47:52 -0700 Subject: [PATCH 07/54] [JSC] Fix integer overflow on armv7 in CompleteSubspace::tryAllocateSlow https://bugs.webkit.org/show_bug.cgi?id=289157 Reviewed by Yusuke Suzuki. Avoids integer overflow when multiplying by ramSize. * Source/JavaScriptCore/heap/CompleteSubspace.cpp: (JSC::CompleteSubspace::tryAllocateSlow): Canonical link: https://commits.webkit.org/291887@main (cherry picked from commit 47b01a388dd821685e33f444397698a758c19fde) --- Source/JavaScriptCore/heap/CompleteSubspace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/JavaScriptCore/heap/CompleteSubspace.cpp b/Source/JavaScriptCore/heap/CompleteSubspace.cpp index 0c41b4ea0b47..62c11706e3d0 100644 --- a/Source/JavaScriptCore/heap/CompleteSubspace.cpp +++ b/Source/JavaScriptCore/heap/CompleteSubspace.cpp @@ -130,7 +130,7 @@ void* CompleteSubspace::tryAllocateSlow(VM& vm, size_t size, GCDeferralContext* vm.heap.collectIfNecessaryOrDefer(deferralContext); if (UNLIKELY(Options::maxHeapSizeAsRAMSizeMultiple())) { - if (vm.heap.capacity() > Options::maxHeapSizeAsRAMSizeMultiple() * WTF::ramSize()) + if (vm.heap.capacity() > static_cast(Options::maxHeapSizeAsRAMSizeMultiple()) * static_cast(WTF::ramSize())) return nullptr; } From 0a00ebbbb72962ea2a9b3233a42a23125ad18ae6 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Tue, 11 Mar 2025 10:08:16 -0700 Subject: [PATCH 08/54] [JSC][armv7] Fix YarrInterpreter alignment checks https://bugs.webkit.org/show_bug.cgi?id=288079 Reviewed by Yusuke Suzuki and Justin Michaud. Compute required alignment in a platform independent way at compile time using constexpr. * Source/JavaScriptCore/yarr/YarrInterpreter.cpp: (JSC::Yarr::Interpreter::DisjunctionContext::allocationSize): (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::allocationSize): Canonical link: https://commits.webkit.org/291952@main (cherry picked from commit 6040dcdd450165720f3f141e3d07cbc3f0cd7f21) --- Source/JavaScriptCore/yarr/YarrInterpreter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp index 0ed882f454f8..71901ad19ceb 100644 --- a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp +++ b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp @@ -114,9 +114,9 @@ class Interpreter { static size_t allocationSize(unsigned numberOfFrames) { - static_assert(alignof(DisjunctionContext) <= sizeof(void*)); + constexpr size_t alignment = std::max(alignof(DisjunctionContext), sizeof(uintptr_t)); size_t rawSize = sizeof(DisjunctionContext) - sizeof(uintptr_t) + Checked(numberOfFrames) * sizeof(uintptr_t); - size_t roundedSize = roundUpToMultipleOf(rawSize); + size_t roundedSize = roundUpToMultipleOf(rawSize); RELEASE_ASSERT(roundedSize >= rawSize); return roundedSize; } @@ -203,9 +203,9 @@ class Interpreter { static size_t allocationSize(unsigned numBackupIds) { - static_assert(alignof(ParenthesesDisjunctionContext) <= sizeof(void*)); + constexpr size_t alignment = std::max(alignof(ParenthesesDisjunctionContext), sizeof(unsigned)); size_t rawSize = sizeof(ParenthesesDisjunctionContext) + Checked(numBackupIds) * sizeof(unsigned); - size_t roundedSize = roundUpToMultipleOf(rawSize); + size_t roundedSize = roundUpToMultipleOf(rawSize); RELEASE_ASSERT(roundedSize >= rawSize); return roundedSize; } From a1478c604c9a7bb2b40471f71bdc14548fe8c91c Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 12 Mar 2025 09:19:37 -0700 Subject: [PATCH 09/54] [ARMv7] Fix wasm to js when useJIT=0 https://bugs.webkit.org/show_bug.cgi?id=289585 Reviewed by Yusuke Suzuki. We missed storing a tag for the callee's callee. The JIT version of this stub uses storeCell. * Source/JavaScriptCore/wasm/WasmOperations.cpp: (JSC::Wasm::JSC_DEFINE_JIT_OPERATION): Canonical link: https://commits.webkit.org/292019@main (cherry picked from commit a9bf19a5216da295160b0739f2de629eeb146d2a) --- Source/JavaScriptCore/wasm/WasmOperations.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/JavaScriptCore/wasm/WasmOperations.cpp b/Source/JavaScriptCore/wasm/WasmOperations.cpp index 9f613e1d242f..25c325dd156c 100644 --- a/Source/JavaScriptCore/wasm/WasmOperations.cpp +++ b/Source/JavaScriptCore/wasm/WasmOperations.cpp @@ -419,12 +419,18 @@ JSC_DEFINE_JIT_OPERATION(operationWasmToJSExitMarshalArguments, bool, (void* sp, // materializeImportJSCell and store *access.operator()(calleeFrame, CallFrameSlot::callee * static_cast(sizeof(Register))) = std::bit_cast(importableFunction->importFunction); +#if USE(JSVALUE32_64) + *access.operator()(calleeFrame, CallFrameSlot::callee * sizeof(Register) + TagOffset) = JSValue::CellTag; +#endif *access.operator()(calleeFrame, CallFrameSlot::argumentCountIncludingThis * static_cast(sizeof(Register)) + PayloadOffset) = argCount + 1; // including this = +1 // set up codeblock auto singletonCallee = CalleeBits::boxNativeCallee(&WasmToJSCallee::singleton()); *access.operator()(cfr, CallFrameSlot::codeBlock * sizeof(Register)) = std::bit_cast(instance); *access.operator()(cfr, CallFrameSlot::callee * sizeof(Register)) = std::bit_cast(singletonCallee); +#if USE(JSVALUE32_64) + *access.operator()(cfr, CallFrameSlot::callee * sizeof(Register) + TagOffset) = JSValue::NativeCalleeTag; +#endif OPERATION_RETURN(scope, true); } From d65f2fa6eb956d6086478fbcfe0890759b398c25 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Mon, 24 Mar 2025 13:17:31 -0700 Subject: [PATCH 10/54] [JSC][armv7] Verify MacroAssemblerARMv7::branch32 usage in debug builds https://bugs.webkit.org/show_bug.cgi?id=288083 Reviewed by Yusuke Suzuki and Justin Michaud. On armv7 certain uses of branchPtr cause it to clobber its own arguments, leading to bogus assembly. Catch this pitfall at least in debug builds and fix instances of this bug. * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::branch32): * Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp: (JSC::InlineCacheCompiler::compile): * Source/JavaScriptCore/wasm/WasmBBQJIT.cpp: (JSC::Wasm::BBQJITImpl::BBQJIT::addLoopOSREntrypoint): Canonical link: https://commits.webkit.org/292608@main (cherry picked from commit 42c141462b40cec8182b5730d783a7b9b1477904) --- .../assembler/MacroAssemblerARMv7.h | 16 +++++++++++++++- Source/JavaScriptCore/wasm/WasmBBQJIT.cpp | 7 ++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index e2b80afe45cb..0128cee55c51 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -2552,10 +2552,24 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right) { - if (left == ARMRegisters::sp) { + if (left == ARMRegisters::sp && right == addressTempRegister && cond == Equal) { + m_assembler.sub_S(addressTempRegister, left, addressTempRegister); + return Jump(makeBranch(Zero)); + } else if (left == ARMRegisters::sp && right == addressTempRegister && cond == NotEqual) { + m_assembler.sub_S(addressTempRegister, left, addressTempRegister); + return Jump(makeBranch(NonZero)); + } else if (right == ARMRegisters::sp && left == addressTempRegister && cond == Equal) { + m_assembler.sub_S(addressTempRegister, right, addressTempRegister); + return Jump(makeBranch(Zero)); + } else if (right == ARMRegisters::sp && left == addressTempRegister && cond == NotEqual) { + m_assembler.sub_S(addressTempRegister, right, addressTempRegister); + return Jump(makeBranch(NonZero)); + } else if (left == ARMRegisters::sp) { + ASSERT(right != addressTempRegister); move(left, addressTempRegister); m_assembler.cmp(addressTempRegister, right); } else if (right == ARMRegisters::sp) { + ASSERT(left != addressTempRegister); move(right, addressTempRegister); m_assembler.cmp(left, addressTempRegister); } else diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp b/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp index b9cb2b4578a1..4f4d9a1738b4 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp @@ -3183,10 +3183,15 @@ MacroAssembler::Label BBQJIT::addLoopOSREntrypoint() #endif // The loop_osr slow path should have already checked that we have enough space. We have already destroyed the llint stack, and unwind will see the BBQ catch - // since we already replaced callee. So, we just assert that this case doesn't happen to avoid reading a corrupted frame from the bbq catch handler. + // since we already replaced callee. So, we just assert that this case doesn't happen to avoid reading a corrupted frame from the bbq catch handler. MacroAssembler::JumpList overflow; +#if !CPU(ADDRESS64) + overflow.append(m_jit.branchPtr(CCallHelpers::Above, wasmScratchGPR, GPRInfo::callFrameRegister)); + overflow.append(m_jit.branchPtr(CCallHelpers::Below, wasmScratchGPR, CCallHelpers::Address(GPRInfo::wasmContextInstancePointer, JSWebAssemblyInstance::offsetOfSoftStackLimit()))); +#else overflow.append(m_jit.branchPtr(CCallHelpers::Above, MacroAssembler::stackPointerRegister, GPRInfo::callFrameRegister)); overflow.append(m_jit.branchPtr(CCallHelpers::Below, MacroAssembler::stackPointerRegister, CCallHelpers::Address(GPRInfo::wasmContextInstancePointer, JSWebAssemblyInstance::offsetOfSoftStackLimit()))); +#endif overflow.linkThunk(CodeLocationLabel(Thunks::singleton().stub(crashDueToBBQStackOverflowGenerator).code()), &m_jit); // This operation shuffles around values on the stack, until everything is in the right place. Then, From 34d9e5f513fd3244ab2f588d1e1aa536f797cbda Mon Sep 17 00:00:00 2001 From: Thomas Devoogdt Date: Tue, 25 Mar 2025 16:53:00 -0700 Subject: [PATCH 11/54] ResourceLoadInfo: fix compilation if VIDEO or is not enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugs.webkit.org/show_bug.cgi?id=290259 Reviewed by Adrian Perez de Castro. /home/thomas/br-test-pkg/bootlin-armv7-glibc/build/webkitgtk-2.48.0/Source/WebCore/loader/ResourceLoadInfo.cpp:88:32: error: ‘TextTrackResource’ is not a member of ‘WebCore::CachedResource::Type’ 88 | case CachedResource::Type::TextTrackResource: | ^~~~~~~~~~~~~~~~~ Commit https://github.com/WebKit/WebKit/commit/951a118e17cd92adc3aa31129af7cd348fac91e9 "Fix missing includes and guards when certain features are disabled", added guards to TextTrackResource in CachedResource, but forgot to add this one. Signed-off-by: Thomas Devoogdt Canonical link: https://commits.webkit.org/292680@main (cherry picked from commit 120eef401f7c2e88f6b976a9316149d838a74004) --- Source/WebCore/loader/ResourceLoadInfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/WebCore/loader/ResourceLoadInfo.cpp b/Source/WebCore/loader/ResourceLoadInfo.cpp index 4582f7f6013e..595cdc986f22 100644 --- a/Source/WebCore/loader/ResourceLoadInfo.cpp +++ b/Source/WebCore/loader/ResourceLoadInfo.cpp @@ -84,8 +84,10 @@ OptionSet toResourceType(CachedResource::Type type, ResourceReques #endif return { ResourceType::Other }; +#if ENABLE(VIDEO) case CachedResource::Type::TextTrackResource: return { ResourceType::Media }; +#endif }; ASSERT_NOT_REACHED(); From 5f0c5fd6f163f5401451d1e90d23d2a5591f260a Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Tue, 27 May 2025 14:44:09 -0700 Subject: [PATCH 12/54] [ARMv7] Skip branch compaction when diff would cause misalignment https://bugs.webkit.org/show_bug.cgi?id=293629 Reviewed by Yusuke Suzuki. It is super difficult to track alignment when branch compaction might shift instructions by 2 bytes. This makes it easy to tear writes to the jit region, so let's just skip it for now in those cases. * Source/JavaScriptCore/assembler/ARMv7Assembler.h: (JSC::ARMv7Assembler::computeJumpType): Canonical link: https://commits.webkit.org/295468@main (cherry picked from commit 432f62587fcb880419b9a4149d5339e5918571b8) --- Source/JavaScriptCore/assembler/ARMv7Assembler.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h index b07a820c2188..4a868ecd632f 100644 --- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h @@ -2550,28 +2550,34 @@ class ARMv7Assembler { const int paddingSize = JUMP_ENUM_SIZE(jumpType); + const auto isAligned = [paddingSize](const int linkSize) constexpr { + // Let's skip compactions that would cause later instructions to become unaligned + // This way, we don't need to fix up concurrently-patchable branches later on. + return (paddingSize - linkSize) % sizeof(uint32_t) == 0; + }; + if (jumpType == JumpCondition) { // 2-byte conditional T1 const uint16_t* jumpT1Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT1))); - if (canBeJumpT1(jumpT1Location, to)) + if (canBeJumpT1(jumpT1Location, to) && isAligned(JUMP_ENUM_SIZE(LinkJumpT1))) return LinkJumpT1; // 4-byte conditional T3 const uint16_t* jumpT3Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT3))); - if (canBeJumpT3(jumpT3Location, to)) + if (canBeJumpT3(jumpT3Location, to) && isAligned(JUMP_ENUM_SIZE(LinkJumpT3))) return LinkJumpT3; // 4-byte conditional T4 with IT const uint16_t* conditionalJumpT4Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkConditionalJumpT4))); - if (canBeJumpT4(conditionalJumpT4Location, to)) + if (canBeJumpT4(conditionalJumpT4Location, to) && isAligned(JUMP_ENUM_SIZE(LinkConditionalJumpT4))) return LinkConditionalJumpT4; } else { // 2-byte unconditional T2 const uint16_t* jumpT2Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT2))); - if (canBeJumpT2(jumpT2Location, to)) + if (canBeJumpT2(jumpT2Location, to) && isAligned(JUMP_ENUM_SIZE(LinkJumpT2))) return LinkJumpT2; // 4-byte unconditional T4 const uint16_t* jumpT4Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT4))); - if (canBeJumpT4(jumpT4Location, to)) + if (canBeJumpT4(jumpT4Location, to) && isAligned(JUMP_ENUM_SIZE(LinkJumpT4))) return LinkJumpT4; // use long jump sequence return LinkBX; From fec1390e3675db5d575be46d8e700b9ed57a7ae4 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Wed, 9 Jul 2025 10:27:01 -0700 Subject: [PATCH 13/54] [JSC] Fix ARMv7 segfault in BBQJIT by avoid the use of `wasmScratchGPR` https://bugs.webkit.org/show_bug.cgi?id=295498 Reviewed by Justin Michaud. WASM BBQJIT on 32-bit uses wasmScratchGPR when loading F32/F64 constants, causing segmentation faults in JetStream3's tfjs-wasm. The issue occurs when emitCheckAndPrepareAndMaterializePointerApply stores a memory address in wasmScratchGPR, then passes it to a functor. If the functor loads a floating-point constant, it overwrites wasmScratchGPR, corrupting the address and causing null pointer access. This patch fixes by using MacroAssembler's move32ToFloat and move64ToDouble directly with immediate values, eliminating the use of wasmScratchGPR. * Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp: (JSC::Wasm::BBQJITImpl::BBQJIT::emitMoveConst): Canonical link: https://commits.webkit.org/297169@main (cherry picked from commit 93a792f5574a5fea86f235f999bd7320d98579da) --- Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp index 5e9e5f734792..d1b32969c2c5 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp @@ -3476,13 +3476,10 @@ void BBQJIT::emitMoveConst(Value constant, Location loc) m_jit.move(Imm32(constant.asI64lo()), loc.asGPRlo()); break; case TypeKind::F32: - m_jit.move(Imm32(constant.asI32()), wasmScratchGPR); - m_jit.move32ToFloat(wasmScratchGPR, loc.asFPR()); + m_jit.move32ToFloat(Imm32(constant.asI32()), loc.asFPR()); break; case TypeKind::F64: - m_jit.move(Imm32(constant.asI64hi()), wasmScratchGPR2); - m_jit.move(Imm32(constant.asI64lo()), wasmScratchGPR); - m_jit.move64ToDouble(wasmScratchGPR2, wasmScratchGPR, loc.asFPR()); + m_jit.move64ToDouble(Imm64(constant.asI64()), loc.asFPR()); break; default: RELEASE_ASSERT_NOT_REACHED_WITH_MESSAGE("Unimplemented constant typekind."); From 0fb92d1ab7e454a20463061221ea916b1872d1c3 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Mon, 14 Jul 2025 09:49:38 -0700 Subject: [PATCH 14/54] Add additional padding for patchable jumps and calls on armv7 https://bugs.webkit.org/show_bug.cgi?id=295724 Reviewed by Sosuke Suzuki. On ARMv7, we cannot store atomically to unaligned addresses. On other platforms, this patch should be a no-op, but it aligns some patchable places for ARMv7. A follow-up patch will change the way we do patching. Canonical link: https://commits.webkit.org/297343@main (cherry picked from commit f652173c6459317c53fc96c50401adc6708d8aa2) --- Source/JavaScriptCore/assembler/ARMv7Assembler.h | 2 +- Source/JavaScriptCore/assembler/LinkBuffer.cpp | 2 +- Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h index 4a868ecd632f..e9028ce1075c 100644 --- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h @@ -3184,7 +3184,7 @@ class ARMv7Assembler { ASSERT(!(reinterpret_cast(instruction) & 1)); ASSERT(!(reinterpret_cast(target) & 1)); - linkBX(writeTarget, instruction, target); + linkBX(writeTarget, instruction, target); uint16_t newInstruction = ifThenElse(cond, true, true) | OP_IT; machineCodeCopy(writeTarget - 6, &newInstruction, sizeof(uint16_t)); } diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.cpp b/Source/JavaScriptCore/assembler/LinkBuffer.cpp index e39d5c412c6e..a9679bc12708 100644 --- a/Source/JavaScriptCore/assembler/LinkBuffer.cpp +++ b/Source/JavaScriptCore/assembler/LinkBuffer.cpp @@ -462,7 +462,7 @@ void LinkBuffer::copyCompactAndLinkCode(MacroAssembler& macroAssembler, JITCompi void LinkBuffer::linkCode(MacroAssembler& macroAssembler, JITCompilationEffort effort) { // Ensure that the end of the last invalidation point does not extend beyond the end of the buffer. - macroAssembler.padBeforePatch(); + macroAssembler.label(); #if ENABLE(JIT) #if !ENABLE(BRANCH_COMPACTION) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 0128cee55c51..2e14664bea9b 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -2995,11 +2995,16 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { return Call(m_assembler.b(), Call::LinkableNearTail); } + ALWAYS_INLINE void padBeforePatch() + { + (void)label(); + m_assembler.alignWithNop(sizeof(uint64_t)); + } + ALWAYS_INLINE Call threadSafePatchableNearCall() { invalidateAllTempRegisters(); padBeforePatch(); - m_assembler.alignWithNop(sizeof(int)); m_assembler.bl(); return Call(m_assembler.labelIgnoringWatchpoints(), Call::LinkableNear); } @@ -3008,7 +3013,6 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { { invalidateAllTempRegisters(); padBeforePatch(); - m_assembler.alignWithNop(sizeof(int)); return Call(m_assembler.b(), Call::LinkableNearTail); } From 73e0fdd835acb9b8352b719b14798a5755d28c4d Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Mon, 21 Jul 2025 07:56:02 -0700 Subject: [PATCH 15/54] [ARMv7] Add padding to align patchable calls https://bugs.webkit.org/show_bug.cgi?id=296221 Reviewed by Sosuke Suzuki. This should be a no-op on other platforms, but it makes sure extra padding won't confuse the repatching logic. Canonical link: https://commits.webkit.org/297678@main (cherry picked from commit 8d0d636bb91329d45356b882af603282506a427c) --- Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp | 1 + Source/JavaScriptCore/jit/JITMathIC.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp b/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp index 3dcde2b7ca1a..e769e42958a1 100644 --- a/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp +++ b/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp @@ -102,6 +102,7 @@ void JITByIdGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) void JITByIdGenerator::generateFastCommon(CCallHelpers& jit, size_t inlineICSize) { ASSERT(!m_stubInfo->useDataIC); + jit.padBeforePatch(); // On ARMv7, this ensures that the patchable jump does not make the inline code too large. m_start = jit.label(); size_t startSize = jit.m_assembler.buffer().codeSize(); m_slowPathJump = jit.jump(); diff --git a/Source/JavaScriptCore/jit/JITMathIC.h b/Source/JavaScriptCore/jit/JITMathIC.h index 2f91c8543e10..5c893d404771 100644 --- a/Source/JavaScriptCore/jit/JITMathIC.h +++ b/Source/JavaScriptCore/jit/JITMathIC.h @@ -69,6 +69,8 @@ class JITMathIC { bool generateInline(CCallHelpers& jit, MathICGenerationState& state, bool shouldEmitProfiling = true) { + jit.padBeforePatch(); // Make sure that the first patchable jump below is aligned, but don't count alignment in the inline size. + // On ARMv7, this ensures that the patchable jump does not make the inline code too large. state.fastPathStart = jit.label(); size_t startSize = jit.m_assembler.buffer().codeSize(); From 7566b7f4794ed35fed59e70084f61631bbdd8fcb Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Thu, 31 Jul 2025 11:38:04 -0700 Subject: [PATCH 16/54] [ARMv7] Set temporaryCallFrame in WebAssembly.asm https://bugs.webkit.org/show_bug.cgi?id=294597 Reviewed by Justin Michaud. ARMv7 can't rely on BUILTIN_FRAME_ADDRESS (it's broken on GCC). Properly initialize temporaryCallFrame in WebAssembly.asm. This should really be `or (not USE_BUILTIN_FRAME_ADDRESS)`, but we need to keep the number of configuration values down to avoid a combinatorial explosion in the size of LLIntAssembly.h. When we have a fix for GCC, we can just drop the reliance on temporaryCallFrame, but in the meantime this avoids flaky tests in EWS. * Source/JavaScriptCore/llint/WebAssembly.asm: Canonical link: https://commits.webkit.org/298095@main (cherry picked from commit fe797d6f6ba6dd16e331f7b0de522cf2a47a38b7) --- Source/JavaScriptCore/llint/WebAssembly.asm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/JavaScriptCore/llint/WebAssembly.asm b/Source/JavaScriptCore/llint/WebAssembly.asm index 147c745bc938..47ffdb2f285b 100644 --- a/Source/JavaScriptCore/llint/WebAssembly.asm +++ b/Source/JavaScriptCore/llint/WebAssembly.asm @@ -993,6 +993,11 @@ else end) end +# Should be (not USE_BUILTIN_FRAME_ADDRESS) but need to keep down the size of LLIntAssembly.h +if ASSERT_ENABLED or ARMv7 + storep cfr, (constexpr (JSWebAssemblyInstance::offsetOfTemporaryCallFrame()))[wasmInstance] +end + move wasmInstance, a0 move ws0, a1 cCall2(_operationGetWasmCalleeStackSize) @@ -1131,7 +1136,7 @@ end loadp (constexpr (JSWebAssemblyInstance::offsetOfVM()))[wasmInstance], a0 copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(a0, a1) -if ASSERT_ENABLED +if ASSERT_ENABLED or ARMv7 storep cfr, (constexpr (JSWebAssemblyInstance::offsetOfTemporaryCallFrame()))[wasmInstance] end From 3f7735bf28e278158dfcc18dfa2cfca3d12a3151 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Thu, 31 Jul 2025 12:30:46 -0700 Subject: [PATCH 17/54] [ARMv7] Avoid unaligned strd https://bugs.webkit.org/show_bug.cgi?id=293694 Reviewed by Yusuke Suzuki and Sosuke Suzuki. Not all armv7 chips are required to suport unaligned strd instructions. For example, my Neoverse N1 does not support it. This is documented at https://developer.arm.com/documentation/100748/0624/Alignment-support-in-Arm-Compiler-for-Embedded-6/Aligned-and-unaligned-accesses. We should remove these lowerings to support all armv7 processors. In the future, we may want to add them back when we can handle the alignment check separately. * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::storePair32): Canonical link: https://commits.webkit.org/298097@main (cherry picked from commit 5e2002044e76e8a593ca5630ee6e71c760a01463) --- .../assembler/MacroAssemblerARMv7.h | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 2e14664bea9b..fc8357409f72 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -1303,26 +1303,11 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { void storePair32(TrustedImm32 imm1, TrustedImm32 imm2, Address address) { - // We cannot re-use the two register version of `storePair32` defined - // below here because we can only use the `addressTempRegister` as a - // scratch register if the `strd` case is taken. int32_t absOffset = address.offset; if (absOffset < 0) absOffset = -absOffset; - if (!(absOffset & ~0x3fc)) { - RegisterID src1 = getCachedAddressTempRegisterIDAndInvalidate(); - move(imm1, src1); - RegisterID src2 = src1; - if (imm1.m_value != imm2.m_value) { - src2 = getCachedDataTempRegisterIDAndInvalidate(); - move(imm2, src2); - } - ASSERT(src1 != address.base && src2 != address.base); - m_assembler.strd(src1, src2, address.base, address.offset, /* index: */ true, /* wback: */ false); - } else { - store32(imm1, address); - store32(imm2, address.withOffset(4)); - } + store32(imm1, address); + store32(imm2, address.withOffset(4)); } void storePair32(RegisterID src1, RegisterID src2, RegisterID dest) @@ -1340,12 +1325,9 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { int32_t absOffset = address.offset; if (absOffset < 0) absOffset = -absOffset; - if (!(absOffset & ~0x3fc)) - m_assembler.strd(src1, src2, address.base, address.offset, /* index: */ true, /* wback: */ false); - else { - store32(src1, address); - store32(src2, address.withOffset(4)); - } + // strd does not support unaligned accesses on some chips, so we avoid it. + store32(src1, address); + store32(src2, address.withOffset(4)); } void storePair32(RegisterID src1, RegisterID src2, BaseIndex address) From 3bdd57d894c486c6d89ff2aefa903676ee97ef67 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Fri, 29 Aug 2025 08:16:51 -0700 Subject: [PATCH 18/54] [JSC] Fix shiftI64 spilling only on one side of a branch on 32-bit https://bugs.webkit.org/show_bug.cgi?id=298046 Reviewed by Justin Michaud. The program import-mutable-global.js generates the following in armv7: 1. if shift is zero jump to end 2. if shift is less than 32 do: 2.1 spill r0, r1 to use as scratch 2.2 do the shift ... 4. end however, if we take shift is zero and we jump to end, BBQ still thinks we did the spill and reloads r0, r1, loading garbage. This PR fixes the issue by doing the spill as soon as we enter the function, so we always reload the right values. * Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp: (JSC::Wasm::BBQJITImpl::BBQJIT::shiftI64Helper): Canonical link: https://commits.webkit.org/299328@main (cherry picked from commit e4f7416dd860af0af66f3a0a3ce8c10ad5c5ee8d) --- Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp index d1b32969c2c5..edda87da1269 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp @@ -2302,12 +2302,13 @@ PartialResult WARN_UNUSED_RETURN BBQJIT::addI64ShrU(Value lhs, Value rhs, Value& void BBQJIT::shiftI64Helper(ShiftI64HelperOp op, Location lhsLocation, Location rhsLocation, Location resultLocation) { + ScratchScope<1, 0> scratches(*this, lhsLocation, rhsLocation, resultLocation); + auto shift = rhsLocation.asGPRlo(); m_jit.and32(TrustedImm32(63), rhsLocation.asGPRlo(), shift); auto zero = m_jit.branch32(RelationalCondition::Equal, shift, TrustedImm32(0)); auto aboveOrEqual32 = m_jit.branch32(RelationalCondition::AboveOrEqual, shift, TrustedImm32(32)); // shift < 32 - ScratchScope<1, 0> scratches(*this, lhsLocation, rhsLocation, resultLocation); auto carry = scratches.gpr(0); m_jit.move(TrustedImm32(32), carry); m_jit.sub32(carry, shift, carry); @@ -2325,7 +2326,7 @@ void BBQJIT::shiftI64Helper(ShiftI64HelperOp op, Location lhsLocation, Location m_jit.urshift32(lhsLocation.asGPRhi(), shift, resultLocation.asGPRhi()); m_jit.urshift32(lhsLocation.asGPRlo(), shift, resultLocation.asGPRlo()); m_jit.or32(carry, resultLocation.asGPRlo()); - } else if (op ==ShiftI64HelperOp::Rshift) { + } else if (op == ShiftI64HelperOp::Rshift) { m_jit.lshift32(lhsLocation.asGPRhi(), carry, carry); ASSERT(resultLocation.asGPRhi() != shift); ASSERT(resultLocation.asGPRhi() != lhsLocation.asGPRlo()); @@ -2343,7 +2344,7 @@ void BBQJIT::shiftI64Helper(ShiftI64HelperOp op, Location lhsLocation, Location } else if (op == ShiftI64HelperOp::Urshift) { m_jit.urshift32(lhsLocation.asGPRhi(), shift, resultLocation.asGPRlo()); m_jit.xor32(resultLocation.asGPRhi(), resultLocation.asGPRhi()); - } else if (op ==ShiftI64HelperOp::Rshift) { + } else if (op == ShiftI64HelperOp::Rshift) { ASSERT(resultLocation.asGPRlo() != lhsLocation.asGPRhi()); m_jit.rshift32(lhsLocation.asGPRhi(), shift, resultLocation.asGPRlo()); m_jit.rshift32(lhsLocation.asGPRhi(), TrustedImm32(31), resultLocation.asGPRhi()); From 1438b5383d8a453c897890901af3b0795369c2e7 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Fri, 5 Sep 2025 05:31:48 -0700 Subject: [PATCH 19/54] [ARMv7] Opt out of LLD on 32-bits https://bugs.webkit.org/show_bug.cgi?id=298390 Reviewed by Adrian Perez de Castro. LLD runs out of address space when trying to link on 32-bits. Opt out of using it when that's the case, at least for ARMv7. Canonical link: https://commits.webkit.org/299619@main (cherry picked from commit 741df3fb836f6f6148c9bef4d53b168c14552309) --- Source/cmake/OptionsCommon.cmake | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Source/cmake/OptionsCommon.cmake b/Source/cmake/OptionsCommon.cmake index bd2055ca2950..da627816d6a4 100644 --- a/Source/cmake/OptionsCommon.cmake +++ b/Source/cmake/OptionsCommon.cmake @@ -34,10 +34,23 @@ if (WTF_CPU_ARM) endif () endif () +# NB: We can't use CMAKE_HOST_SYSTEM_PROCESSOR as its value is on armv8l is +# "aarch64". Also, `uname` is not available on Windows, but Windows doesn't +# currently use this variable. +execute_process(COMMAND uname -m OUTPUT_VARIABLE WTF_HOST_SYSTEM_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE) + +if ("${WTF_HOST_SYSTEM_MACHINE}" MATCHES "^armv[78]") + set(BUILDING_ON_32_BITS TRUE) +else () + set(BUILDING_ON_32_BITS FALSE) +endif () + +set(LLD_UNUSABLE_BECAUSE_OF_ADDRESS_SPACE_EXHAUSTION ${BUILDING_ON_32_BITS}) + # Use ld.lld when building with LTO, or for debug builds, if available. # FIXME: With CMake 3.22+ full conditional syntax can be used in # cmake_dependent_option() -if (LTO_MODE OR DEVELOPER_MODE) +if (LTO_MODE OR DEVELOPER_MODE AND (NOT LLD_UNUSABLE_BECAUSE_OF_ADDRESS_SPACE_EXHAUSTION)) set(TRY_USE_LD_LLD ON) endif () CMAKE_DEPENDENT_OPTION(USE_LD_LLD "Use LLD linker" ON From 5f1bffb5e85e63fe9d04fd515eccd09476bbf122 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Thu, 25 Sep 2025 22:00:25 -0700 Subject: [PATCH 20/54] [ARMv7] Preserve return address without ISA mode bit https://bugs.webkit.org/show_bug.cgi?id=299515 Reviewed by Yusuke Suzuki. On ARMv7, the least significant bit in the link register indicates the mode (ARM/Thumb) of the code that we return to. Callers of preserveReturnAddressAfterCall care about the return address and when calling the throwExceptionFromOMGThunk (as introduced in 300298@main) the LSB being set results in a return address outside the function, whose CallSiteIndex can therefore not be looked up. Simply clear the LSB when preserving the return address on ARMv7. Canonical link: https://commits.webkit.org/300555@main (cherry picked from commit 4d672bf7ca92bcdf9ceac15576d4443c36343476) --- Source/JavaScriptCore/jit/AssemblyHelpers.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/JavaScriptCore/jit/AssemblyHelpers.h b/Source/JavaScriptCore/jit/AssemblyHelpers.h index 6dc930310825..ddc2126dcf09 100644 --- a/Source/JavaScriptCore/jit/AssemblyHelpers.h +++ b/Source/JavaScriptCore/jit/AssemblyHelpers.h @@ -554,10 +554,19 @@ class AssemblyHelpers : public MacroAssembler { emitFunctionEpilogueWithEmptyFrame(); } +#if CPU(ARM_THUMB2) + ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg) + { + // Clear LSB in LR; it's not part of the return address, it only + // signifies that we return to Thumb code. + and32(TrustedImm32(0xfffffffe), linkRegister, reg); + } +#else ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg) { move(linkRegister, reg); } +#endif ALWAYS_INLINE void restoreReturnAddressBeforeReturn(RegisterID reg) { From e10c8ea43c735d5d6676a4cf7b5d086b15eedb97 Mon Sep 17 00:00:00 2001 From: Efe Can Icoz Date: Tue, 7 Oct 2025 04:30:50 -0700 Subject: [PATCH 21/54] Thumb mode not detected on gcc for arm https://bugs.webkit.org/show_bug.cgi?id=300217 Reviewed by Adrian Perez de Castro. Add "-mthumb" flag to GCC to enable compiling thumb2 instruction set if supported. * Source/cmake/OptionsCommon.cmake: Canonical link: https://commits.webkit.org/301124@main (cherry picked from commit 5528017994db81391afaba90dc2c1909d1d8842f) --- Source/cmake/OptionsCommon.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmake/OptionsCommon.cmake b/Source/cmake/OptionsCommon.cmake index da627816d6a4..3ddab5906e12 100644 --- a/Source/cmake/OptionsCommon.cmake +++ b/Source/cmake/OptionsCommon.cmake @@ -20,7 +20,7 @@ if (WTF_CPU_ARM) int main() {} ") - if (COMPILER_IS_CLANG AND NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")) + if (COMPILER_IS_GCC_OR_CLANG AND NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")) set(CLANG_EXTRA_ARM_ARGS " -mthumb") endif () From 959dfa77acd2ff911a47c25c79491ba77e738658 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Tue, 14 Oct 2025 07:39:31 -0700 Subject: [PATCH 22/54] [JSC][32-bit] Fix missing move when shift == 0 in BBQ https://bugs.webkit.org/show_bug.cgi?id=300509 Reviewed by Justin Michaud. In shiftI64Helper, we would check if the shift amount was zero and just jump to the end, without moving the lhs to the result. No new tests, but this was found when analysing the crash in JetStream3's tfjs-wasm.js. 32-bit JSC still crashes when running that test but this gets us a little bit further. * Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp: (JSC::Wasm::BBQJITImpl::BBQJIT::shiftI64Helper): Canonical link: https://commits.webkit.org/301475@main (cherry picked from commit 3fcedc7fe6c82ffdda06219e621b38dda67bdf58) --- Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp index edda87da1269..eeb5bb6611cb 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp @@ -2308,6 +2308,7 @@ void BBQJIT::shiftI64Helper(ShiftI64HelperOp op, Location lhsLocation, Location m_jit.and32(TrustedImm32(63), rhsLocation.asGPRlo(), shift); auto zero = m_jit.branch32(RelationalCondition::Equal, shift, TrustedImm32(0)); auto aboveOrEqual32 = m_jit.branch32(RelationalCondition::AboveOrEqual, shift, TrustedImm32(32)); + // shift < 32 auto carry = scratches.gpr(0); m_jit.move(TrustedImm32(32), carry); @@ -2334,7 +2335,10 @@ void BBQJIT::shiftI64Helper(ShiftI64HelperOp op, Location lhsLocation, Location m_jit.urshift32(lhsLocation.asGPRlo(), shift, resultLocation.asGPRlo()); m_jit.or32(carry, resultLocation.asGPRlo()); } - auto done = m_jit.jump(); + + JumpList done; + done.append(m_jit.jump()); + // shift >= 32 aboveOrEqual32.link(&m_jit); m_jit.sub32(shift, TrustedImm32(32), shift); @@ -2349,8 +2353,15 @@ void BBQJIT::shiftI64Helper(ShiftI64HelperOp op, Location lhsLocation, Location m_jit.rshift32(lhsLocation.asGPRhi(), shift, resultLocation.asGPRlo()); m_jit.rshift32(lhsLocation.asGPRhi(), TrustedImm32(31), resultLocation.asGPRhi()); } + // The following move is only emitted if the lhs != res, so when they are the same, we + // can just fallthrough + if (lhsLocation != resultLocation) + done.append(m_jit.jump()); + // shift == 0 zero.link(&m_jit); + emitMove(TypeKind::I64, lhsLocation, resultLocation); + done.link(&m_jit); } From 91cabb8d17684729ae7d3d86825f135e189cc709 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Wed, 15 Oct 2025 05:25:28 -0700 Subject: [PATCH 23/54] [JSC] Added missing r3 store on armv7's jit.print https://bugs.webkit.org/show_bug.cgi?id=300707 Reviewed by Justin Michaud. r3 was missing from the list of registers being saved before the print call. * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp: (JSC::MacroAssembler::probe): Canonical link: https://commits.webkit.org/301546@main (cherry picked from commit 44ac40fabf2f69513ed206b8787356612f8874eb) --- Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp index a29367a90250..56a3d5c706d9 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp @@ -194,6 +194,8 @@ struct IncomingRecord { uintptr_t r0; uintptr_t r1; uintptr_t r2; + uintptr_t r3; + uintptr_t alignmentPadding; }; #define IN_LR_OFFSET (0 * PTR_SIZE) @@ -202,7 +204,9 @@ struct IncomingRecord { #define IN_R0_OFFSET (3 * PTR_SIZE) #define IN_R1_OFFSET (4 * PTR_SIZE) #define IN_R2_OFFSET (5 * PTR_SIZE) -#define IN_SIZE (6 * PTR_SIZE) +#define IN_R3_OFFSET (6 * PTR_SIZE) +#define IN_ALIGNMENT_PADDING_OFFSET (7 * PTR_SIZE) +#define IN_SIZE (8 * PTR_SIZE) static_assert(IN_LR_OFFSET == offsetof(IncomingRecord, lr), "IN_LR_OFFSET is incorrect"); static_assert(IN_IP_OFFSET == offsetof(IncomingRecord, ip), "IN_IP_OFFSET is incorrect"); @@ -210,6 +214,8 @@ static_assert(IN_APSR_OFFSET == offsetof(IncomingRecord, apsr), "IN_APSR_OFFSET static_assert(IN_R0_OFFSET == offsetof(IncomingRecord, r0), "IN_R0_OFFSET is incorrect"); static_assert(IN_R1_OFFSET == offsetof(IncomingRecord, r1), "IN_R1_OFFSET is incorrect"); static_assert(IN_R2_OFFSET == offsetof(IncomingRecord, r2), "IN_R2_OFFSET is incorrect"); +static_assert(IN_R3_OFFSET == offsetof(IncomingRecord, r3), "IN_R3_OFFSET is incorrect"); +static_assert(IN_ALIGNMENT_PADDING_OFFSET == offsetof(IncomingRecord, alignmentPadding), "IN_ALIGNMENT_PADDING_OFFSET is incorrect"); static_assert(IN_SIZE == sizeof(IncomingRecord), "IN_SIZE is incorrect"); asm ( @@ -375,6 +381,7 @@ void MacroAssembler::probe(Probe::Function function, void* arg, SavedFPWidth) store32(r0, Address(sp, offsetof(IncomingRecord, r0))); store32(r1, Address(sp, offsetof(IncomingRecord, r1))); store32(r2, Address(sp, offsetof(IncomingRecord, r2))); + store32(r3, Address(sp, offsetof(IncomingRecord, r3))); // The following may emit a T1 mov instruction, which is effectively a movs. // This means we must first preserve the apsr flags above first. From 43159f99672bb415f9e210546974275f8b35f7a5 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Fri, 24 Oct 2025 00:36:15 -0700 Subject: [PATCH 24/54] [run-javascriptcore-tests] Allow running armv7 tests on native aarch64 https://bugs.webkit.org/show_bug.cgi?id=301350 Reviewed by Justin Michaud. This is convenient to be able to run the tests after cross-building for ARMv7 on an aarch64 box that can natively run ARMv7 binaries. Canonical link: https://commits.webkit.org/302076@main (cherry picked from commit 0713bc1a8923961b69ba02d84239754647c0c141) --- Tools/Scripts/run-javascriptcore-tests | 7 ++++--- Tools/Scripts/webkitdirs.pm | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Tools/Scripts/run-javascriptcore-tests b/Tools/Scripts/run-javascriptcore-tests index 920cd1b463c8..2fe99635692d 100755 --- a/Tools/Scripts/run-javascriptcore-tests +++ b/Tools/Scripts/run-javascriptcore-tests @@ -583,7 +583,7 @@ if (defined $archs) { # For running tests, arm64e should map to arm64 $archs = "arm64" if $archs eq "arm64e"; -if ($archs ne nativeArchitecture($remotes) && (nativeArchitecture($remotes) ne "arm64" || !isAppleMacWebKit())) { +if ($archs ne nativeArchitecture($remotes) && (nativeArchitecture($remotes) ne "arm64")) { die "Cannot run tests with $archs on this machine"; } @@ -665,7 +665,7 @@ sub runTest { unshift @command, $artifact_exec_wrapper; } unshift @command, ("xcrun", "-sdk", xcodeSDK(), "sim") if willUseIOSSimulatorSDK(); - unshift @command, ("/usr/bin/arch", "-$archs") if $archs ne nativeArchitecture($remotes); + unshift @command, ("/usr/bin/arch", "-$archs") if isAppleMacWebKit() && $archs ne nativeArchitecture($remotes); unshift @command, wrapperPrefixIfNeeded() if isGtk() or isWPE(); if ($envVars ne "") { @@ -833,7 +833,8 @@ sub runJSCStressTests "/usr/bin/env", "ruby", "Tools/Scripts/run-jsc-stress-tests", "-j", jscPath($productDir), "-o", $jscStressResultsDir, "--arch", $archs); - if (nativeArchitecture($remotes) ne $archs) { + if (isAppleMacWebKit() && nativeArchitecture($remotes) ne $archs) { + # Forces use of the Mac-specific /usr/bin/arch in run-jsc-stress-tests. push(@jscStressDriverCmd, "--force-architecture"); push(@jscStressDriverCmd, $archs); } diff --git a/Tools/Scripts/webkitdirs.pm b/Tools/Scripts/webkitdirs.pm index 1f159b9d831c..aaee3c5276ef 100755 --- a/Tools/Scripts/webkitdirs.pm +++ b/Tools/Scripts/webkitdirs.pm @@ -534,6 +534,7 @@ sub determineNativeArchitecture($) $output = "arm64"; } + $output = "arm64" if $output =~ m/^aarch64$/; $output = "arm" if $output =~ m/^armv[78]l$/; $nativeArchitectureMap{@{$remotes}} = $output; } From 938492fc2a4615507951a15faa42ef7981248bdd Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Tue, 11 Nov 2025 13:29:56 -0800 Subject: [PATCH 25/54] [JSC][32-bit] Fix BBQ's I64Or https://bugs.webkit.org/show_bug.cgi?id=301931 Reviewed by Justin Michaud. When running JS3 I noticed the following code: [ 0x22d] I64Or 0xf1b953fa: orr.w r1, r2, r4 0xf1b953fe: orr.w r0, r1, r3 Here, lhs is (r1, r2), rhs is (r3, r4) and result is (r0, r1), so when we write to resultHi (r1), we override the value in lhs, then read it again in the second orr, leading to a wrong result. This patch implements i64or in the ARMv7 backend and fixes this problem by calculating the low or to a scratch, calculating hi to the destination, then moving the low or from the scratch to the destination. * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::or64): * Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp: (JSC::Wasm::BBQJITImpl::BBQJIT::addI64Or): Canonical link: https://commits.webkit.org/302862@main (cherry picked from commit c977165dfa4c852c7b6b029d8fc7be710cebd8a3) --- .../JavaScriptCore/assembler/MacroAssemblerARMv7.h | 13 +++++++++++++ Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp | 3 +-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index fc8357409f72..65ccbd8f6dbc 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -540,6 +540,19 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { } } + void or64(RegisterID op1Hi, RegisterID op1Lo, RegisterID op2Hi, RegisterID op2Lo, RegisterID destHi, RegisterID destLo) + { + if (destLo != op1Hi && destLo != op2Hi) { + m_assembler.orr(destLo, op1Lo, op2Lo); + m_assembler.orr(destHi, op1Hi, op2Hi); + } else { + RegisterID scratch = getCachedDataTempRegisterIDAndInvalidate(); + m_assembler.orr(scratch, op1Lo, op2Lo); + m_assembler.orr(destHi, op1Hi, op2Hi); + move(scratch, destLo); + } + } + void rotateRight32(RegisterID op1, RegisterID op2, RegisterID dest) { m_assembler.ror(dest, op1, op2); diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp index eeb5bb6611cb..d7d42ccd063d 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQJIT32_64.cpp @@ -2237,8 +2237,7 @@ PartialResult WARN_UNUSED_RETURN BBQJIT::addI64Or(Value lhs, Value rhs, Value& r "I64Or", TypeKind::I64, BLOCK(Value::fromI64(lhs.asI64() | rhs.asI64())), BLOCK( - m_jit.or32(lhsLocation.asGPRhi(), rhsLocation.asGPRhi(), resultLocation.asGPRhi()); - m_jit.or32(lhsLocation.asGPRlo(), rhsLocation.asGPRlo(), resultLocation.asGPRlo()); + m_jit.or64(lhsLocation.asGPRhi(), lhsLocation.asGPRlo(), rhsLocation.asGPRhi(), rhsLocation.asGPRlo(), resultLocation.asGPRhi(), resultLocation.asGPRlo()); ), BLOCK( m_jit.move(ImmHelpers::regLocation(lhsLocation, rhsLocation).asGPRhi(), resultLocation.asGPRhi()); From 2c38e34d56a195230f9c565afc07ca7626d758f3 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Fri, 14 Nov 2025 09:41:42 -0800 Subject: [PATCH 26/54] [JSC][ARMv7] Don't issue a ldrd when the register holding the address is also a destination https://bugs.webkit.org/show_bug.cgi?id=302469 Reviewed by Justin Michaud. This patch expands a ldrd into a pair of ldr if any of the destination registers is also the register holding the memory address. Before: 0xf1502462: ldrd r0, r1, [r0] After: 0xf1502462: ldr r1, [r0, #4] 0xf1502464: ldr r0, [r0] * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::loadPair32): Canonical link: https://commits.webkit.org/303043@main (cherry picked from commit 93ba069cf1bab91677362638030f126820ef373a) --- .../assembler/MacroAssemblerARMv7.h | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 65ccbd8f6dbc..aa763a8a074a 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -1093,23 +1093,32 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { loadPair32(Address(scratch), dest1, dest2); } else { ASSERT(dest1 != dest2); // If it is the same, ldp becomes illegal instruction. - int32_t absOffset = address.u.offset; - if (absOffset < 0) - absOffset = -absOffset; - if (!(absOffset & ~0x3fc)) { - if ((dest1 == addressTempRegister) || (dest2 == addressTempRegister)) - invalidateCachedAddressTempRegister(); - if ((dest1 == dataTempRegister) || (dest2 == dataTempRegister)) - cachedDataTempRegister().invalidate(); - m_assembler.ldrd(dest1, dest2, address.base, address.u.offset, /* index: */ true, /* wback: */ false); - } else if (address.base == dest1) { + // Check if dest1 or dest2 aliases the base register to avoid UNPREDICTABLE ldrd behavior + if (address.base == dest1) { + // Load high word first to avoid clobbering base register ArmAddress highAddress(address.base, address.u.offset + 4); load32(highAddress, dest2); load32(address, dest1); - } else { + } else if (address.base == dest2) { + // Load low word first to avoid clobbering base register load32(address, dest1); ArmAddress highAddress(address.base, address.u.offset + 4); load32(highAddress, dest2); + } else { + int32_t absOffset = address.u.offset; + if (absOffset < 0) + absOffset = -absOffset; + if (!(absOffset & ~0x3fc)) { + if ((dest1 == addressTempRegister) || (dest2 == addressTempRegister)) + invalidateCachedAddressTempRegister(); + if ((dest1 == dataTempRegister) || (dest2 == dataTempRegister)) + cachedDataTempRegister().invalidate(); + m_assembler.ldrd(dest1, dest2, address.base, address.u.offset, /* index: */ true, /* wback: */ false); + } else { + load32(address, dest1); + ArmAddress highAddress(address.base, address.u.offset + 4); + load32(highAddress, dest2); + } } } } From aa5da394dd39c8ea0ee291945676eb83df9121cd Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Thu, 20 Nov 2025 06:47:51 -0800 Subject: [PATCH 27/54] [JSC][32-bit] Optimize test32 and compare32 with branchless code generation https://bugs.webkit.org/show_bug.cgi?id=302016 Reviewed by Justin Michaud. This PR replace IT blocks with branchless instruction sequences for common test32 and compare32 operations. This PR also removes NOPs in conditional moves via condition inversions, and adds assertions for invalid Carry/Overflow conditions (tst doesn't set these flags). * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::invert): (JSC::MacroAssemblerARMv7::commuteCompareToZeroIntoTest): (JSC::MacroAssemblerARMv7::branch32): (JSC::MacroAssemblerARMv7::compare32): (JSC::MacroAssemblerARMv7::test32): (JSC::MacroAssemblerARMv7::moveConditionally32): (JSC::MacroAssemblerARMv7::moveConditionallyTest32): (JSC::MacroAssemblerARMv7::moveDoubleConditionally32): (JSC::MacroAssemblerARMv7::moveDoubleConditionallyTest32): (JSC::MacroAssemblerARMv7::moveDoubleOrNop): Deleted. (JSC::MacroAssemblerARMv7::moveOrNop): Deleted. Canonical link: https://commits.webkit.org/303329@main (cherry picked from commit 3baaaee049d934750e4ac547eb41a2d3eb421df1) --- .../assembler/MacroAssemblerARMv7.h | 359 ++++++++++++++---- 1 file changed, 295 insertions(+), 64 deletions(-) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index aa763a8a074a..ebdd81810a69 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -29,6 +29,7 @@ #if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2) #include +#include #include "ARMv7Assembler.h" #include "AbstractMacroAssembler.h" @@ -1664,14 +1665,6 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { move64ToDouble(scratch2, scratch1, dest); } - void moveDoubleOrNop(FPRegisterID src, FPRegisterID dest) - { - if (src != dest) - m_assembler.vmov(dest, src); - else - nop(); - } - void moveZeroToFloat(FPRegisterID reg) { static double zeroConstant = 0.; @@ -2314,18 +2307,6 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { invalidateCachedAddressTempRegister(); } - // For use in IT blocks, where we need to generate an instruction even if - // src == dest. This should be pretty uncommon, so it's simpler to generate - // a nop. - void moveOrNop(RegisterID src, RegisterID dest) - { - if (src == dest) { - nop(); - return; - } - move(src, dest); - } - void move(TrustedImmPtr imm, RegisterID dest) { move(TrustedImm32(imm), dest); @@ -2388,6 +2369,27 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { return static_cast(cond ^ 1); } + static ResultCondition invert(ResultCondition cond) + { + return static_cast(cond ^ 1); + } + + static std::optional commuteCompareToZeroIntoTest(RelationalCondition cond) + { + switch (cond) { + case Equal: + return Zero; + case NotEqual: + return NonZero; + case LessThan: + return Signed; + case GreaterThanOrEqual: + return PositiveOrZero; + default: + return std::nullopt; + } + } + void nop() { m_assembler.nop(); @@ -2583,6 +2585,11 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right) { + if (!right.m_value) { + if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) + return branchTest32(*resultCondition, left, left); + } + compare32AndSetFlags(left, right); return Jump(makeBranch(cond)); } @@ -3080,6 +3087,13 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) { + if (!right.m_value) { + if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) { + test32(*resultCondition, left, left, dest); + return; + } + } + compare32AndSetFlags(left, right); m_assembler.it(armV7Condition(cond), false); m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1)); @@ -3128,31 +3142,143 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { void test32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest) { - m_assembler.tst(op1, op2); - m_assembler.it(armV7Condition(cond), false); - m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1)); - m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0)); + switch (cond) { + case Zero: + if (op1 == op2) { + m_assembler.clz(dest, op1); + m_assembler.lsr(dest, dest, 5); + } else { + m_assembler.eor(dest, op1, op2); + m_assembler.clz(dest, dest); + m_assembler.lsr(dest, dest, 5); + } + return; + + case NonZero: + if (op1 == op2) { + m_assembler.clz(dest, op1); + m_assembler.lsr(dest, dest, 5); + m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); + } else { + m_assembler.eor(dest, op1, op2); + m_assembler.clz(dest, dest); + m_assembler.lsr(dest, dest, 5); + m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); + } + return; + + case Signed: + if (op1 == op2) + m_assembler.lsr(dest, op1, 31); + else { + m_assembler.ARM_and(dest, op1, op2); + m_assembler.lsr(dest, dest, 31); + } + return; + + case PositiveOrZero: + if (op1 == op2) { + m_assembler.lsr(dest, op1, 31); + m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); + } else { + m_assembler.ARM_and(dest, op1, op2); + m_assembler.lsr(dest, dest, 31); + m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); + } + return; + + default: + // tst instruction doesn't set Carry or Overflow flags + RELEASE_ASSERT_NOT_REACHED(); + break; + } } void test32(ResultCondition cond, RegisterID op1, TrustedImm32 mask, RegisterID dest) { - test32(op1, mask); - m_assembler.it(armV7Condition(cond), false); - m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1)); - m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0)); + // Special case: mask == -1 is equivalent to testing register against itself + if (mask.m_value == -1) { + test32(cond, op1, op1, dest); + return; + } + + // Special case: mask == 0x80000000 is sign bit testing + if (mask.m_value == static_cast(0x80000000)) { + switch (cond) { + case NonZero: + case Signed: + m_assembler.lsr(dest, op1, 31); + return; + case Zero: + case PositiveOrZero: + m_assembler.lsr(dest, op1, 31); + m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); + return; + default: + // tst instruction doesn't set Carry or Overflow flag + RELEASE_ASSERT_NOT_REACHED(); + } + } + + switch (cond) { + case Zero: { + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(mask.m_value); + if (armImm.isValid()) + m_assembler.ARM_and(dest, op1, armImm); + else { + move(mask, dest); + m_assembler.ARM_and(dest, op1, dest); + } + m_assembler.clz(dest, dest); + m_assembler.lsr(dest, dest, 5); + return; + } + case NonZero: { + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(mask.m_value); + if (armImm.isValid()) + m_assembler.ARM_and(dest, op1, armImm); + else { + move(mask, dest); + m_assembler.ARM_and(dest, op1, dest); + } + m_assembler.clz(dest, dest); + m_assembler.lsr(dest, dest, 5); + m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); + return; + } + case Signed: { + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(mask.m_value); + if (armImm.isValid()) + m_assembler.ARM_and(dest, op1, armImm); + else { + move(mask, dest); + m_assembler.ARM_and(dest, op1, dest); + } + m_assembler.lsr(dest, dest, 31); + return; + } + case PositiveOrZero: { + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(mask.m_value); + if (armImm.isValid()) + m_assembler.ARM_and(dest, op1, armImm); + else { + move(mask, dest); + m_assembler.ARM_and(dest, op1, dest); + } + m_assembler.lsr(dest, dest, 31); + m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); + return; + } + default: + // tst instruction doesn't set Carry or Overflow flag + RELEASE_ASSERT_NOT_REACHED(); + } } - // FIXME: - // The mask should be optional... paerhaps the argument order should be - // dest-src, operations always have a dest? ... possibly not true, considering - // asm ops like test, or pseudo ops like pop(). void test32(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest) { load32(address, addressTempRegister); - test32(addressTempRegister, mask); - m_assembler.it(armV7Condition(cond), false); - m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1)); - m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0)); + test32(cond, addressTempRegister, mask, dest); } void test8(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest) @@ -3168,25 +3294,61 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID src, RegisterID dest) { + if (src == dest) + return; + m_assembler.cmp(left, right); m_assembler.it(armV7Condition(cond)); - moveOrNop(src, dest); + move(src, dest); } void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) { + if (thenCase == elseCase) { + move(thenCase, dest); + return; + } + m_assembler.cmp(left, right); - m_assembler.it(armV7Condition(cond), false); - moveOrNop(thenCase, dest); - moveOrNop(elseCase, dest); + if (thenCase == dest) { + m_assembler.it(armV7Condition(invert(cond))); + move(elseCase, dest); + } else if (elseCase == dest) { + m_assembler.it(armV7Condition(cond)); + move(thenCase, dest); + } else { + m_assembler.it(armV7Condition(cond), false); + move(thenCase, dest); + move(elseCase, dest); + } } void moveConditionally32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) { + if (thenCase == elseCase) { + move(thenCase, dest); + return; + } + + if (!right.m_value) { + if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) { + moveConditionallyTest32(*resultCondition, left, left, thenCase, elseCase, dest); + return; + } + } + compare32AndSetFlags(left, right); - m_assembler.it(armV7Condition(cond), false); - moveOrNop(thenCase, dest); - moveOrNop(elseCase, dest); + if (thenCase == dest) { + m_assembler.it(armV7Condition(invert(cond))); + move(elseCase, dest); + } else if (elseCase == dest) { + m_assembler.it(armV7Condition(cond)); + move(thenCase, dest); + } else { + m_assembler.it(armV7Condition(cond), false); + move(thenCase, dest); + move(elseCase, dest); + } } void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest) @@ -3200,18 +3362,14 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { void moveConditionallyTest32(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) { - // These are all correctness checks. We use an IT block, so we need to - // generate a specific number of instructions. Specifically, move(x, x) - // would not generate an instruction, so the IT block would apply to - // some later, unrelated instruction. if (thenCase == elseCase) { move(thenCase, dest); return; } + m_assembler.tst(left, right); if (thenCase == dest) { - m_assembler.it(armV7Condition(cond), false); - nop(); + m_assembler.it(armV7Condition(invert(cond))); move(elseCase, dest); } else if (elseCase == dest) { m_assembler.it(armV7Condition(cond)); @@ -3225,42 +3383,115 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { void moveConditionallyTest32(ResultCondition cond, RegisterID left, TrustedImm32 right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) { + // easy case: both assignments are the same, so we just ignore the condition + if (thenCase == elseCase) { + move(thenCase, dest); + return; + } + test32(left, right); - m_assembler.it(armV7Condition(cond), false); - moveOrNop(thenCase, dest); - moveOrNop(elseCase, dest); + if (thenCase == dest) { + m_assembler.it(armV7Condition(invert(cond))); + move(elseCase, dest); + } else if (elseCase == dest) { + m_assembler.it(armV7Condition(cond)); + move(thenCase, dest); + } else { + m_assembler.it(armV7Condition(cond), false); + move(thenCase, dest); + move(elseCase, dest); + } } void moveDoubleConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest) { + if (thenCase == elseCase) { + moveDouble(thenCase, dest); + return; + } + m_assembler.cmp(left, right); - m_assembler.it(armV7Condition(cond), false); - moveDoubleOrNop(thenCase, dest); - moveDoubleOrNop(elseCase, dest); + if (thenCase == dest) { + m_assembler.it(armV7Condition(invert(cond))); + moveDouble(elseCase, dest); + } else if (elseCase == dest) { + m_assembler.it(armV7Condition(cond)); + moveDouble(thenCase, dest); + } else { + m_assembler.it(armV7Condition(cond), false); + moveDouble(thenCase, dest); + moveDouble(elseCase, dest); + } } void moveDoubleConditionally32(RelationalCondition cond, RegisterID left, TrustedImm32 right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest) { + if (thenCase == elseCase) { + moveDouble(thenCase, dest); + return; + } + + if (!right.m_value) { + if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) { + moveDoubleConditionallyTest32(*resultCondition, left, left, thenCase, elseCase, dest); + return; + } + } + compare32AndSetFlags(left, right); - m_assembler.it(armV7Condition(cond), false); - moveDoubleOrNop(thenCase, dest); - moveDoubleOrNop(elseCase, dest); + if (thenCase == dest) { + m_assembler.it(armV7Condition(invert(cond))); + moveDouble(elseCase, dest); + } else if (elseCase == dest) { + m_assembler.it(armV7Condition(cond)); + moveDouble(thenCase, dest); + } else { + m_assembler.it(armV7Condition(cond), false); + moveDouble(thenCase, dest); + moveDouble(elseCase, dest); + } } void moveDoubleConditionallyTest32(ResultCondition cond, RegisterID left, RegisterID right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest) { + if (thenCase == elseCase) { + moveDouble(thenCase, dest); + return; + } + m_assembler.tst(left, right); - m_assembler.it(armV7Condition(cond), false); - moveDoubleOrNop(thenCase, dest); - moveDoubleOrNop(elseCase, dest); + if (thenCase == dest) { + m_assembler.it(armV7Condition(invert(cond))); + moveDouble(elseCase, dest); + } else if (elseCase == dest) { + m_assembler.it(armV7Condition(cond)); + moveDouble(thenCase, dest); + } else { + m_assembler.it(armV7Condition(cond), false); + moveDouble(thenCase, dest); + moveDouble(elseCase, dest); + } } void moveDoubleConditionallyTest32(ResultCondition cond, RegisterID left, TrustedImm32 right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest) { + if (thenCase == elseCase) { + moveDouble(thenCase, dest); + return; + } + test32(left, right); - m_assembler.it(armV7Condition(cond), false); - moveDoubleOrNop(thenCase, dest); - moveDoubleOrNop(elseCase, dest); + if (thenCase == dest) { + m_assembler.it(armV7Condition(invert(cond))); + moveDouble(elseCase, dest); + } else if (elseCase == dest) { + m_assembler.it(armV7Condition(cond)); + moveDouble(thenCase, dest); + } else { + m_assembler.it(armV7Condition(cond), false); + moveDouble(thenCase, dest); + moveDouble(elseCase, dest); + } } ALWAYS_INLINE DataLabel32 moveWithPatch(TrustedImm32 imm, RegisterID dst) From 0dbb52547428b86736fb60a74829198c99f93d93 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 14 Jan 2026 06:29:38 -0800 Subject: [PATCH 28/54] [32-bit] Armv7 tail call shuffler should not run out of registers when loading cells. https://bugs.webkit.org/show_bug.cgi?id=305427 Reviewed by Yusuke Suzuki. Patch by @emutavchi downstream: https://github.com/WebPlatformForEmbedded/WPEWebKit/pull/1593. We find ourselves in a state where canLoad says yes, because our JSValue can be loaded via FPR, but we choose to load it via GPR instead because we do not have two gprs free. This inconsistency causes an assertion failure, and incorrect tail call shuffling. This can only happen if loadsIntoFPR is true, but loadsIntoGPR is false. In addition, everything DisplacedInJSStack must either have loadsIntoFPR or loadsIntoGPR, so no other corner cases need to be considered. Canonical link: https://commits.webkit.org/305572@main (cherry picked from commit 9cc23c0e75b77974539bcb414eacef33bf94ed02) --- JSTests/stress/tail-call-register-pressure.js | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 JSTests/stress/tail-call-register-pressure.js diff --git a/JSTests/stress/tail-call-register-pressure.js b/JSTests/stress/tail-call-register-pressure.js new file mode 100644 index 000000000000..721c6eac5fae --- /dev/null +++ b/JSTests/stress/tail-call-register-pressure.js @@ -0,0 +1,137 @@ +"use strict"; + +function getModuleExports() { + return () => {} +}; + +function ownKeys(ee, te) { + var re = Object.keys(ee); + if (Object.getOwnPropertySymbols) { + var ne = Object.getOwnPropertySymbols(ee); + te && (ne = ne.filter((function(te) { + return Object.getOwnPropertyDescriptor(ee, te).enumerable + }))), + re.push.apply(re, ne) + } + return re +} + +function _objectSpread(ee) { + for (var te = 1; te < arguments.length; te++) { + var re = null != arguments[te] ? arguments[te] : {}; + te % 2 ? ownKeys(Object(re), !0).forEach((function(te) { + getModuleExports()(ee, te, re[te]) + })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(ee, Object.getOwnPropertyDescriptors(re)) : ownKeys(Object(re)).forEach((function(te) { + Object.defineProperty(ee, te, Object.getOwnPropertyDescriptor(re, te)) + })) + } + return ee +} + +var ae = { + cleanAndTrimSelfLink: function() { + } +}; + +var browseItems = function(ee, te, re) { + function parseBrowseItem(ee, te, re, ne, ie) { + var ce, le, de, he; + if (ee.hasEmbedded("linearInfo")) { + var fe = ee.getEmbedded("linearInfo"), + pe = Object(ae.cleanSelfLink)(fe.getFirstAction("channel").getRawActionUrl()); + if (!ne[pe] && !ie) return; + } + + var ge = function parseBrowseItemUrl(ee, te) { + var re = ee.getProp("entityId"), + ne = ee.getProp("entityType"), + ie = ee.getProp("seriesProgramId"), + oe = ee.getProp("_type"); + return "entity/".concat(re) + }(ee, he), + me = ee.getProps(); + if (("NETWORK" !== te || ee.hasEmbedded("contentProvider")) && ("3X4_PROGRAM_LINEAR" !== te || ee.hasEmbedded("linearInfo"))) { + var ve = ee.hasAction("programImageLink") ? ee.getFirstAction("programImageLink") : re.programImageLink, + Se = ee.hasAction("programFallbackImageLink"), + _t = Se ? ee.getFirstAction("programFallbackImageLink") : re.programFallbackImageLink; + + var Et, kt, Tt, Pt = _t.setParams(de).getActionUrl(); + return Et = Se ? Pt : ve.setParams(de).getActionUrl(), me.contentRating && me.contentRatingScheme && (kt = { + scheme: me.contentRatingScheme, + name: me.contentRating + }), (null === (ce = me.ordering) || void 0 === ce ? void 0 : ce.criticScore) && (null === (le = me.ordering) || void 0 === le ? void 0 : le.fanScore) && (Tt = { + rt: { + criticScore: Math.floor(me.ordering.criticScore), + criticCertified: Math.floor(me.ordering.criticScore) >= 75, + criticRotten: Math.floor(me.ordering.criticScore) < 60, + fanScore: Math.floor(me.ordering.fanScore), + fanRotten: Math.floor(me.ordering.fanScore) < 60 + } + }), _objectSpread({ + _type: me._type + }, me.adBrand && { + adBrand: me.adBrand + }, {}, me.entityId && { + entityId: me.entityId + }, {}, me.entityType && { + entityType: me.entityType + }, {}, me.episodeNumber && { + episodeNumber: me.episodeNumber + }, {}, he && { + linearInfo: he + }, {}, me.numberOfEpisodes && { + numberOfEpisodes: me.numberOfEpisodes + }, {}, me.programType && { + programType: me.programType + }, {}, kt && { + rating: kt + }, {}, Tt && { + reviews: Tt + }, {}, me.hasDVS && { + dvs: me.hasDVS + }, {}, me.isHD && { + hd: me.isHD + }, {}, me.closedCaption && { + cc: me.closedCaption + }, {}, me.isSAP && { + sap: me.isSAP + }, {}, me.releaseYear && { + releaseYear: me.releaseYear + }, {}, me.seasonNumber && { + seasonNumber: me.seasonNumber + }, {}, me.seriesTitle && { + seriesTitle: me.seriesTitle + }, {}, { + tileRenderStyle: me.tileRenderStyle || te, + title: me.title, + subtitle: me.subtitle, + image: Et, + fallbackImage: Pt, + url: ge + }) + } + } + + return parseBrowseItem(ee, te, re,{},{}) +} + +const runTest = function() { + for (var i = 1; i < 100; ++i) { + browseItems( + { + hasAction: () => {}, + hasEmbedded: (i) => { return i === "contentProvider"; }, + getProp: () => { return undefined }, + getProps: () => { return {} }, + getFirstAction: () => { return { getRawActionUrl: () => "url" } }, + }, + {}, + { + programImageLink: { setParams: () => { return { getActionUrl: () => "programImageLink" }; } }, + programFallbackImageLink: { setParams: () => { return { getActionUrl: () => "programFallbackImageLinkrl" }; } }, + } + ) + } +} + +runTest() From 1426d3fb07ef84860c83fded2240130bad10c559 Mon Sep 17 00:00:00 2001 From: Geoffrey Garen Date: Thu, 21 May 2026 06:17:43 -0700 Subject: [PATCH 29/54] [CMake] Fix a race in the jsc-armv7 build https://bugs.webkit.org/show_bug.cgi?id=315241 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed by Adrian Perez de Castro. I saw this build race in EWS on jsc-armv7. * Source/JavaScriptCore/CMakeLists.txt: Make JavaScriptCoreSharedScripts depend on JSCBuiltins. Both depend on the same generated .py files in ${JavaScriptCore_SCRIPTS_DIR}. A parallel Make build can race two `cmake -E copy_if_different` invocations on the same destination — leaving a half-written .py. Canonical link: https://commits.webkit.org/313660@main (cherry picked from commit 3d4cdae16665cf3a34135e31a9c2e97eb52e5592) --- Source/JavaScriptCore/CMakeLists.txt | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt index 9239b6ad248d..162838ed53d9 100644 --- a/Source/JavaScriptCore/CMakeLists.txt +++ b/Source/JavaScriptCore/CMakeLists.txt @@ -1549,14 +1549,7 @@ endif () add_custom_target(JavaScriptCoreSharedScripts DEPENDS ${JavaScriptCore_SCRIPTS}) add_dependencies(JavaScriptCore JavaScriptCoreSharedScripts ${JavaScriptCore_EXTRA_DEPENDENCIES}) - -if (CMAKE_GENERATOR MATCHES "Visual Studio") - # JavaScriptCoreSharedScripts and JSCBuiltins targets need to have - # a direct or indirect dependency for CMake Visual Studio - # generator to eliminate duplicated custom commands. Otherwise, - # JavaScriptCore_SCRIPTS will be generated in both projects. - add_dependencies(JavaScriptCoreSharedScripts JSCBuiltins) -endif () +add_dependencies(JavaScriptCoreSharedScripts JSCBuiltins) if (ENABLE_JAVASCRIPT_SHELL) add_subdirectory(shell) From 267784fc3d21f5ce6cf67f2fa6f65a3e2079f090 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 4 Apr 2025 04:11:45 -0700 Subject: [PATCH 30/54] CodeBlock should reset its StubInfo when jettisoned https://bugs.webkit.org/show_bug.cgi?id=288554 rdar://144072285 Reviewed by Yusuke Suzuki. CodeBlock's StubInfo can keep watchpoints alive which do not ref data they hold, meaning that when the CodeBlock is jettisoned, we may have dangling pointers to data that was freed during a GC. * Source/JavaScriptCore/bytecode/CodeBlock.cpp: (JSC::CodeBlock::jettison): Originally-landed-as: 289651.190@safari-7621-branch (15053072f223). rdar://148056646 Canonical link: https://commits.webkit.org/293230@main (cherry picked from commit 3f23dc57bfa8b29236edacbd7207752e836cfe20) --- Source/JavaScriptCore/bytecode/CodeBlock.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 2371380fae87..386f48d13100 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -2169,6 +2169,15 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod CODEBLOCK_LOG_EVENT(codeBlock, "jettison", ("due to ", reason, ", counting = ", mode == CountReoptimization, ", detail = ", pointerDump(detail))); RELEASE_ASSERT(reason != Profiler::NotJettisoned); + +#if ENABLE(JIT) + ConcurrentJSLocker locker(m_lock); + forEachStructureStubInfo([&](StructureStubInfo& stubInfo) { + stubInfo.reset(locker, this); + return IterationStatus::Continue; + }); +#endif + #if ENABLE(DFG_JIT) if (DFG::shouldDumpDisassembly()) { From 697c992b5b377ed38990c0dacb91ca83b9dec404 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 4 Apr 2025 11:05:37 -0700 Subject: [PATCH 31/54] LLInt GetByIdModeMetadata should not hold potentially dead structure IDs https://bugs.webkit.org/show_bug.cgi?id=287567 rdar://144076957 Reviewed by Yijia Huang and Yusuke Suzuki. GetByIdModeMetadata does not reset its structure ID upon transitioning to ArrayLengthMode, meaning that this could get held over across another reset. This could later cause access to a freed (or reallocated) structure ID. This patch also cleans up the code in `setProtoLoadMode` slightly to clear up the specific writes being performed. This does not apply to other modes, since they set their structure ID explicitly. Since the mutator thread is the thread changing modes, it will only invalidate the structure ID after the call to clearToDefaultModeWithoutCache finishes, meaning that the structure ID already is cleared. * Source/JavaScriptCore/bytecode/GetByIdMetadata.h: (JSC::GetByIdModeMetadata::clearToDefaultModeWithoutCache): (JSC::GetByIdModeMetadata::setUnsetMode): (JSC::GetByIdModeMetadata::setArrayLengthMode): (JSC::GetByIdModeMetadata::setProtoLoadMode): * Source/JavaScriptCore/bytecode/GetByStatus.cpp: (JSC::GetByStatus::computeFromLLInt): Originally-landed-as: 289651.165@safari-7621-branch (a93595279e2b). rdar://148058163 Canonical link: https://commits.webkit.org/293257@main (cherry picked from commit 78b9637e3457ef457fa6578d362071d1569b8793) --- Source/JavaScriptCore/bytecode/GetByIdMetadata.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Source/JavaScriptCore/bytecode/GetByIdMetadata.h b/Source/JavaScriptCore/bytecode/GetByIdMetadata.h index 0bdf298f49ba..0f1489cb0861 100644 --- a/Source/JavaScriptCore/bytecode/GetByIdMetadata.h +++ b/Source/JavaScriptCore/bytecode/GetByIdMetadata.h @@ -136,22 +136,32 @@ inline void GetByIdModeMetadata::setUnsetMode(Structure* structure) { mode = GetByIdMode::Unset; unsetMode.structureID = structure->id(); + defaultMode.cachedOffset = 0; } inline void GetByIdModeMetadata::setArrayLengthMode() { mode = GetByIdMode::ArrayLength; + // We should clear the structure ID to avoid the old structure ID being saved. + defaultMode.structureID = StructureID(); + defaultMode.cachedOffset = 0; // Prevent the prototype cache from ever happening. hitCountForLLIntCaching = 0; } inline void GetByIdModeMetadata::setProtoLoadMode(Structure* structure, PropertyOffset offset, JSObject* cachedSlot) { - mode = GetByIdMode::ProtoLoad; // This must be first set. In 64bit architecture, this field is shared with protoLoadMode.cachedSlot. + // We rely on ProtoLoad being 0, or else the high bits of the pointer would write the wrong mode and hit count + static_assert(!static_cast>(GetByIdMode::ProtoLoad)); // In 64bit architecture, this field is shared with protoLoadMode.cachedSlot. + protoLoadMode.structureID = structure->id(); protoLoadMode.cachedOffset = offset; + // We know that this pointer will remain valid because it will be cleared by either a watchpoint fire or // during GC when we clear the LLInt caches. + + // The write to cachedSlot also writes the mode, since they overlap in the struct layout. We know that + // the mode ProtoLoad is 0 by the static assertion above. protoLoadMode.cachedSlot = cachedSlot; ASSERT(mode == GetByIdMode::ProtoLoad); From d05f2a3350766a8ca75269f55335edc5089eaf1c Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Fri, 13 Jun 2025 12:43:36 -0700 Subject: [PATCH 32/54] [JSC] Eagerly unlinking CodeBlock when jettisoning https://bugs.webkit.org/show_bug.cgi?id=294420 rdar://153246940 Reviewed by Keith Miller. Let's make CodeBlock jettisoning a bit safer. Regardless of the type of CodeBlock, when it is getting jettisoning, ensuring unlinking it from CallLinkInfo is fine. * Source/JavaScriptCore/bytecode/CodeBlock.cpp: (JSC::CodeBlock::jettison): Canonical link: https://commits.webkit.org/296207@main (cherry picked from commit 96299421a779288a492d3beb182f3d667569e306) --- Source/JavaScriptCore/bytecode/CodeBlock.cpp | 46 ++++++++++---------- Source/JavaScriptCore/bytecode/CodeBlock.h | 5 +-- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 386f48d13100..5ae893b0be6b 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -2108,7 +2108,6 @@ CodeBlock* CodeBlock::newReplacement() return ownerExecutable()->newReplacementCodeBlockFor(specializationKind()); } -#if ENABLE(JIT) CodeBlock* CodeBlock::replacement() { const ClassInfo* classInfo = this->classInfo(); @@ -2129,6 +2128,7 @@ CodeBlock* CodeBlock::replacement() return nullptr; } +#if ENABLE(JIT) DFG::CapabilityLevel CodeBlock::computeCapabilityLevel() { const ClassInfo* classInfo = this->classInfo(); @@ -2245,10 +2245,9 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod } } } - if (DFG::shouldDumpDisassembly()) dataLog(" Did invalidate ", *this, "\n"); - + // Count the reoptimization if that's what the user wanted. if (mode == CountReoptimization) { // FIXME: Maybe this should call alternative(). @@ -2257,32 +2256,33 @@ void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mod if (DFG::shouldDumpDisassembly()) dataLog(" Did count reoptimization for ", *this, "\n"); } - - if (this != replacement()) { - // This means that we were never the entrypoint. This can happen for OSR entry code - // blocks. - return; - } - - if (alternative()) - alternative()->optimizeAfterWarmUp(); - - if (reason != Profiler::JettisonDueToOldAge && reason != Profiler::JettisonDueToVMTraps) - tallyFrequentExitSites(); #endif // ENABLE(DFG_JIT) - // Jettison can happen during GC. We don't want to install code to a dead executable - // because that would add a dead object to the remembered set. - if (vm.heap.currentThreadIsDoingGCWork() && !vm.heap.isMarked(ownerExecutable())) - return; + // If this is not true, then this means that we were never the entrypoint. This can happen for OSR entry code blocks. + if (this == replacement()) { +#if ENABLE(DFG_JIT) + if (alternative()) + alternative()->optimizeAfterWarmUp(); - // This accomplishes (2). - ownerExecutable()->installCode(vm, alternative(), codeType(), specializationKind(), reason); + if (reason != Profiler::JettisonDueToOldAge && reason != Profiler::JettisonDueToVMTraps) + tallyFrequentExitSites(); +#endif // ENABLE(DFG_JIT) + // Jettison can happen during GC. We don't want to install code to a dead executable + // because that would add a dead object to the remembered set. + if (!vm.heap.currentThreadIsDoingGCWork() || vm.heap.isMarked(ownerExecutable())) { + // This accomplishes (2). + ownerExecutable()->installCode(vm, alternative(), codeType(), specializationKind(), reason); #if ENABLE(DFG_JIT) - if (DFG::shouldDumpDisassembly()) - dataLog(" Did install baseline version of ", *this, "\n"); + if (DFG::shouldDumpDisassembly()) + dataLog(" Did install baseline version of ", *this, "\n"); #endif // ENABLE(DFG_JIT) + } + } + + // Regardless of whether it is used or replaced or upgraded already or not, since this is already jettisoned, + // there is no reason to keep it linked. Unlink incoming calls. + unlinkOrUpgradeIncomingCalls(vm, nullptr); } JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin) diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index f4f8d9823020..ba46f6956f2e 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -310,7 +310,8 @@ class CodeBlock : public JSCell { // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind()) CodeBlock* newReplacement(); - + CodeBlock* replacement(); + void setJITCode(Ref&& code) { if (!code->isShared()) @@ -340,8 +341,6 @@ class CodeBlock : public JSCell { CodePtr addressForCallConcurrently(const ConcurrentJSLocker&, ArityCheckMode) const; #if ENABLE(JIT) - CodeBlock* replacement(); - DFG::CapabilityLevel computeCapabilityLevel(); DFG::CapabilityLevel capabilityLevel(); DFG::CapabilityLevel capabilityLevelState() { return static_cast(m_capabilityLevelState); } From 8fdd69fb202272c8e81d0f5621f94331213c35da Mon Sep 17 00:00:00 2001 From: Dan Hecht Date: Tue, 2 Sep 2025 14:05:54 -0700 Subject: [PATCH 33/54] [JSC] Avoid dangling pointers in WeakBlock list https://bugs.webkit.org/show_bug.cgi?id=298236 rdar://157587352 Reviewed by Keith Miller. Before this change, DoublyLinkedList leaves the next/prev pointers in a dangling state when removing a node from the list. Then, if the node is re-added, the next/prev pointers are reset when necessary. Let's make a stronger invariant: if the node is not in the list, then the prev/next pointers are nullptr. (Note that the converse is not true for single element lists.) Then, add some asserts to verify the WeakSet's WeakBlock list lifecycle to try to help track down a mysterious crash. The WeakBlock ownership can be transferred from the WeakSet to the Heap, at which point the prev/next should be nulled out and, after this change, no longer dangling. Bonus: remove MarkedSpace::freeOrShrinkBlock() since it's never called. Canonical link: https://commits.webkit.org/299454@main (cherry picked from commit c90e64eec92dad9dfa49801778997c6e449ce1c6) --- Source/JavaScriptCore/heap/Heap.cpp | 2 ++ Source/JavaScriptCore/heap/MarkedSpace.cpp | 10 ---------- Source/JavaScriptCore/heap/MarkedSpace.h | 1 - Source/JavaScriptCore/heap/WeakBlock.cpp | 1 + Source/JavaScriptCore/heap/WeakSet.cpp | 7 ++----- Source/WTF/wtf/DoublyLinkedList.h | 18 ++++++++---------- 6 files changed, 13 insertions(+), 26 deletions(-) diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp index 1c77d0eaefcb..df2c155dd458 100644 --- a/Source/JavaScriptCore/heap/Heap.cpp +++ b/Source/JavaScriptCore/heap/Heap.cpp @@ -2650,6 +2650,7 @@ bool Heap::shouldDoFullCollection() void Heap::addLogicallyEmptyWeakBlock(WeakBlock* block) { + RELEASE_ASSERT(!block->next() && !block->prev()); m_logicallyEmptyWeakBlocks.append(block); } @@ -2668,6 +2669,7 @@ bool Heap::sweepNextLogicallyEmptyWeakBlock() return false; WeakBlock* block = m_logicallyEmptyWeakBlocks[m_indexOfNextLogicallyEmptyWeakBlockToSweep]; + RELEASE_ASSERT(!block->next() && !block->prev()); block->sweep(); if (block->isEmpty()) { diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp index 839529595783..27e9d559013e 100644 --- a/Source/JavaScriptCore/heap/MarkedSpace.cpp +++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp @@ -382,16 +382,6 @@ void MarkedSpace::freeBlock(MarkedBlock::Handle* block) delete block; } -void MarkedSpace::freeOrShrinkBlock(MarkedBlock::Handle* block) -{ - if (!block->isEmpty()) { - block->shrink(); - return; - } - - freeBlock(block); -} - void MarkedSpace::shrink() { forEachDirectory( diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h index d96188890e18..bbfabb4dd9a3 100644 --- a/Source/JavaScriptCore/heap/MarkedSpace.h +++ b/Source/JavaScriptCore/heap/MarkedSpace.h @@ -133,7 +133,6 @@ class MarkedSpace { void shrink(); void freeBlock(MarkedBlock::Handle*); - void freeOrShrinkBlock(MarkedBlock::Handle*); void didAddBlock(MarkedBlock::Handle*); void didConsumeFreeList(MarkedBlock::Handle*); diff --git a/Source/JavaScriptCore/heap/WeakBlock.cpp b/Source/JavaScriptCore/heap/WeakBlock.cpp index a6221ca32c18..fd37275e6a0f 100644 --- a/Source/JavaScriptCore/heap/WeakBlock.cpp +++ b/Source/JavaScriptCore/heap/WeakBlock.cpp @@ -47,6 +47,7 @@ WeakBlock* WeakBlock::create(JSC::Heap& heap, CellContainer container) void WeakBlock::destroy(JSC::Heap& heap, WeakBlock* block) { + RELEASE_ASSERT(!block->next() && !block->prev()); block->~WeakBlock(); WeakBlockMalloc::free(block); heap.didFreeBlock(WeakBlock::blockSize); diff --git a/Source/JavaScriptCore/heap/WeakSet.cpp b/Source/JavaScriptCore/heap/WeakSet.cpp index 09f33394e6df..cd421900b0f5 100644 --- a/Source/JavaScriptCore/heap/WeakSet.cpp +++ b/Source/JavaScriptCore/heap/WeakSet.cpp @@ -37,12 +37,9 @@ WeakSet::~WeakSet() remove(); JSC::Heap& heap = *this->heap(); - WeakBlock* next = nullptr; - for (WeakBlock* block = m_blocks.head(); block; block = next) { - next = block->next(); + while (WeakBlock* block = m_blocks.removeHead()) WeakBlock::destroy(heap, block); - } - m_blocks.clear(); + ASSERT(m_blocks.isEmpty()); } void WeakSet::sweep() diff --git a/Source/WTF/wtf/DoublyLinkedList.h b/Source/WTF/wtf/DoublyLinkedList.h index ecef018c5f32..f14eaa6963db 100644 --- a/Source/WTF/wtf/DoublyLinkedList.h +++ b/Source/WTF/wtf/DoublyLinkedList.h @@ -41,8 +41,8 @@ template class DoublyLinkedListNode { template inline DoublyLinkedListNode::DoublyLinkedListNode() { - setPrev(0); - setNext(0); + setPrev(nullptr); + setNext(nullptr); } template inline void DoublyLinkedListNode::setPrev(T* prev) @@ -90,8 +90,8 @@ class DoublyLinkedList { }; template inline DoublyLinkedList::DoublyLinkedList() - : m_head(0) - , m_tail(0) + : m_head(nullptr) + , m_tail(nullptr) { } @@ -126,37 +126,33 @@ template inline T* DoublyLinkedList::tail() const template inline void DoublyLinkedList::push(T* node) { + ASSERT(!node->prev() && !node->next()); if (!m_head) { ASSERT(!m_tail); m_head = node; m_tail = node; - node->setPrev(0); - node->setNext(0); return; } ASSERT(m_tail); m_head->setPrev(node); node->setNext(m_head); - node->setPrev(0); m_head = node; } template inline void DoublyLinkedList::append(T* node) { + ASSERT(!node->prev() && !node->next()); if (!m_tail) { ASSERT(!m_head); m_head = node; m_tail = node; - node->setPrev(0); - node->setNext(0); return; } ASSERT(m_head); m_tail->setNext(node); node->setPrev(m_tail); - node->setNext(0); m_tail = node; } @@ -177,6 +173,8 @@ template inline void DoublyLinkedList::remove(T* node) ASSERT(node == m_tail); m_tail = node->prev(); } + node->setNext(nullptr); + node->setPrev(nullptr); } template inline T* DoublyLinkedList::removeHead() From 6afc2ab98f863db47c6da8ba05d70618bcfc8ff9 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 28 May 2025 20:46:37 -0600 Subject: [PATCH 34/54] Exclude non-user portions of the main thread stack from stack scanning on 32 bits. https://bugs.webkit.org/show_bug.cgi?id=293720 Reviewed by Yusuke Suzuki. On 32-bit armv7/linux we run into an issue where the environment strings located at the bottom of the stack, as well as some random bits inside the libc portion of the stack are interpreted as cells pointing into the heap, keeping actually dead objects alive. Yusuke previously attempted to fix this by excluding environ and before, but there are additional fake roots only a few hundred bytes below that. This patch excludes the caller of main entirely. * Source/JavaScriptCore/jsc.cpp: (jscmain): * Source/JavaScriptCore/runtime/JSLock.cpp: (JSC::JSLock::didAcquireLock): * Source/WTF/wtf/StackBounds.cpp: (WTF::StackBounds::setBottomOfMainThreadMain): (WTF::StackBounds::currentThreadStackBoundsInternal): * Source/WTF/wtf/StackBounds.h: (WTF::StackBounds::checkConsistency const): * Source/WebKit/WebProcess/gtk/WebProcessMainGtk.cpp: (WebKit::WebProcessMain): * Source/WebKit/WebProcess/wpe/WebProcessMainWPE.cpp: (WebKit::WebProcessMain): (cherry picked from commit 0f53210b857995d1df662c3f977de37817c1be35) --- Source/JavaScriptCore/jsc.cpp | 1 + Source/JavaScriptCore/runtime/JSLock.cpp | 4 +++ Source/WTF/wtf/StackBounds.cpp | 32 ++++++++++++++++--- Source/WTF/wtf/StackBounds.h | 7 ++-- .../WebProcess/gtk/WebProcessMainGtk.cpp | 2 ++ .../WebProcess/wpe/WebProcessMainWPE.cpp | 2 ++ 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp index 1dfd6103d008..7f8f141550f7 100644 --- a/Source/JavaScriptCore/jsc.cpp +++ b/Source/JavaScriptCore/jsc.cpp @@ -4415,6 +4415,7 @@ int jscmain(int argc, char** argv) JSC::Config::enableRestrictedOptions(); JSC::Options::machExceptionHandlerSandboxPolicy = JSC::Options::SandboxPolicy::Allow; + WTF::StackBounds::setBottomOfMainThreadMain(__builtin_frame_address(0)); WTF::initializeMainThread(); // Note that the options parsing can affect VM creation, and thus diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp index ca0175a06c3f..fc509c05ac63 100644 --- a/Source/JavaScriptCore/runtime/JSLock.cpp +++ b/Source/JavaScriptCore/runtime/JSLock.cpp @@ -155,6 +155,10 @@ void JSLock::didAcquireLock() samplingProfiler->noticeJSLockAcquisition(); } #endif +#if ASSERT_ENABLED + StackBounds::currentThreadStackBounds(); // Check stack bounds consistency. +#endif + } void JSLock::unlock() diff --git a/Source/WTF/wtf/StackBounds.cpp b/Source/WTF/wtf/StackBounds.cpp index 57acb25b5967..f1807584d9f5 100644 --- a/Source/WTF/wtf/StackBounds.cpp +++ b/Source/WTF/wtf/StackBounds.cpp @@ -21,6 +21,8 @@ #include "config.h" #include +#include "MainThread.h" + #if OS(DARWIN) #include @@ -50,6 +52,18 @@ namespace WTF { +#if !CPU(ADDRESS64) +static std::atomic bottomOfMainThreadMain = nullptr; +#endif + +void StackBounds::setBottomOfMainThreadMain([[maybe_unused]] void* stack) +{ +#if !CPU(ADDRESS64) + RELEASE_ASSERT(bottomOfMainThreadMain == nullptr); + bottomOfMainThreadMain = stack; +#endif +} + #if OS(DARWIN) StackBounds StackBounds::newThreadStackBounds(PlatformThreadHandle thread) @@ -149,15 +163,23 @@ StackBounds StackBounds::currentThreadStackBoundsInternal() static char** oldestEnviron = environ; - // In 32bit architecture, it is possible that environment variables are having a characters which looks like a pointer, - // and conservative GC will find it as a live pointer. We would like to avoid that to precisely exclude non user stack - // data region from this stack bounds. As the article (https://lwn.net/Articles/631631/) and the elf loader implementation - // explain how Linux main thread stack is organized, environment variables vector is placed on the stack, so we can exclude - // environment variables if we use `environ` global variable as a origin of the stack. + // On 32bit, it is possible that environment variables and other random data in libc have bytes which look like a pointer, + // and conservative GC will find it as a live pointer. We would like to avoid that, so we exclude the non-user stack + // data region from these stack bounds. This article explains how the main thread looks (https://lwn.net/Articles/631631/). + // + // First, we exclude environment variables by using `environ` global variable as a origin of the stack. // But `setenv` / `putenv` may alter `environ` variable's content. So we record the oldest `environ` variable content, and use it. + StackBounds stackBounds { origin, bound }; if (stackBounds.contains(oldestEnviron)) stackBounds = { oldestEnviron, bound }; + + // Then, we exclude any greater region based on manual calls to setBottomOfMainThreadMain. +#if !CPU(ADDRESS64) + if (stackBounds.contains(bottomOfMainThreadMain)) + stackBounds = { bottomOfMainThreadMain, bound }; +#endif + return stackBounds; } #endif diff --git a/Source/WTF/wtf/StackBounds.h b/Source/WTF/wtf/StackBounds.h index 574bf5103b2d..c69ff2da14dc 100644 --- a/Source/WTF/wtf/StackBounds.h +++ b/Source/WTF/wtf/StackBounds.h @@ -63,6 +63,7 @@ class StackBounds { result.checkConsistency(); return result; } + WTF_EXPORT_PRIVATE static void setBottomOfMainThreadMain(void*); void* origin() const { @@ -142,10 +143,10 @@ class StackBounds { void checkConsistency() const { -#if ASSERT_ENABLED +#if ASSERT_ENABLED || OS(LINUX) void* currentPosition = currentStackPointer(); - ASSERT(m_origin != m_bound); - ASSERT(currentPosition < m_origin && currentPosition > m_bound); + RELEASE_ASSERT(m_origin != m_bound); + RELEASE_ASSERT(currentPosition < m_origin && currentPosition > m_bound); #endif } diff --git a/Source/WebKit/WebProcess/gtk/WebProcessMainGtk.cpp b/Source/WebKit/WebProcess/gtk/WebProcessMainGtk.cpp index ff864ef3353f..cd4baeba624b 100644 --- a/Source/WebKit/WebProcess/gtk/WebProcessMainGtk.cpp +++ b/Source/WebKit/WebProcess/gtk/WebProcessMainGtk.cpp @@ -31,6 +31,7 @@ #include "WebProcess.h" #include #include +#include #if USE(GSTREAMER) #include @@ -103,6 +104,7 @@ int WebProcessMain(int argc, char** argv) // This call needs to happen before any threads begin execution unsetenv("GTK_THEME"); + WTF::StackBounds::setBottomOfMainThreadMain(__builtin_frame_address(0)); return AuxiliaryProcessMain(argc, argv); } diff --git a/Source/WebKit/WebProcess/wpe/WebProcessMainWPE.cpp b/Source/WebKit/WebProcess/wpe/WebProcessMainWPE.cpp index 31088ef69279..e9f3374cbfbf 100644 --- a/Source/WebKit/WebProcess/wpe/WebProcessMainWPE.cpp +++ b/Source/WebKit/WebProcess/wpe/WebProcessMainWPE.cpp @@ -30,6 +30,7 @@ #include "AuxiliaryProcessMain.h" #include "WebProcess.h" #include +#include #if USE(GCRYPT) #include @@ -95,6 +96,7 @@ class WebProcessMainWPE final : public AuxiliaryProcessMainBase { int WebProcessMain(int argc, char** argv) { + WTF::StackBounds::setBottomOfMainThreadMain(__builtin_frame_address(0)); return AuxiliaryProcessMain(argc, argv); } From 3c80bde1fb747e1e2bdfe1ddf2e5ae607f339432 Mon Sep 17 00:00:00 2001 From: Xabier Rodriguez-Calvar Date: Tue, 3 Sep 2024 22:25:49 -0700 Subject: [PATCH 35/54] Clamp setCurrentTimeFromBindings to prevent negative time https://bugs.webkit.org/show_bug.cgi?id=278646 Reviewed by Eric Carlson. Just clamp the value to avoid negative numbers when seeking. Also return in GStreamer ports infinity as maxTimeSeekable for live streams. Test: imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm Also another bunch of tests have now corrected expectations. * LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt: * LayoutTests/platform/glib/TestExpectations: * LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/audio_loop_seek_to_eos-expected.txt: * LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt: Removed. * LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/video_loop_base-expected.txt: * Source/WebCore/html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::setCurrentTimeForBindings): * Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::maxTimeSeekable const): Canonical link: https://commits.webkit.org/283134@main (cherry picked from commit 081be276c2aad615354966555af0bd0c6b49e9ad) --- .../seeking/seek-to-currentTime-expected.txt | 2 +- .../seeking/seek-to-negative-time-expected.txt | 2 +- LayoutTests/platform/glib/TestExpectations | 1 + .../media-elements/audio_loop_seek_to_eos-expected.txt | 4 +--- .../seeking/seek-to-negative-time-expected.txt | 3 --- .../media-elements/video_loop_base-expected.txt | 4 +--- Source/WebCore/html/HTMLMediaElement.cpp | 2 ++ .../graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp | 8 +++++--- 8 files changed, 12 insertions(+), 14 deletions(-) delete mode 100644 LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime-expected.txt index 931c222b6124..73257f619cbe 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime-expected.txt @@ -1,3 +1,3 @@ -FAIL seek to currentTime assert_greater_than: seekable ranges expected a number greater than 0 but got 0 +PASS seek to currentTime diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt index d0c88023f41a..3c55340a6be8 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt @@ -1,3 +1,3 @@ -FAIL seek to negative time assert_equals: currentTime after setting expected 0 but got -1 +PASS seek to negative time diff --git a/LayoutTests/platform/glib/TestExpectations b/LayoutTests/platform/glib/TestExpectations index ed805d30964f..8b7a290b526a 100644 --- a/LayoutTests/platform/glib/TestExpectations +++ b/LayoutTests/platform/glib/TestExpectations @@ -1080,6 +1080,7 @@ webkit.org/b/276587 webrtc/video-av1.html [ Pass Timeout ] webkit.org/b/254520 media/video-ended-event-negative-playback.html [ Failure Timeout Pass ] webkit.org/b/254519 media/media-continues-playing-after-replace-source.html [ Failure Pass ] webkit.org/b/254518 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy.https.sub.html [ Crash Failure Timeout Pass ] +webkit.org/b/278913 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm [ Failure ] webkit.org/b/254521 imported/w3c/web-platform-tests/media-source/mediasource-getvideoplaybackquality.html [ Pass Failure ] webkit.org/b/262986 imported/w3c/web-platform-tests/media-source/mediasource-detach.html [ Pass Crash ] webkit.org/b/254522 media/video-volume.html [ Pass Failure ] diff --git a/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/audio_loop_seek_to_eos-expected.txt b/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/audio_loop_seek_to_eos-expected.txt index 914f09bb5d84..1f6630cfa1ed 100644 --- a/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/audio_loop_seek_to_eos-expected.txt +++ b/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/audio_loop_seek_to_eos-expected.txt @@ -1,5 +1,3 @@ -Harness Error (TIMEOUT), message = null - -TIMEOUT seeking to the end of looping audio Test timed out +PASS seeking to the end of looping audio diff --git a/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt b/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt deleted file mode 100644 index de5a7168fbe4..000000000000 --- a/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time-expected.txt +++ /dev/null @@ -1,3 +0,0 @@ - -FAIL seek to negative time The index is not in the allowed range. - diff --git a/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/video_loop_base-expected.txt b/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/video_loop_base-expected.txt index bb133e76ff90..6d75e0656d0e 100644 --- a/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/video_loop_base-expected.txt +++ b/LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/video_loop_base-expected.txt @@ -1,5 +1,3 @@ -Harness Error (TIMEOUT), message = null - -NOTRUN Check if video.loop is set to true that expecting the seeking event is fired more than once +PASS Check if video.loop is set to true that expecting the seeking event is fired more than once diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index fcb715c16d38..ae58e985c591 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -4090,6 +4090,8 @@ ExceptionOr HTMLMediaElement::setCurrentTimeForBindings(double time) if (m_mediaController) return Exception { ExceptionCode::InvalidStateError }; + time = clampTo(time, 0.0); + if (m_readyState == HAVE_NOTHING || !m_player) { m_defaultPlaybackStartPosition = MediaTime::createWithDouble(time); return { }; diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index aef56943a2ec..eb2d66d9c24c 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -915,12 +915,14 @@ const PlatformTimeRanges& MediaPlayerPrivateGStreamer::buffered() const MediaTime MediaPlayerPrivateGStreamer::maxTimeSeekable() const { - GST_TRACE_OBJECT(pipeline(), "errorOccured: %s, isLiveStream: %s", boolForPrinting(m_didErrorOccur), boolForPrinting(m_isLiveStream)); + GST_TRACE_OBJECT(pipeline(), "errorOccured: %s", boolForPrinting(m_didErrorOccur)); if (m_didErrorOccur) return MediaTime::zeroTime(); - if (m_isLiveStream.value_or(false)) - return MediaTime::zeroTime(); + bool isLiveStream = m_isLiveStream.value_or(false); + GST_TRACE_OBJECT(pipeline(), "isLiveStream: %s", boolForPrinting(isLiveStream)); + if (isLiveStream) + return MediaTime::positiveInfiniteTime(); if (isMediaStreamPlayer()) return MediaTime::zeroTime(); From f73bafe509d0dfe31c24cfb4a178a49405087ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Oca=C3=B1a=20Gonz=C3=A1lez?= Date: Fri, 6 Sep 2024 04:18:02 -0700 Subject: [PATCH 36/54] [HTMLMediaElement] Reschedule timeupdate event if fired too early https://bugs.webkit.org/show_bug.cgi?id=279055 Reviewed by Xabier Rodriguez-Calvar. HTMLMediaElement fires 'timeupdate' every 250ms in repeating timer. If the timer is fired before 250ms from the last occurrence, it is silently skipped and needs to wait for another 250ms. As a result, the gap between two following timeupdate events may vary 250-500ms. This may happen in two cases: 1) Non-periodic timeupdate event is scheduled for any reason. 2) When the difference between two timer calls is lower than 250ms. This may happen when there are multiple timers to handle at the same time in ThreadTimers (maxDurationOfFiringTimers). Original author: Andrzej Surdej See: https://github.com/WebPlatformForEmbedded/WPEWebKit/pull/1392 * Source/WebCore/html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::scheduleTimeupdateEvent): Schedule next event on the remaining time difference so that maxTimeupdateEventFrequency is honored, instead of waiting a full cycle. Canonical link: https://commits.webkit.org/283264@main (cherry picked from commit fb9b6139ada37294400d2a7d4edcff97bb15c1c8) --- Source/WebCore/html/HTMLMediaElement.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index ae58e985c591..c5ac966f3fca 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -4854,8 +4854,11 @@ void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent) Seconds timedelta = now - m_clockTimeAtLastUpdateEvent; // throttle the periodic events - if (periodicEvent && timedelta < maxTimeupdateEventFrequency) + if (periodicEvent && timedelta < maxTimeupdateEventFrequency) { + // Reschedule the timer to fire at the correct time, ensuring that no full cycles are skipped + m_playbackProgressTimer.start(maxTimeupdateEventFrequency - timedelta, maxTimeupdateEventFrequency); return; + } // Some media engines make multiple "time changed" callbacks at the same time, but we only want one // event at a given time so filter here From 1ae2964c4c830111596bd3481c11b456c9401086 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Mon, 13 Jan 2025 05:23:24 -0800 Subject: [PATCH 37/54] [WPE] AcceleratedSurfaceLibWPE::clientResize should use the given size https://bugs.webkit.org/show_bug.cgi?id=285835 Reviewed by Adrian Perez de Castro. And not the size already set in the main thread. * Source/WebKit/WebProcess/WebPage/libwpe/AcceleratedSurfaceLibWPE.cpp: (WebKit::AcceleratedSurfaceLibWPE::clientResize): Canonical link: https://commits.webkit.org/288798@main (cherry picked from commit b2973211f1541e3d24d4600f535e0acb2487217f) --- .../WebProcess/WebPage/libwpe/AcceleratedSurfaceLibWPE.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebKit/WebProcess/WebPage/libwpe/AcceleratedSurfaceLibWPE.cpp b/Source/WebKit/WebProcess/WebPage/libwpe/AcceleratedSurfaceLibWPE.cpp index babfd11a5692..0f1fe9288baf 100644 --- a/Source/WebKit/WebProcess/WebPage/libwpe/AcceleratedSurfaceLibWPE.cpp +++ b/Source/WebKit/WebProcess/WebPage/libwpe/AcceleratedSurfaceLibWPE.cpp @@ -100,7 +100,7 @@ uint64_t AcceleratedSurfaceLibWPE::surfaceID() const void AcceleratedSurfaceLibWPE::clientResize(const IntSize& size) { ASSERT(m_backend); - wpe_renderer_backend_egl_target_resize(m_backend, std::max(1, m_size.width()), std::max(1, m_size.height())); + wpe_renderer_backend_egl_target_resize(m_backend, std::max(1, size.width()), std::max(1, size.height())); } void AcceleratedSurfaceLibWPE::willRenderFrame() From 70e1c27bbc1e00d52c91a1558b6e877bda95fdd6 Mon Sep 17 00:00:00 2001 From: Xabier Rodriguez-Calvar Date: Wed, 30 Jul 2025 08:10:39 -0700 Subject: [PATCH 38/54] [EME][Thunder] Avoid crashing with null answers during session load https://bugs.webkit.org/show_bug.cgi?id=296690 Reviewed by Philippe Normand. OpenCDM/Thunder can answer with a null message when loading a wrong session. We need to deal with that. * Source/WebCore/platform/graphics/gstreamer/eme/CDMThunder.cpp: (WebCore::CDMInstanceSessionThunder::loadSession): Canonical link: https://commits.webkit.org/298032@main (cherry picked from commit 386dfe0b3ce29d43faf58a2381b5c0efbd1ffb28) --- Source/WebCore/platform/graphics/gstreamer/eme/CDMThunder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/graphics/gstreamer/eme/CDMThunder.cpp b/Source/WebCore/platform/graphics/gstreamer/eme/CDMThunder.cpp index dbe0195d802f..6b50751075fc 100644 --- a/Source/WebCore/platform/graphics/gstreamer/eme/CDMThunder.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/eme/CDMThunder.cpp @@ -680,7 +680,7 @@ void CDMInstanceSessionThunder::loadSession(LicenseType licenseType, const Strin } } else { GST_ERROR("session %s not loaded", m_sessionID.utf8().data()); - if (responseMessage->isEmpty()) + if (!responseMessage || responseMessage->isEmpty()) callback(std::nullopt, std::nullopt, std::nullopt, SuccessValue::Failed, sessionLoadFailureFromThunder({ })); else { auto responseData = responseMessage->extractData(); From c0bb02e718c1604efb61afebadfad18e8646bd8d Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 8 Jul 2026 08:56:15 -0600 Subject: [PATCH 39/54] unreviewed unified build fixes --- Source/WebCore/bindings/js/ScriptModuleLoader.cpp | 1 + Source/WebCore/dom/LoadableClassicScript.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/Source/WebCore/bindings/js/ScriptModuleLoader.cpp b/Source/WebCore/bindings/js/ScriptModuleLoader.cpp index c03badb533f0..8dace6a8e312 100644 --- a/Source/WebCore/bindings/js/ScriptModuleLoader.cpp +++ b/Source/WebCore/bindings/js/ScriptModuleLoader.cpp @@ -38,6 +38,7 @@ #include "MIMETypeRegistry.h" #include "ModuleFetchFailureKind.h" #include "ModuleFetchParameters.h" +#include "ScriptController.h" #include "ScriptSourceCode.h" #include "ServiceWorkerGlobalScope.h" #include "ShadowRealmGlobalScope.h" diff --git a/Source/WebCore/dom/LoadableClassicScript.cpp b/Source/WebCore/dom/LoadableClassicScript.cpp index 0750676fa3b9..ab0860957abb 100644 --- a/Source/WebCore/dom/LoadableClassicScript.cpp +++ b/Source/WebCore/dom/LoadableClassicScript.cpp @@ -27,6 +27,7 @@ #include "LoadableClassicScript.h" #include "DefaultResourceLoadPriority.h" +#include "Document.h" #include "Element.h" #include "FetchIdioms.h" #include "LoadableScriptError.h" From f6c53131cdfca61c398d510c36d9a44340627679 Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Mon, 7 Apr 2025 16:16:34 -0700 Subject: [PATCH 40/54] [JSC] GetByIdModeMetadata's mode needs to be set when not using 64bit pointer https://bugs.webkit.org/show_bug.cgi?id=289017 rdar://145852436 Reviewed by Mark Lam. On environment having 32bit pointer or non-little-endian, mode needs to be set. * Source/JavaScriptCore/bytecode/GetByIdMetadata.h: (JSC::GetByIdModeMetadata::setProtoLoadMode): Originally-landed-as: 289651.211@safari-7621-branch (38a19eb3b7c0). rdar://148052940 Canonical link: https://commits.webkit.org/293387@main (cherry picked from commit ae20fcabf1c18ac51d3f82b980630005646226ef) --- Source/JavaScriptCore/bytecode/GetByIdMetadata.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/JavaScriptCore/bytecode/GetByIdMetadata.h b/Source/JavaScriptCore/bytecode/GetByIdMetadata.h index 0f1489cb0861..d504c4a8aa3e 100644 --- a/Source/JavaScriptCore/bytecode/GetByIdMetadata.h +++ b/Source/JavaScriptCore/bytecode/GetByIdMetadata.h @@ -151,8 +151,12 @@ inline void GetByIdModeMetadata::setArrayLengthMode() inline void GetByIdModeMetadata::setProtoLoadMode(Structure* structure, PropertyOffset offset, JSObject* cachedSlot) { +#if CPU(LITTLE_ENDIAN) && CPU(ADDRESS64) // We rely on ProtoLoad being 0, or else the high bits of the pointer would write the wrong mode and hit count static_assert(!static_cast>(GetByIdMode::ProtoLoad)); // In 64bit architecture, this field is shared with protoLoadMode.cachedSlot. +#else + mode = GetByIdMode::ProtoLoad; +#endif protoLoadMode.structureID = structure->id(); protoLoadMode.cachedOffset = offset; From 324a8496c8982efd83f478700f269596197fe428 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 8 Jul 2026 22:38:13 -0600 Subject: [PATCH 41/54] [JSC][ARMv7] test32 must use AND, not EOR, when materializing Zero/NonZero with distinct registers Regressed by the branchless test32/compare32 codegen change (bug 302016, 303329@main): the register-register test32 overload emitted the compare32 equality idiom (eor+clz+lsr, computing op1 == op2) for the Zero/NonZero result conditions, where test32 semantics require (op1 & op2) == 0. The same-register and immediate-mask forms were correct, so JS tiers never exposed it; OMG's fused i32.eqz(i32.and(a, b)) materializes Test32 with distinct registers and produced inverted flag logic (8bitbench-wasm state corruption / browser JetStream3 stalls on ARMv7). Also applies upstream: 303329@main carries the same latent bug. Co-Authored-By: Claude Fable 5 --- .../stress/omg-test32-distinct-registers.js | 33 +++++++++++++++++++ .../assembler/MacroAssemblerARMv7.h | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 JSTests/wasm/stress/omg-test32-distinct-registers.js diff --git a/JSTests/wasm/stress/omg-test32-distinct-registers.js b/JSTests/wasm/stress/omg-test32-distinct-registers.js new file mode 100644 index 000000000000..10444cedfac9 --- /dev/null +++ b/JSTests/wasm/stress/omg-test32-distinct-registers.js @@ -0,0 +1,33 @@ +//@ requireOptions("--useConcurrentJIT=false") +// Regression test for test32(Zero/NonZero, op1, op2, dest) with op1 != op2 on ARMv7: +// materializing (op1 & op2) == 0 must use AND, not EOR (EOR computes op1 == op2). +// OMG fuses i32.eqz(i32.and(a, b)) into a single materialized Test32, which is the +// only tier that exercises the distinct-register form. +// https://bugs.webkit.org/show_bug.cgi?id=302016 (regressed in 303329@main) + +// (module +// (func (export "f") (param i32 i32) (result i32) +// local.get 0 +// local.get 1 +// i32.and +// i32.eqz)) +const bytes = new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, // \0asm v1 + 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, // type: (i32,i32)->i32 + 0x03, 0x02, 0x01, 0x00, // func + 0x07, 0x05, 0x01, 0x01, 0x66, 0x00, 0x00, // export "f" + 0x0a, 0x0a, 0x01, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x71, 0x45, 0x0b, // code +]); + +const f = new WebAssembly.Instance(new WebAssembly.Module(bytes)).exports.f; + +for (let i = 0; i < 300000; i++) { + // (2 & 1) == 0, but 2 != 1: EOR-based Zero materialization returns 0 instead of 1. + let got = f(2, 1); + if (got !== 1) + throw new Error("f(2, 1) should be 1 ((2&1)==0), got " + got + " at iteration " + i); + // (3 & 1) != 0 and 3 != 1: both idioms agree; guards the NonZero path shape too. + got = f(3, 1); + if (got !== 0) + throw new Error("f(3, 1) should be 0 ((3&1)!=0), got " + got + " at iteration " + i); +} diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index ebdd81810a69..301b29fed204 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -3148,7 +3148,7 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { m_assembler.clz(dest, op1); m_assembler.lsr(dest, dest, 5); } else { - m_assembler.eor(dest, op1, op2); + m_assembler.ARM_and(dest, op1, op2); m_assembler.clz(dest, dest); m_assembler.lsr(dest, dest, 5); } @@ -3160,7 +3160,7 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { m_assembler.lsr(dest, dest, 5); m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); } else { - m_assembler.eor(dest, op1, op2); + m_assembler.ARM_and(dest, op1, op2); m_assembler.clz(dest, dest); m_assembler.lsr(dest, dest, 5); m_assembler.eor(dest, dest, ARMThumbImmediate::makeEncodedImm(1)); From 5a67a8720435befa82282786c5f1a598da1c7604 Mon Sep 17 00:00:00 2001 From: Keith Miller Date: Wed, 29 Jan 2025 07:36:45 -0800 Subject: [PATCH 42/54] Revert 287649@main since it breaks tests on ARM64 https://bugs.webkit.org/show_bug.cgi?id=286679 rdar://143819751 Unreviewed, revert. * JSTests/wasm/stress/tail-call-simple-i64.js: Removed. * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::transfer64): Deleted. * Source/JavaScriptCore/b3/B3LowerToAir.cpp: * Source/JavaScriptCore/b3/B3LowerToAir32_64.cpp: * Source/JavaScriptCore/b3/B3MoveConstants.cpp: * Source/JavaScriptCore/b3/air/AirCustom.h: (JSC::B3::Air::WasmBoundsCheckCustom::forEachArg): * Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp: * Source/JavaScriptCore/jit/Width.h: * Source/JavaScriptCore/runtime/JSCJSValue.cpp: (JSC::JSValue::dumpInContextAssumingStructure const): * Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp: (JSC::Wasm::OMGIRGenerator::emitIndirectCall): (JSC::Wasm::OMGIRGenerator::createCallPatchpoint): (JSC::Wasm::prepareForTailCallImpl): (JSC::Wasm::OMGIRGenerator::createTailCallPatchpoint): (JSC::Wasm::OMGIRGenerator::addCall): (JSC::Wasm::OMGIRGenerator::createCallConstrainedArgs): Deleted. * Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp: (JSC::Wasm::OMGIRGenerator::addArguments): (JSC::Wasm::OMGIRGenerator::emitIndirectCall): (JSC::Wasm::OMGIRGenerator::createCallPatchpoint): (JSC::Wasm::prepareForTailCallImpl): (JSC::Wasm::OMGIRGenerator::createTailCallPatchpoint): (JSC::Wasm::OMGIRGenerator::addCall): (JSC::Wasm::OMGIRGenerator::createCallConstrainedArgs): Deleted. Canonical link: https://commits.webkit.org/289498@main (cherry picked from commit 82b8457380cf38489bd334ea7f5a8486cc9e217d) --- JSTests/wasm/stress/tail-call-simple-i64.js | 72 ---- .../assembler/MacroAssemblerARMv7.h | 11 - Source/JavaScriptCore/b3/B3LowerToAir.cpp | 3 +- .../JavaScriptCore/b3/B3LowerToAir32_64.cpp | 6 +- Source/JavaScriptCore/b3/B3MoveConstants.cpp | 6 - Source/JavaScriptCore/b3/air/AirCustom.h | 4 +- .../disassembler/CapstoneDisassembler.cpp | 2 - Source/JavaScriptCore/jit/Width.h | 6 - Source/JavaScriptCore/runtime/JSCJSValue.cpp | 2 - .../wasm/WasmOMGIRGenerator.cpp | 229 ++++------ .../wasm/WasmOMGIRGenerator32_64.cpp | 407 +++++------------- 11 files changed, 204 insertions(+), 544 deletions(-) delete mode 100644 JSTests/wasm/stress/tail-call-simple-i64.js diff --git a/JSTests/wasm/stress/tail-call-simple-i64.js b/JSTests/wasm/stress/tail-call-simple-i64.js deleted file mode 100644 index a29cb621e468..000000000000 --- a/JSTests/wasm/stress/tail-call-simple-i64.js +++ /dev/null @@ -1,72 +0,0 @@ -//@ requireOptions("--useWasmTailCalls=true", "--maximumWasmCalleeSIzeForInlining=0") -import { instantiate } from "../wabt-wrapper.js" -import * as assert from "../assert.js" - -let wat = ` -(module - (func $call_same_size (export "call_same_size") (result i64) - (i64.const 600000001337) - (return_call $callee_same_size)) - (func $callee_same_size (param $i i64) (result i64) - (i64.add (local.get $i) (i64.const 42))) - (func $call_same_size_with_stack (export "call_same_size_with_stack") (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) - (i64.const 600000001337) - (i64.const 1) - (i64.const 2) - (i64.const 3) - (i64.const 4) - (i64.const 5) - (i64.const 6) - (i64.const 7) - (i64.const 8) - (i64.const 40000000009) - (return_call $callee_same_size_with_stack)) - (func $callee_same_size_with_stack (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) - (i64.add (local.get $i9) (local.get $i2))) - - (func $call_bigger_with_stack (export "call_bigger_with_stack") (result i64) - (i64.const 600000001337) - (i64.const 1) - (i64.const 2) - (i64.const 3) - (i64.const 4) - (i64.const 5) - (i64.const 6) - (i64.const 7) - (i64.const 8) - (i64.const 500000000090) - (return_call $callee_bigger_with_stack)) - (func $callee_bigger_with_stack (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) - (i64.add (local.get $i9) (local.get $i2))) - (func $call_smaller_with_stack (export "call_smaller_with_stack") (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (param $i10 i64) (param $i11 i64) (result i64) - (i64.const 600000001337) - (i64.const 1) - (i64.const 2) - (i64.const 3) - (i64.const 4) - (i64.const 5) - (i64.const 6) - (i64.const 7) - (i64.const 8) - (i64.const 500000000090) - (return_call $callee_smaller_with_stack)) - (func $callee_smaller_with_stack (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) - (i64.add (local.get $i9) (local.get $i2))) - ) -` -let badArgs = new Array(12).fill(0xAAAAn) - -async function test() { - const instance = await instantiate(wat, {}, { simd: true, tail_call: true, exceptions: true }) - const { call_same_size, call_same_size_with_stack, call_bigger_with_stack, call_smaller_with_stack } = instance.exports - - - for (let i = 0; i < 1000; ++i) { - assert.eq(call_same_size.apply(null, badArgs), 600000001337n + 42n) - assert.eq(call_same_size_with_stack.apply(null, badArgs), 40000000009n + 2n) - assert.eq(call_bigger_with_stack.apply(null, badArgs), 500000000090n + 2n) - assert.eq(call_smaller_with_stack.apply(null, badArgs), 500000000090n + 2n) - } -} - -await assert.asyncTest(test()) \ No newline at end of file diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 301b29fed204..69c321e85ab8 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -1398,17 +1398,6 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { store32(dataTempRegister, dest); } - // Warning: not atomic. - void transfer64(Address src, Address dest) - { - if (src == dest) - return; - load32(src, dataTempRegister); - store32(dataTempRegister, dest); - load32(src.withOffset(sizeof(int)), dataTempRegister); - store32(dataTempRegister, dest.withOffset(sizeof(int))); - } - void transferPtr(Address src, Address dest) { transfer32(src, dest); diff --git a/Source/JavaScriptCore/b3/B3LowerToAir.cpp b/Source/JavaScriptCore/b3/B3LowerToAir.cpp index 20c92b7f9fc7..6309a91ba4dc 100644 --- a/Source/JavaScriptCore/b3/B3LowerToAir.cpp +++ b/Source/JavaScriptCore/b3/B3LowerToAir.cpp @@ -45,6 +45,7 @@ #undef LoadFence #undef MemoryFence +#if USE(JSVALUE64) #include "AirBlockInsertionSet.h" #include "AirCCallSpecial.h" #include "AirCode.h" @@ -85,8 +86,6 @@ IGNORE_RETURN_TYPE_WARNINGS_BEGIN WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN -#if USE(JSVALUE64) - namespace JSC { namespace B3 { namespace { diff --git a/Source/JavaScriptCore/b3/B3LowerToAir32_64.cpp b/Source/JavaScriptCore/b3/B3LowerToAir32_64.cpp index d2993fd2cf35..1d0a1a0893ee 100644 --- a/Source/JavaScriptCore/b3/B3LowerToAir32_64.cpp +++ b/Source/JavaScriptCore/b3/B3LowerToAir32_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2024 Apple Inc. All rights reserved. + * Copyright (C) 2015-2019 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,8 +66,6 @@ IGNORE_RETURN_TYPE_WARNINGS_BEGIN #endif -WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN - namespace JSC { namespace B3 { namespace { @@ -5604,8 +5602,6 @@ void lowerToAir(Procedure& procedure) } } // namespace JSC::B3 -WTF_ALLOW_UNSAFE_BUFFER_USAGE_END - #if !ASSERT_ENABLED IGNORE_RETURN_TYPE_WARNINGS_END #endif diff --git a/Source/JavaScriptCore/b3/B3MoveConstants.cpp b/Source/JavaScriptCore/b3/B3MoveConstants.cpp index a971a7dbf230..c4336ae157ab 100644 --- a/Source/JavaScriptCore/b3/B3MoveConstants.cpp +++ b/Source/JavaScriptCore/b3/B3MoveConstants.cpp @@ -340,12 +340,6 @@ class MoveConstants { if (child->type().isVector()) continue; - // BigImms don't work reliably for 32-bit, so this is the most reliable. - if constexpr (is32Bit()) { - if (child->hasDouble() && !WTF::isIdentical(child->asDouble(), 0.0)) - continue; - } - ValueKey key = child->key(); child = m_insertionSet.insertValue( valueIndex, key.materialize(m_proc, value->origin())); diff --git a/Source/JavaScriptCore/b3/air/AirCustom.h b/Source/JavaScriptCore/b3/air/AirCustom.h index 0f187687127a..18f0644faa26 100644 --- a/Source/JavaScriptCore/b3/air/AirCustom.h +++ b/Source/JavaScriptCore/b3/air/AirCustom.h @@ -317,8 +317,8 @@ struct WasmBoundsCheckCustom : public CommonCustomBase { template static void forEachArg(Inst& inst, const Func& functor) { - functor(inst.args[0], Arg::Use, GP, WidthPtr); - functor(inst.args[1], Arg::Use, GP, WidthPtr); + functor(inst.args[0], Arg::Use, GP, pointerWidth()); + functor(inst.args[1], Arg::Use, GP, pointerWidth()); } template diff --git a/Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp b/Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp index 94941c0d7c7e..a1075bbed5a0 100644 --- a/Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp +++ b/Source/JavaScriptCore/disassembler/CapstoneDisassembler.cpp @@ -26,7 +26,6 @@ #include "config.h" #if ENABLE(DISASSEMBLER) && USE(CAPSTONE) -WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN #include "AssemblyComments.h" #include "Disassembler.h" @@ -81,5 +80,4 @@ bool tryToDisassemble(const CodePtr& codePtr, size_t size, vo } // namespace JSC -WTF_ALLOW_UNSAFE_BUFFER_USAGE_END #endif // ENABLE(DISASSEMBLER) && USE(CAPSTONE) diff --git a/Source/JavaScriptCore/jit/Width.h b/Source/JavaScriptCore/jit/Width.h index 09641bc83f90..8fd16e0d298c 100644 --- a/Source/JavaScriptCore/jit/Width.h +++ b/Source/JavaScriptCore/jit/Width.h @@ -44,12 +44,6 @@ static constexpr Width Width32 = Width::Width32; static constexpr Width Width64 = Width::Width64; static constexpr Width Width128 = Width::Width128; -#if CPU(ADDRESS64) -static constexpr Width WidthPtr = Width::Width64; -#else -static constexpr Width WidthPtr = Width::Width32; -#endif - enum class PreservedWidth : uint8_t { PreservesNothing = 0, Preserves64 = 1, diff --git a/Source/JavaScriptCore/runtime/JSCJSValue.cpp b/Source/JavaScriptCore/runtime/JSCJSValue.cpp index ea2ca174f393..39a848c3f0a2 100644 --- a/Source/JavaScriptCore/runtime/JSCJSValue.cpp +++ b/Source/JavaScriptCore/runtime/JSCJSValue.cpp @@ -270,14 +270,12 @@ void JSValue::dumpInContextAssumingStructure( #if USE(JSVALUE64) out.printf("Double: %lld, %lf", (long long)reinterpretDoubleToInt64(asDouble()), asDouble()); #else -WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN union { double asDouble; uint32_t asTwoInt32s[2]; } u; u.asDouble = asDouble(); out.printf("Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble()); -WTF_ALLOW_UNSAFE_BUFFER_USAGE_END #endif } else if (isCell()) { if (structure->classInfoForCells()->isSubClassOf(JSString::info())) { diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp index 3bde8382b8d8..d7d782850355 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp @@ -96,12 +96,6 @@ namespace JSC { namespace Wasm { using namespace B3; namespace { -#if USE(JSVALUE32_64) -using ConstIntPtrValue = Const32Value; -#else -using ConstIntPtrValue = Const64Value; -#endif - namespace WasmOMGIRGeneratorInternal { static constexpr bool verbose = false; static constexpr bool verboseInlining = false; @@ -126,7 +120,6 @@ class OMGIRGenerator { using ArgumentList = Vector; using CallType = CallLinkInfo::CallType; using CallPatchpointData = std::tuple, RefPtr>; - using WasmConstRefValue = Const64Value; static constexpr bool shouldFuseBranchCompare = false; static constexpr bool tierSupportsSIMD = true; @@ -745,12 +738,9 @@ class OMGIRGenerator { PartialResult WARN_UNUSED_RETURN addCallRef(const TypeDefinition&, ArgumentList& args, ResultList& results, CallType = CallType::Call); PartialResult WARN_UNUSED_RETURN addUnreachable(); PartialResult WARN_UNUSED_RETURN addCrash(); - void fillCallResults(Value* callResult, const TypeDefinition& signature, ResultList& results); PartialResult WARN_UNUSED_RETURN emitIndirectCall(Value* calleeInstance, Value* calleeCode, Value* boxedCalleeCallee, const TypeDefinition&, const ArgumentList& args, ResultList&, CallType = CallType::Call); - - Vector createCallConstrainedArgs(BasicBlock*, const CallInformation& wasmCalleeInfo, const ArgumentList&); - auto createCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation&, const ArgumentList& tmpArgs) -> CallPatchpointData; - auto createTailCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; + auto createCallPatchpoint(BasicBlock*, B3::Type, const CallInformation&, const ArgumentList& tmpArgs) -> CallPatchpointData; + auto createTailCallPatchpoint(BasicBlock*, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; bool canInline(FunctionSpaceIndex functionIndexSpace) const; PartialResult WARN_UNUSED_RETURN emitInlineDirectCall(FunctionCodeIndex calleeIndex, const TypeDefinition&, ArgumentList& args, ResultList& results); @@ -1760,7 +1750,7 @@ auto OMGIRGenerator::emitIndirectCall(Value* calleeInstance, Value* calleeCode, const TypeDefinition& callerTypeDefinition = TypeInformation::get(callerTypeIndex).expand(); CallInformation wasmCallerInfoAsCallee = callingConvention.callInformationFor(callerTypeDefinition, CallRole::Callee); - auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { { calleeCode, ValueRep(GPRInfo::wasmScratchGPR0) } }); + auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { { calleeCode, ValueRep(GPRInfo::wasmScratchGPR0) } }); unsigned patchArgsIndex = patchpoint->reps().size(); patchpoint->append(calleeCode, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); patchpoint->append(boxedCalleeCallee, ValueRep::SomeRegister); @@ -1775,7 +1765,7 @@ auto OMGIRGenerator::emitIndirectCall(Value* calleeInstance, Value* calleeCode, } B3::Type returnType = toB3ResultType(&signature); - auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, signature, wasmCalleeInfo, args); + auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, returnType, wasmCalleeInfo, args); // We need to clobber all potential pinned registers since we might be leaving the instance. // We pessimistically assume we're always calling something that is bounds checking so // because the wasm->wasm thunk unconditionally overrides the size registers. @@ -4772,23 +4762,12 @@ auto OMGIRGenerator::addEndToUnreachable(ControlEntry& entry, const Stack& expre return { }; } -Vector OMGIRGenerator::createCallConstrainedArgs(BasicBlock* block, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -{ - Vector constrainedPatchArgs; - for (unsigned i = 0; i < tmpArgs.size(); ++i) { - auto dstLocation = wasmCalleeInfo.params[i]; - constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), dstLocation)); - } - - return constrainedPatchArgs; -} - -auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData +auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, B3::Type returnType, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData { - auto returnType = toB3ResultType(&signature); - - auto constrainedPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfo, tmpArgs); + Vector constrainedPatchArgs; + for (unsigned i = 0; i < tmpArgs.size(); ++i) + constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), wasmCalleeInfo.params[i])); Box exceptionHandle = Box::create(m_hasExceptionHandlers, callSiteIndex()); @@ -4812,10 +4791,9 @@ auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinitio return { patchpoint, exceptionHandle, nullptr }; } -// See createTailCallPatchpoint for the setup before this. -static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) +// See emitTailCallPatchpoint for the setup before this. +static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) { - auto& functionSignature = *signature.as(); const Checked offsetOfFirstSlotFromFP = WTF::roundUpToMultipleOf(wasmCallerInfoAsCallee.headerAndArgumentStackSizeInBytes); JIT_COMMENT(jit, "Set up tail call, new FP offset from FP: ", newFPOffsetFromFP); AllowMacroScratchRegisterUsage allowScratch(jit); @@ -4844,17 +4822,6 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } } - ASSERT(!calleeSaves.find(tmp)); - -#if ASSERT_ENABLED - // Let's make sure we never rely on these slots, so we can use them for scratch in the future. - // ARMv7 does currently use them. - jit.storePtr(MacroAssembler::TrustedImmPtr(0xBEEFAAAA), - CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrameSlot::thisArgument * sizeof(Register))); - jit.storePtr(MacroAssembler::TrustedImmPtr(0xBEEFAAAA), - CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrameSlot::argumentCountIncludingThis * sizeof(Register))); -#endif - const unsigned frameSize = params.code().frameSize(); ASSERT(WTF::roundUpToMultipleOf(frameSize) == frameSize); ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromFP)) == static_cast(std::abs(newFPOffsetFromFP))); @@ -4865,18 +4832,17 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& JIT_COMMENT(jit, "Let's use the caller's frame, so that we always have a valid frame."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebugSIMD([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, signature = Ref(signature), wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, params, functionIndex] (Probe::Context& context) { - auto& functionSignature = *signature->as(); - auto sp = context.gpr(MacroAssembler::stackPointerRegister); - auto fp = context.gpr(GPRInfo::callFrameRegister); + jit.probeDebugSIMD([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, wasmCalleeInfoAsCallee, firstPatchArg, params, functionIndex] (Probe::Context& context) { + uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); + uint64_t fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("Before tail call in function ", functionIndex, " before changing anything: FP: ", RawHex(fp), " SP: ", RawHex(sp)); dataLogLn("New FP will be at ", RawHex(sp + fpOffsetToSPOffset(newFPOffsetFromFP))); CallFrame* fpp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("callee original: ", RawPointer(fpp->callee().rawPtr())); - auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; + auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; dataLogLn("callee original: ", RawHex(wasmCallee), " at ", RawPointer(&wasmCallee)); dataLogLn("retPC original: ", RawPointer(fpp->rawReturnPCForInspection())); - auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uintptr_t)]; + auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uint64_t)]; dataLogLn("retPC original: ", RawHex(retPC), " at ", RawPointer(&retPC)); dataLogLn("callerFrame original: ", RawPointer(fpp->callerFrame())); ASSERT_UNUSED(frameSize, sp + frameSize == fp); @@ -4884,37 +4850,30 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& auto fpl = context.gpr(GPRInfo::callFrameRegister); auto fpi = context.gpr(GPRInfo::callFrameRegister); - unsigned currentPatchArg = firstPatchArg; - auto dumpSrc = [&context, fpl, fpi, fpp] (ValueRep src, Width width) { - dataLog(src, " = "); + for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { + auto src = params[firstPatchArg + i]; + auto dst = wasmCalleeInfoAsCallee.params[i].location; + auto width = wasmCalleeInfoAsCallee.params[i].width; + dataLog("Arg source ", i, " located at ", src, " = "); if (src.isGPR()) dataLog(context.gpr(src.gpr()), " / ", (int) context.gpr(src.gpr())); - else if (src.isFPR() && width <= Width64) + else if (src.isFPR() && width <= Width::Width64) dataLog(context.fpr(src.fpr(), SavedFPWidth::SaveVectors)); else if (src.isFPR()) dataLog(context.vector(src.fpr())); else if (src.isConstant()) dataLog(src.value(), " / ", src.doubleValue()); else - dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(*fpp)])); - }; - - for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { - auto width = functionSignature.argumentType(i).width(); - ASSERT(wasmCalleeInfoAsCallee.params[i].width >= width); - dataLog("Arg source ", i, " located at "); - ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); - dumpSrc(params[currentPatchArg++], width); - - dataLogLn(" ->(final) ", wasmCalleeInfoAsCallee.params[i].location); + dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(uint64_t)])); + dataLogLn(" -> ", dst); } }); } jit.loadPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrame::callerFrameOffset()), MacroAssembler::framePointerRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - auto sp = context.gpr(MacroAssembler::stackPointerRegister); - auto fp = context.gpr(GPRInfo::callFrameRegister); + uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); + uint64_t fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("In the new expanded frame, including F's caller: FP: ", RawHex(fp), " SP: ", RawHex(sp)); }); } @@ -4944,7 +4903,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& return offset; }; - auto doMove = [&jit, tmp] (int srcOffset, int dstOffset, Width width) { + auto doMove = [&] (int srcOffset, int dstOffset, Width width) { JIT_COMMENT(jit, "Do move ", srcOffset, " -> ", dstOffset); auto src = CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset); auto dst = CCallHelpers::Address(MacroAssembler::stackPointerRegister, dstOffset); @@ -4958,8 +4917,8 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { - auto val = context.gpr(tmp); - auto sp = context.gpr(MacroAssembler::stackPointerRegister); + uint64_t val = context.gpr(tmp); + uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); dataLogLn("Move value ", val, " / ", RawHex(val), " at ", RawHex(sp + srcOffset), " -> ", RawHex(sp + dstOffset), " width ", width); }); } @@ -4987,75 +4946,58 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& argsToMove.reserveInitialCapacity(wasmCalleeInfoAsCallee.params.size() + 1); if (clobbersTmp) { - tmpSpill = allocateSpill(WidthPtr); + tmpSpill = allocateSpill(Width::Width64); jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpill)); } // We will complete those moves who's source is closest to the danger frontier first. // That will move the danger frontier. - unsigned currentPatchArg = firstPatchArg; - for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { + + for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { auto dst = wasmCalleeInfoAsCallee.params[i]; - auto dstType = functionSignature.argumentType(i); - ASSERT(dst.width <= Width::Width64); - ASSERT(dst.width >= dstType.width()); if (dst.location.isGPR()) { ASSERT(!calleeSaves.find(dst.location.jsr().payloadGPR())); - currentPatchArg++; continue; } if (dst.location.isFPR()) { ASSERT(!calleeSaves.find(dst.location.fpr())); - currentPatchArg++; continue; } - - auto saveSrc = [tmp, dstType, &allocateSpill, &jit, &fpOffsetToSPOffset](ValueRep src) -> std::tuple { - int srcOffset = 0; - if (src.isGPR()) { - srcOffset = allocateSpill(WidthPtr); - jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (src.isFPR()) { - srcOffset = allocateSpill(dstType.width()); - if (dstType.width() <= Width::Width64) - jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - else - jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (src.isConstant()) { - if (toB3Type(dstType).kind() == Float) { - srcOffset = allocateSpill(Width32); - jit.move(MacroAssembler::TrustedImm32(src.value()), tmp); - jit.store32(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (toB3Type(dstType).kind() == Double) { - srcOffset = allocateSpill(Width64); - jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); - jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else { - srcOffset = allocateSpill(WidthPtr); - jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); - jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } - } else { - ASSERT(src.isStack()); - srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); - } - - return { srcOffset, dstType.width() }; - }; - - ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); - auto [srcOffset, srcWidth] = saveSrc(params[currentPatchArg++]); + auto src = params[firstPatchArg + i]; + ASSERT_UNUSED(lastPatchArg, firstPatchArg + i < lastPatchArg); + + intptr_t srcOffset = -1; + + if (src.isGPR()) { + ASSERT(dst.width <= Width::Width64); + srcOffset = allocateSpill(dst.width); + jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (src.isFPR()) { + srcOffset = allocateSpill(dst.width); + if (dst.width <= Width::Width64) + jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + else + jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (src.isConstant()) { + srcOffset = allocateSpill(dst.width); + ASSERT(dst.width <= Width::Width64); + jit.move(MacroAssembler::TrustedImm64(src.value()), tmp); + jit.store64(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else { + ASSERT(src.isStack()); + srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); + } intptr_t dstOffset = fpOffsetToSPOffset(checkedSum(dst.location.offsetFromFP(), newFPOffsetFromFP).value()); ASSERT(srcOffset >= 0); ASSERT(dstOffset >= 0); JIT_COMMENT(jit, "Arg ", i, " has srcOffset ", srcOffset, " dstOffset ", dstOffset); - argsToMove.append({ srcOffset, dstOffset, srcWidth }); + argsToMove.append({ srcOffset, dstOffset, dst.width }); } argsToMove.append({ fpOffsetToSPOffset(CallFrame::returnPCOffset()), newReturnPCOffset, - WidthPtr + Width::Width64 }); JIT_COMMENT(jit, "ReturnPC has srcOffset ", fpOffsetToSPOffset(CallFrame::returnPCOffset()), " dstOffset ", newReturnPCOffset); @@ -5118,11 +5060,11 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if CPU(ARM) || CPU(ARM64) || CPU(RISCV64) JIT_COMMENT(jit, "Load the return pointer from its saved location."); - jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, newFPOffsetFromSP + OBJECT_OFFSETOF(CallerFrameAndPC, returnPC)), tmp); + jit.load64(CCallHelpers::Address(MacroAssembler::stackPointerRegister, newFPOffsetFromSP + OBJECT_OFFSETOF(CallerFrameAndPC, returnPC)), tmp); jit.move(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } #if CPU(ARM64E) @@ -5131,7 +5073,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit.untagPtr(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } jit.validateUntaggedPtr(MacroAssembler::linkRegister); @@ -5143,7 +5085,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if CPU(X86_64) if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); }); } #endif @@ -5151,31 +5093,31 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if ASSERT_ENABLED for (unsigned i = 2; i < 50; ++i) { // Everthing after sp might be overwritten anyway. - jit.storePtr(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uintptr_t))); + jit.store64(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uint64_t))); } #endif JIT_COMMENT(jit, "OK, now we can jump."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([wasmCalleeInfoAsCallee] (Probe::Context& context) { - dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); - auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uintptr_t); + dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uint64_t); dataLogLn("New (callee) FP at prologue will be at ", RawPointer(newFP)); - auto fpl = std::bit_cast(newFP); - auto fpi = std::bit_cast(newFP); + auto fpl = static_cast(newFP); + auto fpi = reinterpret_cast(newFP); for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { auto arg = wasmCalleeInfoAsCallee.params[i]; auto src = arg.location; dataLog("Arg ", i, " located at ", arg.location, " = "); if (arg.location.isGPR()) - dataLog(context.gpr(arg.location.jsr().payloadGPR()), " / ", (int) context.gpr(arg.location.jsr().payloadGPR())); + dataLog(context.gpr(arg.location.jsr().gpr()), " / ", (int) context.gpr(arg.location.jsr().gpr())); else if (arg.location.isFPR() && arg.width <= Width::Width64) dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::SaveVectors)); else if (arg.location.isFPR()) dataLog(context.vector(arg.location.fpr())); else - dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(*fpi)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(*fpi)])); + dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(uint32_t)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(uint32_t)])); dataLogLn(); } }); @@ -5186,7 +5128,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } // See also: https://leaningtech.com/fantastic-tail-calls-and-how-to-implement-them/, a blog post about contributing this feature. -auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData +auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData { m_makesTailCalls = true; // Our args are placed in argument registers or locals. @@ -5256,20 +5198,20 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefin ASSERT(wasmCalleeInfoAsCallee.params.size() == tmpArgSourceLocations.size()); unsigned firstPatchArg = patchArgs.size(); - auto constrainedArgPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfoAsCallee, tmpArgSourceLocations); - - for (unsigned i = 0; i < constrainedArgPatchArgs.size(); ++i) { - auto src = constrainedArgPatchArgs[i].value(); - auto dst = constrainedArgPatchArgs[i].rep(); - ASSERT(dst.isStack() || dst.isFPR() || dst.isGPR()); - if (!dst.isStack()) { + for (unsigned i = 0; i < tmpArgSourceLocations.size(); ++i) { + auto src = get(block, tmpArgSourceLocations[i]); + auto dst = wasmCalleeInfoAsCallee.params[i]; + ASSERT(dst.location.isStack() || dst.location.isFPR() || dst.location.isGPR()); + ASSERT(dst.width >= src->resultWidth()); + if (!dst.location.isStack()) { // We will restore callee saves before jumping to the callee. // The calling convention should guarantee this anyway, but let's document it just in case. - ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.isGPR() ? Reg(dst.gpr()) : Reg(dst.fpr()), IgnoreVectors)); - patchArgs.append(constrainedArgPatchArgs[i]); + ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.location.isGPR() ? Reg(dst.location.jsr().gpr()) : Reg(dst.location.fpr()), IgnoreVectors)); + patchArgs.append(ConstrainedValue(src, dst)); continue; } - patchArgs.append(ConstrainedValue(src, ValueRep::LateColdAny)); + ASSERT(dst.width >= Width64); + patchArgs.append(src); } unsigned lastPatchArg = patchArgs.size(); @@ -5290,9 +5232,9 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefin firstPatchArg += m_proc.resultCount(patchpoint->type()); lastPatchArg += m_proc.resultCount(patchpoint->type()); - auto prepareForCall = createSharedTask([signature = Ref(signature), wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + auto prepareForCall = createSharedTask([wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { ASSERT(newFPOffsetFromFP >= 0 || params.code().frameSize() >= static_cast(-newFPOffsetFromFP)); - prepareForTailCallImpl(functionIndex, jit, params, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); + prepareForTailCallImpl(functionIndex, jit, params, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); }); return { patchpoint, nullptr, WTFMove(prepareForCall) }; @@ -5462,7 +5404,6 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe AllowMacroScratchRegisterUsage allowScratch(jit); if (prepareForCall) prepareForCall->run(jit, params); - ASSERT(!isTailCall || !handle); if (handle) handle->generate(jit, params, this); if (isTailCall) @@ -5484,12 +5425,12 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe jumpDestination = m_currentBlock->appendNew(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast(JSWebAssemblyInstance::offsetOfImportFunctionStub(functionIndexSpace))); if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitCallToImport(patchpoint, handle, prepareForCall); return { }; } - auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, signature, wasmCalleeInfo, args); + auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, returnType, wasmCalleeInfo, args); emitCallToImport(patchpoint, handle, prepareForCall); if (returnType != B3::Void) @@ -5530,7 +5471,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe }; if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitUnlinkedWasmToWasmCall(patchpoint, handle, prepareForCall); return { }; } @@ -5546,7 +5487,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe // 1. It is not tail-call. So this does not clobber the arguments of this function. // 2. We are not changing instance. Thus, |this| of this function's arguments are the same and OK. - auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, signature, wasmCalleeInfo, args); + auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, returnType, wasmCalleeInfo, args); emitUnlinkedWasmToWasmCall(patchpoint, handle, prepareForCall); // We need to clobber the size register since the LLInt always bounds checks if (useSignalingMemory() || m_info.memory.isShared()) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index 906474b28800..e6c17d4cef13 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -862,10 +862,8 @@ class OMGIRGenerator { PartialResult WARN_UNUSED_RETURN addCrash(); void fillCallResults(Value* callResult, const TypeDefinition& signature, ResultList& results); PartialResult WARN_UNUSED_RETURN emitIndirectCall(Value* calleeInstance, Value* calleeCode, Value* boxedCalleeCallee, const TypeDefinition&, const ArgumentList& args, ResultList&, CallType = CallType::Call); - - Vector createCallConstrainedArgs(BasicBlock*, const CallInformation& wasmCalleeInfo, const ArgumentList&); auto createCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation&, const ArgumentList& tmpArgs) -> CallPatchpointData; - auto createTailCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; + auto createTailCallPatchpoint(BasicBlock*, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; bool canInline(FunctionSpaceIndex functionIndexSpace) const; PartialResult WARN_UNUSED_RETURN emitInlineDirectCall(FunctionCodeIndex calleeIndex, const TypeDefinition&, ArgumentList& args, ResultList& results); @@ -1749,7 +1747,7 @@ auto OMGIRGenerator::addArguments(const TypeDefinition& signature) -> PartialRes patch->effects.writes = HeapRange::top(); m_currentBlock->append(patch); patch->setGenerator([functionIndex = m_functionIndex, signature = signature.as(), wasmCallInfo] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - jit.probeDebug([functionIndex, signature, wasmCallInfo] (Probe::Context& context) { + jit.probeDebugSIMD([functionIndex, signature, wasmCallInfo] (Probe::Context& context) { dataLogLn(" General Add arguments, fucntion ", functionIndex, " FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); auto fpl = context.gpr(GPRInfo::callFrameRegister); @@ -1761,12 +1759,10 @@ auto OMGIRGenerator::addArguments(const TypeDefinition& signature) -> PartialRes auto width = rep.width; dataLog(" Arg source ", i, " located at ", src, " = "); - if (src.isGPR()) { + if (src.isGPR()) dataLog(context.gpr(src.jsr().payloadGPR()), " / ", (int) context.gpr(src.jsr().payloadGPR())); - if (src.jsr().tagGPR()) - dataLog(" Upper bits: ", context.gpr(src.jsr().tagGPR()), " / ", (int) context.gpr(src.jsr().tagGPR())); - } else if (src.isFPR() && width <= Width::Width64) - dataLog(context.fpr(src.fpr(), SavedFPWidth::DontSaveVectors)); + else if (src.isFPR() && width <= Width::Width64) + dataLog(context.fpr(src.fpr(), SavedFPWidth::SaveVectors)); else if (src.isFPR()) RELEASE_ASSERT_NOT_REACHED(); else @@ -1997,10 +1993,6 @@ auto OMGIRGenerator::addCrash() -> PartialResult return { }; } - -static constexpr int tailCallPatchpointScratchOffsets[] = { CallFrameSlot::thisArgument * sizeof(Register), CallFrameSlot::argumentCountIncludingThis * sizeof(Register) }; -static constexpr int tailCallPatchpointScratchCount = sizeof(tailCallPatchpointScratchOffsets) / sizeof(tailCallPatchpointScratchOffsets[0]); - void OMGIRGenerator::fillCallResults(Value* callResult, const TypeDefinition& signature, ResultList& results) { B3::Type returnType = toB3ResultType(&signature); @@ -2101,38 +2093,16 @@ auto OMGIRGenerator::emitIndirectCall(Value* calleeInstance, Value* calleeCode, const TypeDefinition& callerTypeDefinition = TypeInformation::get(callerTypeIndex).expand(); CallInformation wasmCallerInfoAsCallee = callingConvention.callInformationFor(callerTypeDefinition, CallRole::Callee); - auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { { calleeCode, ValueRep(GPRInfo::wasmScratchGPR0) } }); unsigned patchArgsIndex = patchpoint->reps().size(); - if (is32Bit()) { - patchpoint->append(calleeCode, ValueRep::stackArgument(0)); - patchpoint->append(boxedCalleeCallee, ValueRep::stackArgument(8)); - } else { - patchpoint->append(calleeCode, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); - patchpoint->append(boxedCalleeCallee, ValueRep::SomeRegister); - } + patchpoint->append(calleeCode, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); + patchpoint->append(boxedCalleeCallee, ValueRep::SomeRegister); patchArgsIndex += m_proc.resultCount(patchpoint->type()); patchpoint->setGenerator([prepareForCall = prepareForCall, patchArgsIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); prepareForCall->run(jit, params); - GPRReg callTarget; - GPRReg callee; - if (is32Bit() && params[patchArgsIndex + 1].isStack()) { - callee = MacroAssembler::addressTempRegister; - jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, - tailCallPatchpointScratchOffsets[1] - sizeof(CallerFrameAndPC)), callee); - } else - callee = params[patchArgsIndex + 1].gpr(); - - jit.storeWasmCalleeCallee(callee, sizeof(CallerFrameAndPC) - prologueStackPointerDelta()); - - if (is32Bit() && params[patchArgsIndex].isStack()) { - callTarget = MacroAssembler::addressTempRegister; - jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, - tailCallPatchpointScratchOffsets[0] - sizeof(CallerFrameAndPC)), callTarget); - } else - callTarget = params[patchArgsIndex].gpr(); - - jit.farJump(callTarget, WasmEntryPtrTag); + jit.storeWasmCalleeCallee(params[patchArgsIndex + 1].gpr(), sizeof(CallerFrameAndPC) - prologueStackPointerDelta()); + jit.farJump(params[patchArgsIndex].gpr(), WasmEntryPtrTag); }); return { }; } @@ -5123,49 +5093,26 @@ auto OMGIRGenerator::addEndToUnreachable(ControlEntry& entry, const Stack& expre return { }; } -Vector OMGIRGenerator::createCallConstrainedArgs(BasicBlock* block, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) + +auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData { - Vector constrainedPatchArgs; - for (unsigned i = 0; i < tmpArgs.size(); ++i) { - auto dstLocation = wasmCalleeInfo.params[i]; - if (tmpArgs[i]->type() == Int64 && dstLocation.location.isGPR()) { - auto int64 = get(block, tmpArgs[i]); - auto hi = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64HighBits); - auto lo = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64LowBits); - constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::reg(dstLocation.location.jsr().payloadGPR()))); - constrainedPatchArgs.append(B3::ConstrainedValue(hi, ValueRep::reg(dstLocation.location.jsr().tagGPR()))); - continue; - } + auto& functionSignature = *signature.as(); + auto returnType = toB3ResultType(&signature); + Vector constrainedPatchArgs; + Vector constrainedPatchArgsHighBits; + for (unsigned i = 0; i < tmpArgs.size(); ++i) { if (tmpArgs[i]->type() == Int64) { auto int64 = get(block, tmpArgs[i]); - auto hi = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64HighBits); - auto lo = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64LowBits); - - if (dstLocation.location.isStack()) { - constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::stack(dstLocation.location.offsetFromFP()))); - constrainedPatchArgs.append(B3::ConstrainedValue(hi, ValueRep::stack(dstLocation.location.offsetFromFP() + sizeof(int)))); - } else { - ASSERT(dstLocation.location.isStackArgument()); - constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::stackArgument(dstLocation.location.offsetFromSP()))); - constrainedPatchArgs.append(B3::ConstrainedValue(hi, ValueRep::stackArgument(dstLocation.location.offsetFromSP() + sizeof(int)))); - } + auto hi = append(m_proc, origin(), Int32, int64, ExtractValue::s_int64HighBits); + auto lo = append(m_proc, origin(), Int32, int64, ExtractValue::s_int64LowBits); + constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::reg(wasmCalleeInfo.params[i].location.jsr().payloadGPR()))); + constrainedPatchArgsHighBits.append(B3::ConstrainedValue(hi, ValueRep::reg(wasmCalleeInfo.params[i].location.jsr().tagGPR()))); continue; } - constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), dstLocation)); + constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), wasmCalleeInfo.params[i])); } - return constrainedPatchArgs; -} - - -auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData -{ - auto& functionSignature = *signature.as(); - auto returnType = toB3ResultType(&signature); - - auto constrainedPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfo, tmpArgs); - Box exceptionHandle = Box::create(m_hasExceptionHandlers, callSiteIndex()); PatchpointValue* patchpoint = m_proc.add(returnType, origin()); @@ -5174,6 +5121,7 @@ auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinitio patchpoint->clobberEarly(RegisterSetBuilder::macroClobberedGPRs()); patchpoint->clobberLate(RegisterSetBuilder::registersToSaveForJSCall(m_proc.usesSIMD() ? RegisterSetBuilder::allRegisters() : RegisterSetBuilder::allScalarRegisters())); patchpoint->appendVector(constrainedPatchArgs); + patchpoint->appendVector(constrainedPatchArgsHighBits); *exceptionHandle = preparePatchpointForExceptions(block, patchpoint); @@ -5223,10 +5171,9 @@ auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinitio return { patchpoint, exceptionHandle, nullptr }; } -// See createTailCallPatchpoint for the setup before this. -static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) +// See emitTailCallPatchpoint for the setup before this. +static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) { - auto& functionSignature = *signature.as(); const Checked offsetOfFirstSlotFromFP = WTF::roundUpToMultipleOf(wasmCallerInfoAsCallee.headerAndArgumentStackSizeInBytes); JIT_COMMENT(jit, "Set up tail call, new FP offset from FP: ", newFPOffsetFromFP); AllowMacroScratchRegisterUsage allowScratch(jit); @@ -5237,10 +5184,6 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& auto tmp = jit.scratchRegister(); int tmpSpill = 0; - // If we pass a stack location to the patchpoint in arugmentCountIncludingThis, preserve it here. - bool stackPatchArg[tailCallPatchpointScratchCount] = { false, false }; - int stackPatchArgSpill[tailCallPatchpointScratchCount] = { 0, 0 }; - // Set up a valid frame so that we can clobber this one. RegisterAtOffsetList calleeSaves = params.code().calleeSaveRegisterAtOffsetList(); jit.emitRestore(calleeSaves); @@ -5259,44 +5202,9 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } } - for (unsigned i = lastPatchArg; i < params.size(); ++i) { - auto arg = params[i]; - if (arg.isStack()) { - unsigned scratch = -1; - for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { - if (!stackPatchArg[i]) { - scratch = i; - break; - } - } - ASSERT(scratch >= 0 && !stackPatchArg[scratch]); - stackPatchArg[scratch] = true; - if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebug([arg] (Probe::Context& context) { - dataLogLn("patch arg spill: ", RawHex(context.gpr(MacroAssembler::framePointerRegister)[arg.offsetFromFP() / sizeof(uintptr_t)])); - }); - } - // A convinent and save place to stash it. - jit.transferPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, arg.offsetFromFP()), - CCallHelpers::Address(MacroAssembler::framePointerRegister, tailCallPatchpointScratchOffsets[scratch])); - } else - ASSERT(arg.isGPR() || arg.isFPR()); - } - -#if ASSERT_ENABLED - // Let's make sure we never rely on these slots, since they may be used for scratch. - for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { - if (!stackPatchArg[i]) { - jit.storePtr(MacroAssembler::TrustedImmPtr(0xBEEFAAAA), - CCallHelpers::Address(MacroAssembler::framePointerRegister, tailCallPatchpointScratchOffsets[i])); - } - } -#endif - - ASSERT(!calleeSaves.find(tmp) || !clobbersTmp); - const unsigned frameSize = params.code().frameSize(); - ASSERT(WTF::roundUpToMultipleOf(frameSize + sizeof(CallerFrameAndPC)) == frameSize + sizeof(CallerFrameAndPC)); + ASSERT(WTF::roundUpToMultipleOf(frameSize) == frameSize); + ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromFP)) == static_cast(std::abs(newFPOffsetFromFP))); auto fpOffsetToSPOffset = [frameSize](int32_t offset) { return checkedSum(safeCast(frameSize), offset).value(); @@ -5304,18 +5212,17 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& JIT_COMMENT(jit, "Let's use the caller's frame, so that we always have a valid frame."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebug([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, signature = Ref(signature), wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, params, functionIndex] (Probe::Context& context) { - auto& functionSignature = *signature->as(); - auto sp = context.gpr(MacroAssembler::stackPointerRegister); - auto fp = context.gpr(GPRInfo::callFrameRegister); + jit.probeDebugSIMD([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, wasmCalleeInfoAsCallee, firstPatchArg, params, functionIndex] (Probe::Context& context) { + uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); + uint64_t fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("Before tail call in function ", functionIndex, " before changing anything: FP: ", RawHex(fp), " SP: ", RawHex(sp)); dataLogLn("New FP will be at ", RawHex(sp + fpOffsetToSPOffset(newFPOffsetFromFP))); CallFrame* fpp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("callee original: ", RawPointer(fpp->callee().rawPtr())); - auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; + auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; dataLogLn("callee original: ", RawHex(wasmCallee), " at ", RawPointer(&wasmCallee)); dataLogLn("retPC original: ", RawPointer(fpp->rawReturnPCForInspection())); - auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uintptr_t)]; + auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uint64_t)]; dataLogLn("retPC original: ", RawHex(retPC), " at ", RawPointer(&retPC)); dataLogLn("callerFrame original: ", RawPointer(fpp->callerFrame())); ASSERT_UNUSED(frameSize, sp + frameSize == fp); @@ -5323,43 +5230,30 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& auto fpl = context.gpr(GPRInfo::callFrameRegister); auto fpi = context.gpr(GPRInfo::callFrameRegister); - unsigned currentPatchArg = firstPatchArg; - auto dumpSrc = [&context, fpl, fpi, fpp] (ValueRep src, Width width) { - dataLog(src, " = "); + for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { + auto src = params[firstPatchArg + i]; + auto dst = wasmCalleeInfoAsCallee.params[i].location; + auto width = wasmCalleeInfoAsCallee.params[i].width; + dataLog("Arg source ", i, " located at ", src, " = "); if (src.isGPR()) dataLog(context.gpr(src.gpr()), " / ", (int) context.gpr(src.gpr())); - else if (src.isFPR() && width <= Width64) - dataLog(context.fpr(src.fpr(), SavedFPWidth::DontSaveVectors)); + else if (src.isFPR() && width <= Width::Width64) + dataLog(context.fpr(src.fpr(), SavedFPWidth::SaveVectors)); else if (src.isFPR()) RELEASE_ASSERT_NOT_REACHED(); else if (src.isConstant()) dataLog(src.value(), " / ", src.doubleValue()); else - dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(*fpp)])); - }; - - for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { - auto width = functionSignature.argumentType(i).width(); - ASSERT(wasmCalleeInfoAsCallee.params[i].width >= width); - dataLog("Arg source ", i, " located at "); - ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); - dumpSrc(params[currentPatchArg++], width); - if (is32Bit() && functionSignature.argumentType(i).isI64()) { - dataLog(" (Upper bits: "); - ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); - dumpSrc(params[currentPatchArg++], width); - dataLog(")"); - } - - dataLogLn(" ->(final) ", wasmCalleeInfoAsCallee.params[i].location); + dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(uint64_t)])); + dataLogLn(" -> ", dst); } }); } jit.loadPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrame::callerFrameOffset()), MacroAssembler::framePointerRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - auto sp = context.gpr(MacroAssembler::stackPointerRegister); - auto fp = context.gpr(GPRInfo::callFrameRegister); + uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); + uint64_t fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("In the new expanded frame, including F's caller: FP: ", RawHex(fp), " SP: ", RawHex(sp)); }); } @@ -5389,30 +5283,25 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& return offset; }; - auto doMove = [&jit, tmp] (int srcOffset, int dstOffset, Width width) { + auto doMove = [&] (int srcOffset, int dstOffset, Width width) { JIT_COMMENT(jit, "Do move ", srcOffset, " -> ", dstOffset); auto src = CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset); auto dst = CCallHelpers::Address(MacroAssembler::stackPointerRegister, dstOffset); if (width <= Width32) jit.transfer32(src, dst); - else if (width <= Width64) - jit.transfer64(src, dst); - else { - jit.transfer64(src, dst); - jit.transfer64(src.withOffset(bytesForWidth(Width::Width64)), dst.withOffset(bytesForWidth(Width::Width64))); - } + else + RELEASE_ASSERT_NOT_REACHED(); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.loadPtr(dst, tmp); - jit.probeDebug([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { - auto val = context.gpr(tmp); - auto sp = context.gpr(MacroAssembler::stackPointerRegister); + jit.probeDebugSIMD([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { + uint64_t val = context.gpr(tmp); + uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); dataLogLn("Move value ", val, " / ", RawHex(val), " at ", RawHex(sp + srcOffset), " -> ", RawHex(sp + dstOffset), " width ", width); }); } }; // This should grow down towards SP (towards 0) as we move stuff out of the way. - int safeAreaLowerBound = fpOffsetToSPOffset(CallFrameSlot::firstArgument * sizeof(Register)); + int safeAreaLowerBound = fpOffsetToSPOffset(CallFrameSlot::codeBlock * sizeof(Register)); const int stackUpperBound = fpOffsetToSPOffset(offsetOfFirstSlotFromFP); // ArgN in the stack diagram ASSERT(safeAreaLowerBound > 0); ASSERT(safeAreaLowerBound < stackUpperBound); @@ -5433,106 +5322,61 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& argsToMove.reserveInitialCapacity(wasmCalleeInfoAsCallee.params.size() + 1); if (clobbersTmp) { - tmpSpill = allocateSpill(WidthPtr); + tmpSpill = allocateSpill(Width::Width64); jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpill)); } - - for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { - if (stackPatchArg[i]) { - stackPatchArgSpill[i] = allocateSpill(WidthPtr); - jit.transferPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, fpOffsetToSPOffset(tailCallPatchpointScratchOffsets[i])), CCallHelpers::Address(MacroAssembler::stackPointerRegister, stackPatchArgSpill[i])); - } - } - // We will complete those moves who's source is closest to the danger frontier first. // That will move the danger frontier. - unsigned currentPatchArg = firstPatchArg; - for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { + + for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { auto dst = wasmCalleeInfoAsCallee.params[i]; - auto dstType = functionSignature.argumentType(i); - ASSERT(dst.width <= Width::Width64); - ASSERT(dst.width >= dstType.width()); if (dst.location.isGPR()) { ASSERT(!calleeSaves.find(dst.location.jsr().payloadGPR())); - currentPatchArg += dstType.width() == Width64 ? 2 : 1; continue; } if (dst.location.isFPR()) { ASSERT(!calleeSaves.find(dst.location.fpr())); - currentPatchArg++; continue; } - - auto saveSrc = [tmp, dstType, &allocateSpill, &jit, &fpOffsetToSPOffset](ValueRep src) -> std::tuple { - int srcOffset = 0; - if (src.isGPR()) { - srcOffset = allocateSpill(WidthPtr); - jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - return { srcOffset, WidthPtr }; - } - if (src.isFPR()) { - srcOffset = allocateSpill(dstType.width()); - if (dstType.width() <= Width::Width64) - jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - else - jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (src.isConstant()) { - if (toB3Type(dstType).kind() == Float) { - srcOffset = allocateSpill(Width32); - jit.move(MacroAssembler::TrustedImm32(src.value()), tmp); - jit.store32(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (toB3Type(dstType).kind() == Double) { - srcOffset = allocateSpill(Width64); - jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); - jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - jit.move(MacroAssembler::TrustedImmPtr(src.value() >> 32), tmp); - jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset + sizeof(int))); - } else { - srcOffset = allocateSpill(WidthPtr); - jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); - jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - return { srcOffset, WidthPtr }; - } - } else { - ASSERT(src.isStack()); - srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); - - if (is32Bit() && toB3Type(dstType).kind() == Int64) - return { srcOffset, WidthPtr }; - } - - return { srcOffset, dstType.width() }; - }; - - ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); - auto [srcOffset, srcWidth] = saveSrc(params[currentPatchArg++]); + auto src = params[firstPatchArg + i]; + ASSERT_UNUSED(lastPatchArg, firstPatchArg + i < lastPatchArg); + + intptr_t srcOffset = -1; + + if (src.isGPR()) { + ASSERT(dst.width <= Width::Width32); + srcOffset = allocateSpill(dst.width); + jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (src.isFPR()) { + srcOffset = allocateSpill(dst.width); + if (dst.width <= Width::Width64) + jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + else + jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (src.isConstant()) { + srcOffset = allocateSpill(dst.width); + ASSERT(dst.width <= Width::Width32); + jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); + jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else { + ASSERT(src.isStack()); + srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); + } intptr_t dstOffset = fpOffsetToSPOffset(checkedSum(dst.location.offsetFromFP(), newFPOffsetFromFP).value()); ASSERT(srcOffset >= 0); ASSERT(dstOffset >= 0); JIT_COMMENT(jit, "Arg ", i, " has srcOffset ", srcOffset, " dstOffset ", dstOffset); - argsToMove.append({ srcOffset, dstOffset, srcWidth }); - - if (is32Bit() && srcWidth < dstType.width()) { - ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); - auto [srcOffsetUpperBits, srcWidthUpperBits] = saveSrc(params[currentPatchArg++]); - ASSERT(srcWidthUpperBits == WidthPtr); - argsToMove.append({ srcOffsetUpperBits, dstOffset + sizeof(int), srcWidthUpperBits }); - } + argsToMove.append({ srcOffset, dstOffset, dst.width }); } argsToMove.append({ fpOffsetToSPOffset(CallFrame::returnPCOffset()), newReturnPCOffset, - WidthPtr + Width::Width64 }); JIT_COMMENT(jit, "ReturnPC has srcOffset ", fpOffsetToSPOffset(CallFrame::returnPCOffset()), " dstOffset ", newReturnPCOffset); - for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { - if (stackPatchArg[i]) - argsToMove.append({ stackPatchArgSpill[i], fpOffsetToSPOffset(tailCallPatchpointScratchOffsets[i] + newFPOffsetFromFP), WidthPtr }); - } - std::sort( argsToMove.begin(), argsToMove.end(), [] (const auto& left, const auto& right) { @@ -5583,7 +5427,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& // Also pop callee. auto newFPOffsetFromSP = fpOffsetToSPOffset(newFPOffsetFromFP); ASSERT(newFPOffsetFromSP > 0); - ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromSP) + sizeof(CallerFrameAndPC)) == static_cast(std::abs(newFPOffsetFromSP) + sizeof(CallerFrameAndPC))); + ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromSP)) == static_cast(std::abs(newFPOffsetFromSP))); auto newSPAtPrologueOffsetFromSP = newFPOffsetFromSP + prologueStackPointerDelta(); @@ -5596,7 +5440,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit.move(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } #if CPU(ARM64E) @@ -5605,7 +5449,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit.untagPtr(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } jit.validateUntaggedPtr(MacroAssembler::linkRegister); @@ -5617,7 +5461,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if CPU(X86_64) if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); }); } #endif @@ -5625,33 +5469,31 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if ASSERT_ENABLED for (unsigned i = 2; i < 50; ++i) { // Everthing after sp might be overwritten anyway. - jit.storePtr(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uintptr_t))); + jit.storePtr(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uint64_t))); } #endif JIT_COMMENT(jit, "OK, now we can jump."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebug([wasmCalleeInfoAsCallee] (Probe::Context& context) { - dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); - auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uintptr_t); + jit.probeDebugSIMD([wasmCalleeInfoAsCallee] (Probe::Context& context) { + dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uint64_t); dataLogLn("New (callee) FP at prologue will be at ", RawPointer(newFP)); - auto fpl = std::bit_cast(newFP); - auto fpi = std::bit_cast(newFP); + auto fpl = static_cast(newFP); + auto fpi = reinterpret_cast(newFP); for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { auto arg = wasmCalleeInfoAsCallee.params[i]; auto src = arg.location; dataLog("Arg ", i, " located at ", arg.location, " = "); - if (arg.location.isGPR()) { + if (arg.location.isGPR()) dataLog(context.gpr(arg.location.jsr().payloadGPR()), " / ", (int) context.gpr(arg.location.jsr().payloadGPR())); - if (src.jsr().tagGPR()) - dataLog(" Upper bits: ", context.gpr(src.jsr().tagGPR()), " / ", (int) context.gpr(src.jsr().tagGPR())); - } else if (arg.location.isFPR() && arg.width <= Width::Width64) - dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::DontSaveVectors)); + else if (arg.location.isFPR() && arg.width <= Width::Width64) + dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::SaveVectors)); else if (arg.location.isFPR()) RELEASE_ASSERT_NOT_REACHED(); else - dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(*fpi)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(*fpi)])); + dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(uint32_t)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(uint32_t)])); dataLogLn(); } }); @@ -5662,7 +5504,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } // See also: https://leaningtech.com/fantastic-tail-calls-and-how-to-implement-them/, a blog post about contributing this feature. -auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData +auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData { m_makesTailCalls = true; // Our args are placed in argument registers or locals. @@ -5671,6 +5513,7 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefin // - Restore and re-sign lr // - Restore our caller's FP so that the stack area we write to is always valid // - Move stack args from our stack to their final resting spots. Note that they might overlap. + // - Move argumentCountIncludingThis (a.k.a. callSiteIndex) to its final spot, since WASM uses it for exceptions. // Layout of stack right now, and after this patchpoint. // // @@ -5723,31 +5566,28 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefin #if ASSERT_ENABLED for (unsigned i = 0; i < patchArgs.size(); ++i) { // We will clobber our stack, so we shouldn't be reading any special extra patch args from it after this point. - // If we do need a stack arg, we can only save one. - ASSERT(patchArgs[i].rep().isReg() - || patchArgs[i].rep().isConstant() - || (patchArgs[i].rep().isStackArgument() && patchArgs.size() == 1)); - ASSERT(!patchArgs[i].rep().isReg() || !scratchRegisters.contains(patchArgs[i].rep().reg(), IgnoreVectors)); + ASSERT(patchArgs[i].rep().isReg() || patchArgs[i].rep().isConstant()); + ASSERT(!scratchRegisters.contains(patchArgs[i].rep().reg(), IgnoreVectors)); } #endif ASSERT(wasmCalleeInfoAsCallee.params.size() == tmpArgSourceLocations.size()); unsigned firstPatchArg = patchArgs.size(); - auto constrainedArgPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfoAsCallee, tmpArgSourceLocations); - - for (unsigned i = 0; i < constrainedArgPatchArgs.size(); ++i) { - auto src = constrainedArgPatchArgs[i].value(); - auto dst = constrainedArgPatchArgs[i].rep(); - ASSERT(dst.isStack() || dst.isFPR() || dst.isGPR()); - if (!dst.isStack()) { + for (unsigned i = 0; i < tmpArgSourceLocations.size(); ++i) { + auto src = get(block, tmpArgSourceLocations[i]); + auto dst = wasmCalleeInfoAsCallee.params[i]; + ASSERT(dst.location.isStack() || dst.location.isFPR() || dst.location.isGPR()); + ASSERT(dst.width >= src->resultWidth()); + if (!dst.location.isStack()) { // We will restore callee saves before jumping to the callee. // The calling convention should guarantee this anyway, but let's document it just in case. - ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.isGPR() ? Reg(dst.gpr()) : Reg(dst.fpr()), IgnoreVectors)); - patchArgs.append(constrainedArgPatchArgs[i]); + ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.location.isGPR() ? Reg(dst.location.jsr().payloadGPR()) : Reg(dst.location.fpr()), IgnoreVectors)); + patchArgs.append(ConstrainedValue(src, dst)); continue; } - patchArgs.append(ConstrainedValue(src, ValueRep::LateColdAny)); + ASSERT(dst.width >= Width64); + patchArgs.append(src); } unsigned lastPatchArg = patchArgs.size(); @@ -5768,9 +5608,9 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefin firstPatchArg += m_proc.resultCount(patchpoint->type()); lastPatchArg += m_proc.resultCount(patchpoint->type()); - auto prepareForCall = createSharedTask([signature = Ref(signature), wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + auto prepareForCall = createSharedTask([wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { ASSERT(newFPOffsetFromFP >= 0 || params.code().frameSize() >= static_cast(-newFPOffsetFromFP)); - prepareForTailCallImpl(functionIndex, jit, params, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); + prepareForTailCallImpl(functionIndex, jit, params, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); }); return { patchpoint, nullptr, WTFMove(prepareForCall) }; @@ -5904,15 +5744,12 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe if (isTailCall || isTailCallInlineCaller) m_makesTailCalls = true; - m_proc.requestCallArgAreaSizeInBytes(calleeStackSize + sizeof(Register)); + m_proc.requestCallArgAreaSizeInBytes(calleeStackSize); if (m_info.isImportedFunctionFromFunctionIndexSpace(functionIndexSpace)) { auto emitCallToImport = [&, this](PatchpointValue* patchpoint, Box handle, RefPtr prepareForCall) -> void { unsigned patchArgsIndex = patchpoint->reps().size(); - if (is32Bit() && isTailCall) - patchpoint->append(jumpDestination, ValueRep::stackArgument(0)); - else - patchpoint->append(jumpDestination, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); + patchpoint->append(jumpDestination, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); // We need to clobber all potential pinned registers since we might be leaving the instance. // We pessimistically assume we could be calling to something that is bounds checking. // FIXME: We shouldn't have to do this: https://bugs.webkit.org/show_bug.cgi?id=172181 @@ -5922,24 +5759,10 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe AllowMacroScratchRegisterUsage allowScratch(jit); if (prepareForCall) prepareForCall->run(jit, params); - ASSERT(!isTailCall || !handle); if (handle) handle->generate(jit, params, this); - if (isTailCall) { - GPRReg callTarget; - if (is32Bit() && params[patchArgsIndex].isStack()) { - callTarget = MacroAssembler::addressTempRegister; - jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, - tailCallPatchpointScratchOffsets[0] - sizeof(CallerFrameAndPC)), callTarget); - } else - callTarget = params[patchArgsIndex].gpr(); - if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebug([callTarget] (Probe::Context& context) { - dataLogLn("Can now jump: ", RawHex(context.gpr(callTarget))); - }); - } - jit.farJump(callTarget, WasmEntryPtrTag); - } + if (isTailCall) + jit.farJump(params[patchArgsIndex].gpr(), WasmEntryPtrTag); else { jit.call(params[patchArgsIndex].gpr(), WasmEntryPtrTag); // Restore the stack pointer since it may have been lowered if our callee did a tail call. @@ -5957,7 +5780,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe jumpDestination = append(heapImports(), m_proc, Load, pointerType(), origin(), instanceValue(), safeCast(JSWebAssemblyInstance::offsetOfImportFunctionStub(functionIndexSpace))); if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitCallToImport(patchpoint, handle, prepareForCall); return { }; } @@ -6003,7 +5826,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe }; if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitUnlinkedWasmToWasmCall(patchpoint, handle, prepareForCall); return { }; } From 48ec0a48e35aa4cc77a06eda4ed859fdbeae5ede Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 12 Mar 2025 20:00:35 -0700 Subject: [PATCH 43/54] [ARMv7] [Re-Land] Implement OMG tail calls https://bugs.webkit.org/show_bug.cgi?id=282870 Reviewed by OOPS. This patch re-lands 287649@main, removing a spurious assert on 64-bit. Implement OMG tail calls. The big difference from 64-bit is that Int64 args (but not double args) need to be split when entering into the patchpoint. We also have no non-callee-save registers to pass into the tail call patchpoint, so we re-purpose some unused slots on the stack. * JSTests/wasm/stress/tail-call-simple-i64.js: Added. (from.string_appeared_here.import.as.assert.from.string_appeared_here.let.wat.module.func.call_same_size.export.string_appeared_here.result.i64.i64.const.600000001337.return_call.callee_same_size.func.callee_same_size.param.i.i64.result.i64.i64.add.local.i.i64.const.42.func.call_same_size_with_stack.export.string_appeared_here.param.i0.i64.param.i1.i64.param.i2.i64.param.i3.i64.param.i4.i64.param.i5.i64.param.i6.i64.param.i7.i64.param.i8.i64.param.i9.i64.result.i64.i64.const.600000001337.i64.const.1.i64.const.2.i64.const.3.i64.const.4.i64.const.5.i64.const.6.i64.const.7.i64.const.8.i64.const.40000000009.return_call.callee_same_size_with_stack.func.callee_same_size_with_stack.param.i0.i64.param.i1.i64.param.i2.i64.param.i3.i64.param.i4.i64.param.i5.i64.param.i6.i64.param.i7.i64.param.i8.i64.param.i9.i64.result.i64.i64.add.local.i9.local.i2.func.call_bigger_with_stack.export.string_appeared_here.result.i64.i64.const.600000001337.i64.const.1.i64.const.2.i64.const.3.i64.const.4.i64.const.5.i64.const.6.i64.const.7.i64.const.8.i64.const.500000000090.return_call.callee_bigger_with_stack.func.callee_bigger_with_stack.param.i0.i64.param.i1.i64.param.i2.i64.param.i3.i64.param.i4.i64.param.i5.i64.param.i6.i64.param.i7.i64.param.i8.i64.param.i9.i64.result.i64.i64.add.local.i9.local.i2.func.call_smaller_with_stack.export.string_appeared_here.param.i0.i64.param.i1.i64.param.i2.i64.param.i3.i64.param.i4.i64.param.i5.i64.param.i6.i64.param.i7.i64.param.i8.i64.param.i9.i64.param.i10.i64.param.i11.i64.result.i64.i64.const.600000001337.i64.const.1.i64.const.2.i64.const.3.i64.const.4.i64.const.5.i64.const.6.i64.const.7.i64.const.8.i64.const.500000000090.return_call.callee_smaller_with_stack.func.callee_smaller_with_stack.param.i0.i64.param.i1.i64.param.i2.i64.param.i3.i64.param.i4.i64.param.i5.i64.param.i6.i64.param.i7.i64.param.i8.i64.param.i9.i64.result.i64.i64.add.local.i9.local.i2.let.badArgs.new.Array.12.fill.0xAAAAn.async test): * Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::transfer64): * Source/JavaScriptCore/jit/Width.h: * Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp: * Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp: (JSC::Wasm::OMGIRGenerator::addArguments): (JSC::Wasm::OMGIRGenerator::emitIndirectCall): (JSC::Wasm::OMGIRGenerator::createCallConstrainedArgs): (JSC::Wasm::OMGIRGenerator::createCallPatchpoint): (JSC::Wasm::prepareForTailCallImpl): (JSC::Wasm::OMGIRGenerator::createTailCallPatchpoint): Originally-landed-as: 287649@main (da8e66a). https://bugs.webkit.org/show_bug.cgi?id=282870 Canonical link: https://commits.webkit.org/292059@main (cherry picked from commit ec39ad5c01f7f39c39ca58ae580421cec8f01683) --- JSTests/wasm/stress/tail-call-simple-i64.js | 72 ++++ .../assembler/MacroAssemblerARMv7.h | 11 + Source/JavaScriptCore/b3/B3MoveConstants.cpp | 6 + Source/JavaScriptCore/jit/Width.h | 6 + .../wasm/WasmOMGIRGenerator.cpp | 230 ++++++---- .../wasm/WasmOMGIRGenerator32_64.cpp | 407 +++++++++++++----- 6 files changed, 532 insertions(+), 200 deletions(-) create mode 100644 JSTests/wasm/stress/tail-call-simple-i64.js diff --git a/JSTests/wasm/stress/tail-call-simple-i64.js b/JSTests/wasm/stress/tail-call-simple-i64.js new file mode 100644 index 000000000000..a29cb621e468 --- /dev/null +++ b/JSTests/wasm/stress/tail-call-simple-i64.js @@ -0,0 +1,72 @@ +//@ requireOptions("--useWasmTailCalls=true", "--maximumWasmCalleeSIzeForInlining=0") +import { instantiate } from "../wabt-wrapper.js" +import * as assert from "../assert.js" + +let wat = ` +(module + (func $call_same_size (export "call_same_size") (result i64) + (i64.const 600000001337) + (return_call $callee_same_size)) + (func $callee_same_size (param $i i64) (result i64) + (i64.add (local.get $i) (i64.const 42))) + (func $call_same_size_with_stack (export "call_same_size_with_stack") (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) + (i64.const 600000001337) + (i64.const 1) + (i64.const 2) + (i64.const 3) + (i64.const 4) + (i64.const 5) + (i64.const 6) + (i64.const 7) + (i64.const 8) + (i64.const 40000000009) + (return_call $callee_same_size_with_stack)) + (func $callee_same_size_with_stack (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) + (i64.add (local.get $i9) (local.get $i2))) + + (func $call_bigger_with_stack (export "call_bigger_with_stack") (result i64) + (i64.const 600000001337) + (i64.const 1) + (i64.const 2) + (i64.const 3) + (i64.const 4) + (i64.const 5) + (i64.const 6) + (i64.const 7) + (i64.const 8) + (i64.const 500000000090) + (return_call $callee_bigger_with_stack)) + (func $callee_bigger_with_stack (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) + (i64.add (local.get $i9) (local.get $i2))) + (func $call_smaller_with_stack (export "call_smaller_with_stack") (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (param $i10 i64) (param $i11 i64) (result i64) + (i64.const 600000001337) + (i64.const 1) + (i64.const 2) + (i64.const 3) + (i64.const 4) + (i64.const 5) + (i64.const 6) + (i64.const 7) + (i64.const 8) + (i64.const 500000000090) + (return_call $callee_smaller_with_stack)) + (func $callee_smaller_with_stack (param $i0 i64) (param $i1 i64) (param $i2 i64) (param $i3 i64) (param $i4 i64) (param $i5 i64) (param $i6 i64) (param $i7 i64) (param $i8 i64) (param $i9 i64) (result i64) + (i64.add (local.get $i9) (local.get $i2))) + ) +` +let badArgs = new Array(12).fill(0xAAAAn) + +async function test() { + const instance = await instantiate(wat, {}, { simd: true, tail_call: true, exceptions: true }) + const { call_same_size, call_same_size_with_stack, call_bigger_with_stack, call_smaller_with_stack } = instance.exports + + + for (let i = 0; i < 1000; ++i) { + assert.eq(call_same_size.apply(null, badArgs), 600000001337n + 42n) + assert.eq(call_same_size_with_stack.apply(null, badArgs), 40000000009n + 2n) + assert.eq(call_bigger_with_stack.apply(null, badArgs), 500000000090n + 2n) + assert.eq(call_smaller_with_stack.apply(null, badArgs), 500000000090n + 2n) + } +} + +await assert.asyncTest(test()) \ No newline at end of file diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 69c321e85ab8..301b29fed204 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -1398,6 +1398,17 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { store32(dataTempRegister, dest); } + // Warning: not atomic. + void transfer64(Address src, Address dest) + { + if (src == dest) + return; + load32(src, dataTempRegister); + store32(dataTempRegister, dest); + load32(src.withOffset(sizeof(int)), dataTempRegister); + store32(dataTempRegister, dest.withOffset(sizeof(int))); + } + void transferPtr(Address src, Address dest) { transfer32(src, dest); diff --git a/Source/JavaScriptCore/b3/B3MoveConstants.cpp b/Source/JavaScriptCore/b3/B3MoveConstants.cpp index c4336ae157ab..a971a7dbf230 100644 --- a/Source/JavaScriptCore/b3/B3MoveConstants.cpp +++ b/Source/JavaScriptCore/b3/B3MoveConstants.cpp @@ -340,6 +340,12 @@ class MoveConstants { if (child->type().isVector()) continue; + // BigImms don't work reliably for 32-bit, so this is the most reliable. + if constexpr (is32Bit()) { + if (child->hasDouble() && !WTF::isIdentical(child->asDouble(), 0.0)) + continue; + } + ValueKey key = child->key(); child = m_insertionSet.insertValue( valueIndex, key.materialize(m_proc, value->origin())); diff --git a/Source/JavaScriptCore/jit/Width.h b/Source/JavaScriptCore/jit/Width.h index 8fd16e0d298c..bc64e5e9ef3f 100644 --- a/Source/JavaScriptCore/jit/Width.h +++ b/Source/JavaScriptCore/jit/Width.h @@ -44,6 +44,12 @@ static constexpr Width Width32 = Width::Width32; static constexpr Width Width64 = Width::Width64; static constexpr Width Width128 = Width::Width128; +#if USE(JSVALUE64) +static constexpr Width WidthPtr = Width::Width64; +#else +static constexpr Width WidthPtr = Width::Width32; +#endif + enum class PreservedWidth : uint8_t { PreservesNothing = 0, Preserves64 = 1, diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp index d7d782850355..ccaa43d1212c 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp @@ -96,6 +96,12 @@ namespace JSC { namespace Wasm { using namespace B3; namespace { +#if USE(JSVALUE32_64) +using ConstIntPtrValue = Const32Value; +#else +using ConstIntPtrValue = Const64Value; +#endif + namespace WasmOMGIRGeneratorInternal { static constexpr bool verbose = false; static constexpr bool verboseInlining = false; @@ -120,6 +126,7 @@ class OMGIRGenerator { using ArgumentList = Vector; using CallType = CallLinkInfo::CallType; using CallPatchpointData = std::tuple, RefPtr>; + using WasmConstRefValue = Const64Value; static constexpr bool shouldFuseBranchCompare = false; static constexpr bool tierSupportsSIMD = true; @@ -738,9 +745,12 @@ class OMGIRGenerator { PartialResult WARN_UNUSED_RETURN addCallRef(const TypeDefinition&, ArgumentList& args, ResultList& results, CallType = CallType::Call); PartialResult WARN_UNUSED_RETURN addUnreachable(); PartialResult WARN_UNUSED_RETURN addCrash(); + void fillCallResults(Value* callResult, const TypeDefinition& signature, ResultList& results); PartialResult WARN_UNUSED_RETURN emitIndirectCall(Value* calleeInstance, Value* calleeCode, Value* boxedCalleeCallee, const TypeDefinition&, const ArgumentList& args, ResultList&, CallType = CallType::Call); - auto createCallPatchpoint(BasicBlock*, B3::Type, const CallInformation&, const ArgumentList& tmpArgs) -> CallPatchpointData; - auto createTailCallPatchpoint(BasicBlock*, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; + + Vector createCallConstrainedArgs(BasicBlock*, const CallInformation& wasmCalleeInfo, const ArgumentList&); + auto createCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation&, const ArgumentList& tmpArgs) -> CallPatchpointData; + auto createTailCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; bool canInline(FunctionSpaceIndex functionIndexSpace) const; PartialResult WARN_UNUSED_RETURN emitInlineDirectCall(FunctionCodeIndex calleeIndex, const TypeDefinition&, ArgumentList& args, ResultList& results); @@ -1750,7 +1760,7 @@ auto OMGIRGenerator::emitIndirectCall(Value* calleeInstance, Value* calleeCode, const TypeDefinition& callerTypeDefinition = TypeInformation::get(callerTypeIndex).expand(); CallInformation wasmCallerInfoAsCallee = callingConvention.callInformationFor(callerTypeDefinition, CallRole::Callee); - auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { { calleeCode, ValueRep(GPRInfo::wasmScratchGPR0) } }); + auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { { calleeCode, ValueRep(GPRInfo::wasmScratchGPR0) } }); unsigned patchArgsIndex = patchpoint->reps().size(); patchpoint->append(calleeCode, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); patchpoint->append(boxedCalleeCallee, ValueRep::SomeRegister); @@ -1765,7 +1775,7 @@ auto OMGIRGenerator::emitIndirectCall(Value* calleeInstance, Value* calleeCode, } B3::Type returnType = toB3ResultType(&signature); - auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, returnType, wasmCalleeInfo, args); + auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, signature, wasmCalleeInfo, args); // We need to clobber all potential pinned registers since we might be leaving the instance. // We pessimistically assume we're always calling something that is bounds checking so // because the wasm->wasm thunk unconditionally overrides the size registers. @@ -4762,12 +4772,24 @@ auto OMGIRGenerator::addEndToUnreachable(ControlEntry& entry, const Stack& expre return { }; } +Vector OMGIRGenerator::createCallConstrainedArgs(BasicBlock* block, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) +{ + Vector constrainedPatchArgs; + constrainedPatchArgs.reserveCapacity(tmpArgs.size()); + for (unsigned i = 0; i < tmpArgs.size(); ++i) { + auto dstLocation = wasmCalleeInfo.params[i]; + constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), dstLocation)); + } + + return constrainedPatchArgs; +} + -auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, B3::Type returnType, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData +auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData { - Vector constrainedPatchArgs; - for (unsigned i = 0; i < tmpArgs.size(); ++i) - constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), wasmCalleeInfo.params[i])); + auto returnType = toB3ResultType(&signature); + + auto constrainedPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfo, tmpArgs); Box exceptionHandle = Box::create(m_hasExceptionHandlers, callSiteIndex()); @@ -4791,9 +4813,10 @@ auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, B3::Type returnType return { patchpoint, exceptionHandle, nullptr }; } -// See emitTailCallPatchpoint for the setup before this. -static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) +// See createTailCallPatchpoint for the setup before this. +static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) { + auto& functionSignature = *signature.as(); const Checked offsetOfFirstSlotFromFP = WTF::roundUpToMultipleOf(wasmCallerInfoAsCallee.headerAndArgumentStackSizeInBytes); JIT_COMMENT(jit, "Set up tail call, new FP offset from FP: ", newFPOffsetFromFP); AllowMacroScratchRegisterUsage allowScratch(jit); @@ -4822,6 +4845,17 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } } + ASSERT(!calleeSaves.find(tmp)); + +#if ASSERT_ENABLED + // Let's make sure we never rely on these slots, so we can use them for scratch in the future. + // ARMv7 does currently use them. + jit.storePtr(MacroAssembler::TrustedImmPtr(0xBEEFAAAA), + CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrameSlot::thisArgument * sizeof(Register))); + jit.storePtr(MacroAssembler::TrustedImmPtr(0xBEEFAAAA), + CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrameSlot::argumentCountIncludingThis * sizeof(Register))); +#endif + const unsigned frameSize = params.code().frameSize(); ASSERT(WTF::roundUpToMultipleOf(frameSize) == frameSize); ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromFP)) == static_cast(std::abs(newFPOffsetFromFP))); @@ -4832,17 +4866,18 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& JIT_COMMENT(jit, "Let's use the caller's frame, so that we always have a valid frame."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebugSIMD([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, wasmCalleeInfoAsCallee, firstPatchArg, params, functionIndex] (Probe::Context& context) { - uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); - uint64_t fp = context.gpr(GPRInfo::callFrameRegister); + jit.probeDebugSIMD([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, signature = Ref(signature), wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, params, functionIndex] (Probe::Context& context) { + auto& functionSignature = *signature->as(); + auto sp = context.gpr(MacroAssembler::stackPointerRegister); + auto fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("Before tail call in function ", functionIndex, " before changing anything: FP: ", RawHex(fp), " SP: ", RawHex(sp)); dataLogLn("New FP will be at ", RawHex(sp + fpOffsetToSPOffset(newFPOffsetFromFP))); CallFrame* fpp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("callee original: ", RawPointer(fpp->callee().rawPtr())); - auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; + auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; dataLogLn("callee original: ", RawHex(wasmCallee), " at ", RawPointer(&wasmCallee)); dataLogLn("retPC original: ", RawPointer(fpp->rawReturnPCForInspection())); - auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uint64_t)]; + auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uint64_t)]; dataLogLn("retPC original: ", RawHex(retPC), " at ", RawPointer(&retPC)); dataLogLn("callerFrame original: ", RawPointer(fpp->callerFrame())); ASSERT_UNUSED(frameSize, sp + frameSize == fp); @@ -4850,30 +4885,37 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& auto fpl = context.gpr(GPRInfo::callFrameRegister); auto fpi = context.gpr(GPRInfo::callFrameRegister); - for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { - auto src = params[firstPatchArg + i]; - auto dst = wasmCalleeInfoAsCallee.params[i].location; - auto width = wasmCalleeInfoAsCallee.params[i].width; - dataLog("Arg source ", i, " located at ", src, " = "); + unsigned currentPatchArg = firstPatchArg; + auto dumpSrc = [&context, fpl, fpi, fpp] (ValueRep src, Width width) { + dataLog(src, " = "); if (src.isGPR()) dataLog(context.gpr(src.gpr()), " / ", (int) context.gpr(src.gpr())); - else if (src.isFPR() && width <= Width::Width64) + else if (src.isFPR() && width <= Width64) dataLog(context.fpr(src.fpr(), SavedFPWidth::SaveVectors)); else if (src.isFPR()) dataLog(context.vector(src.fpr())); else if (src.isConstant()) dataLog(src.value(), " / ", src.doubleValue()); else - dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(uint64_t)])); - dataLogLn(" -> ", dst); + dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(*fpp)])); + }; + + for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { + auto width = functionSignature.argumentType(i).width(); + ASSERT(wasmCalleeInfoAsCallee.params[i].width >= width); + dataLog("Arg source ", i, " located at "); + ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); + dumpSrc(params[currentPatchArg++], width); + + dataLogLn(" ->(final) ", wasmCalleeInfoAsCallee.params[i].location); } }); } jit.loadPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrame::callerFrameOffset()), MacroAssembler::framePointerRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); - uint64_t fp = context.gpr(GPRInfo::callFrameRegister); + auto sp = context.gpr(MacroAssembler::stackPointerRegister); + auto fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("In the new expanded frame, including F's caller: FP: ", RawHex(fp), " SP: ", RawHex(sp)); }); } @@ -4903,7 +4945,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& return offset; }; - auto doMove = [&] (int srcOffset, int dstOffset, Width width) { + auto doMove = [&jit, tmp] (int srcOffset, int dstOffset, Width width) { JIT_COMMENT(jit, "Do move ", srcOffset, " -> ", dstOffset); auto src = CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset); auto dst = CCallHelpers::Address(MacroAssembler::stackPointerRegister, dstOffset); @@ -4917,8 +4959,8 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { - uint64_t val = context.gpr(tmp); - uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); + auto val = context.gpr(tmp); + auto sp = context.gpr(MacroAssembler::stackPointerRegister); dataLogLn("Move value ", val, " / ", RawHex(val), " at ", RawHex(sp + srcOffset), " -> ", RawHex(sp + dstOffset), " width ", width); }); } @@ -4946,58 +4988,75 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& argsToMove.reserveInitialCapacity(wasmCalleeInfoAsCallee.params.size() + 1); if (clobbersTmp) { - tmpSpill = allocateSpill(Width::Width64); + tmpSpill = allocateSpill(WidthPtr); jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpill)); } // We will complete those moves who's source is closest to the danger frontier first. // That will move the danger frontier. - - for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { + unsigned currentPatchArg = firstPatchArg; + for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { auto dst = wasmCalleeInfoAsCallee.params[i]; + auto dstType = functionSignature.argumentType(i); + ASSERT(dst.width <= Width::Width64 || is64Bit()); + ASSERT(dst.width >= dstType.width()); if (dst.location.isGPR()) { ASSERT(!calleeSaves.find(dst.location.jsr().payloadGPR())); + currentPatchArg++; continue; } if (dst.location.isFPR()) { ASSERT(!calleeSaves.find(dst.location.fpr())); + currentPatchArg++; continue; } - auto src = params[firstPatchArg + i]; - ASSERT_UNUSED(lastPatchArg, firstPatchArg + i < lastPatchArg); - - intptr_t srcOffset = -1; - - if (src.isGPR()) { - ASSERT(dst.width <= Width::Width64); - srcOffset = allocateSpill(dst.width); - jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (src.isFPR()) { - srcOffset = allocateSpill(dst.width); - if (dst.width <= Width::Width64) - jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - else - jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (src.isConstant()) { - srcOffset = allocateSpill(dst.width); - ASSERT(dst.width <= Width::Width64); - jit.move(MacroAssembler::TrustedImm64(src.value()), tmp); - jit.store64(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else { - ASSERT(src.isStack()); - srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); - } + + auto saveSrc = [tmp, dstType, &allocateSpill, &jit, &fpOffsetToSPOffset](ValueRep src) -> std::tuple { + int srcOffset = 0; + if (src.isGPR()) { + srcOffset = allocateSpill(WidthPtr); + jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (src.isFPR()) { + srcOffset = allocateSpill(dstType.width()); + if (dstType.width() <= Width::Width64) + jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + else + jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (src.isConstant()) { + if (toB3Type(dstType).kind() == Float) { + srcOffset = allocateSpill(Width32); + jit.move(MacroAssembler::TrustedImm32(src.value()), tmp); + jit.store32(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (toB3Type(dstType).kind() == Double) { + srcOffset = allocateSpill(Width64); + jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); + jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else { + srcOffset = allocateSpill(WidthPtr); + jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); + jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } + } else { + ASSERT(src.isStack()); + srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); + } + + return { srcOffset, dstType.width() }; + }; + + ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); + auto [srcOffset, srcWidth] = saveSrc(params[currentPatchArg++]); intptr_t dstOffset = fpOffsetToSPOffset(checkedSum(dst.location.offsetFromFP(), newFPOffsetFromFP).value()); ASSERT(srcOffset >= 0); ASSERT(dstOffset >= 0); JIT_COMMENT(jit, "Arg ", i, " has srcOffset ", srcOffset, " dstOffset ", dstOffset); - argsToMove.append({ srcOffset, dstOffset, dst.width }); + argsToMove.append({ srcOffset, dstOffset, srcWidth }); } argsToMove.append({ fpOffsetToSPOffset(CallFrame::returnPCOffset()), newReturnPCOffset, - Width::Width64 + WidthPtr }); JIT_COMMENT(jit, "ReturnPC has srcOffset ", fpOffsetToSPOffset(CallFrame::returnPCOffset()), " dstOffset ", newReturnPCOffset); @@ -5060,11 +5119,11 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if CPU(ARM) || CPU(ARM64) || CPU(RISCV64) JIT_COMMENT(jit, "Load the return pointer from its saved location."); - jit.load64(CCallHelpers::Address(MacroAssembler::stackPointerRegister, newFPOffsetFromSP + OBJECT_OFFSETOF(CallerFrameAndPC, returnPC)), tmp); + jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, newFPOffsetFromSP + OBJECT_OFFSETOF(CallerFrameAndPC, returnPC)), tmp); jit.move(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } #if CPU(ARM64E) @@ -5073,7 +5132,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit.untagPtr(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } jit.validateUntaggedPtr(MacroAssembler::linkRegister); @@ -5085,7 +5144,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if CPU(X86_64) if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); }); } #endif @@ -5093,31 +5152,31 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if ASSERT_ENABLED for (unsigned i = 2; i < 50; ++i) { // Everthing after sp might be overwritten anyway. - jit.store64(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uint64_t))); + jit.storePtr(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uintptr_t))); } #endif JIT_COMMENT(jit, "OK, now we can jump."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([wasmCalleeInfoAsCallee] (Probe::Context& context) { - dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); - auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uint64_t); + dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uintptr_t); dataLogLn("New (callee) FP at prologue will be at ", RawPointer(newFP)); - auto fpl = static_cast(newFP); - auto fpi = reinterpret_cast(newFP); + auto fpl = std::bit_cast(newFP); + auto fpi = std::bit_cast(newFP); for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { auto arg = wasmCalleeInfoAsCallee.params[i]; auto src = arg.location; dataLog("Arg ", i, " located at ", arg.location, " = "); if (arg.location.isGPR()) - dataLog(context.gpr(arg.location.jsr().gpr()), " / ", (int) context.gpr(arg.location.jsr().gpr())); + dataLog(context.gpr(arg.location.jsr().payloadGPR()), " / ", (int) context.gpr(arg.location.jsr().payloadGPR())); else if (arg.location.isFPR() && arg.width <= Width::Width64) dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::SaveVectors)); else if (arg.location.isFPR()) dataLog(context.vector(arg.location.fpr())); else - dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(uint32_t)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(uint32_t)])); + dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(*fpi)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(*fpi)])); dataLogLn(); } }); @@ -5128,7 +5187,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } // See also: https://leaningtech.com/fantastic-tail-calls-and-how-to-implement-them/, a blog post about contributing this feature. -auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData +auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData { m_makesTailCalls = true; // Our args are placed in argument registers or locals. @@ -5198,20 +5257,20 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation ASSERT(wasmCalleeInfoAsCallee.params.size() == tmpArgSourceLocations.size()); unsigned firstPatchArg = patchArgs.size(); - for (unsigned i = 0; i < tmpArgSourceLocations.size(); ++i) { - auto src = get(block, tmpArgSourceLocations[i]); - auto dst = wasmCalleeInfoAsCallee.params[i]; - ASSERT(dst.location.isStack() || dst.location.isFPR() || dst.location.isGPR()); - ASSERT(dst.width >= src->resultWidth()); - if (!dst.location.isStack()) { + auto constrainedArgPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfoAsCallee, tmpArgSourceLocations); + + for (unsigned i = 0; i < constrainedArgPatchArgs.size(); ++i) { + auto src = constrainedArgPatchArgs[i].value(); + auto dst = constrainedArgPatchArgs[i].rep(); + ASSERT(dst.isStack() || dst.isFPR() || dst.isGPR()); + if (!dst.isStack()) { // We will restore callee saves before jumping to the callee. // The calling convention should guarantee this anyway, but let's document it just in case. - ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.location.isGPR() ? Reg(dst.location.jsr().gpr()) : Reg(dst.location.fpr()), IgnoreVectors)); - patchArgs.append(ConstrainedValue(src, dst)); + ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.isGPR() ? Reg(dst.gpr()) : Reg(dst.fpr()), IgnoreVectors)); + patchArgs.append(constrainedArgPatchArgs[i]); continue; } - ASSERT(dst.width >= Width64); - patchArgs.append(src); + patchArgs.append(ConstrainedValue(src, ValueRep::LateColdAny)); } unsigned lastPatchArg = patchArgs.size(); @@ -5232,9 +5291,9 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation firstPatchArg += m_proc.resultCount(patchpoint->type()); lastPatchArg += m_proc.resultCount(patchpoint->type()); - auto prepareForCall = createSharedTask([wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + auto prepareForCall = createSharedTask([signature = Ref(signature), wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { ASSERT(newFPOffsetFromFP >= 0 || params.code().frameSize() >= static_cast(-newFPOffsetFromFP)); - prepareForTailCallImpl(functionIndex, jit, params, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); + prepareForTailCallImpl(functionIndex, jit, params, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); }); return { patchpoint, nullptr, WTFMove(prepareForCall) }; @@ -5404,6 +5463,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe AllowMacroScratchRegisterUsage allowScratch(jit); if (prepareForCall) prepareForCall->run(jit, params); + ASSERT(!isTailCall || !handle); if (handle) handle->generate(jit, params, this); if (isTailCall) @@ -5425,12 +5485,12 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe jumpDestination = m_currentBlock->appendNew(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast(JSWebAssemblyInstance::offsetOfImportFunctionStub(functionIndexSpace))); if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitCallToImport(patchpoint, handle, prepareForCall); return { }; } - auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, returnType, wasmCalleeInfo, args); + auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, signature, wasmCalleeInfo, args); emitCallToImport(patchpoint, handle, prepareForCall); if (returnType != B3::Void) @@ -5471,7 +5531,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe }; if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitUnlinkedWasmToWasmCall(patchpoint, handle, prepareForCall); return { }; } @@ -5487,7 +5547,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe // 1. It is not tail-call. So this does not clobber the arguments of this function. // 2. We are not changing instance. Thus, |this| of this function's arguments are the same and OK. - auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, returnType, wasmCalleeInfo, args); + auto [patchpoint, handle, prepareForCall] = createCallPatchpoint(m_currentBlock, signature, wasmCalleeInfo, args); emitUnlinkedWasmToWasmCall(patchpoint, handle, prepareForCall); // We need to clobber the size register since the LLInt always bounds checks if (useSignalingMemory() || m_info.memory.isShared()) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index e6c17d4cef13..57b07ddd0ba7 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -862,8 +862,10 @@ class OMGIRGenerator { PartialResult WARN_UNUSED_RETURN addCrash(); void fillCallResults(Value* callResult, const TypeDefinition& signature, ResultList& results); PartialResult WARN_UNUSED_RETURN emitIndirectCall(Value* calleeInstance, Value* calleeCode, Value* boxedCalleeCallee, const TypeDefinition&, const ArgumentList& args, ResultList&, CallType = CallType::Call); + + Vector createCallConstrainedArgs(BasicBlock*, const CallInformation& wasmCalleeInfo, const ArgumentList&); auto createCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation&, const ArgumentList& tmpArgs) -> CallPatchpointData; - auto createTailCallPatchpoint(BasicBlock*, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; + auto createTailCallPatchpoint(BasicBlock*, const TypeDefinition&, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData; bool canInline(FunctionSpaceIndex functionIndexSpace) const; PartialResult WARN_UNUSED_RETURN emitInlineDirectCall(FunctionCodeIndex calleeIndex, const TypeDefinition&, ArgumentList& args, ResultList& results); @@ -1747,7 +1749,7 @@ auto OMGIRGenerator::addArguments(const TypeDefinition& signature) -> PartialRes patch->effects.writes = HeapRange::top(); m_currentBlock->append(patch); patch->setGenerator([functionIndex = m_functionIndex, signature = signature.as(), wasmCallInfo] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - jit.probeDebugSIMD([functionIndex, signature, wasmCallInfo] (Probe::Context& context) { + jit.probeDebug([functionIndex, signature, wasmCallInfo] (Probe::Context& context) { dataLogLn(" General Add arguments, fucntion ", functionIndex, " FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); auto fpl = context.gpr(GPRInfo::callFrameRegister); @@ -1759,10 +1761,12 @@ auto OMGIRGenerator::addArguments(const TypeDefinition& signature) -> PartialRes auto width = rep.width; dataLog(" Arg source ", i, " located at ", src, " = "); - if (src.isGPR()) + if (src.isGPR()) { dataLog(context.gpr(src.jsr().payloadGPR()), " / ", (int) context.gpr(src.jsr().payloadGPR())); - else if (src.isFPR() && width <= Width::Width64) - dataLog(context.fpr(src.fpr(), SavedFPWidth::SaveVectors)); + if (src.jsr().tagGPR()) + dataLog(" Upper bits: ", context.gpr(src.jsr().tagGPR()), " / ", (int) context.gpr(src.jsr().tagGPR())); + } else if (src.isFPR() && width <= Width::Width64) + dataLog(context.fpr(src.fpr(), SavedFPWidth::DontSaveVectors)); else if (src.isFPR()) RELEASE_ASSERT_NOT_REACHED(); else @@ -1993,6 +1997,10 @@ auto OMGIRGenerator::addCrash() -> PartialResult return { }; } + +static constexpr int tailCallPatchpointScratchOffsets[] = { CallFrameSlot::thisArgument * sizeof(Register), CallFrameSlot::argumentCountIncludingThis * sizeof(Register) }; +static constexpr int tailCallPatchpointScratchCount = sizeof(tailCallPatchpointScratchOffsets) / sizeof(tailCallPatchpointScratchOffsets[0]); + void OMGIRGenerator::fillCallResults(Value* callResult, const TypeDefinition& signature, ResultList& results) { B3::Type returnType = toB3ResultType(&signature); @@ -2093,16 +2101,38 @@ auto OMGIRGenerator::emitIndirectCall(Value* calleeInstance, Value* calleeCode, const TypeDefinition& callerTypeDefinition = TypeInformation::get(callerTypeIndex).expand(); CallInformation wasmCallerInfoAsCallee = callingConvention.callInformationFor(callerTypeDefinition, CallRole::Callee); - auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { { calleeCode, ValueRep(GPRInfo::wasmScratchGPR0) } }); + auto [patchpoint, _, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); unsigned patchArgsIndex = patchpoint->reps().size(); - patchpoint->append(calleeCode, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); - patchpoint->append(boxedCalleeCallee, ValueRep::SomeRegister); + if (is32Bit()) { + patchpoint->append(calleeCode, ValueRep::stackArgument(0)); + patchpoint->append(boxedCalleeCallee, ValueRep::stackArgument(8)); + } else { + patchpoint->append(calleeCode, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); + patchpoint->append(boxedCalleeCallee, ValueRep::SomeRegister); + } patchArgsIndex += m_proc.resultCount(patchpoint->type()); patchpoint->setGenerator([prepareForCall = prepareForCall, patchArgsIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); prepareForCall->run(jit, params); - jit.storeWasmCalleeCallee(params[patchArgsIndex + 1].gpr(), sizeof(CallerFrameAndPC) - prologueStackPointerDelta()); - jit.farJump(params[patchArgsIndex].gpr(), WasmEntryPtrTag); + GPRReg callTarget; + GPRReg callee; + if (is32Bit() && params[patchArgsIndex + 1].isStack()) { + callee = MacroAssembler::addressTempRegister; + jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, + tailCallPatchpointScratchOffsets[1] - sizeof(CallerFrameAndPC)), callee); + } else + callee = params[patchArgsIndex + 1].gpr(); + + jit.storeWasmCalleeCallee(callee, sizeof(CallerFrameAndPC) - prologueStackPointerDelta()); + + if (is32Bit() && params[patchArgsIndex].isStack()) { + callTarget = MacroAssembler::addressTempRegister; + jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, + tailCallPatchpointScratchOffsets[0] - sizeof(CallerFrameAndPC)), callTarget); + } else + callTarget = params[patchArgsIndex].gpr(); + + jit.farJump(callTarget, WasmEntryPtrTag); }); return { }; } @@ -5093,26 +5123,49 @@ auto OMGIRGenerator::addEndToUnreachable(ControlEntry& entry, const Stack& expre return { }; } - -auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData +Vector OMGIRGenerator::createCallConstrainedArgs(BasicBlock* block, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) { - auto& functionSignature = *signature.as(); - auto returnType = toB3ResultType(&signature); - - Vector constrainedPatchArgs; - Vector constrainedPatchArgsHighBits; + Vector constrainedPatchArgs; for (unsigned i = 0; i < tmpArgs.size(); ++i) { + auto dstLocation = wasmCalleeInfo.params[i]; + if (tmpArgs[i]->type() == Int64 && dstLocation.location.isGPR()) { + auto int64 = get(block, tmpArgs[i]); + auto hi = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64HighBits); + auto lo = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64LowBits); + constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::reg(dstLocation.location.jsr().payloadGPR()))); + constrainedPatchArgs.append(B3::ConstrainedValue(hi, ValueRep::reg(dstLocation.location.jsr().tagGPR()))); + continue; + } + if (tmpArgs[i]->type() == Int64) { auto int64 = get(block, tmpArgs[i]); - auto hi = append(m_proc, origin(), Int32, int64, ExtractValue::s_int64HighBits); - auto lo = append(m_proc, origin(), Int32, int64, ExtractValue::s_int64LowBits); - constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::reg(wasmCalleeInfo.params[i].location.jsr().payloadGPR()))); - constrainedPatchArgsHighBits.append(B3::ConstrainedValue(hi, ValueRep::reg(wasmCalleeInfo.params[i].location.jsr().tagGPR()))); + auto hi = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64HighBits); + auto lo = append(block, m_proc, origin(), Int32, int64, ExtractValue::s_int64LowBits); + + if (dstLocation.location.isStack()) { + constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::stack(dstLocation.location.offsetFromFP()))); + constrainedPatchArgs.append(B3::ConstrainedValue(hi, ValueRep::stack(dstLocation.location.offsetFromFP() + sizeof(int)))); + } else { + ASSERT(dstLocation.location.isStackArgument()); + constrainedPatchArgs.append(B3::ConstrainedValue(lo, ValueRep::stackArgument(dstLocation.location.offsetFromSP()))); + constrainedPatchArgs.append(B3::ConstrainedValue(hi, ValueRep::stackArgument(dstLocation.location.offsetFromSP() + sizeof(int)))); + } continue; } - constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), wasmCalleeInfo.params[i])); + constrainedPatchArgs.append(B3::ConstrainedValue(get(block, tmpArgs[i]), dstLocation)); } + return constrainedPatchArgs; +} + + +auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCalleeInfo, const ArgumentList& tmpArgs) -> CallPatchpointData +{ + auto& functionSignature = *signature.as(); + auto returnType = toB3ResultType(&signature); + + auto constrainedPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfo, tmpArgs); + Box exceptionHandle = Box::create(m_hasExceptionHandlers, callSiteIndex()); PatchpointValue* patchpoint = m_proc.add(returnType, origin()); @@ -5121,7 +5174,6 @@ auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinitio patchpoint->clobberEarly(RegisterSetBuilder::macroClobberedGPRs()); patchpoint->clobberLate(RegisterSetBuilder::registersToSaveForJSCall(m_proc.usesSIMD() ? RegisterSetBuilder::allRegisters() : RegisterSetBuilder::allScalarRegisters())); patchpoint->appendVector(constrainedPatchArgs); - patchpoint->appendVector(constrainedPatchArgsHighBits); *exceptionHandle = preparePatchpointForExceptions(block, patchpoint); @@ -5171,9 +5223,10 @@ auto OMGIRGenerator::createCallPatchpoint(BasicBlock* block, const TypeDefinitio return { patchpoint, exceptionHandle, nullptr }; } -// See emitTailCallPatchpoint for the setup before this. -static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) +// See createTailCallPatchpoint for the setup before this. +static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit, const B3::StackmapGenerationParams& params, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, unsigned firstPatchArg, unsigned lastPatchArg, int32_t newFPOffsetFromFP) { + auto& functionSignature = *signature.as(); const Checked offsetOfFirstSlotFromFP = WTF::roundUpToMultipleOf(wasmCallerInfoAsCallee.headerAndArgumentStackSizeInBytes); JIT_COMMENT(jit, "Set up tail call, new FP offset from FP: ", newFPOffsetFromFP); AllowMacroScratchRegisterUsage allowScratch(jit); @@ -5184,6 +5237,10 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& auto tmp = jit.scratchRegister(); int tmpSpill = 0; + // If we pass a stack location to the patchpoint in arugmentCountIncludingThis, preserve it here. + bool stackPatchArg[tailCallPatchpointScratchCount] = { false, false }; + int stackPatchArgSpill[tailCallPatchpointScratchCount] = { 0, 0 }; + // Set up a valid frame so that we can clobber this one. RegisterAtOffsetList calleeSaves = params.code().calleeSaveRegisterAtOffsetList(); jit.emitRestore(calleeSaves); @@ -5202,9 +5259,44 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } } + for (unsigned i = lastPatchArg; i < params.size(); ++i) { + auto arg = params[i]; + if (arg.isStack()) { + unsigned scratch = -1; + for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { + if (!stackPatchArg[i]) { + scratch = i; + break; + } + } + ASSERT(scratch >= 0 && !stackPatchArg[scratch]); + stackPatchArg[scratch] = true; + if (WasmOMGIRGeneratorInternal::verboseTailCalls) { + jit.probeDebug([arg] (Probe::Context& context) { + dataLogLn("patch arg spill: ", RawHex(context.gpr(MacroAssembler::framePointerRegister)[arg.offsetFromFP() / sizeof(uintptr_t)])); + }); + } + // A convinent and save place to stash it. + jit.transferPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, arg.offsetFromFP()), + CCallHelpers::Address(MacroAssembler::framePointerRegister, tailCallPatchpointScratchOffsets[scratch])); + } else + ASSERT(arg.isGPR() || arg.isFPR()); + } + +#if ASSERT_ENABLED + // Let's make sure we never rely on these slots, since they may be used for scratch. + for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { + if (!stackPatchArg[i]) { + jit.storePtr(MacroAssembler::TrustedImmPtr(0xBEEFAAAA), + CCallHelpers::Address(MacroAssembler::framePointerRegister, tailCallPatchpointScratchOffsets[i])); + } + } +#endif + + ASSERT(!calleeSaves.find(tmp) || !clobbersTmp); + const unsigned frameSize = params.code().frameSize(); - ASSERT(WTF::roundUpToMultipleOf(frameSize) == frameSize); - ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromFP)) == static_cast(std::abs(newFPOffsetFromFP))); + ASSERT(WTF::roundUpToMultipleOf(frameSize + sizeof(CallerFrameAndPC)) == frameSize + sizeof(CallerFrameAndPC)); auto fpOffsetToSPOffset = [frameSize](int32_t offset) { return checkedSum(safeCast(frameSize), offset).value(); @@ -5212,17 +5304,18 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& JIT_COMMENT(jit, "Let's use the caller's frame, so that we always have a valid frame."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebugSIMD([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, wasmCalleeInfoAsCallee, firstPatchArg, params, functionIndex] (Probe::Context& context) { - uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); - uint64_t fp = context.gpr(GPRInfo::callFrameRegister); + jit.probeDebug([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, signature = Ref(signature), wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, params, functionIndex] (Probe::Context& context) { + auto& functionSignature = *signature->as(); + auto sp = context.gpr(MacroAssembler::stackPointerRegister); + auto fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("Before tail call in function ", functionIndex, " before changing anything: FP: ", RawHex(fp), " SP: ", RawHex(sp)); dataLogLn("New FP will be at ", RawHex(sp + fpOffsetToSPOffset(newFPOffsetFromFP))); CallFrame* fpp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("callee original: ", RawPointer(fpp->callee().rawPtr())); - auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; + auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; dataLogLn("callee original: ", RawHex(wasmCallee), " at ", RawPointer(&wasmCallee)); dataLogLn("retPC original: ", RawPointer(fpp->rawReturnPCForInspection())); - auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uint64_t)]; + auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uint64_t)]; dataLogLn("retPC original: ", RawHex(retPC), " at ", RawPointer(&retPC)); dataLogLn("callerFrame original: ", RawPointer(fpp->callerFrame())); ASSERT_UNUSED(frameSize, sp + frameSize == fp); @@ -5230,30 +5323,43 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& auto fpl = context.gpr(GPRInfo::callFrameRegister); auto fpi = context.gpr(GPRInfo::callFrameRegister); - for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { - auto src = params[firstPatchArg + i]; - auto dst = wasmCalleeInfoAsCallee.params[i].location; - auto width = wasmCalleeInfoAsCallee.params[i].width; - dataLog("Arg source ", i, " located at ", src, " = "); + unsigned currentPatchArg = firstPatchArg; + auto dumpSrc = [&context, fpl, fpi, fpp] (ValueRep src, Width width) { + dataLog(src, " = "); if (src.isGPR()) dataLog(context.gpr(src.gpr()), " / ", (int) context.gpr(src.gpr())); - else if (src.isFPR() && width <= Width::Width64) - dataLog(context.fpr(src.fpr(), SavedFPWidth::SaveVectors)); + else if (src.isFPR() && width <= Width64) + dataLog(context.fpr(src.fpr(), SavedFPWidth::DontSaveVectors)); else if (src.isFPR()) RELEASE_ASSERT_NOT_REACHED(); else if (src.isConstant()) dataLog(src.value(), " / ", src.doubleValue()); else - dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(uint64_t)])); - dataLogLn(" -> ", dst); + dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpp[src.offsetFromFP() / sizeof(*fpp)])); + }; + + for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { + auto width = functionSignature.argumentType(i).width(); + ASSERT(wasmCalleeInfoAsCallee.params[i].width >= width); + dataLog("Arg source ", i, " located at "); + ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); + dumpSrc(params[currentPatchArg++], width); + if (is32Bit() && functionSignature.argumentType(i).isI64()) { + dataLog(" (Upper bits: "); + ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); + dumpSrc(params[currentPatchArg++], width); + dataLog(")"); + } + + dataLogLn(" ->(final) ", wasmCalleeInfoAsCallee.params[i].location); } }); } jit.loadPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, CallFrame::callerFrameOffset()), MacroAssembler::framePointerRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); - uint64_t fp = context.gpr(GPRInfo::callFrameRegister); + auto sp = context.gpr(MacroAssembler::stackPointerRegister); + auto fp = context.gpr(GPRInfo::callFrameRegister); dataLogLn("In the new expanded frame, including F's caller: FP: ", RawHex(fp), " SP: ", RawHex(sp)); }); } @@ -5283,25 +5389,30 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& return offset; }; - auto doMove = [&] (int srcOffset, int dstOffset, Width width) { + auto doMove = [&jit, tmp] (int srcOffset, int dstOffset, Width width) { JIT_COMMENT(jit, "Do move ", srcOffset, " -> ", dstOffset); auto src = CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset); auto dst = CCallHelpers::Address(MacroAssembler::stackPointerRegister, dstOffset); if (width <= Width32) jit.transfer32(src, dst); - else - RELEASE_ASSERT_NOT_REACHED(); + else if (width <= Width64) + jit.transfer64(src, dst); + else { + jit.transfer64(src, dst); + jit.transfer64(src.withOffset(bytesForWidth(Width::Width64)), dst.withOffset(bytesForWidth(Width::Width64))); + } if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebugSIMD([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { - uint64_t val = context.gpr(tmp); - uint64_t sp = context.gpr(MacroAssembler::stackPointerRegister); + jit.loadPtr(dst, tmp); + jit.probeDebug([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { + auto val = context.gpr(tmp); + auto sp = context.gpr(MacroAssembler::stackPointerRegister); dataLogLn("Move value ", val, " / ", RawHex(val), " at ", RawHex(sp + srcOffset), " -> ", RawHex(sp + dstOffset), " width ", width); }); } }; // This should grow down towards SP (towards 0) as we move stuff out of the way. - int safeAreaLowerBound = fpOffsetToSPOffset(CallFrameSlot::codeBlock * sizeof(Register)); + int safeAreaLowerBound = fpOffsetToSPOffset(CallFrameSlot::firstArgument * sizeof(Register)); const int stackUpperBound = fpOffsetToSPOffset(offsetOfFirstSlotFromFP); // ArgN in the stack diagram ASSERT(safeAreaLowerBound > 0); ASSERT(safeAreaLowerBound < stackUpperBound); @@ -5322,61 +5433,106 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& argsToMove.reserveInitialCapacity(wasmCalleeInfoAsCallee.params.size() + 1); if (clobbersTmp) { - tmpSpill = allocateSpill(Width::Width64); + tmpSpill = allocateSpill(WidthPtr); jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpill)); } + + for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { + if (stackPatchArg[i]) { + stackPatchArgSpill[i] = allocateSpill(WidthPtr); + jit.transferPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, fpOffsetToSPOffset(tailCallPatchpointScratchOffsets[i])), CCallHelpers::Address(MacroAssembler::stackPointerRegister, stackPatchArgSpill[i])); + } + } + // We will complete those moves who's source is closest to the danger frontier first. // That will move the danger frontier. - - for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { + unsigned currentPatchArg = firstPatchArg; + for (unsigned i = 0; i < functionSignature.argumentCount(); ++i) { auto dst = wasmCalleeInfoAsCallee.params[i]; + auto dstType = functionSignature.argumentType(i); + ASSERT(dst.width <= Width::Width64); + ASSERT(dst.width >= dstType.width()); if (dst.location.isGPR()) { ASSERT(!calleeSaves.find(dst.location.jsr().payloadGPR())); + currentPatchArg += dstType.width() == Width64 ? 2 : 1; continue; } if (dst.location.isFPR()) { ASSERT(!calleeSaves.find(dst.location.fpr())); + currentPatchArg++; continue; } - auto src = params[firstPatchArg + i]; - ASSERT_UNUSED(lastPatchArg, firstPatchArg + i < lastPatchArg); - - intptr_t srcOffset = -1; - - if (src.isGPR()) { - ASSERT(dst.width <= Width::Width32); - srcOffset = allocateSpill(dst.width); - jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (src.isFPR()) { - srcOffset = allocateSpill(dst.width); - if (dst.width <= Width::Width64) - jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - else - jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else if (src.isConstant()) { - srcOffset = allocateSpill(dst.width); - ASSERT(dst.width <= Width::Width32); - jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); - jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); - } else { - ASSERT(src.isStack()); - srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); - } + + auto saveSrc = [tmp, dstType, &allocateSpill, &jit, &fpOffsetToSPOffset](ValueRep src) -> std::tuple { + int srcOffset = 0; + if (src.isGPR()) { + srcOffset = allocateSpill(WidthPtr); + jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + return { srcOffset, WidthPtr }; + } + if (src.isFPR()) { + srcOffset = allocateSpill(dstType.width()); + if (dstType.width() <= Width::Width64) + jit.storeDouble(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + else + jit.storeVector(src.fpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (src.isConstant()) { + if (toB3Type(dstType).kind() == Float) { + srcOffset = allocateSpill(Width32); + jit.move(MacroAssembler::TrustedImm32(src.value()), tmp); + jit.store32(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + } else if (toB3Type(dstType).kind() == Double) { + srcOffset = allocateSpill(Width64); + jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); + jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + jit.move(MacroAssembler::TrustedImmPtr(src.value() >> 32), tmp); + jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset + sizeof(int))); + } else { + srcOffset = allocateSpill(WidthPtr); + jit.move(MacroAssembler::TrustedImmPtr(src.value()), tmp); + jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); + return { srcOffset, WidthPtr }; + } + } else { + ASSERT(src.isStack()); + srcOffset = fpOffsetToSPOffset(src.offsetFromFP()); + + if (is32Bit() && toB3Type(dstType).kind() == Int64) + return { srcOffset, WidthPtr }; + } + + return { srcOffset, dstType.width() }; + }; + + ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); + auto [srcOffset, srcWidth] = saveSrc(params[currentPatchArg++]); intptr_t dstOffset = fpOffsetToSPOffset(checkedSum(dst.location.offsetFromFP(), newFPOffsetFromFP).value()); ASSERT(srcOffset >= 0); ASSERT(dstOffset >= 0); JIT_COMMENT(jit, "Arg ", i, " has srcOffset ", srcOffset, " dstOffset ", dstOffset); - argsToMove.append({ srcOffset, dstOffset, dst.width }); + argsToMove.append({ srcOffset, dstOffset, srcWidth }); + + if (is32Bit() && srcWidth < dstType.width()) { + ASSERT_UNUSED(lastPatchArg, currentPatchArg < lastPatchArg); + auto [srcOffsetUpperBits, srcWidthUpperBits] = saveSrc(params[currentPatchArg++]); + ASSERT(srcWidthUpperBits == WidthPtr); + argsToMove.append({ srcOffsetUpperBits, dstOffset + sizeof(int), srcWidthUpperBits }); + } } argsToMove.append({ fpOffsetToSPOffset(CallFrame::returnPCOffset()), newReturnPCOffset, - Width::Width64 + WidthPtr }); JIT_COMMENT(jit, "ReturnPC has srcOffset ", fpOffsetToSPOffset(CallFrame::returnPCOffset()), " dstOffset ", newReturnPCOffset); + for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { + if (stackPatchArg[i]) + argsToMove.append({ stackPatchArgSpill[i], fpOffsetToSPOffset(tailCallPatchpointScratchOffsets[i] + newFPOffsetFromFP), WidthPtr }); + } + std::sort( argsToMove.begin(), argsToMove.end(), [] (const auto& left, const auto& right) { @@ -5427,7 +5583,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& // Also pop callee. auto newFPOffsetFromSP = fpOffsetToSPOffset(newFPOffsetFromFP); ASSERT(newFPOffsetFromSP > 0); - ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromSP)) == static_cast(std::abs(newFPOffsetFromSP))); + ASSERT(WTF::roundUpToMultipleOf(std::abs(newFPOffsetFromSP) + sizeof(CallerFrameAndPC)) == static_cast(std::abs(newFPOffsetFromSP) + sizeof(CallerFrameAndPC))); auto newSPAtPrologueOffsetFromSP = newFPOffsetFromSP + prologueStackPointerDelta(); @@ -5440,7 +5596,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit.move(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("tagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } #if CPU(ARM64E) @@ -5449,7 +5605,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& jit.untagPtr(tmp, MacroAssembler::linkRegister); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); + dataLogLn("untagged return pc: ", RawHex(context.gpr(MacroAssembler::linkRegister))); }); } jit.validateUntaggedPtr(MacroAssembler::linkRegister); @@ -5461,7 +5617,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if CPU(X86_64) if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); }); } #endif @@ -5469,31 +5625,33 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #if ASSERT_ENABLED for (unsigned i = 2; i < 50; ++i) { // Everthing after sp might be overwritten anyway. - jit.storePtr(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uint64_t))); + jit.storePtr(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uintptr_t))); } #endif JIT_COMMENT(jit, "OK, now we can jump."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebugSIMD([wasmCalleeInfoAsCallee] (Probe::Context& context) { - dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); - auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uint64_t); + jit.probeDebug([wasmCalleeInfoAsCallee] (Probe::Context& context) { + dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uintptr_t); dataLogLn("New (callee) FP at prologue will be at ", RawPointer(newFP)); - auto fpl = static_cast(newFP); - auto fpi = reinterpret_cast(newFP); + auto fpl = std::bit_cast(newFP); + auto fpi = std::bit_cast(newFP); for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { auto arg = wasmCalleeInfoAsCallee.params[i]; auto src = arg.location; dataLog("Arg ", i, " located at ", arg.location, " = "); - if (arg.location.isGPR()) + if (arg.location.isGPR()) { dataLog(context.gpr(arg.location.jsr().payloadGPR()), " / ", (int) context.gpr(arg.location.jsr().payloadGPR())); - else if (arg.location.isFPR() && arg.width <= Width::Width64) - dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::SaveVectors)); + if (src.jsr().tagGPR()) + dataLog(" Upper bits: ", context.gpr(src.jsr().tagGPR()), " / ", (int) context.gpr(src.jsr().tagGPR())); + } else if (arg.location.isFPR() && arg.width <= Width::Width64) + dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::DontSaveVectors)); else if (arg.location.isFPR()) RELEASE_ASSERT_NOT_REACHED(); else - dataLog(fpl[src.offsetFromFP() / sizeof(uint64_t)], " / ", fpi[src.offsetFromFP() / sizeof(uint32_t)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(uint32_t)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(uint64_t)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(uint32_t)])); + dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(*fpi)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(*fpi)])); dataLogLn(); } }); @@ -5504,7 +5662,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } // See also: https://leaningtech.com/fantastic-tail-calls-and-how-to-implement-them/, a blog post about contributing this feature. -auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation wasmCallerInfoAsCallee, CallInformation wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData +auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, const TypeDefinition& signature, const CallInformation& wasmCallerInfoAsCallee, const CallInformation& wasmCalleeInfoAsCallee, const ArgumentList& tmpArgSourceLocations, Vector patchArgs) -> CallPatchpointData { m_makesTailCalls = true; // Our args are placed in argument registers or locals. @@ -5513,7 +5671,6 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation // - Restore and re-sign lr // - Restore our caller's FP so that the stack area we write to is always valid // - Move stack args from our stack to their final resting spots. Note that they might overlap. - // - Move argumentCountIncludingThis (a.k.a. callSiteIndex) to its final spot, since WASM uses it for exceptions. // Layout of stack right now, and after this patchpoint. // // @@ -5566,28 +5723,31 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation #if ASSERT_ENABLED for (unsigned i = 0; i < patchArgs.size(); ++i) { // We will clobber our stack, so we shouldn't be reading any special extra patch args from it after this point. - ASSERT(patchArgs[i].rep().isReg() || patchArgs[i].rep().isConstant()); - ASSERT(!scratchRegisters.contains(patchArgs[i].rep().reg(), IgnoreVectors)); + // If we do need a stack arg, we can only save one. + ASSERT(patchArgs[i].rep().isReg() + || patchArgs[i].rep().isConstant() + || (patchArgs[i].rep().isStackArgument() && patchArgs.size() == 1)); + ASSERT(!patchArgs[i].rep().isReg() || !scratchRegisters.contains(patchArgs[i].rep().reg(), IgnoreVectors)); } #endif ASSERT(wasmCalleeInfoAsCallee.params.size() == tmpArgSourceLocations.size()); unsigned firstPatchArg = patchArgs.size(); - for (unsigned i = 0; i < tmpArgSourceLocations.size(); ++i) { - auto src = get(block, tmpArgSourceLocations[i]); - auto dst = wasmCalleeInfoAsCallee.params[i]; - ASSERT(dst.location.isStack() || dst.location.isFPR() || dst.location.isGPR()); - ASSERT(dst.width >= src->resultWidth()); - if (!dst.location.isStack()) { + auto constrainedArgPatchArgs = createCallConstrainedArgs(block, wasmCalleeInfoAsCallee, tmpArgSourceLocations); + + for (unsigned i = 0; i < constrainedArgPatchArgs.size(); ++i) { + auto src = constrainedArgPatchArgs[i].value(); + auto dst = constrainedArgPatchArgs[i].rep(); + ASSERT(dst.isStack() || dst.isFPR() || dst.isGPR()); + if (!dst.isStack()) { // We will restore callee saves before jumping to the callee. // The calling convention should guarantee this anyway, but let's document it just in case. - ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.location.isGPR() ? Reg(dst.location.jsr().payloadGPR()) : Reg(dst.location.fpr()), IgnoreVectors)); - patchArgs.append(ConstrainedValue(src, dst)); + ASSERT_UNUSED(forbiddenArgumentRegisters, !forbiddenArgumentRegisters.contains(dst.isGPR() ? Reg(dst.gpr()) : Reg(dst.fpr()), IgnoreVectors)); + patchArgs.append(constrainedArgPatchArgs[i]); continue; } - ASSERT(dst.width >= Width64); - patchArgs.append(src); + patchArgs.append(ConstrainedValue(src, ValueRep::LateColdAny)); } unsigned lastPatchArg = patchArgs.size(); @@ -5608,9 +5768,9 @@ auto OMGIRGenerator::createTailCallPatchpoint(BasicBlock* block, CallInformation firstPatchArg += m_proc.resultCount(patchpoint->type()); lastPatchArg += m_proc.resultCount(patchpoint->type()); - auto prepareForCall = createSharedTask([wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + auto prepareForCall = createSharedTask([signature = Ref(signature), wasmCalleeInfoAsCallee, wasmCallerInfoAsCallee, newFPOffsetFromFP, firstPatchArg, lastPatchArg, functionIndex = m_functionIndex](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { ASSERT(newFPOffsetFromFP >= 0 || params.code().frameSize() >= static_cast(-newFPOffsetFromFP)); - prepareForTailCallImpl(functionIndex, jit, params, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); + prepareForTailCallImpl(functionIndex, jit, params, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, newFPOffsetFromFP); }); return { patchpoint, nullptr, WTFMove(prepareForCall) }; @@ -5744,12 +5904,15 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe if (isTailCall || isTailCallInlineCaller) m_makesTailCalls = true; - m_proc.requestCallArgAreaSizeInBytes(calleeStackSize); + m_proc.requestCallArgAreaSizeInBytes(calleeStackSize + sizeof(Register)); if (m_info.isImportedFunctionFromFunctionIndexSpace(functionIndexSpace)) { auto emitCallToImport = [&, this](PatchpointValue* patchpoint, Box handle, RefPtr prepareForCall) -> void { unsigned patchArgsIndex = patchpoint->reps().size(); - patchpoint->append(jumpDestination, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); + if (is32Bit() && isTailCall) + patchpoint->append(jumpDestination, ValueRep::stackArgument(0)); + else + patchpoint->append(jumpDestination, ValueRep(GPRInfo::nonPreservedNonArgumentGPR0)); // We need to clobber all potential pinned registers since we might be leaving the instance. // We pessimistically assume we could be calling to something that is bounds checking. // FIXME: We shouldn't have to do this: https://bugs.webkit.org/show_bug.cgi?id=172181 @@ -5759,10 +5922,24 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe AllowMacroScratchRegisterUsage allowScratch(jit); if (prepareForCall) prepareForCall->run(jit, params); + ASSERT(!isTailCall || !handle); if (handle) handle->generate(jit, params, this); - if (isTailCall) - jit.farJump(params[patchArgsIndex].gpr(), WasmEntryPtrTag); + if (isTailCall) { + GPRReg callTarget; + if (is32Bit() && params[patchArgsIndex].isStack()) { + callTarget = MacroAssembler::addressTempRegister; + jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, + tailCallPatchpointScratchOffsets[0] - sizeof(CallerFrameAndPC)), callTarget); + } else + callTarget = params[patchArgsIndex].gpr(); + if (WasmOMGIRGeneratorInternal::verboseTailCalls) { + jit.probeDebug([callTarget] (Probe::Context& context) { + dataLogLn("Can now jump: ", RawHex(context.gpr(callTarget))); + }); + } + jit.farJump(callTarget, WasmEntryPtrTag); + } else { jit.call(params[patchArgsIndex].gpr(), WasmEntryPtrTag); // Restore the stack pointer since it may have been lowered if our callee did a tail call. @@ -5780,7 +5957,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe jumpDestination = append(heapImports(), m_proc, Load, pointerType(), origin(), instanceValue(), safeCast(JSWebAssemblyInstance::offsetOfImportFunctionStub(functionIndexSpace))); if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitCallToImport(patchpoint, handle, prepareForCall); return { }; } @@ -5826,7 +6003,7 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe }; if (isTailCall) { - auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); + auto [patchpoint, handle, prepareForCall] = createTailCallPatchpoint(m_currentBlock, signature, wasmCallerInfoAsCallee, wasmCalleeInfoAsCallee, args, { }); emitUnlinkedWasmToWasmCall(patchpoint, handle, prepareForCall); return { }; } From 821083eec307fa9348303eb29218f7ab52d5afb0 Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Thu, 6 Feb 2025 11:15:40 -0800 Subject: [PATCH 44/54] [JSC] Do not use stored call-site-index for OMG https://bugs.webkit.org/show_bug.cgi?id=287138 rdar://144289165 Reviewed by Keith Miller. This patch leverages PC to CodeOriginMap in OMG and avoids storing CallSiteIndex for each inlinig function entrance and exit. Wasm can have super very small functions. And when they get inlined, storing CallSiteIndex itself becomes huge bottleneck. In this patch, we implement stack frame traversing mechanism without using CallSiteIndex stored in the stack frame. 1. For the top-most frame, we rely on CallSiteIndex still. So whenever we throw an error from wasm, we set CallSiteIndex to the stack before that. 2. For the stack traversing for the caller functions, we use PC to look up the corresponding CallSiteIndex. We construct PC to CallSiteIndex map in OMG and StackVisitor will query to OMG callee to obtain appropriate CallSiteIndex with PC. 3. (1) does not work for bound-checking exception since we need to throw an error before storing CallSiteIndex. So in the wasm fault signal handler, we store PC to wasm instance. And we store appropriate CallSiteIndex in the function throwing an error actually. We use stored PC to obtain CallSiteIndex. * Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj: * Source/JavaScriptCore/Sources.txt: * Source/JavaScriptCore/b3/B3Procedure.h: * Source/JavaScriptCore/b3/air/AirCode.h: * Source/JavaScriptCore/b3/air/AirCustom.cpp: (JSC::B3::Air::WasmBoundsCheckCustom::generate): * Source/JavaScriptCore/b3/testb3_7.cpp: (testWasmBoundsCheck): * Source/JavaScriptCore/b3/testb3_8.cpp: (testStoreAfterClobberExitsSideways): (testStoreAfterClobberExitsSidewaysSuccessor): * Source/JavaScriptCore/interpreter/CallFrame.h: (JSC::CallFrame::rawReturnPC const): (JSC::CallFrame::rawReturnPCForInspection const): Deleted. * Source/JavaScriptCore/interpreter/StackVisitor.cpp: (JSC::StackVisitor::StackVisitor): (JSC::StackVisitor::updatePreviousReturnPCIfNecessary): (JSC::StackVisitor::readNonInlinedFrame): (JSC::StackVisitor::readInlinableNativeCalleeFrame): (JSC::StackVisitor::readInlinedFrame): * Source/JavaScriptCore/interpreter/StackVisitor.h: (JSC::StackVisitor::Frame::returnPC const): * Source/JavaScriptCore/jit/PCToCodeOriginMap.cpp: (JSC::PCToCodeOriginMapBuilder::PCToCodeOriginMapBuilder): * Source/JavaScriptCore/jit/PCToCodeOriginMap.h: * Source/JavaScriptCore/runtime/MachineContext.h: (JSC::MachineContext::stackPointerImpl): (JSC::MachineContext::framePointerImpl): (JSC::MachineContext::instructionPointerImpl): (JSC::MachineContext::argumentPointer<1>): (JSC::MachineContext::wasmInstancePointer): (JSC::MachineContext::llintInstructionPointer): * Source/JavaScriptCore/tools/VMInspector.cpp: (JSC::VMInspector::dumpRegisters): * Source/JavaScriptCore/wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * Source/JavaScriptCore/wasm/WasmCallee.cpp: (JSC::Wasm::OptimizingJITCallee::tryGetCallSiteIndex const): (JSC::Wasm::OptimizingJITCallee::materializePCToOriginMap): * Source/JavaScriptCore/wasm/WasmCallee.h: * Source/JavaScriptCore/wasm/WasmCompilationContext.cpp: Removed. * Source/JavaScriptCore/wasm/WasmCompilationContext.h: * Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp: (JSC::Wasm::trapHandler): * Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp: (JSC::Wasm::OMGIRGenerator::OMGIRGenerator): (JSC::Wasm::OMGIRGenerator::emitExceptionCheck): (JSC::Wasm::OMGIRGenerator::addTableGet): (JSC::Wasm::OMGIRGenerator::addTableSet): (JSC::Wasm::OMGIRGenerator::addRefAsNonNull): (JSC::Wasm::OMGIRGenerator::addTableInit): (JSC::Wasm::OMGIRGenerator::addTableFill): (JSC::Wasm::OMGIRGenerator::addTableCopy): (JSC::Wasm::OMGIRGenerator::addUnreachable): (JSC::Wasm::OMGIRGenerator::addMemoryFill): (JSC::Wasm::OMGIRGenerator::addMemoryInit): (JSC::Wasm::OMGIRGenerator::addMemoryCopy): (JSC::Wasm::OMGIRGenerator::load): (JSC::Wasm::OMGIRGenerator::store): (JSC::Wasm::OMGIRGenerator::fixupPointerPlusOffsetForAtomicOps): (JSC::Wasm::OMGIRGenerator::atomicLoad): (JSC::Wasm::OMGIRGenerator::atomicStore): (JSC::Wasm::OMGIRGenerator::atomicBinaryRMW): (JSC::Wasm::OMGIRGenerator::atomicCompareExchange): (JSC::Wasm::OMGIRGenerator::atomicWait): (JSC::Wasm::OMGIRGenerator::atomicNotify): (JSC::Wasm::OMGIRGenerator::addI31GetS): (JSC::Wasm::OMGIRGenerator::addI31GetU): (JSC::Wasm::OMGIRGenerator::pushArrayNew): (JSC::Wasm::OMGIRGenerator::addArrayGet): (JSC::Wasm::OMGIRGenerator::emitArrayNullCheck): (JSC::Wasm::OMGIRGenerator::addArraySet): (JSC::Wasm::OMGIRGenerator::addArrayLen): (JSC::Wasm::OMGIRGenerator::addArrayFill): (JSC::Wasm::OMGIRGenerator::addArrayCopy): (JSC::Wasm::OMGIRGenerator::addArrayInitElem): (JSC::Wasm::OMGIRGenerator::addArrayInitData): (JSC::Wasm::OMGIRGenerator::addStructNew): (JSC::Wasm::OMGIRGenerator::addStructNewDefault): (JSC::Wasm::OMGIRGenerator::addStructGet): (JSC::Wasm::OMGIRGenerator::addStructSet): (JSC::Wasm::OMGIRGenerator::emitRefTestOrCast): (JSC::Wasm::OMGIRGenerator::addThrow): (JSC::Wasm::OMGIRGenerator::addThrowRef): (JSC::Wasm::OMGIRGenerator::addRethrow): (JSC::Wasm::prepareForTailCallImpl): (JSC::Wasm::OMGIRGenerator::emitInlineDirectCall): (JSC::Wasm::OMGIRGenerator::addCall): (JSC::Wasm::OMGIRGenerator::addCallIndirect): (JSC::Wasm::OMGIRGenerator::addCallRef): (JSC::Wasm::OMGIRGenerator::origin): (JSC::Wasm::parseAndCompileOMG): (JSC::Wasm::OMGIRGenerator::emitChecksForModOrDiv): (JSC::Wasm::OMGIRGenerator::addI32TruncSF64): (JSC::Wasm::OMGIRGenerator::addI32TruncSF32): (JSC::Wasm::OMGIRGenerator::addI32TruncUF64): (JSC::Wasm::OMGIRGenerator::addI32TruncUF32): (JSC::Wasm::OMGIRGenerator::addI64TruncSF64): (JSC::Wasm::OMGIRGenerator::addI64TruncUF64): (JSC::Wasm::OMGIRGenerator::addI64TruncSF32): (JSC::Wasm::OMGIRGenerator::addI64TruncUF32): * Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp: (JSC::Wasm::OMGIRGenerator::OMGIRGenerator): (JSC::Wasm::prepareForTailCallImpl): (JSC::Wasm::parseAndCompileOMG): * Source/JavaScriptCore/wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp: (JSC::Wasm::OSREntryPlan::work): * Source/JavaScriptCore/wasm/WasmOpcodeOrigin.h: * Source/JavaScriptCore/wasm/WasmOperations.cpp: (JSC::Wasm::JSC_DEFINE_NOEXCEPT_JIT_OPERATION): * Source/JavaScriptCore/wasm/WasmSlowPaths.cpp: (JSC::LLInt::slow_path_wasm_throw_exception): * Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h: * Source/WTF/wtf/PlatformHave.h: Canonical link: https://commits.webkit.org/289952@main (cherry picked from commit 005a3beb2bcf620a267ea0739f9b67d9b68f57dc) --- .../JavaScriptCore.xcodeproj/project.pbxproj | 2 - Source/JavaScriptCore/Sources.txt | 1 - Source/JavaScriptCore/b3/B3Procedure.h | 3 +- Source/JavaScriptCore/b3/air/AirCode.h | 3 +- Source/JavaScriptCore/b3/air/AirCustom.cpp | 4 +- Source/JavaScriptCore/b3/testb3_7.cpp | 2 +- Source/JavaScriptCore/b3/testb3_8.cpp | 4 +- Source/JavaScriptCore/interpreter/CallFrame.h | 2 +- .../interpreter/StackVisitor.cpp | 39 ++- .../JavaScriptCore/interpreter/StackVisitor.h | 30 +- .../JavaScriptCore/jit/PCToCodeOriginMap.cpp | 6 +- Source/JavaScriptCore/jit/PCToCodeOriginMap.h | 8 +- .../JavaScriptCore/runtime/MachineContext.h | 252 +++++++------- Source/JavaScriptCore/tools/VMInspector.cpp | 2 +- Source/JavaScriptCore/wasm/WasmBBQPlan.cpp | 3 +- Source/JavaScriptCore/wasm/WasmCallee.cpp | 42 +++ Source/JavaScriptCore/wasm/WasmCallee.h | 9 + .../wasm/WasmCompilationContext.cpp | 51 --- .../wasm/WasmCompilationContext.h | 13 +- .../wasm/WasmFaultSignalHandler.cpp | 17 +- .../wasm/WasmOMGIRGenerator.cpp | 309 +++++++++--------- .../wasm/WasmOMGIRGenerator32_64.cpp | 12 +- Source/JavaScriptCore/wasm/WasmOMGPlan.cpp | 7 +- .../JavaScriptCore/wasm/WasmOSREntryPlan.cpp | 7 + Source/JavaScriptCore/wasm/WasmOpcodeOrigin.h | 6 +- Source/JavaScriptCore/wasm/WasmOperations.cpp | 2 +- Source/JavaScriptCore/wasm/WasmSlowPaths.cpp | 11 + .../wasm/js/JSWebAssemblyInstance.h | 4 + Source/WTF/wtf/PlatformHave.h | 2 +- 29 files changed, 453 insertions(+), 400 deletions(-) delete mode 100644 Source/JavaScriptCore/wasm/WasmCompilationContext.cpp diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index 4ff37171a787..1cb55286ef22 100644 --- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -5562,7 +5562,6 @@ E32D4DE426DAFD4300D4533A /* TemporalCalendarConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporalCalendarConstructor.h; sourceTree = ""; }; E32D4DE526DAFD4300D4533A /* TemporalCalendarConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporalCalendarConstructor.cpp; sourceTree = ""; }; E32D51A52C6D0FD600B013D1 /* WasmCompilationContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmCompilationContext.h; sourceTree = ""; }; - E32D51A62C6D0FD600B013D1 /* WasmCompilationContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmCompilationContext.cpp; sourceTree = ""; }; E32D51A72C6D0FD600B013D1 /* WasmOpcodeCounter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmOpcodeCounter.h; sourceTree = ""; }; E32D51A82C6D0FD600B013D1 /* WasmOpcodeCounter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOpcodeCounter.cpp; sourceTree = ""; }; E32D51A92C6D0FD600B013D1 /* WasmSourceMappingURLSectionParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmSourceMappingURLSectionParser.h; sourceTree = ""; }; @@ -7783,7 +7782,6 @@ 53FD04D11D7AB187003287D3 /* WasmCallingConvention.cpp */, 53FD04D21D7AB187003287D3 /* WasmCallingConvention.h */, E337B966224324E50093A820 /* WasmCapabilities.h */, - E32D51A62C6D0FD600B013D1 /* WasmCompilationContext.cpp */, E32D51A52C6D0FD600B013D1 /* WasmCompilationContext.h */, E37CFB2D22F27C57009A7B38 /* WasmCompilationMode.cpp */, E3BD2B7522F275020011765C /* WasmCompilationMode.h */, diff --git a/Source/JavaScriptCore/Sources.txt b/Source/JavaScriptCore/Sources.txt index 5535646857ee..5af7fa9a78c9 100644 --- a/Source/JavaScriptCore/Sources.txt +++ b/Source/JavaScriptCore/Sources.txt @@ -1138,7 +1138,6 @@ wasm/WasmBranchHintsSectionParser.cpp wasm/WasmCallee.cpp wasm/WasmCalleeGroup.cpp wasm/WasmCallingConvention.cpp -wasm/WasmCompilationContext.cpp wasm/WasmCompilationMode.cpp wasm/WasmConstExprGenerator.cpp wasm/WasmContext.cpp diff --git a/Source/JavaScriptCore/b3/B3Procedure.h b/Source/JavaScriptCore/b3/B3Procedure.h index c35bed6683ec..0b832f85a592 100644 --- a/Source/JavaScriptCore/b3/B3Procedure.h +++ b/Source/JavaScriptCore/b3/B3Procedure.h @@ -61,13 +61,14 @@ class Dominators; class NaturalLoops; class Value; class Variable; +class WasmBoundsCheckValue; namespace Air { class Code; class StackSlot; } // namespace Air -typedef void WasmBoundsCheckGeneratorFunction(CCallHelpers&, GPRReg); +typedef void WasmBoundsCheckGeneratorFunction(CCallHelpers&, WasmBoundsCheckValue*, GPRReg); typedef SharedTask WasmBoundsCheckGenerator; // This represents B3's view of a piece of code. Note that this object must exist in a 1:1 diff --git a/Source/JavaScriptCore/b3/air/AirCode.h b/Source/JavaScriptCore/b3/air/AirCode.h index 3c0bd0e1590a..2d8f6c19aebc 100644 --- a/Source/JavaScriptCore/b3/air/AirCode.h +++ b/Source/JavaScriptCore/b3/air/AirCode.h @@ -51,6 +51,7 @@ class CCallHelpers; namespace B3 { class Procedure; +class WasmBoundsCheckValue; #if !ASSERT_ENABLED IGNORE_RETURN_TYPE_WARNINGS_BEGIN @@ -65,7 +66,7 @@ class CFG; class Code; class Disassembler; -typedef void WasmBoundsCheckGeneratorFunction(CCallHelpers&, GPRReg); +typedef void WasmBoundsCheckGeneratorFunction(CCallHelpers&, WasmBoundsCheckValue*, GPRReg); typedef SharedTask WasmBoundsCheckGenerator; typedef void PrologueGeneratorFunction(CCallHelpers&, Code&); diff --git a/Source/JavaScriptCore/b3/air/AirCustom.cpp b/Source/JavaScriptCore/b3/air/AirCustom.cpp index d2ee5a4160be..22285cddb2b2 100644 --- a/Source/JavaScriptCore/b3/air/AirCustom.cpp +++ b/Source/JavaScriptCore/b3/air/AirCustom.cpp @@ -226,11 +226,11 @@ MacroAssembler::Jump WasmBoundsCheckCustom::generate(Inst& inst, CCallHelpers& j outOfBounds.link(&jit); switch (value->boundsType()) { case WasmBoundsCheckValue::Type::Pinned: - context.code->wasmBoundsCheckGenerator()->run(jit, value->bounds().pinnedSize); + context.code->wasmBoundsCheckGenerator()->run(jit, value, value->bounds().pinnedSize); break; case WasmBoundsCheckValue::Type::Maximum: - context.code->wasmBoundsCheckGenerator()->run(jit, InvalidGPRReg); + context.code->wasmBoundsCheckGenerator()->run(jit, value, InvalidGPRReg); break; } })); diff --git a/Source/JavaScriptCore/b3/testb3_7.cpp b/Source/JavaScriptCore/b3/testb3_7.cpp index f03a27b343e9..0cf311aaee42 100644 --- a/Source/JavaScriptCore/b3/testb3_7.cpp +++ b/Source/JavaScriptCore/b3/testb3_7.cpp @@ -1199,7 +1199,7 @@ void testWasmBoundsCheck(unsigned offset) GPRReg pinned = GPRInfo::argumentGPR1; proc.pinRegister(pinned); - proc.setWasmBoundsCheckGenerator([=] (CCallHelpers& jit, GPRReg pinnedGPR) { + proc.setWasmBoundsCheckGenerator([=](CCallHelpers& jit, WasmBoundsCheckValue*, GPRReg pinnedGPR) { CHECK_EQ(pinnedGPR, pinned); // This should always work because a function this simple should never have callee diff --git a/Source/JavaScriptCore/b3/testb3_8.cpp b/Source/JavaScriptCore/b3/testb3_8.cpp index 894539b92795..5fd340d7644e 100644 --- a/Source/JavaScriptCore/b3/testb3_8.cpp +++ b/Source/JavaScriptCore/b3/testb3_8.cpp @@ -1109,7 +1109,7 @@ void testStoreAfterClobberExitsSideways() proc.pinRegister(reg); }); - proc.setWasmBoundsCheckGenerator([=] (CCallHelpers& jit, GPRReg pinnedGPR) { + proc.setWasmBoundsCheckGenerator([=](CCallHelpers& jit, WasmBoundsCheckValue*, GPRReg pinnedGPR) { CHECK_EQ(pinnedGPR, pinnedSizeGPR); jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR); @@ -1299,7 +1299,7 @@ void testStoreAfterClobberExitsSidewaysSuccessor() proc.pinRegister(reg); }); - proc.setWasmBoundsCheckGenerator([=] (CCallHelpers& jit, GPRReg pinnedGPR) { + proc.setWasmBoundsCheckGenerator([=](CCallHelpers& jit, WasmBoundsCheckValue*, GPRReg pinnedGPR) { CHECK_EQ(pinnedGPR, pinnedSizeGPR); jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR); diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h index 6a51e2964199..c632dfe45ac7 100644 --- a/Source/JavaScriptCore/interpreter/CallFrame.h +++ b/Source/JavaScriptCore/interpreter/CallFrame.h @@ -210,7 +210,7 @@ using JSInstruction = BaseInstruction; static constexpr ptrdiff_t callerFrameOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame); } - void* rawReturnPCForInspection() const { return callerFrameAndPC().returnPC; } + void* rawReturnPC() const { return callerFrameAndPC().returnPC; } void* returnPCForInspection() const { return removeCodePtrTag(callerFrameAndPC().returnPC); } bool hasReturnPC() const { return !!callerFrameAndPC().returnPC; } void clearReturnPC() { callerFrameAndPC().returnPC = nullptr; } diff --git a/Source/JavaScriptCore/interpreter/StackVisitor.cpp b/Source/JavaScriptCore/interpreter/StackVisitor.cpp index 1747a3b23861..2bef56ea4bc5 100644 --- a/Source/JavaScriptCore/interpreter/StackVisitor.cpp +++ b/Source/JavaScriptCore/interpreter/StackVisitor.cpp @@ -42,10 +42,7 @@ namespace JSC { StackVisitor::StackVisitor(CallFrame* startFrame, VM& vm, bool skipFirstFrame) { - m_frame.m_index = 0; - m_frame.m_isWasmFrame = false; - m_frame.m_wasmDistanceFromDeepestInlineFrame = 0; - CallFrame* topFrame; + CallFrame* topFrame = nullptr; if (startFrame) { ASSERT(!vm.topCallFrame || static_cast(vm.topCallFrame) != vm.topEntryFrame); @@ -58,12 +55,7 @@ StackVisitor::StackVisitor(CallFrame* startFrame, VM& vm, bool skipFirstFrame) if (startFrame == vm.topCallFrame) startFrame = topFrame; } - - } else { - m_frame.m_entryFrame = nullptr; - topFrame = nullptr; } - m_frame.m_callerIsEntryFrame = false; readFrame(topFrame); // Find the frame the caller wants to start unwinding from. @@ -106,6 +98,15 @@ void StackVisitor::unwindToMachineCodeBlockFrame() #endif } +inline CallFrame* StackVisitor::updatePreviousReturnPCIfNecessary(CallFrame* callFrame) +{ + if (m_frame.m_callFrame) { + if (m_frame.m_callFrame != callFrame) + m_previousReturnPC = m_frame.m_callFrame->rawReturnPC(); + } + return callFrame; +} + void StackVisitor::readFrame(CallFrame* callFrame) { if (!callFrame) { @@ -158,7 +159,8 @@ void StackVisitor::readFrame(CallFrame* callFrame) void StackVisitor::readNonInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin) { - m_frame.m_callFrame = callFrame; + m_frame.m_callFrame = updatePreviousReturnPCIfNecessary(callFrame); + m_frame.m_returnPC = m_previousReturnPC; m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); m_frame.m_callerEntryFrame = m_frame.m_entryFrame; m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_callerEntryFrame); @@ -187,8 +189,9 @@ void StackVisitor::readInlinableNativeCalleeFrame(CallFrame* callFrame) #if ENABLE(WEBASSEMBLY) auto& wasmCallee = static_cast(callee); auto depth = m_frame.m_wasmDistanceFromDeepestInlineFrame; + m_frame.m_callFrame = updatePreviousReturnPCIfNecessary(callFrame); + m_frame.m_returnPC = m_previousReturnPC; m_frame.m_isWasmFrame = true; - m_frame.m_callFrame = callFrame; m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); m_frame.m_callerEntryFrame = m_frame.m_entryFrame; m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_callerEntryFrame); @@ -206,7 +209,13 @@ void StackVisitor::readInlinableNativeCalleeFrame(CallFrame* callFrame) const auto& omgCallee = *static_cast(&wasmCallee); bool isInlined = false; - auto origin = omgCallee.getOrigin(callFrame->callSiteIndex().bits(), depth, isInlined); + + // Because PC is just after the call instruction, to query to the origin for the call instruction, we decrease it by 1. + // While it can be pointing at the broken offset (e.g. all ARM64 instructions are 4-byte aligned), it is still fine since map is controlling pc with range. + auto callSiteIndexFromPC = omgCallee.tryGetCallSiteIndex(std::bit_cast(std::bit_cast(removeCodePtrTag(m_frame.m_returnPC)) - 1)); + CallSiteIndex callSiteIndex = callSiteIndexFromPC.value_or(callFrame->callSiteIndex()); + + auto origin = omgCallee.getOrigin(callSiteIndex.bits(), depth, isInlined); if (!isInlined) return; @@ -224,7 +233,8 @@ void StackVisitor::readInlinableNativeCalleeFrame(CallFrame* callFrame) break; } case NativeCallee::Category::InlineCache: { - m_frame.m_callFrame = callFrame; + m_frame.m_callFrame = updatePreviousReturnPCIfNecessary(callFrame); + m_frame.m_returnPC = m_previousReturnPC; m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); m_frame.m_callerEntryFrame = m_frame.m_entryFrame; m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_callerEntryFrame); @@ -262,7 +272,8 @@ void StackVisitor::readInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin if (isInlined) { InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame(); - m_frame.m_callFrame = callFrame; + m_frame.m_callFrame = updatePreviousReturnPCIfNecessary(callFrame); + m_frame.m_returnPC = m_previousReturnPC; m_frame.m_inlineDFGCallFrame = inlineCallFrame; if (inlineCallFrame->argumentCountRegister.isValid()) m_frame.m_argumentCountIncludingThis = callFrame->r(inlineCallFrame->argumentCountRegister).unboxedInt32(); diff --git a/Source/JavaScriptCore/interpreter/StackVisitor.h b/Source/JavaScriptCore/interpreter/StackVisitor.h index eba81db2c4ba..5b25bf346976 100644 --- a/Source/JavaScriptCore/interpreter/StackVisitor.h +++ b/Source/JavaScriptCore/interpreter/StackVisitor.h @@ -77,6 +77,7 @@ class StackVisitor { return nullptr; #endif } + void* returnPC() const { return m_returnPC; } bool isNativeFrame() const { return !codeBlock() && !isNativeCalleeFrame(); } bool isInlinedDFGFrame() const { return !isNativeCalleeFrame() && !!inlineCallFrame(); } @@ -117,21 +118,22 @@ class StackVisitor { void setToEnd(); #if ENABLE(DFG_JIT) - InlineCallFrame* m_inlineDFGCallFrame; + InlineCallFrame* m_inlineDFGCallFrame { nullptr }; #endif unsigned m_wasmDistanceFromDeepestInlineFrame { 0 }; - CallFrame* m_callFrame; - EntryFrame* m_entryFrame; - EntryFrame* m_callerEntryFrame; - CallFrame* m_callerFrame; - CalleeBits m_callee; - CodeBlock* m_codeBlock; - size_t m_index; - size_t m_argumentCountIncludingThis; - BytecodeIndex m_bytecodeIndex; - bool m_callerIsEntryFrame : 1; - bool m_isWasmFrame : 1; - Wasm::IndexOrName m_wasmFunctionIndexOrName; + CallFrame* m_callFrame { nullptr }; + EntryFrame* m_entryFrame { nullptr }; + EntryFrame* m_callerEntryFrame { nullptr }; + CallFrame* m_callerFrame { nullptr }; + CalleeBits m_callee { }; + CodeBlock* m_codeBlock { nullptr }; + void* m_returnPC { nullptr }; + size_t m_index { 0 }; + size_t m_argumentCountIncludingThis { 0 }; + BytecodeIndex m_bytecodeIndex { }; + bool m_callerIsEntryFrame : 1 { false }; + bool m_isWasmFrame : 1 { false }; + Wasm::IndexOrName m_wasmFunctionIndexOrName { }; friend class StackVisitor; }; @@ -175,8 +177,10 @@ class StackVisitor { #if ENABLE(DFG_JIT) void readInlinedFrame(CallFrame*, CodeOrigin*); #endif + CallFrame* updatePreviousReturnPCIfNecessary(CallFrame*); Frame m_frame; + void* m_previousReturnPC { nullptr }; bool m_topEntryFrameIsEmpty { false }; }; diff --git a/Source/JavaScriptCore/jit/PCToCodeOriginMap.cpp b/Source/JavaScriptCore/jit/PCToCodeOriginMap.cpp index b993875e611c..146c682159eb 100644 --- a/Source/JavaScriptCore/jit/PCToCodeOriginMap.cpp +++ b/Source/JavaScriptCore/jit/PCToCodeOriginMap.cpp @@ -107,7 +107,7 @@ PCToCodeOriginMapBuilder::PCToCodeOriginMapBuilder(PCToCodeOriginMapBuilder&& ot { } #if ENABLE(FTL_JIT) -PCToCodeOriginMapBuilder::PCToCodeOriginMapBuilder(JSTag, VM& vm, B3::PCToOriginMap b3PCToOriginMap) +PCToCodeOriginMapBuilder::PCToCodeOriginMapBuilder(JSTag, VM& vm, const B3::PCToOriginMap& b3PCToOriginMap) : m_shouldBuildMapping(vm.shouldBuilderPCToCodeOriginMapping()) { if (!m_shouldBuildMapping) @@ -123,8 +123,8 @@ PCToCodeOriginMapBuilder::PCToCodeOriginMapBuilder(JSTag, VM& vm, B3::PCToOrigin } #endif -#if ENABLE(WEBASSEMBLY_OMGJIT) || ENABLE(WEBASSEMBLY_BBQJIT) -PCToCodeOriginMapBuilder::PCToCodeOriginMapBuilder(WasmTag, B3::PCToOriginMap b3PCToOriginMap) +#if ENABLE(WEBASSEMBLY_OMGJIT) +PCToCodeOriginMapBuilder::PCToCodeOriginMapBuilder(WasmTag, const B3::PCToOriginMap& b3PCToOriginMap) : m_shouldBuildMapping(true) { for (const B3::PCToOriginMap::OriginRange& originRange : b3PCToOriginMap.ranges()) { diff --git a/Source/JavaScriptCore/jit/PCToCodeOriginMap.h b/Source/JavaScriptCore/jit/PCToCodeOriginMap.h index e8f29263189a..c5db08e4b5ef 100644 --- a/Source/JavaScriptCore/jit/PCToCodeOriginMap.h +++ b/Source/JavaScriptCore/jit/PCToCodeOriginMap.h @@ -34,7 +34,7 @@ namespace JSC { -#if ENABLE(FTL_JIT) || ENABLE(WEBASSEMBLY_OMGJIT) || ENABLE(WEBASSEMBLY_BBQJIT) +#if ENABLE(FTL_JIT) || ENABLE(WEBASSEMBLY_OMGJIT) namespace B3 { class PCToOriginMap; } @@ -57,12 +57,12 @@ class PCToCodeOriginMapBuilder { #if ENABLE(FTL_JIT) enum JSTag { JSCodeOriginMap }; - PCToCodeOriginMapBuilder(JSTag, VM&, B3::PCToOriginMap); + PCToCodeOriginMapBuilder(JSTag, VM&, const B3::PCToOriginMap&); #endif -#if ENABLE(WEBASSEMBLY_OMGJIT) || ENABLE(WEBASSEMBLY_BBQJIT) +#if ENABLE(WEBASSEMBLY_OMGJIT) enum WasmTag { WasmCodeOriginMap }; - PCToCodeOriginMapBuilder(WasmTag, B3::PCToOriginMap); + PCToCodeOriginMapBuilder(WasmTag, const B3::PCToOriginMap&); #endif void appendItem(MacroAssembler::Label label, const CodeOrigin& origin) diff --git a/Source/JavaScriptCore/runtime/MachineContext.h b/Source/JavaScriptCore/runtime/MachineContext.h index 28ab3561a2e0..ba2aae72a5a7 100644 --- a/Source/JavaScriptCore/runtime/MachineContext.h +++ b/Source/JavaScriptCore/runtime/MachineContext.h @@ -50,6 +50,7 @@ inline void setInstructionPointer(PlatformRegisters&, void *); template void*& argumentPointer(PlatformRegisters&); template void* argumentPointer(const PlatformRegisters&); +void* wasmInstancePointer(const PlatformRegisters&); #if !ENABLE(C_LOOP) void*& llintInstructionPointer(PlatformRegisters&); void* llintInstructionPointer(const PlatformRegisters&); @@ -73,6 +74,7 @@ inline CodePtr instructionPointer(const mcontext_t&); template void*& argumentPointer(mcontext_t&); template void* argumentPointer(const mcontext_t&); +void* wasmInstancePointer(const mcontext_t&); #if !ENABLE(C_LOOP) void*& llintInstructionPointer(mcontext_t&); void* llintInstructionPointer(const mcontext_t&); @@ -88,9 +90,7 @@ static inline void*& stackPointerImpl(PlatformRegisters& regs) #if OS(DARWIN) #if __DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.__esp); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.__rsp); #elif CPU(PPC) || CPU(PPC64) return reinterpret_cast(regs.__r1); @@ -102,12 +102,8 @@ static inline void*& stackPointerImpl(PlatformRegisters& regs) #else // !__DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.esp); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.rsp); -#elif CPU(PPC) || CPU(PPC64) - return reinterpret_cast(regs.r1); #else #error Unknown Architecture #endif @@ -118,8 +114,6 @@ static inline void*& stackPointerImpl(PlatformRegisters& regs) #if CPU(ARM) return reinterpret_cast((uintptr_t&) regs.Sp); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) regs.IntSp); #elif CPU(X86) return reinterpret_cast((uintptr_t&) regs.Esp); #elif CPU(X86_64) @@ -166,48 +160,36 @@ static inline void*& stackPointerImpl(mcontext_t& machineContext) return stackPointerImpl(machineContext->__ss); #elif OS(FREEBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.mc_esp); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.mc_rsp); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_SP]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.mc_gpregs.gp_sp); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.mc_regs[29]); #else #error Unknown Architecture #endif #elif OS(NETBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_UESP]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_RSP]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_SP]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_SP]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_SP]); #else #error Unknown Architecture #endif #elif OS(FUCHSIA) || OS(LINUX) || OS(HURD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_ESP]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_RSP]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.arm_sp); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.sp); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.gregs[29]); #elif CPU(RISCV64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[REG_SP]); #else @@ -242,14 +224,8 @@ static inline void*& framePointerImpl(PlatformRegisters& regs) #if __DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.__ebp); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.__rbp); -#elif CPU(ARM_THUMB2) - return reinterpret_cast(regs.__r[7]); -#elif CPU(ARM) - return reinterpret_cast(regs.__r[11]); #elif CPU(ARM64) return reinterpret_cast(regs.__x[29]); #else @@ -258,9 +234,7 @@ static inline void*& framePointerImpl(PlatformRegisters& regs) #else // !__DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.esp); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.rsp); #else #error Unknown Architecture @@ -272,8 +246,6 @@ static inline void*& framePointerImpl(PlatformRegisters& regs) #if CPU(ARM) return reinterpret_cast((uintptr_t&) regs.R11); -#elif CPU(MIPS) -#error Dont know what to do with mips. Do we even need this? #elif CPU(X86) return reinterpret_cast((uintptr_t&) regs.Ebp); #elif CPU(X86_64) @@ -311,32 +283,24 @@ static inline void*& framePointerImpl(mcontext_t& machineContext) return framePointerImpl(machineContext->__ss); #elif OS(FREEBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.mc_ebp); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.mc_rbp); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_FP]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.mc_gpregs.gp_x[29]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.mc_regs[30]); #else #error Unknown Architecture #endif #elif OS(NETBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_EBP]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_RBP]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_FP]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_FP]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_S8]); #else #error Unknown Architecture #endif @@ -344,16 +308,12 @@ static inline void*& framePointerImpl(mcontext_t& machineContext) #elif OS(FUCHSIA) || OS(LINUX) || OS(HURD) // The following sequence depends on glibc's sys/ucontext.h. -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_EBP]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_RBP]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.arm_fp); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.regs[29]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.gregs[30]); #elif CPU(RISCV64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[REG_S0]); #else @@ -397,9 +357,7 @@ static inline void*& instructionPointerImpl(PlatformRegisters& regs) #if OS(DARWIN) #if __DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.__eip); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.__rip); #elif CPU(ARM_THUMB2) || CPU(ARM) return reinterpret_cast(regs.__pc); @@ -408,9 +366,7 @@ static inline void*& instructionPointerImpl(PlatformRegisters& regs) #endif #else // !__DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.eip); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.rip); #else #error Unknown Architecture @@ -422,8 +378,6 @@ static inline void*& instructionPointerImpl(PlatformRegisters& regs) #if CPU(ARM) return reinterpret_cast((uintptr_t&) regs.Pc); -#elif CPU(MIPS) -#error Dont know what to do with mips. Do we even need this? #elif CPU(X86) return reinterpret_cast((uintptr_t&) regs.Eip); #elif CPU(X86_64) @@ -491,32 +445,24 @@ static inline void*& instructionPointerImpl(mcontext_t& machineContext) return instructionPointerImpl(machineContext->__ss); #elif OS(FREEBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.mc_eip); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.mc_rip); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_PC]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.mc_gpregs.gp_elr); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.mc_pc); #else #error Unknown Architecture #endif #elif OS(NETBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_EIP]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_RIP]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_PC]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_PC]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_EPC]); #else #error Unknown Architecture #endif @@ -524,16 +470,12 @@ static inline void*& instructionPointerImpl(mcontext_t& machineContext) #elif OS(FUCHSIA) || OS(LINUX) || OS(HURD) // The following sequence depends on glibc's sys/ucontext.h. -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_EIP]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_RIP]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.arm_pc); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.pc); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.pc); #elif CPU(RISCV64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[REG_PC]); #else @@ -598,9 +540,7 @@ inline void*& argumentPointer<1>(PlatformRegisters& regs) #if OS(DARWIN) #if __DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.__edx); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.__rsi); #elif CPU(ARM_THUMB2) || CPU(ARM) return reinterpret_cast(regs.__r[1]); @@ -612,9 +552,7 @@ inline void*& argumentPointer<1>(PlatformRegisters& regs) #else // !__DARWIN_UNIX03 -#if CPU(X86) - return reinterpret_cast(regs.edx); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast(regs.rsi); #else #error Unknown Architecture @@ -626,8 +564,6 @@ inline void*& argumentPointer<1>(PlatformRegisters& regs) #if CPU(ARM) return reinterpret_cast((uintptr_t&) regs.R1); -#elif CPU(MIPS) -#error Dont know what to do with mips. Do we even need this? #elif CPU(X86) return reinterpret_cast((uintptr_t&) regs.Edx); #elif CPU(X86_64) @@ -641,6 +577,47 @@ inline void*& argumentPointer<1>(PlatformRegisters& regs) #endif } +inline void* wasmInstancePointer(const PlatformRegisters& regs) +{ +#if OS(DARWIN) +#if __DARWIN_UNIX03 + +#if CPU(X86_64) + return reinterpret_cast(regs.__rbx); +#elif CPU(ARM64) + return reinterpret_cast(regs.__x[19]); +#else +#error Unknown Architecture +#endif + +#else // !__DARWIN_UNIX03 + +#if CPU(X86_64) + return reinterpret_cast(regs.rbx); +#else +#error Unknown Architecture +#endif + +#endif // __DARWIN_UNIX03 + +#elif OS(WINDOWS) + +#if CPU(ARM) + return reinterpret_cast((uintptr_t) regs.R10); +#elif CPU(X86) + return reinterpret_cast((uintptr_t) regs.Ebx); +#elif CPU(X86_64) + return reinterpret_cast((uintptr_t) regs.Rbx); +#else +#error Unknown Architecture +#endif + +#elif HAVE(MACHINE_CONTEXT) + return wasmInstancePointer(regs.machineContext); +#endif +} + + template inline void* argumentPointer(const PlatformRegisters& regs) { @@ -656,32 +633,24 @@ inline void*& argumentPointer<1>(mcontext_t& machineContext) return argumentPointer<1>(machineContext->__ss); #elif OS(FREEBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.mc_edx); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.mc_rsi); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_R1]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.mc_gpregs.gp_x[1]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.mc_regs[5]); #else #error Unknown Architecture #endif #elif OS(NETBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_EDX]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_RSI]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_R1]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_X1]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_A1]); #else #error Unknown Architecture #endif @@ -689,16 +658,12 @@ inline void*& argumentPointer<1>(mcontext_t& machineContext) #elif OS(FUCHSIA) || OS(LINUX) || OS(HURD) // The following sequence depends on glibc's sys/ucontext.h. -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_EDX]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_RSI]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.arm_r1); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.regs[1]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.gregs[5]); #elif CPU(RISCV64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[REG_A0 + 1]); #else @@ -719,6 +684,64 @@ inline void*& argumentPointer<1>(mcontext_t& machineContext) #endif } +inline void* wasmInstancePointer(const mcontext_t& machineContext) +{ +#if OS(DARWIN) + return wasmInstancePointer(machineContext->__ss); +#elif OS(FREEBSD) + +#if CPU(X86_64) + return reinterpret_cast((uintptr_t) machineContext.mc_rbx); +#elif CPU(ARM) + return reinterpret_cast((uintptr_t) machineContext.__gregs[_REG_R10]); +#elif CPU(ARM64) + return reinterpret_cast((uintptr_t) machineContext.mc_gpregs.gp_x[19]); +#else +#error Unknown Architecture +#endif + +#elif OS(NETBSD) + +#if CPU(X86_64) + return reinterpret_cast((uintptr_t) machineContext.__gregs[_REG_RBX]); +#elif CPU(ARM) + return reinterpret_cast((uintptr_t) machineContext.__gregs[_REG_R10]); +#elif CPU(ARM64) + return reinterpret_cast((uintptr_t) machineContext.__gregs[_REG_X19]); +#else +#error Unknown Architecture +#endif + +#elif OS(FUCHSIA) || OS(LINUX) || OS(HURD) + +// The following sequence depends on glibc's sys/ucontext.h. +#if CPU(X86_64) + return reinterpret_cast((uintptr_t) machineContext.gregs[REG_RBX]); +#elif CPU(ARM) + return reinterpret_cast((uintptr_t) machineContext.arm_r10); +#elif CPU(ARM64) + return reinterpret_cast((uintptr_t) machineContext.regs[19]); +#elif CPU(RISCV64) + return reinterpret_cast((uintptr_t) machineContext.__gregs[9]); +#else +#error Unknown Architecture +#endif + +#elif OS(QNX) +#if CPU(X86_64) + return reinterpret_cast((uintptr_t) machineContext.cpu.rbx); +#elif CPU(ARM64) + return reinterpret_cast((uintptr_t) machineContext.cpu.gpr[19]); +#else +#error Unknown Architecture +#endif + +#else +#error Need a way to get the frame pointer for another thread on this platform +#endif +} + + template inline void* argumentPointer(const mcontext_t& machineContext) { @@ -734,15 +757,9 @@ inline void*& llintInstructionPointer(PlatformRegisters& regs) #if OS(DARWIN) #if __DARWIN_UNIX03 -#if CPU(X86) - static_assert(LLInt::LLIntPC == X86Registers::esi, "Wrong LLInt PC."); - return reinterpret_cast(regs.__esi); -#elif CPU(X86_64) +#if CPU(X86_64) static_assert(LLInt::LLIntPC == X86Registers::r8, "Wrong LLInt PC."); return reinterpret_cast(regs.__r8); -#elif CPU(ARM) - static_assert(LLInt::LLIntPC == ARMRegisters::r8, "Wrong LLInt PC."); - return reinterpret_cast(regs.__r[8]); #elif CPU(ARM64) static_assert(LLInt::LLIntPC == ARM64Registers::x4, "Wrong LLInt PC."); return reinterpret_cast(regs.__x[4]); @@ -751,10 +768,7 @@ inline void*& llintInstructionPointer(PlatformRegisters& regs) #endif #else // !__DARWIN_UNIX03 -#if CPU(X86) - static_assert(LLInt::LLIntPC == X86Registers::esi, "Wrong LLInt PC."); - return reinterpret_cast(regs.esi); -#elif CPU(X86_64) +#if CPU(X86_64) static_assert(LLInt::LLIntPC == X86Registers::r8, "Wrong LLInt PC."); return reinterpret_cast(regs.r8); #else @@ -768,8 +782,6 @@ inline void*& llintInstructionPointer(PlatformRegisters& regs) #if CPU(ARM) static_assert(LLInt::LLIntPC == ARMRegisters::r8, "Wrong LLInt PC."); return reinterpret_cast((uintptr_t&) regs.R8); -#elif CPU(MIPS) -#error Dont know what to do with mips. Do we even need this? #elif CPU(X86) static_assert(LLInt::LLIntPC == X86Registers::esi, "Wrong LLInt PC."); return reinterpret_cast((uintptr_t&) regs.Esi); @@ -800,32 +812,24 @@ inline void*& llintInstructionPointer(mcontext_t& machineContext) return llintInstructionPointer(machineContext->__ss); #elif OS(FREEBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.mc_esi); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.mc_r8); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_R8]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.mc_gpregs.gp_x[4]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.mc_regs[12]); #else #error Unknown Architecture #endif #elif OS(NETBSD) -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_ESI]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_R8]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_R8]); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_X4]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.__gregs[_REG_T4]); #else #error Unknown Architecture #endif @@ -833,16 +837,12 @@ inline void*& llintInstructionPointer(mcontext_t& machineContext) #elif OS(FUCHSIA) || OS(LINUX) || OS(HURD) // The following sequence depends on glibc's sys/ucontext.h. -#if CPU(X86) - return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_ESI]); -#elif CPU(X86_64) +#if CPU(X86_64) return reinterpret_cast((uintptr_t&) machineContext.gregs[REG_R8]); #elif CPU(ARM) return reinterpret_cast((uintptr_t&) machineContext.arm_r8); #elif CPU(ARM64) return reinterpret_cast((uintptr_t&) machineContext.regs[4]); -#elif CPU(MIPS) - return reinterpret_cast((uintptr_t&) machineContext.gregs[12]); #elif CPU(RISCV64) return reinterpret_cast((uintptr_t&) machineContext.__gregs[14]); #else diff --git a/Source/JavaScriptCore/tools/VMInspector.cpp b/Source/JavaScriptCore/tools/VMInspector.cpp index 33184b6f6dba..c54d4666e562 100644 --- a/Source/JavaScriptCore/tools/VMInspector.cpp +++ b/Source/JavaScriptCore/tools/VMInspector.cpp @@ -502,7 +502,7 @@ SUPPRESS_ASAN void VMInspector::dumpRegisters(CallFrame* callFrame) dataLogF("% 4d CallerFrame : %10p %p \n", registerNumber++, it++, callFrame->callerFrame()); if constexpr (isARM64E()) - dataLogF("% 4d ReturnPC : %10p %p (pac signed %p) \n", registerNumber++, it++, callFrame->returnPCForInspection(), callFrame->rawReturnPCForInspection()); + dataLogF("% 4d ReturnPC : %10p %p (pac signed %p) \n", registerNumber++, it++, callFrame->returnPCForInspection(), callFrame->rawReturnPC()); else dataLogF("% 4d ReturnPC : %10p %p \n", registerNumber++, it++, callFrame->returnPCForInspection()); dataLogF("% 4d CodeBlock : %10p 0x%llx ", registerNumber++, it++, (long long)codeBlock); diff --git a/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp b/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp index eb48707467a9..dff5d8ce4d98 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp @@ -109,7 +109,8 @@ void BBQPlan::work(CompilationEffort) Vector> loopEntrypointLocations; computeExceptionHandlerAndLoopEntrypointLocations(exceptionHandlerLocations, loopEntrypointLocations, function.get(), context, linkBuffer); - computePCToCodeOriginMap(context, linkBuffer); + if (context.pcToCodeOriginMapBuilder) + context.pcToCodeOriginMap = Box::create(WTFMove(*context.pcToCodeOriginMapBuilder), linkBuffer); bool alreadyDumped = dumpDisassembly(context, linkBuffer, m_functionIndex, signature, functionIndexSpace); function->entrypoint.compilation = makeUnique( diff --git a/Source/JavaScriptCore/wasm/WasmCallee.cpp b/Source/JavaScriptCore/wasm/WasmCallee.cpp index 8d1a29cacc50..4dd1c0a2d91e 100644 --- a/Source/JavaScriptCore/wasm/WasmCallee.cpp +++ b/Source/JavaScriptCore/wasm/WasmCallee.cpp @@ -455,6 +455,19 @@ IndexOrName OptimizingJITCallee::getOrigin(unsigned csi, unsigned depth, bool& i return indexOrName(); } +std::optional OptimizingJITCallee::tryGetCallSiteIndex(const void* pc) const +{ + constexpr bool verbose = false; + if (m_callSiteIndexMap) { + dataLogLnIf(verbose, "Querying ", RawPointer(pc)); + if (std::optional codeOrigin = m_callSiteIndexMap->findPC(removeCodePtrTag(pc))) { + dataLogLnIf(verbose, "Found ", *codeOrigin); + return CallSiteIndex { codeOrigin->bytecodeIndex().offset() }; + } + } + return std::nullopt; +} + const StackMap& OptimizingJITCallee::stackmap(CallSiteIndex callSiteIndex) const { auto iter = m_stackmaps.find(callSiteIndex); @@ -469,6 +482,35 @@ const StackMap& OptimizingJITCallee::stackmap(CallSiteIndex callSiteIndex) const RELEASE_ASSERT(iter != m_stackmaps.end()); return iter->value; } + +Box OptimizingJITCallee::materializePCToOriginMap(B3::PCToOriginMap&& originMap, LinkBuffer& linkBuffer) +{ + constexpr bool shouldBuildMapping = true; + PCToCodeOriginMapBuilder samplingProfilerBuilder(shouldBuildMapping); + PCToCodeOriginMapBuilder builder(shouldBuildMapping); + for (const B3::PCToOriginMap::OriginRange& originRange : originMap.ranges()) { + B3::Origin b3Origin = originRange.origin; + auto* origin = std::bit_cast(b3Origin.data()); + if (origin) { + // We stash the location into a BytecodeIndex. + samplingProfilerBuilder.appendItem(originRange.label, CodeOrigin(BytecodeIndex(origin->m_opcodeOrigin.location()))); + builder.appendItem(originRange.label, CodeOrigin(BytecodeIndex(origin->m_callSiteIndex.bits()))); + } else { + samplingProfilerBuilder.appendItem(originRange.label, PCToCodeOriginMapBuilder::defaultCodeOrigin()); + builder.appendItem(originRange.label, PCToCodeOriginMapBuilder::defaultCodeOrigin()); + } + } + + Box samplingProfilerMap = nullptr; + if (Options::useSamplingProfiler()) + samplingProfilerMap = Box::create(WTFMove(samplingProfilerBuilder), linkBuffer); + auto map = Box::create(WTFMove(builder), linkBuffer); + WTF::storeStoreFence(); + m_callSiteIndexMap = WTFMove(map); + + return samplingProfilerMap; +} + #endif JSEntrypointCallee::JSEntrypointCallee(TypeIndex typeIndex, bool usesSIMD) diff --git a/Source/JavaScriptCore/wasm/WasmCallee.h b/Source/JavaScriptCore/wasm/WasmCallee.h index 491a68458c52..3a7e404af69b 100644 --- a/Source/JavaScriptCore/wasm/WasmCallee.h +++ b/Source/JavaScriptCore/wasm/WasmCallee.h @@ -29,6 +29,7 @@ #include "JITCompilation.h" #include "NativeCallee.h" +#include "PCToCodeOriginMap.h" #include "RegisterAtOffsetList.h" #include "StackAlignment.h" #include "WasmCompilationMode.h" @@ -51,6 +52,10 @@ namespace JSC { class LLIntOffsetsExtractor; +namespace B3 { +class PCToOriginMap; +} + namespace Wasm { class CalleeGroup; @@ -260,6 +265,9 @@ class OptimizingJITCallee : public JITCallee { void addCodeOrigin(unsigned firstInlineCSI, unsigned lastInlineCSI, const Wasm::ModuleInformation&, uint32_t functionIndex); IndexOrName getOrigin(unsigned csi, unsigned depth, bool& isInlined) const; + std::optional tryGetCallSiteIndex(const void*) const; + + Box materializePCToOriginMap(B3::PCToOriginMap&&, LinkBuffer&); protected: OptimizingJITCallee(Wasm::CompilationMode mode, FunctionSpaceIndex index, std::pair>&& name) @@ -282,6 +290,7 @@ class OptimizingJITCallee : public JITCallee { StackMaps m_stackmaps; Vector codeOrigins; Vector, 0> nameSections; + Box m_callSiteIndexMap; }; constexpr int32_t stackCheckUnset = 0; diff --git a/Source/JavaScriptCore/wasm/WasmCompilationContext.cpp b/Source/JavaScriptCore/wasm/WasmCompilationContext.cpp deleted file mode 100644 index 645ec1d79c55..000000000000 --- a/Source/JavaScriptCore/wasm/WasmCompilationContext.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016-2023 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WasmCompilationContext.h" - - -#if ENABLE(WEBASSEMBLY_BBQJIT) || ENABLE(WEBASSEMBLY_OMGJIT) -namespace JSC { - -namespace Wasm { - -void computePCToCodeOriginMap(CompilationContext& context, LinkBuffer& linkBuffer) -{ - if (context.procedure && context.procedure->needsPCToOriginMap()) { - B3::PCToOriginMap originMap = context.procedure->releasePCToOriginMap(); - context.pcToCodeOriginMap = Box::create(PCToCodeOriginMapBuilder(PCToCodeOriginMapBuilder::WasmCodeOriginMap, WTFMove(originMap)), linkBuffer); - return; - } - if (context.pcToCodeOriginMapBuilder) { - context.pcToCodeOriginMap = Box::create(WTFMove(*context.pcToCodeOriginMapBuilder), linkBuffer); - return; - } -} - -} // namespace Wasm -} // namespace JSC - -#endif diff --git a/Source/JavaScriptCore/wasm/WasmCompilationContext.h b/Source/JavaScriptCore/wasm/WasmCompilationContext.h index cc3a4b1277cc..cea41445dba2 100644 --- a/Source/JavaScriptCore/wasm/WasmCompilationContext.h +++ b/Source/JavaScriptCore/wasm/WasmCompilationContext.h @@ -38,9 +38,11 @@ #include "WasmJS.h" #include "WasmMemory.h" #include "WasmModuleInformation.h" +#include "WasmOpcodeOrigin.h" #include "WasmTierUpCount.h" #include #include +#include namespace JSC { @@ -60,6 +62,14 @@ class MemoryInformation; class OptimizingJITCallee; class TierUpCount; +class OMGOrigin { +public: + friend bool operator==(const OMGOrigin&, const OMGOrigin&) = default; + + CallSiteIndex m_callSiteIndex { }; + OpcodeOrigin m_opcodeOrigin { }; +}; + struct CompilationContext { std::unique_ptr jsEntrypointJIT; std::unique_ptr wasmEntrypointJIT; @@ -69,10 +79,9 @@ struct CompilationContext { Box pcToCodeOriginMap; Box pcToCodeOriginMapBuilder; Vector catchEntrypoints; + SegmentedVector origins; }; -void computePCToCodeOriginMap(CompilationContext&, LinkBuffer&); - } // namespace Wasm } // namespace JSC diff --git a/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp b/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp index ac6226a47c9b..7114b819f92f 100644 --- a/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp +++ b/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp @@ -29,6 +29,7 @@ #if ENABLE(WEBASSEMBLY) #include "ExecutableAllocator.h" +#include "JSWebAssemblyInstance.h" #include "LLIntData.h" #include "MachineContext.h" #include "NativeCalleeRegistry.h" @@ -86,25 +87,29 @@ static SignalAction trapHandler(Signal signal, SigInfo& sigInfo, PlatformRegiste if (faultedInActiveGrowableMemory) { dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found active fast memory for faulting address"); - auto didFaultInWasm = [](void* faultingInstruction) { + auto didFaultInWasm = [](void* faultingInstruction) -> std::tuple { if (LLInt::isWasmLLIntPC(faultingInstruction)) - return true; + return { true, nullptr }; auto& calleeRegistry = NativeCalleeRegistry::singleton(); Locker locker { calleeRegistry.getLock() }; for (auto* callee : calleeRegistry.allCallees()) { if (callee->category() != NativeCallee::Category::Wasm) continue; - auto [start, end] = static_cast(callee)->range(); + auto* wasmCallee = static_cast(callee); + auto [start, end] = wasmCallee->range(); dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "function start: ", RawPointer(start), " end: ", RawPointer(end)); if (start <= faultingInstruction && faultingInstruction < end) { dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found match"); - return true; + return { true, wasmCallee }; } } - return false; + return { false, nullptr }; }; - if (didFaultInWasm(faultingInstruction)) { + auto [isWasm, callee] = didFaultInWasm(faultingInstruction); + if (isWasm) { + auto* instance = jsSecureCast(static_cast(MachineContext::wasmInstancePointer(context))); + instance->setFaultPC(faultingInstruction); #if CPU(ARM64E) && HAVE(HARDENED_MACH_EXCEPTIONS) if (g_wtfConfig.signalHandlers.useHardenedHandler) { MachineContext::setInstructionPointer(context, presignedTrampoline); diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp index ccaa43d1212c..927b2825befa 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp @@ -385,8 +385,8 @@ class OMGIRGenerator { return m_callSiteIndex; } - OMGIRGenerator(CalleeGroup&, const ModuleInformation&, OptimizingJITCallee&, Procedure&, Vector&, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode, CompilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry); - OMGIRGenerator(OMGIRGenerator& inlineCaller, OMGIRGenerator& inlineRoot, CalleeGroup&, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args); + OMGIRGenerator(CompilationContext&, CalleeGroup&, const ModuleInformation&, OptimizingJITCallee&, Procedure&, Vector&, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode, CompilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry); + OMGIRGenerator(CompilationContext&, OMGIRGenerator& inlineCaller, OMGIRGenerator& inlineRoot, CalleeGroup&, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args); void computeStackCheckSize(bool& needsOverflowCheck, int32_t& checkSize); @@ -820,7 +820,7 @@ class OMGIRGenerator { return block->appendNew(m_proc, resultType, origin(), operationValue, std::forward(args)...); } - void emitExceptionCheck(CCallHelpers&, ExceptionType); + void emitExceptionCheck(CCallHelpers&, Origin, ExceptionType); void emitWriteBarrierForJSWrapper(); void emitWriteBarrier(Value* cell, Value* instanceCell); @@ -946,6 +946,7 @@ class OMGIRGenerator { void traceCF(Args&&... info); FunctionParser* m_parser { nullptr }; + CompilationContext& m_context; CalleeGroup& m_calleeGroup; const ModuleInformation& m_info; OptimizingJITCallee* m_callee; @@ -1084,8 +1085,9 @@ void OMGIRGenerator::computeStackCheckSize(bool& needsOverflowCheck, int32_t& ch needsOverflowCheck = needsOverflowCheck || needUnderflowCheck; } -OMGIRGenerator::OMGIRGenerator(OMGIRGenerator& parentCaller, OMGIRGenerator& rootCaller, CalleeGroup& calleeGroup, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args) - : m_calleeGroup(calleeGroup) +OMGIRGenerator::OMGIRGenerator(CompilationContext& context, OMGIRGenerator& parentCaller, OMGIRGenerator& rootCaller, CalleeGroup& calleeGroup, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args) + : m_context(context) + , m_calleeGroup(calleeGroup) , m_info(rootCaller.m_info) , m_callee(parentCaller.m_callee) , m_mode(rootCaller.m_mode) @@ -1117,8 +1119,9 @@ OMGIRGenerator::OMGIRGenerator(OMGIRGenerator& parentCaller, OMGIRGenerator& roo m_hasExceptionHandlers = { true }; } -OMGIRGenerator::OMGIRGenerator(CalleeGroup& calleeGroup, const ModuleInformation& info, OptimizingJITCallee& callee, Procedure& procedure, Vector& unlinkedWasmToWasmCalls, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry) - : m_calleeGroup(calleeGroup) +OMGIRGenerator::OMGIRGenerator(CompilationContext& context, CalleeGroup& calleeGroup, const ModuleInformation& info, OptimizingJITCallee& callee, Procedure& procedure, Vector& unlinkedWasmToWasmCalls, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry) + : m_context(context) + , m_calleeGroup(calleeGroup) , m_info(info) , m_callee(&callee) , m_mode(mode) @@ -1147,7 +1150,7 @@ OMGIRGenerator::OMGIRGenerator(CalleeGroup& calleeGroup, const ModuleInformation m_proc.pinRegister(GPRInfo::wasmBoundsCheckingSizeRegister); if (info.memory) { - m_proc.setWasmBoundsCheckGenerator([=, this] (CCallHelpers& jit, GPRReg pinnedGPR) { + m_proc.setWasmBoundsCheckGenerator([=, this](CCallHelpers& jit, WasmBoundsCheckValue* originValue, GPRReg pinnedGPR) { AllowMacroScratchRegisterUsage allowScratch(jit); switch (m_mode) { case MemoryMode::BoundsChecking: @@ -1157,7 +1160,7 @@ OMGIRGenerator::OMGIRGenerator(CalleeGroup& calleeGroup, const ModuleInformation ASSERT_UNUSED(pinnedGPR, InvalidGPRReg == pinnedGPR); break; } - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + this->emitExceptionCheck(jit, originValue->origin(), ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -1300,9 +1303,13 @@ void OMGIRGenerator::reloadMemoryRegistersFromInstance(const MemoryInformation& } } -void OMGIRGenerator::emitExceptionCheck(CCallHelpers& jit, ExceptionType type) +void OMGIRGenerator::emitExceptionCheck(CCallHelpers& jit, Origin origin, ExceptionType type) { jit.move(CCallHelpers::TrustedImm32(static_cast(type)), GPRInfo::argumentGPR1); + if (auto* omgOrigin = std::bit_cast(origin.data())) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::argumentGPR2); + jit.store32(GPRInfo::argumentGPR2, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } jit.jumpThunk(CodeLocationLabel(Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator).code())); } @@ -1535,8 +1542,8 @@ auto OMGIRGenerator::addTableGet(unsigned tableIndex, ExpressionType index, Expr CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1552,8 +1559,8 @@ auto OMGIRGenerator::addTableSet(unsigned tableIndex, ExpressionType index, Expr CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), shouldThrow, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1575,8 +1582,8 @@ auto OMGIRGenerator::addRefAsNonNull(ExpressionType reference, ExpressionType& r { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), get(reference), m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullRefAsNonNull); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullRefAsNonNull); }); } return { }; @@ -1599,8 +1606,8 @@ auto OMGIRGenerator::addTableInit(unsigned elementIndex, unsigned tableIndex, Ex CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1642,8 +1649,8 @@ auto OMGIRGenerator::addTableFill(unsigned tableIndex, ExpressionType offset, Ex CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1663,8 +1670,8 @@ auto OMGIRGenerator::addTableCopy(unsigned dstTableIndex, unsigned srcTableIndex CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1682,8 +1689,8 @@ auto OMGIRGenerator::getLocal(uint32_t index, ExpressionType& result) -> Partial auto OMGIRGenerator::addUnreachable() -> PartialResult { B3::PatchpointValue* unreachable = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - unreachable->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::Unreachable); + unreachable->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::Unreachable); }); unreachable->effects.terminal = true; return { }; @@ -1871,8 +1878,8 @@ auto OMGIRGenerator::addMemoryFill(ExpressionType dstAddress, ExpressionType tar CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -1890,8 +1897,8 @@ auto OMGIRGenerator::addMemoryInit(unsigned dataSegmentIndex, ExpressionType dst CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -1908,8 +1915,8 @@ auto OMGIRGenerator::addMemoryCopy(ExpressionType dstAddress, ExpressionType src CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -2331,8 +2338,8 @@ auto OMGIRGenerator::load(LoadOpType op, ExpressionType pointerVar, ExpressionTy // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (op) { @@ -2432,8 +2439,8 @@ auto OMGIRGenerator::store(StoreOpType op, ExpressionType pointerVar, Expression // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } else emitStoreOp(op, emitCheckAndPreparePointer(pointer, offset, sizeOfStoreOp(op)), value, offset); @@ -2484,8 +2491,8 @@ Value* OMGIRGenerator::fixupPointerPlusOffsetForAtomicOps(ExtAtomicOpType op, Va if (accessWidth(op) != Width8) { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, BitAnd, origin(), pointer, constant(pointerType(), sizeOfAtomicOpMemoryAccess(op) - 1))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::UnalignedMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::UnalignedMemoryAccess); }); } return pointer; @@ -2521,8 +2528,8 @@ auto OMGIRGenerator::atomicLoad(ExtAtomicOpType op, Type valueType, ExpressionTy // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (valueType.kind) { @@ -2559,8 +2566,8 @@ auto OMGIRGenerator::atomicStore(ExtAtomicOpType op, Type valueType, ExpressionT // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } else emitAtomicStoreOp(op, valueType, emitCheckAndPreparePointer(get(pointer), offset, sizeOfAtomicOpMemoryAccess(op)), get(value), offset); @@ -2647,8 +2654,8 @@ auto OMGIRGenerator::atomicBinaryRMW(ExtAtomicOpType op, Type valueType, Express // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (valueType.kind) { @@ -2759,8 +2766,8 @@ auto OMGIRGenerator::atomicCompareExchange(ExtAtomicOpType op, Type valueType, E // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (valueType.kind) { @@ -2799,8 +2806,8 @@ auto OMGIRGenerator::atomicWait(ExtAtomicOpType op, ExpressionType pointerVar, E CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, LessThan, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -2816,8 +2823,8 @@ auto OMGIRGenerator::atomicNotify(ExtAtomicOpType, ExpressionType pointer, Expre CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, LessThan, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -3009,8 +3016,8 @@ auto OMGIRGenerator::addI31GetS(ExpressionType ref, ExpressionType& result) -> P { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), get(ref), m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullI31Get); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullI31Get); }); } @@ -3025,8 +3032,8 @@ auto OMGIRGenerator::addI31GetU(ExpressionType ref, ExpressionType& result) -> P { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), get(ref), m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullI31Get); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullI31Get); }); } @@ -3059,8 +3066,8 @@ Variable* OMGIRGenerator::pushArrayNew(uint32_t typeIndex, Value* initValue, Exp CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadArrayNew); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadArrayNew); }); } @@ -3188,8 +3195,8 @@ auto OMGIRGenerator::addArrayGet(ExtGCOpType arrayGetKind, uint32_t typeIndex, E { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), get(arrayref), m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullArrayGet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullArrayGet); }); } @@ -3199,8 +3206,8 @@ auto OMGIRGenerator::addArrayGet(ExtGCOpType arrayGetKind, uint32_t typeIndex, E { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, AboveEqual, origin(), get(index), arraySize)); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayGet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayGet); }); } @@ -3250,8 +3257,8 @@ void OMGIRGenerator::emitArrayNullCheck(Value* arrayref, ExceptionType exception { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), arrayref, m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, exceptionType); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, exceptionType); }); } @@ -3304,8 +3311,8 @@ auto OMGIRGenerator::addArraySet(uint32_t typeIndex, ExpressionType arrayref, Ex { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, AboveEqual, origin(), get(index), arraySize)); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArraySet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArraySet); }); } @@ -3320,8 +3327,8 @@ auto OMGIRGenerator::addArrayLen(ExpressionType arrayref, ExpressionType& result { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), get(arrayref), m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullArrayLen); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullArrayLen); }); } @@ -3355,8 +3362,8 @@ auto OMGIRGenerator::addArrayFill(uint32_t typeIndex, ExpressionType arrayref, E CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayFill); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayFill); }); } @@ -3378,8 +3385,8 @@ auto OMGIRGenerator::addArrayCopy(uint32_t, ExpressionType dst, ExpressionType d CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayCopy); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayCopy); }); } @@ -3400,8 +3407,8 @@ auto OMGIRGenerator::addArrayInitElem(uint32_t, ExpressionType dst, ExpressionTy CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayInitElem); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayInitElem); }); } @@ -3422,8 +3429,8 @@ auto OMGIRGenerator::addArrayInitData(uint32_t, ExpressionType dst, ExpressionTy CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayInitData); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayInitData); }); } @@ -3443,8 +3450,8 @@ auto OMGIRGenerator::addStructNew(uint32_t typeIndex, ArgumentList& args, Expres { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), structValue, m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadStructNew); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadStructNew); }); } @@ -3470,8 +3477,8 @@ auto OMGIRGenerator::addStructNewDefault(uint32_t typeIndex, ExpressionType& res { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), structValue, m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadStructNew); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadStructNew); }); } @@ -3500,8 +3507,8 @@ auto OMGIRGenerator::addStructGet(ExtGCOpType structGetKind, ExpressionType stru { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), get(structReference), m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullStructGet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullStructGet); }); } @@ -3547,8 +3554,8 @@ auto OMGIRGenerator::addStructSet(ExpressionType structReference, const StructTy { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), get(structReference), m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullStructSet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullStructSet); }); } @@ -3581,8 +3588,8 @@ void OMGIRGenerator::emitRefTestOrCast(CastKind castKind, ExpressionType referen falseBlock = m_proc.addBlock(); } - auto castFailure = [this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::CastFailure); + auto castFailure = [this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::CastFailure); }; // Ensure reference nullness agrees with heap type. @@ -3709,10 +3716,7 @@ void OMGIRGenerator::emitRefTestOrCast(CastKind castKind, ExpressionType referen slowPath->addPredecessor(m_currentBlock); m_currentBlock = slowPath; - // FIXME: It may be worthwhile to JIT inline this in the future. - Value* isSubRTT = m_currentBlock->appendNew(m_proc, B3::Int32, origin(), - m_currentBlock->appendNew(m_proc, origin(), tagCFunction(operationWasmIsSubRTT)), - rtt, targetRTT); + Value* isSubRTT = callWasmOperation(m_currentBlock, B3::Int32, operationWasmIsSubRTT, rtt, targetRTT); emitCheckOrBranchForCast(castKind, m_currentBlock->appendNew(m_proc, Equal, origin(), isSubRTT, constant(Int32, 0)), castFailure, falseBlock); } @@ -4516,9 +4520,13 @@ auto OMGIRGenerator::addThrow(unsigned exceptionIndex, ArgumentList& args, Stack m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, offset); patch->clobber(RegisterSetBuilder::registersToSaveForJSCall(m_proc.usesSIMD() ? RegisterSetBuilder::allRegisters() : RegisterSetBuilder::allScalarRegisters())); PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); - patch->setGenerator([this, exceptionIndex, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patch->setGenerator([this, exceptionIndex, handle, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); + if (auto* omgOrigin = std::bit_cast(origin.data())) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); + jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } emitThrowImpl(jit, exceptionIndex); }); m_currentBlock->append(patch); @@ -4539,13 +4547,17 @@ auto WARN_UNUSED_RETURN OMGIRGenerator::addThrowRef(ExpressionType exn, Stack&) CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), exception, constant(Wasm::toB3Type(exnrefType()), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullExnReference); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullExnReference); }); PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); - patch->setGenerator([this, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patch->setGenerator([this, handle, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); + if (auto* omgOrigin = std::bit_cast(origin.data())) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); + jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } emitThrowRefImpl(jit); }); m_currentBlock->append(patch); @@ -4562,9 +4574,13 @@ auto OMGIRGenerator::addRethrow(unsigned, ControlType& data) -> PartialResult patch->append(instanceValue(), ValueRep::reg(GPRInfo::argumentGPR0)); patch->append(get(data.exception()), ValueRep::reg(GPRInfo::argumentGPR1)); PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); - patch->setGenerator([this, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patch->setGenerator([this, handle, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); + if (auto* omgOrigin = std::bit_cast(origin.data())) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); + jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } emitThrowRefImpl(jit); }); m_currentBlock->append(patch); @@ -5337,9 +5353,9 @@ auto OMGIRGenerator::emitInlineDirectCall(FunctionCodeIndex calleeFunctionIndex, BasicBlock* continuation = m_proc.addBlock(); // Not all inine frames need to save state, but we still need to make sure that there is at least - // one unique csi per inline frame for stack traces to work. + // one unique CallSiteIndex per inline frame for stack traces to work. advanceCallSiteIndex(); - auto firstInlineCSI = advanceCallSiteIndex(); + auto firstInlineCallSiteIndex = advanceCallSiteIndex(); const FunctionData& function = m_info.functions[calleeFunctionIndex]; std::optional inlineeHasExceptionHandlers; @@ -5348,7 +5364,7 @@ auto OMGIRGenerator::emitInlineDirectCall(FunctionCodeIndex calleeFunctionIndex, auto& inlineCallee = m_calleeGroup.wasmEntrypointCalleeFromFunctionIndexSpace(locker, m_calleeGroup.toSpaceIndex(calleeFunctionIndex)); inlineeHasExceptionHandlers = inlineCallee.hasExceptionHandlers(); } - m_protectedInlineeGenerators.append(makeUnique(*this, *m_inlineRoot, m_calleeGroup, calleeFunctionIndex, inlineeHasExceptionHandlers, continuation, WTFMove(getArgs))); + m_protectedInlineeGenerators.append(makeUnique(m_context, *this, *m_inlineRoot, m_calleeGroup, calleeFunctionIndex, inlineeHasExceptionHandlers, continuation, WTFMove(getArgs))); auto& irGenerator = *m_protectedInlineeGenerators.last(); m_protectedInlineeParsers.append(makeUnique>(irGenerator, function.data, calleeSignature, m_info)); auto& parser = *m_protectedInlineeParsers.last(); @@ -5370,24 +5386,18 @@ auto OMGIRGenerator::emitInlineDirectCall(FunctionCodeIndex calleeFunctionIndex, ASSERT(&irGenerator.m_proc == &m_proc); dataLogLnIf(WasmOMGIRGeneratorInternal::verboseInlining, "Block ", *m_currentBlock, " is going to do an inline call to block ", *irGenerator.m_topLevelBlock, " then continue at ", *continuation); - - m_currentBlock->appendNew(m_proc, B3::Store, origin(), - m_currentBlock->appendIntConstant(m_proc, origin(), Int32, firstInlineCSI), - framePointer(), safeCast(CallFrameSlot::argumentCountIncludingThis * sizeof(Register) + TagOffset)); - m_currentBlock->appendNewControlValue(m_proc, B3::Jump, origin(), FrequentedBlock(irGenerator.m_topLevelBlock)); m_currentBlock = continuation; for (unsigned i = 0; i < calleeSignature.as()->returnCount(); ++i) resultList.append(push(m_currentBlock->appendNew(m_proc, B3::Get, origin(), irGenerator.m_inlinedResults[i]))); - auto lastInlineCSI = advanceCallSiteIndex(); + auto lastInlineCallSiteIndex = advanceCallSiteIndex(); + advanceCallSiteIndex(); + m_callee->addCodeOrigin(firstInlineCallSiteIndex, lastInlineCallSiteIndex, m_info, calleeFunctionIndex + m_numImportFunctions); - m_currentBlock->appendNew(m_proc, B3::Store, origin(), - m_currentBlock->appendIntConstant(m_proc, origin(), Int32, advanceCallSiteIndex()), - framePointer(), safeCast(CallFrameSlot::argumentCountIncludingThis * sizeof(Register) + TagOffset)); + dataLogLnIf(WasmOMGIRGeneratorInternal::verboseInlining, "Inlining CallSiteIndex range: ", firstInlineCallSiteIndex, " -> ", lastInlineCallSiteIndex, " [", m_inlineDepth, "]"); - m_callee->addCodeOrigin(firstInlineCSI, lastInlineCSI, m_info, calleeFunctionIndex + m_numImportFunctions); return { }; } @@ -5523,7 +5533,8 @@ auto OMGIRGenerator::addCall(FunctionSpaceIndex functionIndexSpace, const TypeDe handle->generate(jit, params, this); auto calleeMove = jit.storeWasmCalleeCalleePatchable(isTailCall ? sizeof(CallerFrameAndPC) - prologueStackPointerDelta() : 0); - CCallHelpers::Call call = isTailCall ? jit.threadSafePatchableNearTailCall() : jit.threadSafePatchableNearCall(); + auto call = isTailCall ? jit.threadSafePatchableNearTailCall() : jit.threadSafePatchableNearCall(); + jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndexSpace, calleeMove](LinkBuffer& linkBuffer) { unlinkedWasmToWasmCalls->append({ linkBuffer.locationOfNearCall(call), functionIndexSpace, linkBuffer.locationOf(calleeMove) }); }); @@ -5610,8 +5621,8 @@ auto OMGIRGenerator::addCallIndirect(unsigned tableIndex, const TypeDefinition& CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, AboveEqual, origin(), calleeIndex, callableFunctionBufferLength)); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsCallIndirect); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsCallIndirect); }); } @@ -5642,8 +5653,8 @@ auto OMGIRGenerator::addCallIndirect(unsigned tableIndex, const TypeDefinition& CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), calleeSignatureIndex, constant(pointerType(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullTableEntry); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullTableEntry); }); } @@ -5687,8 +5698,8 @@ auto OMGIRGenerator::addCallIndirect(unsigned tableIndex, const TypeDefinition& m_currentBlock = throwBlock; B3::PatchpointValue* throwException = m_currentBlock->appendNew(m_proc, B3::Void, origin()); - throwException->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadSignature); + throwException->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadSignature); }); throwException->effects.terminal = true; @@ -5716,8 +5727,8 @@ auto OMGIRGenerator::addCallRef(const TypeDefinition& originalSignature, Argumen { CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), callee, m_currentBlock->appendNew(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullReference); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullReference); }); } @@ -5784,19 +5795,23 @@ auto OMGIRGenerator::origin() -> Origin { if (!m_parser) return Origin(); - OpcodeOrigin origin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentOpcodeStartingOffset()); + + OpcodeOrigin opcodeOrigin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentOpcodeStartingOffset()); switch (m_parser->currentOpcode()) { case OpType::Ext1: case OpType::ExtGC: case OpType::ExtAtomic: case OpType::ExtSIMD: - origin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentExtendedOpcode(), m_parser->currentOpcodeStartingOffset()); + opcodeOrigin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentExtendedOpcode(), m_parser->currentOpcodeStartingOffset()); break; default: break; } - ASSERT(isValidOpType(static_cast(origin.opcode()))); - return std::bit_cast(origin); + ASSERT(isValidOpType(static_cast(opcodeOrigin.opcode()))); + OMGOrigin result { CallSiteIndex(callSiteIndex()), opcodeOrigin }; + if (m_context.origins.isEmpty() || m_context.origins.last() != result) + m_context.origins.append(result); + return Origin(&m_context.origins.last()); } static bool shouldDumpIRFor(uint32_t functionIndex) @@ -5825,18 +5840,12 @@ Expected, String> parseAndCompileOMG(Compilati if (shouldDumpIRFor(functionIndex + info.importFunctionCount())) procedure.setShouldDumpIR(); - - if (Options::useSamplingProfiler()) { - // FIXME: We should do this based on VM relevant info. - // But this is good enough for our own profiling for now. - // When we start to show this data in web inspector, we'll - // need other hooks into this besides the JSC option. - procedure.setNeedsPCToOriginMap(); - } - - procedure.setOriginPrinter([] (PrintStream& out, Origin origin) { - if (origin.data()) - out.print("Wasm: ", OpcodeOrigin(origin)); + procedure.setNeedsPCToOriginMap(); + procedure.setOriginPrinter([](PrintStream& out, Origin origin) { + if (origin.data()) { + auto* impl = std::bit_cast(origin.data()); + out.print("Wasm: ", impl->m_opcodeOrigin, " CallSiteIndex: ", impl->m_callSiteIndex.bits()); + } }); // This means we cannot use either StackmapGenerationParams::usedRegisters() or @@ -5850,7 +5859,7 @@ Expected, String> parseAndCompileOMG(Compilati procedure.code().setForceIRCRegisterAllocation(); result->outgoingJITDirectCallees = FixedBitVector(info.internalFunctionCount()); - OMGIRGenerator irGenerator(calleeGroup, info, callee, procedure, unlinkedWasmToWasmCalls, result->outgoingJITDirectCallees, result->osrEntryScratchBufferSize, mode, compilationMode, functionIndex, hasExceptionHandlers, loopIndexForOSREntry); + OMGIRGenerator irGenerator(compilationContext, calleeGroup, info, callee, procedure, unlinkedWasmToWasmCalls, result->outgoingJITDirectCallees, result->osrEntryScratchBufferSize, mode, compilationMode, functionIndex, hasExceptionHandlers, loopIndexForOSREntry); FunctionParser parser(irGenerator, function.data, signature, info); WASM_FAIL_IF_HELPER_FAILS(parser.parse()); @@ -5903,8 +5912,8 @@ void OMGIRGenerator::emitChecksForModOrDiv(B3::Opcode operation, Value* left, Va CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), right, constant(type, 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::DivisionByZero); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::DivisionByZero); }); } @@ -5916,8 +5925,8 @@ void OMGIRGenerator::emitChecksForModOrDiv(B3::Opcode operation, Value* left, Va m_currentBlock->appendNew(m_proc, Equal, origin(), left, constant(type, min)), m_currentBlock->appendNew(m_proc, Equal, origin(), right, constant(type, -1)))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::IntegerOverflow); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::IntegerOverflow); }); } } @@ -6186,8 +6195,8 @@ auto OMGIRGenerator::addI32TruncSF64(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = m_currentBlock->appendNew(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6209,8 +6218,8 @@ auto OMGIRGenerator::addI32TruncSF32(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterEqual, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = m_currentBlock->appendNew(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6233,8 +6242,8 @@ auto OMGIRGenerator::addI32TruncUF64(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = m_currentBlock->appendNew(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6256,8 +6265,8 @@ auto OMGIRGenerator::addI32TruncUF32(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = m_currentBlock->appendNew(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6279,8 +6288,8 @@ auto OMGIRGenerator::addI64TruncSF64(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterEqual, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = m_currentBlock->appendNew(m_proc, Int64, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6302,8 +6311,8 @@ auto OMGIRGenerator::addI64TruncUF64(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); Value* signBitConstant; @@ -6345,8 +6354,8 @@ auto OMGIRGenerator::addI64TruncSF32(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterEqual, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = m_currentBlock->appendNew(m_proc, Int64, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6368,8 +6377,8 @@ auto OMGIRGenerator::addI64TruncUF32(ExpressionType argVar, ExpressionType& resu m_currentBlock->appendNew(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = m_currentBlock->appendNew(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = m_currentBlock->appendNew(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); Value* signBitConstant; diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index 57b07ddd0ba7..9b5dcd17737f 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -1396,7 +1396,7 @@ OMGIRGenerator::OMGIRGenerator(CalleeGroup& calleeGroup, const ModuleInformation m_proc.pinRegister(GPRInfo::wasmBoundsCheckingSizeRegister); #endif if (info.memory) { - m_proc.setWasmBoundsCheckGenerator([=, this] (CCallHelpers& jit, GPRReg pinnedGPR) { + m_proc.setWasmBoundsCheckGenerator([=, this](CCallHelpers& jit, WasmBoundsCheckValue*, GPRReg pinnedGPR) { AllowMacroScratchRegisterUsage allowScratch(jit); switch (m_mode) { case MemoryMode::BoundsChecking: @@ -6296,15 +6296,7 @@ Expected, String> parseAndCompileOMG(Compilati if (shouldDumpIRFor(functionIndex + info.importFunctionCount())) procedure.setShouldDumpIR(); - - if (Options::useSamplingProfiler()) { - // FIXME: We should do this based on VM relevant info. - // But this is good enough for our own profiling for now. - // When we start to show this data in web inspector, we'll - // need other hooks into this besides the JSC option. - procedure.setNeedsPCToOriginMap(); - } - + procedure.setNeedsPCToOriginMap(); procedure.setOriginPrinter([] (PrintStream& out, Origin origin) { if (origin.data()) out.print("Wasm: ", OpcodeOrigin(origin)); diff --git a/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp b/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp index 5266239cabff..d38beb1e32cc 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp @@ -156,8 +156,7 @@ void OMGPlan::work(CompilationEffort) Vector> exceptionHandlerLocations; computeExceptionHandlerLocations(exceptionHandlerLocations, internalFunction, context, linkBuffer); - computePCToCodeOriginMap(context, linkBuffer); - + auto samplingProfilerMap = callee->materializePCToOriginMap(context.procedure->releasePCToOriginMap(), linkBuffer); { ScopedPrintStream out; dumpDisassembly(context, linkBuffer, m_functionIndex, signature, functionIndexSpace); @@ -174,8 +173,8 @@ void OMGPlan::work(CompilationEffort) callee->setEntrypoint(WTFMove(omgEntrypoint), WTFMove(unlinkedCalls), WTFMove(internalFunction->stackmaps), WTFMove(internalFunction->exceptionHandlers), WTFMove(exceptionHandlerLocations)); entrypoint = callee->entrypoint(); - if (context.pcToCodeOriginMap) - NativeCalleeRegistry::singleton().addPCToCodeOriginMap(callee.ptr(), WTFMove(context.pcToCodeOriginMap)); + if (samplingProfilerMap) + NativeCalleeRegistry::singleton().addPCToCodeOriginMap(callee.ptr(), WTFMove(samplingProfilerMap)); // We want to make sure we publish our callee at the same time as we link our callsites. This enables us to ensure we // always call the fastest code. Any function linked after us will see our new code and the new callsites, which they diff --git a/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp b/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp index 6df3ffb8a07c..eedb7216fc06 100644 --- a/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp +++ b/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp @@ -30,6 +30,7 @@ #include "JITCompilation.h" #include "LinkBuffer.h" +#include "NativeCalleeRegistry.h" #include "WasmCallee.h" #include "WasmIRGeneratorHelpers.h" #include "WasmMachineThreads.h" @@ -129,6 +130,8 @@ void OSREntryPlan::work(CompilationEffort) Vector> exceptionHandlerLocations; computeExceptionHandlerLocations(exceptionHandlerLocations, internalFunction, context, linkBuffer); + auto samplingProfilerMap = callee->materializePCToOriginMap(context.procedure->releasePCToOriginMap(), linkBuffer); + dumpDisassembly(context, linkBuffer, m_functionIndex, signature, functionIndexSpace); omgEntrypoint.compilation = makeUnique( FINALIZE_CODE_IF(context.procedure->shouldDumpIR(), linkBuffer, JITCompilationPtrTag, nullptr, "WebAssembly OMGForOSREntry function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()), @@ -138,6 +141,10 @@ void OSREntryPlan::work(CompilationEffort) ASSERT(m_calleeGroup.ptr() == m_module->calleeGroupFor(mode())); callee->setEntrypoint(WTFMove(omgEntrypoint), internalFunction->osrEntryScratchBufferSize, WTFMove(unlinkedCalls), WTFMove(internalFunction->stackmaps), WTFMove(internalFunction->exceptionHandlers), WTFMove(exceptionHandlerLocations)); + + if (samplingProfilerMap) + NativeCalleeRegistry::singleton().addPCToCodeOriginMap(callee.ptr(), WTFMove(samplingProfilerMap)); + { Locker locker { m_calleeGroup->m_lock }; m_calleeGroup->recordOMGOSREntryCallee(locker, m_functionIndex, callee.get()); diff --git a/Source/JavaScriptCore/wasm/WasmOpcodeOrigin.h b/Source/JavaScriptCore/wasm/WasmOpcodeOrigin.h index bbc29f5abebd..e49383dc0b1d 100644 --- a/Source/JavaScriptCore/wasm/WasmOpcodeOrigin.h +++ b/Source/JavaScriptCore/wasm/WasmOpcodeOrigin.h @@ -37,11 +37,13 @@ namespace JSC { namespace Wasm { class OpcodeOrigin { WTF_FORBID_HEAP_ALLOCATION; - OpcodeOrigin() = default; - public: void dump(PrintStream&) const; + OpcodeOrigin() = default; + + friend bool operator==(const OpcodeOrigin&, const OpcodeOrigin&) = default; + #if USE(JSVALUE64) OpcodeOrigin(OpType opcode, size_t offset) { diff --git a/Source/JavaScriptCore/wasm/WasmOperations.cpp b/Source/JavaScriptCore/wasm/WasmOperations.cpp index 25c325dd156c..531da5ab6556 100644 --- a/Source/JavaScriptCore/wasm/WasmOperations.cpp +++ b/Source/JavaScriptCore/wasm/WasmOperations.cpp @@ -1893,7 +1893,7 @@ JSC_DEFINE_NOEXCEPT_JIT_OPERATION(operationWasmArrayInitData, UCPUStrictInt32, ( return toUCPUStrictInt32(arrayInitData(instance, dst, dstOffset, srcDataIndex, srcOffset, size)); } -JSC_DEFINE_NOEXCEPT_JIT_OPERATION(operationWasmIsSubRTT, bool, (RTT * maybeSubRTT, RTT* targetRTT)) +JSC_DEFINE_NOEXCEPT_JIT_OPERATION(operationWasmIsSubRTT, bool, (RTT* maybeSubRTT, RTT* targetRTT)) { ASSERT(maybeSubRTT && targetRTT); return maybeSubRTT->isSubRTT(*targetRTT); diff --git a/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp b/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp index 08f03ce82cb1..5d05ef0c251c 100644 --- a/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp +++ b/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp @@ -1355,6 +1355,17 @@ WASM_SLOW_PATH_DECL(i64_trunc_sat_f64_s) extern "C" UGPRPair SYSV_ABI slow_path_wasm_throw_exception(CallFrame* callFrame, JSWebAssemblyInstance* instance, Wasm::ExceptionType exceptionType) { SlowPathFrameTracer tracer(instance->vm(), callFrame); +#if ENABLE(WEBASSEMBLY_BBQJIT) + void* pc = instance->faultPC(); + instance->setFaultPC(nullptr); + auto* callee = callFrame->callee().asNativeCallee(); + ASSERT(callee->category() == NativeCallee::Category::Wasm); + auto& wasmCallee = static_cast(*callee); + if (isAnyOMG(wasmCallee.compilationMode())) { + if (auto callSiteIndexFromPC = static_cast(wasmCallee).tryGetCallSiteIndex(pc)) + callFrame->setCallSiteIndex(callSiteIndexFromPC.value()); + } +#endif WASM_RETURN_TWO(Wasm::throwWasmToJSException(callFrame, exceptionType, instance), nullptr); } diff --git a/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h b/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h index 8df3d99d9968..9c3f47dd7709 100644 --- a/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h +++ b/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h @@ -283,6 +283,9 @@ class JSWebAssemblyInstance final : public JSNonFinalObject { void* softStackLimit() const { return m_softStackLimit; } + void setFaultPC(void* pc) { m_faultPC = pc; }; + void* faultPC() const { return m_faultPC; } + private: JSWebAssemblyInstance(VM&, Structure*, JSWebAssemblyModule*, WebAssemblyModuleRecord*); ~JSWebAssemblyInstance(); @@ -317,6 +320,7 @@ class JSWebAssemblyInstance final : public JSNonFinalObject { BitVector m_passiveDataSegments; FixedVector> m_tags; Vector> importCallees; + void* m_faultPC { nullptr }; }; } // namespace JSC diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h index 045f0b434934..302bd001c036 100644 --- a/Source/WTF/wtf/PlatformHave.h +++ b/Source/WTF/wtf/PlatformHave.h @@ -237,7 +237,7 @@ #define HAVE_HOSTED_CORE_ANIMATION 1 #endif -#if OS(DARWIN) || OS(FUCHSIA) || ((OS(FREEBSD) || OS(NETBSD) || OS(OPENBSD) || OS(LINUX) || OS(QNX)) && (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(ARM64) || CPU(MIPS) || CPU(RISCV64))) +#if OS(DARWIN) || OS(FUCHSIA) || ((OS(FREEBSD) || OS(NETBSD) || OS(OPENBSD) || OS(LINUX) || OS(QNX)) && (CPU(X86_64) || CPU(ARM) || CPU(ARM64) || CPU(RISCV64))) #define HAVE_MACHINE_CONTEXT 1 #endif From 55bf779987c62a478fd06f9e82d42287b49a206f Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Sat, 3 May 2025 06:25:17 -0700 Subject: [PATCH 45/54] Set the opcode origin correctly on Wasm OMG IR Generator for 32bit CPUs https://bugs.webkit.org/show_bug.cgi?id=292428 Reviewed by Justin Michaud. Incorporates relevant changes from WasmOMGIRGenerator.cpp, that set the opcode origin correctly on 32bit CPUs. This fixes the following failures on 32bit when OMG is enabled: - JSTests/wasm/stress/simple-inline-stacktrace.js - JSTests/wasm/stress/simple-inline-stacktrace-with-catch.js - JSTests/wasm/function-tests/stack-trace.js * Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp: (JSC::Wasm::OMGIRGenerator::OMGIRGenerator): adds a new first argument CompilationContext& m_context (JSC::Wasm::OMGIRGenerator::emitInlineDirectCall): adds argument m_context to the call to makeUnique (JSC::Wasm::OMGIRGenerator::origin): incorporates the same changes in this function from WasmOMGIRGenerator.cpp (JSC::Wasm::parseAndCompileOMG): adds new context argument to the OMGIRGenerator constructor Canonical link: https://commits.webkit.org/294475@main (cherry picked from commit 050ce797fa7567c23da29d0cba5508ac5ebb91ca) --- .../wasm/WasmOMGIRGenerator32_64.cpp | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index 9b5dcd17737f..aa483aece5a2 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -495,8 +495,8 @@ class OMGIRGenerator { return m_callSiteIndex; } - OMGIRGenerator(CalleeGroup&, const ModuleInformation&, OptimizingJITCallee&, Procedure&, Vector&, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode, CompilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry); - OMGIRGenerator(OMGIRGenerator& inlineCaller, OMGIRGenerator& inlineRoot, CalleeGroup&, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args); + OMGIRGenerator(CompilationContext&, CalleeGroup&, const ModuleInformation&, OptimizingJITCallee&, Procedure&, Vector&, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode, CompilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry); + OMGIRGenerator(CompilationContext&, OMGIRGenerator& inlineCaller, OMGIRGenerator& inlineRoot, CalleeGroup&, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args); void computeStackCheckSize(bool& needsOverflowCheck, int32_t& checkSize); @@ -1119,6 +1119,7 @@ class OMGIRGenerator { void traceCF(Args&&... info); FunctionParser* m_parser { nullptr }; + CompilationContext& m_context; CalleeGroup& m_calleeGroup; const ModuleInformation& m_info; OptimizingJITCallee* m_callee; @@ -1330,8 +1331,9 @@ void OMGIRGenerator::computeStackCheckSize(bool& needsOverflowCheck, int32_t& ch needsOverflowCheck = needsOverflowCheck || needUnderflowCheck; } -OMGIRGenerator::OMGIRGenerator(OMGIRGenerator& parentCaller, OMGIRGenerator& rootCaller, CalleeGroup& calleeGroup, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args) - : m_calleeGroup(calleeGroup) +OMGIRGenerator::OMGIRGenerator(CompilationContext& context, OMGIRGenerator& parentCaller, OMGIRGenerator& rootCaller, CalleeGroup& calleeGroup, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args) + : m_context(context) + , m_calleeGroup(calleeGroup) , m_info(rootCaller.m_info) , m_callee(parentCaller.m_callee) , m_mode(rootCaller.m_mode) @@ -1364,8 +1366,9 @@ OMGIRGenerator::OMGIRGenerator(OMGIRGenerator& parentCaller, OMGIRGenerator& roo m_hasExceptionHandlers = { true }; } -OMGIRGenerator::OMGIRGenerator(CalleeGroup& calleeGroup, const ModuleInformation& info, OptimizingJITCallee& callee, Procedure& procedure, Vector& unlinkedWasmToWasmCalls, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry) - : m_calleeGroup(calleeGroup) +OMGIRGenerator::OMGIRGenerator(CompilationContext& context, CalleeGroup& calleeGroup, const ModuleInformation& info, OptimizingJITCallee& callee, Procedure& procedure, Vector& unlinkedWasmToWasmCalls, FixedBitVector& outgoingDirectCallees, unsigned& osrEntryScratchBufferSize, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry) + : m_context(context) + , m_calleeGroup(calleeGroup) , m_info(info) , m_callee(&callee) , m_mode(mode) @@ -5825,7 +5828,7 @@ auto OMGIRGenerator::emitInlineDirectCall(FunctionCodeIndex calleeFunctionIndex, auto& inlineCallee = m_calleeGroup.wasmEntrypointCalleeFromFunctionIndexSpace(locker, m_calleeGroup.toSpaceIndex(calleeFunctionIndex)); inlineeHasExceptionHandlers = inlineCallee.hasExceptionHandlers(); } - m_protectedInlineeGenerators.append(makeUnique(*this, *m_inlineRoot, m_calleeGroup, calleeFunctionIndex, inlineeHasExceptionHandlers, continuation, WTFMove(getArgs))); + m_protectedInlineeGenerators.append(makeUnique(m_context, *this, *m_inlineRoot, m_calleeGroup, calleeFunctionIndex, inlineeHasExceptionHandlers, continuation, WTFMove(getArgs))); auto& irGenerator = *m_protectedInlineeGenerators.last(); m_protectedInlineeParsers.append(makeUnique>(irGenerator, function.data, calleeSignature, m_info)); auto& parser = *m_protectedInlineeParsers.last(); @@ -6255,19 +6258,23 @@ auto OMGIRGenerator::origin() -> Origin { if (!m_parser) return Origin(); - OpcodeOrigin origin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentOpcodeStartingOffset()); + + OpcodeOrigin opcodeOrigin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentOpcodeStartingOffset()); switch (m_parser->currentOpcode()) { case OpType::Ext1: case OpType::ExtGC: case OpType::ExtAtomic: case OpType::ExtSIMD: - origin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentExtendedOpcode(), m_parser->currentOpcodeStartingOffset()); + opcodeOrigin = OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentExtendedOpcode(), m_parser->currentOpcodeStartingOffset()); break; default: break; } - ASSERT(isValidOpType(static_cast(origin.opcode()))); - return std::bit_cast(origin); + ASSERT(isValidOpType(static_cast(opcodeOrigin.opcode()))); + OMGOrigin result { CallSiteIndex(callSiteIndex()), opcodeOrigin }; + if (m_context.origins.isEmpty() || m_context.origins.last() != result) + m_context.origins.append(result); + return Origin(&m_context.origins.last()); } static bool shouldDumpIRFor(uint32_t functionIndex) @@ -6313,7 +6320,7 @@ Expected, String> parseAndCompileOMG(Compilati procedure.code().setForceIRCRegisterAllocation(); result->outgoingJITDirectCallees = FixedBitVector(info.internalFunctionCount()); - OMGIRGenerator irGenerator(calleeGroup, info, callee, procedure, unlinkedWasmToWasmCalls, result->outgoingJITDirectCallees, result->osrEntryScratchBufferSize, mode, compilationMode, functionIndex, hasExceptionHandlers, loopIndexForOSREntry); + OMGIRGenerator irGenerator(compilationContext, calleeGroup, info, callee, procedure, unlinkedWasmToWasmCalls, result->outgoingJITDirectCallees, result->osrEntryScratchBufferSize, mode, compilationMode, functionIndex, hasExceptionHandlers, loopIndexForOSREntry); FunctionParser parser(irGenerator, function.data, signature, info); WASM_FAIL_IF_HELPER_FAILS(parser.parse()); From 64c05d421271c55ed373a634684ddbfc1992afaa Mon Sep 17 00:00:00 2001 From: Yusuke Suzuki Date: Thu, 5 Jun 2025 18:14:14 -0700 Subject: [PATCH 46/54] Js/Wasm engine produce an invalid ref.cast runtime fail for func.ref types in hot functions. https://bugs.webkit.org/show_bug.cgi?id=293113 rdar://151464447 Reviewed by Daniel Liu and Keith Miller. 274558@main changed rtt field of WasmToWasmImportableFunction from CompactPtr to normal pointer, but it didn't change OMG code generator's loadCompactPtr. So we are materializing a pointer incorrectly. This patch removes loadCompactPtr and use normal Load for OMG. * JSTests/wasm/stress/resources/wasm-gc-ref-cast.wasm: Added. * JSTests/wasm/stress/resources/wasm-gc-ref-cast.wat: Added. * JSTests/wasm/stress/wasm-gc-ref-cast.mjs: Added. * Source/JavaScriptCore/wasm/WasmFormat.h: * Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp: (JSC::Wasm::OMGIRGenerator::emitLoadRTTFromFuncref): * Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp: (JSC::Wasm::OMGIRGenerator::emitLoadRTTFromFuncref): Canonical link: https://commits.webkit.org/295902@main (cherry picked from commit f63d69092df25f7d58a373a8a59bd06af23ce987) --- .../stress/resources/wasm-gc-ref-cast.wasm | Bin 0 -> 21889 bytes .../stress/resources/wasm-gc-ref-cast.wat | 3505 +++++++++++++++++ JSTests/wasm/stress/wasm-gc-ref-cast.mjs | 139 + Source/JavaScriptCore/wasm/WasmFormat.h | 2 +- .../wasm/WasmOMGIRGenerator.cpp | 7 +- .../wasm/WasmOMGIRGenerator32_64.cpp | 7 +- 6 files changed, 3647 insertions(+), 13 deletions(-) create mode 100644 JSTests/wasm/stress/resources/wasm-gc-ref-cast.wasm create mode 100644 JSTests/wasm/stress/resources/wasm-gc-ref-cast.wat create mode 100644 JSTests/wasm/stress/wasm-gc-ref-cast.mjs diff --git a/JSTests/wasm/stress/resources/wasm-gc-ref-cast.wasm b/JSTests/wasm/stress/resources/wasm-gc-ref-cast.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2c49b554a49d8df306b02202d2c0ea4fc5ba8a8c GIT binary patch literal 21889 zcmcJ133MCBnPyd^aj{9Fd5EG&9SwjwEm0D!%a%m5K~WZENt8rNz6C)5D1rn53IHuK zhiNCVolN35lkp^zeVJ@t#&afFD9&=m82?=JGyGCA$1Wx3SbS}c-TF_GvrCV& zcrfWC{XEXjvN%sF^ioq^mSiji2!57(t!C~+yWeRav)jke9!Le9_9brpRQG#R zT2;U7xs>#A!uFNMwvYTDHE(GzX);W;LUg(kR;joqfPxgvep3LDPtPL!=k)4J3!PKT|tfay7 z9N0oROA|}UumhC`w@q=?p#oZC+=w@)q7DcVs1Ona^B9UvF5U)sZ(afAEZ^*c-2&LH zE5dGd!EOWW_FIBIqnzagea8yWmc7sNYWfnV|0XzZhGiS!?7a!jn^wTtcN3g9u7Gp! zCO8Witm+x6rtWs2N#8fu^m|iBo&F_m&p;*V!)&I>B&OgOn3zgx>Wj>Q9pk3cImTmf zvKK3z$(I;kz|RuD3{seDNgqiiW+sRwzsw*7IqX*|IJE$lgQ=;nRX{B1;8xu%PCuLo zVd4kyds$h6$d}2z(b9xpunxgVLiXEt*@Jr0M+j~B#j6XycwsV=`{30>FLv3p1X^fQ z@lN)z%WAR*B}OdRWx;WVx}n=RFjlm~S+FIba!c@iv7i1s7tyQ}~!59)maPf6||E;~Sa2fdW! zPO9%jeW&%>&6B%P+lF8CZlm69sBgh9>RYHzg#juIpku&#?dQq;s2##DUWf4u4e;Q} zFX8HP$QYe$fzl!%)3H)UgUbanZFy%{Xvwyl6Pv%qU z?wNcko5}Sj6LY2cLVCQENX|?Y63H~1k|1Fl$#Zn=YyLu{}yIPuJISISHA>HZX$iiH{P#PCF6Z!kWmE~`albNkx953W&1;%Xt=4V`tBuJ3l^g;o{k|=k9;t!S071 ze&o?h@%ZJ$m1Jte#`NUXsmyeCc5dq0)W(g4VzD$eHNRoQ#@Rx5{ITl`i*I54_<0L{-pb#`&z*aUKh1}p;cw^f;J=2Sck*}fsb~4n$h+|`{v3aftDJc~ zSP8YD@E-2_ar1G+qva+IVQ0BbL)2OB(w4Z%v}A}chqOFjF3=-yHy-B8hc)t`0A~739(&;%@B72|e)#);`}U=Jh-NcrDzWF^^|rtN{O3OWdoM_c*w26Q_n-gn zYfs&{0rRcr4#AD4YIS)Nm9^LxzWui!dh64F^jE*r0OZfO*01hQ!`s)pLoxo|H-HRVY&P>Nf9G1LH@}DlXt{E_TtAr@Tuh& zKDe$zGZg!J`46A}hvgst_WP@bO@jPVF*{5>_R=%|^4~uBnZJALn+>SE;4#;k zZL#ov z*~}Z#EFa{one(Qv_oaM{8!V*h%wPsTsV*7ZYcMUOdC?%BCd%JbhoVgwiGJHeh#O_r z6lR)1C2y08_Y&T~HdVZRcpG^81^FX3g%(iQW3uJeG7AwdQs4=72w}))9xyxf4f^o_ zQ8akj-&*#DRDs-sy1~jyNG*qS!zuwnYYl1Z8+I8=xwVyRqc+o4Fx^`%cAF*k6ZmhT z>}?~_e}(`2DBI$<+2XfZ;$Ku~Q(^Fk680!d)(?#0F_&gq6~+~<2P6c!I!Ln+#+f+pw&PL{5*h~pasP9TnlOIY=v|vG(h(6f+E61 zLG+ZBUNxlIC0|Hu<5*&&d2Mfmqt6@C{wHsT9yl|gt&RQevEERR3Zjq7q%KkP0@vRY zRtz5Y7%Z%MhLj;g{pQF>3o}&o`y$?QDC{#lhHnNC-mu?L!U2ucuaElQPw;E01kfDWjqs0gr%|@%Cm)m-JqJd^I43SjBYBSd~SeG3Sw+ZyNNc)JG zCQatM5m8~s^RT0h!!X?5UJMv=wzpTsxO;5%lD$!kt=>*1@O%>#3{MDi4)DPq*rg|| zM%$v1=$)95*9-;BS#Q`&D27+>FkrBR-!g@Kk_FJKm`Zj!?1fEymOTvb31N`kjOlA( z0$9WFms_EasZ0aK7YT%e$`Ut%ktUN*L)Ea4bmZDa?1d^nu$fBoRTK9~;$ZA6xAYul zu)HMe4+n^BAQE(wgH{)9STpb$1lwhp8^a91FOmPCJT8Dj~2mv(Knk*$45fic}qj= zkLd>pp|FDa;SrYe7>ckQe5tIhk3jiz_9%HG-ms5!^F{o&ZXPn3xfIe65Qs0yXmcla zWeoxAK6Fv2YKMy;X)O0H8_Rh-ePw0{uSekU8e$OfCfj)MwkMC_wil4_UHaA@L2~En;24`7w+KuNI0?Ll^SsXVLlLN-*TW2|A$V*D zKe7`2+r&FJSQgWxRjo?rMtwKa4te-B;Wh{v5fwC+3$T+u0Dp;i?W&imiq2`QhlmH$ z7y=HQhv|bM?R!cahS-WC^rRC2I`@$$1l9}?PdWjiXahvWi7*rfhY&tI3ZfIaLX~$S z^b7xl>x4u|(Gy`WPG6KEA4bFrHvk`mm>{CBg1{5ROl{Iz;HXBhti+(c$vcPihr`V@ zrAC2+HFv~4Pi;B{Zpkw z8Wgre0H+gR7~HWl4uGt)7~9e~JQDL2qqST>j8i>~ALbwfs(Jls~osg`-@EGlI%T|38tnN43^nKwrYMBnVTS)>H zpV2;JLx>`Pnmt;x#~FwYBY=Sj*aOjF4TR=u#H_-ssRnBb2Wh~_ucBV^sv&)Ug!Or0 z#*o&FR`?J_Llr&;f3SSc13JPJy|tc53oP4>n0^pol+4SW5fyaGYa?YPqQYg%z32&{ zNB3DCNYlMdpeB9G*8rj4jh3xU$pN^hyw1aNh(hqAXa^$Rep;!OS)|;nAJ*>*X&R~s zjeh-5Nb@s&BnsHI6evdYK&^nM1ec*`C+Hlhj+`QX=F6;4#7_}(jv$^9<+2wO8~%@X z6W#^9t@X$_Qg9zlP@!EP#m~N`hyo)5N$Crc#gLlgC@Ltc~j`SqiHJ|x%Owi(yJj6>CCEVCVU z0@6=Y+`HEb^7i^$qIChybffKbp^duGcG=w40xjl7+bz)aQ^f1OhDhB&!X~0RM{cu_ z#t7+*g(M|g5gHThY!$q%kd$m4m|*8s&18$kWG5k=b2C{H8cgn}g0Ha}me|o@HHpnk}LKNKsrDx_QL?>*3K##kozlZuVw3W zuRWxjfHDX^FJU1^KV^2zV)F>>KyGmis~FmP9Ya(QZ>(a-C6D<9gYSE~MQRW!!p;=d zODx1FHHZ`BDXVVTI>l#`D6jo`G&XAG=oXRvobiqIm>=28)? zu3_!W&R~a%?5=kqQ+ZABZxMW2BCV3o2J>rvbBo0$1U8{+He#D+F`6+rww~rj^Z9`J z1&D?GJH!p7U*NO}9PC6DFyqr?(|c%xr)I-1LGLVqZv z?M56#>c?<_H1hW`e^?Gvjh}Hzk5G`Lw`spyH zxv7XLK>0+!qNjQwiJrt8aoxgd!CpZ#4f8deO45!ctHM%PAYtKYL_J{!liQ0Gv0_04 z_vmSTpjmZR4Old*$-{;cK$=qYex^068gqKF8}9QM9&0TDxln}Ruu(iq2v|9`h$p@V zp?8s;0sK{zN`QL|Wdmi|XRsn#-+M7RGCeTAT*U@@Kw4Mar5w-wqqLxE@mc;+6*PEuY+&Ejl;@;q?K9weUu+6ic!VB?@gQWJdxCY_evu0TkJZsN<#psFm=X6q=G`DccHe&CUy{i5}6d*Sx;PEjf(|jcy~{ zVQ7{B*CIxX-i`F4Sw)sO3%iiztTC$RdI5c;zZ>o}_~H{SY(sO7=;UD+l84&J@_E>u z=Ec7iqyZ^t9*~tuBbsT8f`c_1X#5Pck@e|4iD%J~glBl9c?7{Ep}l9MyJYKk{v&dWh{3-bf>3@yK9) z6X%pY%cP!JF@kBq(Gc@Vj!i!>t??lWeGPyzi?VeO~r~NVe%>3+?bfNzU9nTN8^w_P1MDA+3*q_X&3(2%uI-M_;T4mpn z3!}MGJZ@p^!p(y0U`XBwkbU^nzAKd|B?hg2eXUJ*I6pg=$Yt_5n_*jr-C-6AiAB4y zU3WEtR)@Q#m@aj$L~)H&ObD6EJSHUQaj#_!wZL&p6 zB$K#g(07Cs&88_1ZzI#4kHPhlqun=&TMi^n zaf6h+Xk8J>;0i+`yYWt24)>Ll`CKtEnLeMmep-BXvF?Tt8DZW{H$$QuAr9n3-l1Vg zjoqBY1R0)6CuhQP?A-tpC(e)EA3t+;ByzL<;o*^}yyfA>hhfKQZl%v)>h?9h36m*~ z&(G1tmUIdum@Z7>ddTKo4J|{&g%Ql$;%F|FUKpFan8?njx5#TFb=)0_7bg-|vgxgI zfF|f#54G5{b(_?$s)J^QeF$t>b}%R(|eSAwJN9%yLK>dQ@a#P@7zh?6X&6Qy(&?Y;6wjobLs#fkiV z;?kAn47SJvjiD`86Zw;{Ctaelq3_(*PzK?1)796S2KU|F5VFygsX9&fA83e+@rRm~ zt5bD&2job(HLvJ`X=*ESFxrqsBDXk^9}(B4&Zj32?P~}$T@)@lDsE*^Mw)wrc2zNqWurv#q($s9alu6c-8eJXaqzrjh{GTt4O~&%`xl|?A*<#&y ztAM9uXg@!nD`jTWwL+a4!hNI>acdQ3X0!QZqLi15>_>MuAU>Xi zGo>0MT-tlf2nmZTD zlY1;blg`vOOotZTC^MA?3ng3IFdMClYw2tAiEQyiqBu2-o8bKjZ8<$YnMr4{-juhQ z^3_+Hlvg@Z&7Ap;l%_Jp!4^f9c=K#xAu~HaD;AxtoT;=s3UTJ`BS_srX{(^9MckEY zuhhL6TDNw19GX^x;(d%3vYifzHL6XOd-J8KbU|q@&CczK7w5%YYtNbqGj?huK7Rk` z#PEsu_{gb|;fb;HU7njEt(AgyJ6zVurXE@7t%#}#j+PPDcQ^t!+j|&s&0PuP($~e3 z+|!nvFBFg;5R?jVS7@oqrc>BkS?fA)mkm{E5*s96XI(q)(fd^rAwbW8AU*dr(er>t z&qK|=VtyVwTUrm( z=}jvtC^oRimlP`>)tjWvoHq!aEp;~HFt=Dp5NfC5E@grG0_Yc#`Bfqw@E@7aB?^m!Lft)37ZYn!6Y~I(2l0>`P_#MtL4k-@xHO}) ziUVpE2T5BPbPqUywxKX<268b|!#FUHs!T1EN*UfpHj29}LUUqo+_IsEDg$xLa(ycE zhvsIf(aZc!PEh$rpS+B)Iu($?pL%d*myAX20BSD(V&P1PXORTDn}E5`CO9wYgq>>Vg+rXn@DJl z9=0$Qkk*QzA;B2}fk&H-+3ps&gO~0^h!a6}pUV6R%fq?t;fimrfKAncWyAgUfE~bq zEgYoBA$r_JkGnbZ0Q4~C8(x_1lV|ew#^?w;Y9kI-rh_K-*g26g?x{@3>ey<>eh;ZR zJ9$H%>}hrXO}!kCC_|?07{MIq~jwn4GBZ9CbQRI;H!Z(kZ8Ox*qk6(>dmp z&ensSb2`u0caA%q6He)ZQ@ZGs?srNLIHd>KL+}-QXdjjt?GdN{(Te}p#QC`dWv)v- zPQVbsP^lgz+r6wQ8+QV?(g5KKj?hyIrX1&!X@#|Aa;f8dkuQx#Datk|k* zb9<*9sF|wvOetGco7+2!1NS^re^>i;&H{8GBGOLq_VI+G8&dz<7LxN|10xdECr8=cPQ zTikuEa(nDPZz2Oql|s!@Fp^z&KZtZ{dB)e%`MiFC7d zZrC2V`>Pk&Ii>EE_Oi0j`a5g|>QQJ&MrUW|OEjCr*lb`M*(NtjLyG4dl?XxQ$C+aV9@S2}pP!wtVv zevxQ!u(C^zO}`swx7^)}mEl-}W0XBM=D=Pz=72naYj_56r;T;zJ~!6>b+!rX&l?Wd zDEkh&Q4aOmD2^?6?oMc1NTNN8Lb!(qLka+52ky2;m+ZXYUX*-B>Z# z#Idnz_WHwalw+>r>zi%hk*D3L_Xgx{`GmV;G$8lHC#9(O*$`Ij8a(B$o_1HyxT|CM z%6*QV$M@?A+^e|A?q?4$}k%P;q2|4 zy@Rt~(zG<>Y-OgXNNypt=n|9p2A$PSl$GCgj-PPJO_#C+-dq@}4$H zjg}h%Xm4ZOfyT{uO72$n7ZmnMP$z|p=Kbs_AYXbcLy#f8UlU4 z!Zm~A;&`gaTXDLSE(lT1WB8QzIh?>?n?<)3=tvD;20U$5ZPpQqTHQpMU^L}zD>~O4 zY($@4X|nMARV@};z&}HuUx3e9=!k0vGU&tJ?J=>`<-Uw~E8*tibA6 z!FsHwz^c5|;OWsb@r&lE3nSj(Y4ZWA=xZ7ueP|>edvIc8+#j^cqZ8v=J&R_H(<PG0*E%;&SNIBoLOGiVVE;vcMsRh8@~pyZoxu9!39R2o z2h7QtKsTNAlEuLckA;szR=Gz^JEwAf9Y`tA^w!N<6Y`fr4Pb?9{!>MkJ^zJSyQ)x)djt|I~$A4qC( z2X7&k%QO9Z1QD}A0u0#SyV9}MMZtHHS|PZDf9w_(3qI>}fj4O1pGc>C!Qy;zE{%`g zDZie0ERo5IGfHa-dAz|W`mE~___type_5 (struct (field (ref null $SpecialITable___type_2)))) + (type $kotlin.Any___type_6 (struct (field (ref $___type_5)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)))) + (type $___type_7 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (type $kotlin.Number___type_8 (sub $kotlin.Any___type_6 (struct (field (ref $___type_7)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32))))) + (type $___type_9 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (type $kotlin.Companion___type_10 (sub $kotlin.Any___type_6 (struct (field (ref $___type_9)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32))))) + (type $___type_11 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (type $kotlin.UInt___type_12 (sub $kotlin.Any___type_6 (struct (field (ref $___type_11)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut i32))))) + (type $___type_13 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (type $kotlin.wasm.internal.WasmAnyArray___type_14 (array (mut (ref null $kotlin.Any___type_6)))) + (type $kotlin.Array___type_15 (sub $kotlin.Any___type_6 (struct (field (ref $___type_13)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.wasm.internal.WasmAnyArray___type_14)))))) + (type $___type_16 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (rec + (type $kotlin.Companion___type_17 (sub $kotlin.Any___type_6 (struct (field (ref $___type_16)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32))))) + (type $mixin_1___type_18 (struct (field i31ref) (field i64)))) + (type $___type_19 (sub $___type_7 (struct (field (ref null $SpecialITable___type_2))))) + (type $kotlin.Int___type_20 (sub $kotlin.Number___type_8 (struct (field (ref $___type_19)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut i32))))) + (type $___type_21 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (rec + (type $kotlin.Companion___type_22 (sub $kotlin.Any___type_6 (struct (field (ref $___type_21)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32))))) + (type $mixin_1___type_23 (struct (field i31ref) (field i64)))) + (type $____type_24 (func (param (ref null $kotlin.Any___type_6)) (result i32))) + (type $___type_25 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_24))))) + (type $kotlin.wasm.internal.WasmCharArray___type_26 (array (mut i16))) + (type $kotlin.String___type_27 (sub $kotlin.Any___type_6 (struct (field (ref $___type_25)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut i32)) (field (mut (ref null $kotlin.wasm.internal.WasmCharArray___type_26)))))) + (type $kotlin.wasm.internal.WasmLongImmutableArray___type_28 (array i64)) + (type $____type_29 (func (param (ref null $kotlin.Any___type_6)) (result (ref null $kotlin.String___type_27)))) + (type $____type_30 (func (param (ref null $kotlin.Any___type_6)) (result externref))) + (type $___type_31 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (type $kotlin.Throwable___type_32 (sub $kotlin.Any___type_6 (struct (field (ref $___type_31)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $___type_33 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (type $kotlin.wasm.internal.JsExternalBox___type_34 (sub $kotlin.Any___type_6 (struct (field (ref $___type_33)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut externref))))) + (type $___type_35 (sub $___type_31 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30)) (field (ref null $____type_29))))) + (type $kotlin.js.JsException___type_36 (sub $kotlin.Throwable___type_32 (struct (field (ref $___type_35)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut externref))))) + (type $___type_37 (sub $___type_31 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (type $kotlin.Exception___type_38 (sub $kotlin.Throwable___type_32 (struct (field (ref $___type_37)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $___type_39 (sub $___type_37 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (type $kotlin.RuntimeException___type_40 (sub $kotlin.Exception___type_38 (struct (field (ref $___type_39)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $___type_41 (sub $___type_39 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (type $kotlin.IllegalArgumentException___type_42 (sub $kotlin.RuntimeException___type_40 (struct (field (ref $___type_41)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $___type_43 (sub $___type_39 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (rec + (type $kotlin.ArithmeticException___type_44 (sub $kotlin.RuntimeException___type_40 (struct (field (ref $___type_43)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $mixin_1___type_45 (struct (field i31ref) (field i64)))) + (type $___type_46 (sub $___type_39 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (rec + (type $kotlin.IndexOutOfBoundsException___type_47 (sub $kotlin.RuntimeException___type_40 (struct (field (ref $___type_46)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $mixin_2___type_48 (struct (field i31ref) (field f32)))) + (type $___type_49 (sub $___type_39 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (rec + (type $kotlin.IllegalStateException___type_50 (sub $kotlin.RuntimeException___type_40 (struct (field (ref $___type_49)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $mixin_3___type_51 (struct (field i31ref) (field f64)))) + (type $___type_52 (sub $___type_39 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (rec + (type $kotlin.ClassCastException___type_53 (sub $kotlin.RuntimeException___type_40 (struct (field (ref $___type_52)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $mixin_4___type_54 (struct (field i31ref) (field v128)))) + (type $___type_55 (sub $___type_39 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_29)) (field (ref null $____type_30))))) + (rec + (type $kotlin.NullPointerException___type_56 (sub $kotlin.RuntimeException___type_40 (struct (field (ref $___type_55)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Throwable___type_32))) (field (mut externref)) (field (mut (ref null $kotlin.String___type_27))) (field (mut (ref null $kotlin.Any___type_6)))))) + (type $mixin_5___type_57 (struct (field i31ref) (field i8)))) + (type $___type_58 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (rec + (type $kotlin.Unit___type_59 (sub $kotlin.Any___type_6 (struct (field (ref $___type_58)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32))))) + (type $mixin_2___type_60 (struct (field i31ref) (field f32)))) + (type $___type_61 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2))))) + (rec + (type $kotlin.wasm.unsafe.Pointer___type_62 (sub $kotlin.Any___type_6 (struct (field (ref $___type_61)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut i32))))) + (type $mixin_1___type_63 (struct (field i31ref) (field i64)))) + (type $____type_64 (func (param (ref null $kotlin.Any___type_6) i32) (result i32))) + (type $___type_65 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_64))))) + (type $kotlin.wasm.unsafe.MemoryAllocator___type_66 (sub $kotlin.Any___type_6 (struct (field (ref $___type_65)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32))))) + (type $___type_67 (sub $___type_65 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_64))))) + (type $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 (sub $kotlin.wasm.unsafe.MemoryAllocator___type_66 (struct (field (ref $___type_67)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32)) (field (mut (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68))) (field (mut i8)) (field (mut i8)) (field (mut i32))))) + (type $____type_69 (func (param (ref null $kotlin.Any___type_6) (ref null $kotlin.Any___type_6)) (result (ref null $kotlin.Any___type_6)))) + (type $___type_70 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_64)) (field (ref null $____type_69))))) + (type $x$lambda___type_71 (sub $kotlin.Any___type_6 (struct (field (ref $___type_70)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32))))) + (type $___type_72 (sub $___type_5 (struct (field (ref null $SpecialITable___type_2)) (field (ref null $____type_64)) (field (ref null $____type_69))))) + (rec + (type $y$lambda___type_73 (sub $kotlin.Any___type_6 (struct (field (ref $___type_72)) (field (ref null $AnyArray___type_0)) (field (ref $RTTI___type_4)) (field (mut i32))))) + (type $mixin_1___type_74 (struct (field i31ref) (field i64)))) + (type $___type_75 (struct (field (ref null $____type_24)))) + (type $___type_76 (struct)) + (type $___type_77 (struct)) + (type $___type_78 (struct (field (ref null $____type_69)))) + (type $____type_79 (func (param (ref null $kotlin.Number___type_8)) (result (ref null $kotlin.Number___type_8)))) + (type $____type_80 (func (param i32 i32) (result i32))) + (type $____type_81 (func (param i32) (result i32))) + (type $____type_82 (func (param (ref null $kotlin.Companion___type_10)) (result (ref null $kotlin.Companion___type_10)))) + (type $____type_83 (func (param (ref null $kotlin.Array___type_15) i32) (result (ref null $kotlin.Array___type_15)))) + (type $____type_84 (func (param (ref null $kotlin.Array___type_15) i32) (result (ref null $kotlin.Any___type_6)))) + (type $____type_85 (func (param (ref null $kotlin.Array___type_15) i32 (ref null $kotlin.Any___type_6)))) + (type $____type_86 (func (param (ref null $kotlin.Companion___type_17)) (result (ref null $kotlin.Companion___type_17)))) + (type $____type_87 (func (param (ref null $kotlin.Companion___type_22)) (result (ref null $kotlin.Companion___type_22)))) + (type $____type_88 (func (param (ref null $kotlin.String___type_27)) (result (ref null $kotlin.String___type_27)))) + (type $____type_89 (func (param (ref null $kotlin.String___type_27)) (result (ref null $kotlin.wasm.internal.WasmCharArray___type_26)))) + (type $____type_90 (func (param (ref null $kotlin.String___type_27)))) + (type $____type_91 (func (param i32 i32 i32) (result (ref null $kotlin.String___type_27)))) + (type $____type_92 (func (param i32 i32 i32 (ref null $kotlin.wasm.internal.WasmCharArray___type_26)))) + (type $____type_93 (func (param (ref null $kotlin.wasm.internal.WasmCharArray___type_26) i32 i32 i32))) + (type $____type_94 (func (param i32 i32))) + (type $____type_95 (func (param))) + (type $____type_96 (func (param (ref null struct)) (result (ref null $kotlin.String___type_27)))) + (type $____type_97 (func (param (ref null $kotlin.Any___type_6) i64) (result i32))) + (type $____type_98 (func (param (ref null $kotlin.wasm.internal.WasmLongImmutableArray___type_28) i64) (result i32))) + (type $____type_99 (func (param (ref null $kotlin.Any___type_6) i64) (result anyref))) + (type $____type_100 (func (param (ref null $kotlin.Throwable___type_32) (ref null $kotlin.String___type_27) (ref null $kotlin.Throwable___type_32) externref) (result (ref null $kotlin.Throwable___type_32)))) + (type $____type_101 (func (param (ref null $kotlin.Throwable___type_32) (ref null $kotlin.String___type_27) (ref null $kotlin.Throwable___type_32)) (result (ref null $kotlin.Throwable___type_32)))) + (type $____type_102 (func (param (ref null $kotlin.Throwable___type_32) (ref null $kotlin.String___type_27)) (result (ref null $kotlin.Throwable___type_32)))) + (type $____type_103 (func (param (ref null $kotlin.Throwable___type_32)) (result (ref null $kotlin.Throwable___type_32)))) + (type $____type_104 (func (param) (result externref))) + (type $____type_105 (func (param (ref null $kotlin.Throwable___type_32)))) + (type $____type_106 (func (param (ref null $kotlin.String___type_27) (ref null $kotlin.String___type_27) externref))) + (type $____type_107 (func (param externref externref externref) (result nullref))) + (type $____type_108 (func (param externref) (result (ref null $kotlin.js.JsException___type_36)))) + (type $____type_109 (func (param externref) (result (ref null $kotlin.String___type_27)))) + (type $____type_110 (func (param externref) (result i32))) + (type $____type_111 (func (param externref i32 i32 i32))) + (type $____type_112 (func (param (ref null $kotlin.String___type_27)) (result externref))) + (type $____type_113 (func (param i32 i32 externref) (result externref))) + (type $____type_114 (func (param externref) (result externref))) + (type $____type_115 (func (param externref) (result (ref null $kotlin.Any___type_6)))) + (type $____type_116 (func (param externref externref) (result externref))) + (type $____type_117 (func (param (ref null $kotlin.js.JsException___type_36) externref) (result (ref null $kotlin.js.JsException___type_36)))) + (type $____type_118 (func (param (ref null $kotlin.IllegalArgumentException___type_42) (ref null $kotlin.String___type_27)) (result (ref null $kotlin.IllegalArgumentException___type_42)))) + (type $____type_119 (func (param (ref null $kotlin.IllegalArgumentException___type_42)) (result (ref null $kotlin.IllegalArgumentException___type_42)))) + (type $____type_120 (func (param (ref null $kotlin.ArithmeticException___type_44) (ref null $kotlin.String___type_27)) (result (ref null $kotlin.ArithmeticException___type_44)))) + (type $____type_121 (func (param (ref null $kotlin.ArithmeticException___type_44)) (result (ref null $kotlin.ArithmeticException___type_44)))) + (type $____type_122 (func (param (ref null $kotlin.IndexOutOfBoundsException___type_47)) (result (ref null $kotlin.IndexOutOfBoundsException___type_47)))) + (type $____type_123 (func (param (ref null $kotlin.RuntimeException___type_40)) (result (ref null $kotlin.RuntimeException___type_40)))) + (type $____type_124 (func (param (ref null $kotlin.RuntimeException___type_40) (ref null $kotlin.String___type_27)) (result (ref null $kotlin.RuntimeException___type_40)))) + (type $____type_125 (func (param (ref null $kotlin.Exception___type_38)) (result (ref null $kotlin.Exception___type_38)))) + (type $____type_126 (func (param (ref null $kotlin.Exception___type_38) (ref null $kotlin.String___type_27)) (result (ref null $kotlin.Exception___type_38)))) + (type $____type_127 (func (param (ref null $kotlin.IllegalStateException___type_50) (ref null $kotlin.String___type_27)) (result (ref null $kotlin.IllegalStateException___type_50)))) + (type $____type_128 (func (param (ref null $kotlin.IllegalStateException___type_50)) (result (ref null $kotlin.IllegalStateException___type_50)))) + (type $____type_129 (func (param (ref null $kotlin.ClassCastException___type_53)) (result (ref null $kotlin.ClassCastException___type_53)))) + (type $____type_130 (func (param (ref null $kotlin.NullPointerException___type_56)) (result (ref null $kotlin.NullPointerException___type_56)))) + (type $____type_131 (func (param (ref null $kotlin.Unit___type_59)) (result (ref null $kotlin.Unit___type_59)))) + (type $____type_132 (func (param) (result (ref null $kotlin.Unit___type_59)))) + (type $____type_133 (func (param (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)) (result (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)))) + (type $____type_134 (func (param (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68) i32 (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)))) + (type $____type_135 (func (param (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)))) + (type $____type_136 (func (param (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)))) + (type $____type_137 (func (param) (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)))) + (type $____type_138 (func (param) (result (ref null $kotlin.Any___type_6)))) + (type $____type_139 (func (param i32 (ref null $kotlin.Any___type_6)) (result i32))) + (type $____type_140 (func (param) (result (ref null $kotlin.String___type_27)))) + (type $____type_141 (func (param (ref null $x$lambda___type_71)) (result (ref null $x$lambda___type_71)))) + (type $____type_142 (func (param (ref null $y$lambda___type_73)) (result (ref null $y$lambda___type_73)))) + (type $____type_143 (func (param))) + (type $____type_144 (func (param (ref null $kotlin.Throwable___type_32)))) + (func $kotlin.captureStackTrace___fun_0 (import "js_code" "kotlin.captureStackTrace") (type $____type_104)) + (func $kotlin.wasm.internal.throwJsError___fun_1 (import "js_code" "kotlin.wasm.internal.throwJsError") (type $____type_107)) + (func $kotlin.wasm.internal.stringLength___fun_2 (import "js_code" "kotlin.wasm.internal.stringLength") (type $____type_110)) + (func $kotlin.wasm.internal.jsExportStringToWasm___fun_3 (import "js_code" "kotlin.wasm.internal.jsExportStringToWasm") (type $____type_111)) + (func $kotlin.wasm.internal.importStringFromWasm___fun_4 (import "js_code" "kotlin.wasm.internal.importStringFromWasm") (type $____type_113)) + (func $kotlin.wasm.internal.getJsEmptyString___fun_5 (import "js_code" "kotlin.wasm.internal.getJsEmptyString") (type $____type_104)) + (func $kotlin.wasm.internal.isNullish___fun_6 (import "js_code" "kotlin.wasm.internal.isNullish") (type $____type_110)) + (func $kotlin.wasm.internal.getCachedJsObject_$external_fun___fun_7 (import "js_code" "kotlin.wasm.internal.getCachedJsObject_$external_fun") (type $____type_116)) + (func $kotlin.js.stackPlaceHolder_js_code___fun_8 (import "js_code" "kotlin.js.stackPlaceHolder_js_code") (type $____type_104)) + (func $kotlin.js.message_$external_prop_getter___fun_9 (import "js_code" "kotlin.js.message_$external_prop_getter") (type $____type_114)) + (func $kotlin.js.stack_$external_prop_getter___fun_10 (import "js_code" "kotlin.js.stack_$external_prop_getter") (type $____type_114)) + (func $kotlin.js.JsError_$external_class_instanceof___fun_11 (import "js_code" "kotlin.js.JsError_$external_class_instanceof") (type $____type_110)) + (func $kotlin.Number.___fun_12 (type $____type_79) + (param $0_ (ref null $kotlin.Number___type_8)) (result (ref null $kotlin.Number___type_8)) + nop + local.get $0_ + return) + (func $kotlin.ranges.coerceAtMost___fun_13 (type $____type_80) + (param $0_ i32) + (param $1_maximumValue i32) (result i32) ;; type: kotlin.Int ;; type: kotlin.Int + local.get $0_ ;; type: kotlin.Int + local.get $1_maximumValue + i32.gt_s ;; type: kotlin.Int + if (result i32) + local.get $1_maximumValue + else + local.get $0_ + end + return) + (func $kotlin.-impl>___fun_14 (type $____type_81) + (param $0_data i32) (result i32) ;; type: kotlin.Int + local.get $0_data + return) + (func $kotlin.-impl>___fun_15 (type $____type_81) + (param $0_$this i32) (result i32) ;; type: kotlin.UInt + local.get $0_$this + return) + (func $kotlin.Companion.___fun_16 (type $____type_82) + (param $0_ (ref null $kotlin.Companion___type_10)) (result (ref null $kotlin.Companion___type_10)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_10 + ref.null none + global.get $kotlin.Companion_rtti___g_46 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + + i32.const 0 + struct.new $kotlin.Companion___type_10 ;; type: kotlin.Companion + local.set $0_ ;; name: MIN_VALUE, type: kotlin.UInt + end + local.get $0_ ;; type: kotlin.Companion + i32.const 0 ;; name: MAX_VALUE, type: kotlin.UInt + struct.set $kotlin.Companion___type_10 4 + local.get $0_ ;; type: kotlin.Companion + i32.const -1 ;; name: SIZE_BYTES, type: kotlin.Int + struct.set $kotlin.Companion___type_10 5 + local.get $0_ ;; type: kotlin.Companion + i32.const 4 ;; name: SIZE_BITS, type: kotlin.Int + struct.set $kotlin.Companion___type_10 6 + local.get $0_ + i32.const 32 + struct.set $kotlin.Companion___type_10 7 + nop + local.get $0_ + return) + (func $kotlin.Array.___fun_17 (type $____type_83) + (param $0_ (ref null $kotlin.Array___type_15)) + (param $1_size i32) (result (ref null $kotlin.Array___type_15)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_13 + ref.null none + global.get $kotlin.Array_rtti___g_48 + i32.const 0 + + ref.null $kotlin.wasm.internal.WasmAnyArray___type_14 + struct.new $kotlin.Array___type_15 ;; type: kotlin.Int + local.set $0_ + end + local.get $1_size + + ;; const string: "Negative array size" + i32.const 0 + i32.lt_s + if + ref.null none + + i32.const 6 + i32.const 54 + i32.const 19 + call $kotlin.stringLiteral___fun_29 ;; type: kotlin.Array + call $kotlin.IllegalArgumentException.___fun_70 ;; type: kotlin.Int + throw 0 ;; @WasmArrayOf ctor call: kotlin.wasm.internal.WasmAnyArray + end ;; name: storage, type: kotlin.wasm.internal.WasmAnyArray + local.get $0_ + local.get $1_size + array.new_default $kotlin.wasm.internal.WasmAnyArray___type_14 + struct.set $kotlin.Array___type_15 4 + nop + local.get $0_ + return) + (func $kotlin.Array.get___fun_18 (type $____type_84) + (param $0_ (ref null $kotlin.Array___type_15)) + (param $1_index i32) (result (ref null $kotlin.Any___type_6)) ;; type: kotlin.Int ;; type: kotlin.Array ;; name: storage, type: kotlin.wasm.internal.WasmAnyArray + local.get $1_index + local.get $0_ + struct.get $kotlin.Array___type_15 4 ;; type: kotlin.Array ;; name: storage, type: kotlin.wasm.internal.WasmAnyArray + array.len ;; type: kotlin.Int + call $kotlin.wasm.internal.rangeCheck___fun_32 + local.get $0_ + struct.get $kotlin.Array___type_15 4 + local.get $1_index + array.get $kotlin.wasm.internal.WasmAnyArray___type_14 + return) + (func $kotlin.Array.set___fun_19 (type $____type_85) + (param $0_ (ref null $kotlin.Array___type_15)) + (param $1_index i32) + (param $2_value (ref null $kotlin.Any___type_6)) ;; type: kotlin.Int ;; type: kotlin.Array ;; name: storage, type: kotlin.wasm.internal.WasmAnyArray + local.get $1_index + local.get $0_ + struct.get $kotlin.Array___type_15 4 ;; type: kotlin.Array ;; name: storage, type: kotlin.wasm.internal.WasmAnyArray + array.len ;; type: kotlin.Int + call $kotlin.wasm.internal.rangeCheck___fun_32 ;; type: T of kotlin.Array + local.get $0_ + struct.get $kotlin.Array___type_15 4 + local.get $1_index + local.get $2_value + array.set $kotlin.wasm.internal.WasmAnyArray___type_14 + nop) + (func $kotlin.Companion.___fun_20 (type $____type_86) + (param $0_ (ref null $kotlin.Companion___type_17)) (result (ref null $kotlin.Companion___type_17)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_14 + ref.null none + global.get $kotlin.Companion_rtti___g_49 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + + i32.const 0 + struct.new $kotlin.Companion___type_17 ;; type: kotlin.Companion + local.set $0_ ;; name: MIN_VALUE, type: kotlin.Int + end + local.get $0_ ;; type: kotlin.Companion + i32.const -2147483648 ;; name: MAX_VALUE, type: kotlin.Int + struct.set $kotlin.Companion___type_17 4 + local.get $0_ ;; type: kotlin.Companion + i32.const 2147483647 ;; name: SIZE_BYTES, type: kotlin.Int + struct.set $kotlin.Companion___type_17 5 + local.get $0_ ;; type: kotlin.Companion + i32.const 4 ;; name: SIZE_BITS, type: kotlin.Int + struct.set $kotlin.Companion___type_17 6 + local.get $0_ + i32.const 32 + struct.set $kotlin.Companion___type_17 7 + nop + local.get $0_ + return) + (func $kotlin.Int__div-impl___fun_21 (type $____type_80) + (param $0_$this i32) + (param $1_other i32) (result i32) + (local $2_tmp0_subject i32) + (local $3_TABLE_SWITCH_SELECTOR i32) ;; type: kotlin.Int ;; type: kotlin.Int + local.get $1_other + local.tee $2_tmp0_subject + local.set $3_TABLE_SWITCH_SELECTOR + block (result i32) + block (result i32) + block (result i32) + block (result i32) + i32.const 0 + local.get $3_TABLE_SWITCH_SELECTOR + i32.const -1 + i32.sub ;; type: kotlin.Int + br_table 0 1 2 + end + drop + local.get $0_$this + i32.const -2147483648 + i32.eq ;; type: kotlin.Int + if (result i32) ;; type: kotlin.Int + i32.const -2147483648 + else + local.get $0_$this + local.get $1_other + i32.div_s + end + + ;; const string: "Division by zero" + br 2 + end + drop + ref.null none + + i32.const 7 + i32.const 92 + i32.const 16 + call $kotlin.stringLiteral___fun_29 + call $kotlin.ArithmeticException.___fun_72 ;; type: kotlin.Int + throw 0 ;; type: kotlin.Int + end + drop + local.get $0_$this + local.get $1_other + i32.div_s + end + return) + (func $kotlin.Int__rem-impl___fun_22 (type $____type_80) + (param $0_$this i32) + (param $1_other i32) (result i32) + (local $2_tmp0_subject i32) ;; type: kotlin.Int ;; type: kotlin.Int + local.get $1_other + local.tee $2_tmp0_subject + + ;; const string: "Division by zero" + i32.const 0 + i32.eq + if (result i32) + ref.null none + + i32.const 7 + i32.const 92 + i32.const 16 + call $kotlin.stringLiteral___fun_29 ;; type: kotlin.Int + call $kotlin.ArithmeticException.___fun_72 ;; type: kotlin.Int + throw 0 + else + local.get $0_$this + local.get $1_other + i32.rem_s + end + return) + (func $kotlin.Int__toChar-impl___fun_23 (type $____type_81) + (param $0_$this i32) (result i32) ;; type: kotlin.Int + local.get $0_$this + i32.const 65535 + i32.and + return) + (func $kotlin.Companion.___fun_24 (type $____type_87) + (param $0_ (ref null $kotlin.Companion___type_22)) (result (ref null $kotlin.Companion___type_22)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_16 + ref.null none + global.get $kotlin.Companion_rtti___g_50 + + i32.const 0 + struct.new $kotlin.Companion___type_22 + local.set $0_ + end + nop + local.get $0_ + return) + (func $kotlin.access$___fun_25 (type $____type_88) + (param $0_$this (ref null $kotlin.String___type_27)) (result (ref null $kotlin.String___type_27)) ;; type: kotlin.String ;; name: leftIfInSum, type: kotlin.String? + local.get $0_$this + struct.get $kotlin.String___type_27 4 + return) + (func $kotlin.access$___fun_26 (type $____type_89) + (param $0_$this (ref null $kotlin.String___type_27)) (result (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) ;; type: kotlin.String ;; name: _chars, type: kotlin.wasm.internal.WasmCharArray + local.get $0_$this + struct.get $kotlin.String___type_27 6 + return) + (func $kotlin.String.___fun_27 (type $____type_24) + (param $0_ (ref null $kotlin.Any___type_6)) (result i32) + (local $1_tmp0_ (ref null $kotlin.String___type_27)) ;; type: kotlin.Any ;; type: kotlin.String + local.get $0_ ;; name: length, type: kotlin.Int + ref.cast null $kotlin.String___type_27 + local.tee $1_tmp0_ + struct.get $kotlin.String___type_27 5 + return) + (func $kotlin.String.foldChars___fun_28 (type $____type_90) + (param $0_ (ref null $kotlin.String___type_27)) + (local $1_stringLength i32) + (local $2_newArray (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $3_currentStartIndex i32) + (local $4_currentLeftString (ref null $kotlin.String___type_27)) + (local $5_currentLeftStringChars (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $6_currentLeftStringLen i32) + (local $7_tmp0 (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $8_tmp2 (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $9_tmp4 i32) + (local $10_tmp6 i32) + (local $11_tmp8 i32) + (local $12_source (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $13_destination (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $14_sourceIndex i32) + (local $15_destinationIndex i32) + (local $16_length i32) + (local $17_tmp0 i32) + (local $18_value i32) ;; type: kotlin.String ;; name: length, type: kotlin.Int ;; type: kotlin.Int + local.get $0_ ;; @WasmArrayOf ctor call: kotlin.wasm.internal.WasmCharArray + struct.get $kotlin.String___type_27 5 ;; type: kotlin.Int + local.tee $1_stringLength + array.new_default $kotlin.wasm.internal.WasmCharArray___type_26 ;; type: kotlin.String + local.set $2_newArray + local.get $1_stringLength + local.set $3_currentStartIndex + local.get $0_ ;; type: kotlin.String? + local.set $4_currentLeftString + loop + block + local.get $4_currentLeftString + ref.is_null ;; type: kotlin.String? + i32.eqz ;; name: _chars, type: kotlin.wasm.internal.WasmCharArray + i32.eqz + br_if 0 ;; type: kotlin.wasm.internal.WasmCharArray + local.get $4_currentLeftString + struct.get $kotlin.String___type_27 6 ;; type: kotlin.Int + local.tee $5_currentLeftStringChars ;; type: kotlin.Int + array.len + local.set $6_currentLeftStringLen ;; type: kotlin.Int + local.get $3_currentStartIndex + local.get $6_currentLeftStringLen ;; type: kotlin.wasm.internal.WasmCharArray + i32.sub ;; type: kotlin.wasm.internal.WasmCharArray + local.set $3_currentStartIndex + local.get $5_currentLeftStringChars + local.set $7_tmp0 + local.get $2_newArray ;; type: kotlin.Int + local.set $8_tmp2 + i32.const 0 ;; type: kotlin.Int + local.set $9_tmp4 + local.get $3_currentStartIndex + + ;; Inlined call of `kotlin.wasm.internal.copyWasmArray` + local.set $10_tmp6 + local.get $6_currentLeftStringLen ;; type: kotlin.wasm.internal.WasmCharArray + local.set $11_tmp8 + block (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.wasm.internal.WasmCharArray + nop + local.get $7_tmp0 ;; type: kotlin.Int + local.set $12_source + local.get $8_tmp2 ;; type: kotlin.Int + local.set $13_destination + local.get $9_tmp4 ;; type: kotlin.Int + local.set $14_sourceIndex + local.get $10_tmp6 ;; type: kotlin.wasm.internal.WasmCharArray + local.set $15_destinationIndex ;; type: kotlin.Int + local.get $11_tmp8 ;; type: kotlin.wasm.internal.WasmCharArray + local.set $16_length ;; type: kotlin.Int + local.get $13_destination ;; type: kotlin.Int + local.get $15_destinationIndex + local.get $12_source + local.get $14_sourceIndex ;; type: kotlin.Unit? + local.get $16_length + + array.copy $kotlin.wasm.internal.WasmCharArray___type_26 $kotlin.wasm.internal.WasmCharArray___type_26 + global.get $kotlin.Unit_instance___g_8 ;; type: kotlin.String? + br 0 ;; name: leftIfInSum, type: kotlin.String? + end ;; type: kotlin.String? + drop + local.get $4_currentLeftString + struct.get $kotlin.String___type_27 4 + local.set $4_currentLeftString + br 1 ;; type: kotlin.Int + end + end + local.get $3_currentStartIndex + + ;; Inlined call of `kotlin.check` + i32.const 0 + i32.eq ;; type: kotlin.Boolean + local.set $17_tmp0 + block (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.Boolean + nop + local.get $17_tmp0 + + ;; const string: "Check failed." + local.tee $18_value + i32.eqz + if + ref.null none + + i32.const 10 + i32.const 142 + i32.const 13 + call $kotlin.stringLiteral___fun_29 ;; type: kotlin.Unit? + call $kotlin.IllegalStateException.___fun_82 + throw 0 + + end + global.get $kotlin.Unit_instance___g_8 ;; type: kotlin.String + br 0 ;; type: kotlin.wasm.internal.WasmCharArray + end ;; name: _chars, type: kotlin.wasm.internal.WasmCharArray + drop + local.get $0_ ;; type: kotlin.String + local.get $2_newArray ;; name: leftIfInSum, type: kotlin.String? + struct.set $kotlin.String___type_27 6 + local.get $0_ + ref.null none + struct.set $kotlin.String___type_27 4 + nop) + (func $kotlin.stringLiteral___fun_29 (type $____type_91) + (param $0_poolId i32) + (param $1_startAddress i32) + (param $2_length i32) (result (ref null $kotlin.String___type_27)) + (local $3_cached (ref null $kotlin.String___type_27)) + (local $4_chars (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $5_newString (ref null $kotlin.String___type_27)) ;; type: kotlin.Array ;; type: kotlin.Int + global.get $kotlin.wasm.internal.stringPool___g_4 + local.get $0_poolId ;; type: kotlin.String? + call $kotlin.Array.get___fun_18 + ref.cast null $kotlin.String___type_27 + local.tee $3_cached ;; type: kotlin.String? + ref.is_null + i32.eqz + if ;; type: kotlin.Int + local.get $3_cached ;; type: kotlin.Int + return + end + local.get $1_startAddress + + ;; Any parameters + local.get $2_length + array.new_data $kotlin.wasm.internal.WasmCharArray___type_26 0 + ref.cast null $kotlin.wasm.internal.WasmCharArray___type_26 + local.set $4_chars + + global.get $___g_17 + global.get $___g_34 ;; type: kotlin.Int + global.get $kotlin.String_rtti___g_51 ;; type: kotlin.wasm.internal.WasmCharArray + i32.const 0 ;; @WasmPrimitiveConstructor ctor call: kotlin.String + ref.null none + local.get $2_length ;; type: kotlin.Array + local.get $4_chars ;; type: kotlin.Int + struct.new $kotlin.String___type_27 ;; type: kotlin.String + local.set $5_newString + global.get $kotlin.wasm.internal.stringPool___g_4 + local.get $0_poolId ;; type: kotlin.String + local.get $5_newString + call $kotlin.Array.set___fun_19 + local.get $5_newString + return) + (func $kotlin.wasm.internal.unsafeRawMemoryToWasmCharArray___fun_30 (type $____type_92) + (param $0_srcAddr i32) + (param $1_dstOffset i32) + (param $2_dstLength i32) + (param $3_dst (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $4_curAddr i32) + (local $5_srcAddrEndOffset i32) + (local $6_dstIndex i32) + (local $7_char i32) + (local $8_ i32) + (local $9_tmp0 i32) + (local $10_this i32) ;; type: kotlin.Int ;; type: kotlin.Int ;; type: kotlin.Int + local.get $0_srcAddr + local.set $4_curAddr + local.get $0_srcAddr + local.get $2_dstLength + i32.const 2 ;; type: kotlin.Int + i32.mul + i32.add + local.set $5_srcAddrEndOffset + local.get $1_dstOffset ;; type: kotlin.Int + local.set $6_dstIndex ;; type: kotlin.Int + loop + block + local.get $4_curAddr + local.get $5_srcAddrEndOffset ;; type: kotlin.Int + i32.lt_s + i32.eqz + br_if 0 + local.get $4_curAddr ;; type: kotlin.wasm.internal.WasmCharArray + i32.load16_u align=1 ;; type: kotlin.Int + call $kotlin.Int__toChar-impl___fun_23 ;; type: kotlin.Char + local.set $7_char + local.get $3_dst + local.get $6_dstIndex ;; type: kotlin.Int + local.get $7_char + array.set $kotlin.wasm.internal.WasmCharArray___type_26 ;; type: kotlin.Int + local.get $4_curAddr + i32.const 2 ;; type: kotlin.Int + i32.add ;; type: kotlin.Int + local.set $4_curAddr + local.get $6_dstIndex + + ;; Inlined call of `kotlin.Int.inc` + local.tee $8_ ;; type: kotlin.Int + local.set $9_tmp0 + block (result i32) ;; type: kotlin.Int + nop + local.get $9_tmp0 + local.tee $10_this + + i32.const 1 ;; type: kotlin.Int + i32.add + br 0 ;; type: kotlin.Int + end + local.set $6_dstIndex + br 1 + end + end + nop) + (func $kotlin.wasm.internal.unsafeWasmCharArrayToRawMemory___fun_31 (type $____type_93) + (param $0_src (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (param $1_srcOffset i32) + (param $2_srcLength i32) + (param $3_dstAddr i32) + (local $4_curAddr i32) + (local $5_srcEndOffset i32) + (local $6_srcIndex i32) + (local $7_ i32) + (local $8_tmp0 i32) + (local $9_this i32) ;; type: kotlin.Int ;; type: kotlin.Int ;; type: kotlin.Int + local.get $3_dstAddr + local.set $4_curAddr + local.get $1_srcOffset ;; type: kotlin.Int + local.get $2_srcLength + i32.add + local.set $5_srcEndOffset + local.get $1_srcOffset ;; type: kotlin.Int + local.set $6_srcIndex ;; type: kotlin.Int + loop + block + local.get $6_srcIndex + local.get $5_srcEndOffset ;; type: kotlin.Int + i32.lt_s ;; type: kotlin.wasm.internal.WasmCharArray + i32.eqz ;; type: kotlin.Int + br_if 0 + local.get $4_curAddr + local.get $0_src + local.get $6_srcIndex ;; type: kotlin.Int + array.get_u $kotlin.wasm.internal.WasmCharArray___type_26 + i32.store16 align=1 ;; type: kotlin.Int + local.get $4_curAddr + i32.const 2 ;; type: kotlin.Int + i32.add ;; type: kotlin.Int + local.set $4_curAddr + local.get $6_srcIndex + + ;; Inlined call of `kotlin.Int.inc` + local.tee $7_ ;; type: kotlin.Int + local.set $8_tmp0 + block (result i32) ;; type: kotlin.Int + nop + local.get $8_tmp0 + local.tee $9_this + + i32.const 1 ;; type: kotlin.Int + i32.add + br 0 ;; type: kotlin.Int + end + local.set $6_srcIndex + br 1 + end + end + nop) + (func $kotlin.wasm.internal.rangeCheck___fun_32 (type $____type_94) + (param $0_index i32) + (param $1_size i32) ;; type: kotlin.Int + local.get $0_index + i32.const 0 + i32.lt_s ;; type: kotlin.Int + if (result i32) ;; type: kotlin.Int + i32.const 1 + else + local.get $0_index + local.get $1_size + i32.ge_s + end + if + ref.null none + call $kotlin.IndexOutOfBoundsException.___fun_74 + throw 0 + end + nop) + (func $kotlin.wasm.internal.THROW_NPE___fun_33 (type $____type_95) + ref.null none + call $kotlin.NullPointerException.___fun_86 + throw 0) + (func $kotlin.wasm.internal.THROW_CCE___fun_34 (type $____type_95) + ref.null none + call $kotlin.ClassCastException.___fun_84 + throw 0) + (func $kotlin.wasm.internal.getSimpleName___fun_35 (type $____type_96) + (param $0_rtti (ref null struct)) (result (ref null $kotlin.String___type_27)) + (local $1_tmp0_startAddress i32) + (local $2_tmp1_length i32) + (local $3_tmp2_poolId i32) ;; type: kotlin.wasm.internal.reftypes.structref + local.get $0_rtti ;; type: kotlin.wasm.internal.reftypes.structref + ref.cast $RTTI___type_4 + struct.get $RTTI___type_4 5 + local.set $1_tmp0_startAddress + local.get $0_rtti ;; type: kotlin.wasm.internal.reftypes.structref + ref.cast $RTTI___type_4 + struct.get $RTTI___type_4 6 + local.set $2_tmp1_length + local.get $0_rtti ;; type: kotlin.Int + ref.cast $RTTI___type_4 ;; type: kotlin.Int + struct.get $RTTI___type_4 7 ;; type: kotlin.Int + local.tee $3_tmp2_poolId + local.get $1_tmp0_startAddress + local.get $2_tmp1_length + call $kotlin.stringLiteral___fun_29 + return) + (func $kotlin.wasm.internal.isSupportedInterface___fun_36 (type $____type_97) + (param $0_obj (ref null $kotlin.Any___type_6)) + (param $1_interfaceId i64) (result i32) + (local $2_interfaceArray (ref null $kotlin.wasm.internal.WasmLongImmutableArray___type_28)) + (local $3_tmp0_elvis_lhs (ref null $kotlin.wasm.internal.WasmLongImmutableArray___type_28)) ;; type: kotlin.Any + local.get $0_obj ;; type: kotlin.wasm.internal.WasmLongImmutableArray? + struct.get $kotlin.Any___type_6 2 + struct.get $RTTI___type_4 0 + local.tee $3_tmp0_elvis_lhs + ref.is_null + if (result (ref null $kotlin.wasm.internal.WasmLongImmutableArray___type_28)) ;; type: kotlin.wasm.internal.WasmLongImmutableArray? + i32.const 0 + return + else ;; type: kotlin.wasm.internal.WasmLongImmutableArray + local.get $3_tmp0_elvis_lhs ;; type: kotlin.Long + end + local.tee $2_interfaceArray + local.get $1_interfaceId + call $kotlin.wasm.internal.wasmArrayAnyIndexOfValue___fun_37 + i32.const -1 + i32.eq + i32.eqz + return) + (func $kotlin.wasm.internal.wasmArrayAnyIndexOfValue___fun_37 (type $____type_98) + (param $0_array (ref null $kotlin.wasm.internal.WasmLongImmutableArray___type_28)) + (param $1_value i64) (result i32) + (local $2_arraySize i32) + (local $3_index i32) + (local $4_supportedInterface i64) + (local $5_ i32) + (local $6_tmp0 i32) + (local $7_this i32) ;; type: kotlin.wasm.internal.WasmLongImmutableArray + local.get $0_array + array.len + local.set $2_arraySize + i32.const 0 ;; type: kotlin.Int + local.set $3_index ;; type: kotlin.Int + loop + block + local.get $3_index + local.get $2_arraySize ;; type: kotlin.wasm.internal.WasmLongImmutableArray + i32.lt_s ;; type: kotlin.Int + i32.eqz + br_if 0 + local.get $0_array ;; type: kotlin.Long + local.get $3_index ;; type: kotlin.Long + array.get $kotlin.wasm.internal.WasmLongImmutableArray___type_28 + local.tee $4_supportedInterface ;; type: kotlin.Int + local.get $1_value + i64.eq + if ;; type: kotlin.Int + local.get $3_index + return ;; type: kotlin.Int + end + local.get $3_index + + ;; Inlined call of `kotlin.Int.inc` + local.tee $5_ ;; type: kotlin.Int + local.set $6_tmp0 + block (result i32) ;; type: kotlin.Int + nop + local.get $6_tmp0 + local.tee $7_this + + i32.const 1 ;; type: kotlin.Int + i32.add + br 0 ;; type: kotlin.Int + end + local.set $3_index + br 1 + end + end + i32.const -1 + return) + (func $kotlin.wasm.internal.getInterfaceVTable___fun_38 (type $____type_99) + (param $0_obj (ref null $kotlin.Any___type_6)) + (param $1_interfaceId i64) (result anyref) + local.get $0_obj + struct.get $kotlin.Any___type_6 1 + local.get $0_obj + struct.get $kotlin.Any___type_6 2 + struct.get $RTTI___type_4 0 + local.get $1_interfaceId + call $kotlin.wasm.internal.wasmArrayAnyIndexOfValue___fun_37 + array.get (type $AnyArray___type_0) + return) + (func $kotlin.Throwable.___fun_39 (type $____type_100) + (param $0_ (ref null $kotlin.Throwable___type_32)) + (param $1_message (ref null $kotlin.String___type_27)) + (param $2_cause (ref null $kotlin.Throwable___type_32)) + (param $3_jsStack externref) (result (ref null $kotlin.Throwable___type_32)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_18 + ref.null none + global.get $kotlin.Throwable_rtti___g_52 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.Throwable___type_32 ;; type: kotlin.Throwable ;; type: kotlin.String? + local.set $0_ ;; name: message, type: kotlin.String? + end + local.get $0_ ;; type: kotlin.Throwable ;; type: kotlin.Throwable? + local.get $1_message ;; name: cause, type: kotlin.Throwable? + struct.set $kotlin.Throwable___type_32 4 + local.get $0_ ;; type: kotlin.Throwable ;; type: kotlin.js.JsAny + local.get $2_cause ;; name: jsStack, type: kotlin.js.JsAny + struct.set $kotlin.Throwable___type_32 5 + local.get $0_ ;; type: kotlin.Throwable + local.get $3_jsStack ;; name: _stack, type: kotlin.String? + struct.set $kotlin.Throwable___type_32 6 + local.get $0_ ;; type: kotlin.Throwable + ref.null none ;; name: suppressedExceptionsList, type: kotlin.collections.MutableList? + struct.set $kotlin.Throwable___type_32 7 + local.get $0_ + ref.null none + struct.set $kotlin.Throwable___type_32 8 + nop + local.get $0_ + return) + (func $kotlin.Throwable.___fun_40 (type $____type_29) + (param $0_ (ref null $kotlin.Any___type_6)) (result (ref null $kotlin.String___type_27)) + (local $1_tmp0_ (ref null $kotlin.Throwable___type_32)) ;; type: kotlin.Any ;; type: kotlin.Throwable + local.get $0_ ;; name: message, type: kotlin.String? + ref.cast null $kotlin.Throwable___type_32 + local.tee $1_tmp0_ + struct.get $kotlin.Throwable___type_32 4 + return) + (func $kotlin.Throwable.___fun_41 (type $____type_30) + (param $0_ (ref null $kotlin.Any___type_6)) (result externref) + (local $1_tmp0_ (ref null $kotlin.Throwable___type_32)) ;; type: kotlin.Any ;; type: kotlin.Throwable + local.get $0_ ;; name: jsStack, type: kotlin.js.JsAny + ref.cast null $kotlin.Throwable___type_32 + local.tee $1_tmp0_ + struct.get $kotlin.Throwable___type_32 6 + return) + (func $kotlin.Throwable.___fun_42 (type $____type_101) + (param $0_ (ref null $kotlin.Throwable___type_32)) + (param $1_message (ref null $kotlin.String___type_27)) + (param $2_cause (ref null $kotlin.Throwable___type_32)) (result (ref null $kotlin.Throwable___type_32)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_18 + ref.null none + global.get $kotlin.Throwable_rtti___g_52 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.Throwable___type_32 ;; type: kotlin.String? + local.set $0_ ;; type: kotlin.Throwable? + end + local.get $0_ + local.get $1_message + local.get $2_cause + call $kotlin.captureStackTrace__externalAdapter___fun_45 + call $kotlin.Throwable.___fun_39 + drop + nop + local.get $0_ + return) + (func $kotlin.Throwable.___fun_43 (type $____type_102) + (param $0_ (ref null $kotlin.Throwable___type_32)) + (param $1_message (ref null $kotlin.String___type_27)) (result (ref null $kotlin.Throwable___type_32)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_18 + ref.null none + global.get $kotlin.Throwable_rtti___g_52 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.Throwable___type_32 ;; type: kotlin.String? + local.set $0_ + end + local.get $0_ + local.get $1_message + ref.null none + call $kotlin.Throwable.___fun_42 + drop + nop + local.get $0_ + return) + (func $kotlin.Throwable.___fun_44 (type $____type_103) + (param $0_ (ref null $kotlin.Throwable___type_32)) (result (ref null $kotlin.Throwable___type_32)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_18 + ref.null none + global.get $kotlin.Throwable_rtti___g_52 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.Throwable___type_32 + local.set $0_ + end + local.get $0_ + ref.null none + ref.null none + call $kotlin.Throwable.___fun_42 + drop + nop + local.get $0_ + return) + (func $kotlin.captureStackTrace__externalAdapter___fun_45 (type $____type_104) (result externref) + (local $0_tmp0 externref) ;; type: kotlin.js.JsAny? + call $kotlin.captureStackTrace___fun_0 + call $kotlin.wasm.internal.jsCheckIsNullOrUndefinedAdapter___fun_56 + local.tee $0_tmp0 + ref.is_null + if (result externref) ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.THROW_NPE___fun_33 + unreachable + else + local.get $0_tmp0 + end + return) + (func $kotlin.wasm.internal.throwAsJsException___fun_46 (type $____type_105) + (param $0_t (ref null $kotlin.Throwable___type_32)) ;; type: kotlin.Throwable + + ;; Class Virtual call: kotlin.Throwable. ;; type: kotlin.Throwable + local.get $0_t + + local.get $0_t ;; type: kotlin.Throwable + struct.get $kotlin.Throwable___type_32 0 + struct.get $___type_31 1 + call_ref (type $____type_29) ;; type: kotlin.Throwable + + ;; Class Virtual call: kotlin.Throwable. + local.get $0_t ;; type: kotlin.Throwable + struct.get $kotlin.Any___type_6 2 + call $kotlin.wasm.internal.getSimpleName___fun_35 + local.get $0_t + + local.get $0_t + struct.get $kotlin.Throwable___type_32 0 + struct.get $___type_31 2 + call_ref (type $____type_30) + call $kotlin.wasm.internal.throwJsError__externalAdapter___fun_47 + unreachable) + (func $kotlin.wasm.internal.throwJsError__externalAdapter___fun_47 (type $____type_106) + (param $0_message (ref null $kotlin.String___type_27)) + (param $1_wasmTypeName (ref null $kotlin.String___type_27)) + (param $2_stack externref) + (local $3_tmp2 nullref) + (local $4_tmp0 (ref null $kotlin.String___type_27)) + (local $5_tmp1 (ref null $kotlin.String___type_27)) ;; type: kotlin.String? ;; type: kotlin.String? + local.get $0_message + local.tee $4_tmp0 + ref.is_null ;; type: kotlin.String? + if (result externref) + ref.null noextern + else ;; type: kotlin.String? + local.get $4_tmp0 + call $kotlin.wasm.internal.kotlinToJsStringAdapter___fun_50 ;; type: kotlin.String? + end + local.get $1_wasmTypeName + local.tee $5_tmp1 + ref.is_null ;; type: kotlin.String? + if (result externref) + ref.null noextern + else ;; type: kotlin.js.JsAny? + local.get $5_tmp1 + call $kotlin.wasm.internal.kotlinToJsStringAdapter___fun_50 + end ;; type: kotlin.Nothing? + local.get $2_stack + call $kotlin.wasm.internal.throwJsError___fun_1 + local.tee $3_tmp2 + ref.is_null + if ;; type: kotlin.Nothing? + call $kotlin.wasm.internal.THROW_NPE___fun_33 + unreachable + else + unreachable + end + unreachable) + (func $kotlin.wasm.internal.createJsException___fun_48 (type $____type_108) + (param $0_jsError externref) (result (ref null $kotlin.js.JsException___type_36)) ;; type: kotlin.js.JsAny + ref.null none + local.get $0_jsError + call $kotlin.js.JsException.___fun_62 + return) + (func $kotlin.wasm.internal.jsToKotlinStringAdapter___fun_49 (type $____type_109) + (param $0_x externref) (result (ref null $kotlin.String___type_27)) + (local $1_stringLength i32) + (local $2_dstArray (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $3_tmp0 (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $4_this (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $5_allocator (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $6_result (ref null $kotlin.Any___type_6)) + (local $7_tmp (ref null $kotlin.Any___type_6)) + (local $8_tmp0 (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)) + (local $9_allocator (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)) + (local $10_maxStringLength i32) + (local $11_memBuffer i32) + (local $12_tmp0 i32) + (local $13_this i32) + (local $14_srcStartIndex i32) + (local $15_t (ref null $kotlin.Throwable___type_32)) + (local $16_tmp0 (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $17_this (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) ;; type: kotlin.js.JsAny ;; type: kotlin.Int + local.get $0_x ;; @WasmArrayOf ctor call: kotlin.wasm.internal.WasmCharArray + call $kotlin.wasm.internal.stringLength___fun_2 ;; type: kotlin.Int + local.tee $1_stringLength + array.new_default $kotlin.wasm.internal.WasmCharArray___type_26 + local.set $2_dstArray + local.get $1_stringLength ;; type: kotlin.wasm.internal.WasmCharArray + i32.const 0 + i32.eq + + ;; Inlined call of `kotlin.createString` + if + local.get $2_dstArray ;; type: kotlin.wasm.internal.WasmCharArray + local.set $3_tmp0 + + ;; Any parameters + block (result (ref null $kotlin.String___type_27)) + nop + local.get $3_tmp0 + local.set $4_this + + global.get $___g_17 + global.get $___g_34 ;; type: kotlin.wasm.internal.WasmCharArray + global.get $kotlin.String_rtti___g_51 + i32.const 0 ;; type: kotlin.wasm.internal.WasmCharArray + ref.null none ;; @WasmPrimitiveConstructor ctor call: kotlin.String + local.get $4_this + array.len + + local.get $4_this + struct.new $kotlin.String___type_27 + br 0 + + ;; Inlined call of `kotlin.wasm.unsafe.withScopedMemoryAllocator` + end + return + end + block (result (ref null $kotlin.Unit___type_59)) + nop + call $kotlin.wasm.unsafe.createAllocatorInTheNewScope___fun_97 + local.set $5_allocator ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + block (result (ref null $kotlin.Any___type_6)) + block + + ;; Inlined call of `UNKNOWN` + try (result (ref null $kotlin.Throwable___type_32)) + local.get $5_allocator ;; type: kotlin.wasm.unsafe.MemoryAllocator + local.set $8_tmp0 + block (result (ref null $kotlin.Any___type_6)) + nop + local.get $8_tmp0 ;; type: kotlin.wasm.unsafe.MemoryAllocator + local.set $9_allocator ;; type: kotlin.Int + i32.const 32768 ;; type: kotlin.Int + local.set $10_maxStringLength + local.get $9_allocator + local.get $1_stringLength + + ;; Class Virtual call: kotlin.wasm.unsafe.MemoryAllocator.allocate + local.get $10_maxStringLength ;; type: kotlin.wasm.unsafe.MemoryAllocator + call $kotlin.ranges.coerceAtMost___fun_13 + i32.const 2 + i32.mul + + local.get $9_allocator + struct.get $kotlin.wasm.unsafe.MemoryAllocator___type_66 0 + struct.get $___type_65 1 + + ;; Inlined call of `kotlin.UInt.toInt` + call_ref (type $____type_64) + call $kotlin.wasm.unsafe.-impl>___fun_91 ;; type: kotlin.UInt + local.set $12_tmp0 + block (result i32) ;; type: kotlin.UInt + nop + local.get $12_tmp0 + + local.tee $13_this + call $kotlin.-impl>___fun_15 + br 0 + end + local.set $11_memBuffer + i32.const 0 ;; type: kotlin.Int + local.set $14_srcStartIndex ;; type: kotlin.Int + loop ;; type: kotlin.Int + block + local.get $14_srcStartIndex + local.get $1_stringLength + local.get $10_maxStringLength + i32.sub ;; type: kotlin.js.JsAny + i32.lt_s ;; type: kotlin.Int + i32.eqz ;; type: kotlin.Int + br_if 0 ;; type: kotlin.Int + local.get $0_x + local.get $14_srcStartIndex + local.get $10_maxStringLength ;; type: kotlin.Int ;; type: kotlin.Int + local.get $11_memBuffer ;; type: kotlin.Int + call $kotlin.wasm.internal.jsExportStringToWasm___fun_3 ;; type: kotlin.wasm.internal.WasmCharArray + local.get $11_memBuffer + local.get $14_srcStartIndex + local.get $10_maxStringLength ;; type: kotlin.Int ;; type: kotlin.Int + local.get $2_dstArray + call $kotlin.wasm.internal.unsafeRawMemoryToWasmCharArray___fun_30 ;; type: kotlin.Int + local.get $14_srcStartIndex + local.get $10_maxStringLength + i32.add + local.set $14_srcStartIndex + br 1 ;; type: kotlin.js.JsAny ;; type: kotlin.Int + end ;; type: kotlin.Int + end ;; type: kotlin.Int + local.get $0_x + local.get $14_srcStartIndex ;; type: kotlin.Int + local.get $1_stringLength + local.get $14_srcStartIndex + i32.sub ;; type: kotlin.Int ;; type: kotlin.Int + local.get $11_memBuffer ;; type: kotlin.Int + call $kotlin.wasm.internal.jsExportStringToWasm___fun_3 ;; type: kotlin.Int + local.get $11_memBuffer + local.get $14_srcStartIndex ;; type: kotlin.wasm.internal.WasmCharArray + local.get $1_stringLength + local.get $14_srcStartIndex + i32.sub ;; type: kotlin.Unit? + local.get $2_dstArray + + call $kotlin.wasm.internal.unsafeRawMemoryToWasmCharArray___fun_30 + global.get $kotlin.Unit_instance___g_8 + br 0 + end + br 2 + catch 0 + catch_all + ref.null extern ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + call $kotlin.wasm.internal.createJsException___fun_48 + end + local.set $15_t ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: parent, type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + local.get $5_allocator ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.destroy___fun_96 + local.get $5_allocator ;; type: kotlin.Throwable + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 4 + global.set $kotlin.wasm.unsafe.currentAllocator___g_9 + local.get $15_t + + throw 0 + end ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + unreachable + end + local.set $7_tmp ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: parent, type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + local.get $5_allocator ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.destroy___fun_96 + local.get $5_allocator ;; type: kotlin.Any? + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 4 ;; type: kotlin.Any? + global.set $kotlin.wasm.unsafe.currentAllocator___g_9 + local.get $7_tmp + + local.set $6_result + global.get $kotlin.Unit_instance___g_8 ;; type: kotlin.wasm.internal.WasmCharArray + br 0 + end + + ;; Inlined call of `kotlin.createString` + drop + local.get $2_dstArray ;; type: kotlin.wasm.internal.WasmCharArray + local.set $16_tmp0 + + ;; Any parameters + block (result (ref null $kotlin.String___type_27)) + nop + local.get $16_tmp0 + local.set $17_this + + global.get $___g_17 + global.get $___g_34 ;; type: kotlin.wasm.internal.WasmCharArray + global.get $kotlin.String_rtti___g_51 + i32.const 0 ;; type: kotlin.wasm.internal.WasmCharArray + ref.null none ;; @WasmPrimitiveConstructor ctor call: kotlin.String + local.get $17_this + array.len + + local.get $17_this + struct.new $kotlin.String___type_27 + br 0 + end + return) + (func $kotlin.wasm.internal.kotlinToJsStringAdapter___fun_50 (type $____type_112) + (param $0_x (ref null $kotlin.String___type_27)) (result externref) + (local $1_tmp0 (ref null $kotlin.Any___type_6)) + (local $2_this (ref null $kotlin.Any___type_6)) + (local $3_srcArray (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) + (local $4_tmp0 (ref null $kotlin.String___type_27)) + (local $5_this (ref null $kotlin.String___type_27)) + (local $6_stringLength i32) + (local $7_maxStringLength i32) + (local $8_allocator (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $9_result (ref null $kotlin.Any___type_6)) + (local $10_tmp (ref null $kotlin.Any___type_6)) + (local $11_tmp externref) + (local $12_tmp0 (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)) + (local $13_allocator (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)) + (local $14_memBuffer i32) + (local $15_tmp0 i32) + (local $16_this i32) + (local $17_result externref) + (local $18_srcStartIndex i32) + (local $19_t (ref null $kotlin.Throwable___type_32)) ;; type: kotlin.String? + local.get $0_x + ref.is_null + if ;; type: kotlin.String? + ref.null noextern + return + + ;; Inlined call of `kotlin.text.isEmpty` + end + local.get $0_x ;; type: kotlin.CharSequence + local.set $1_tmp0 + block (result i32) ;; type: kotlin.CharSequence + nop ;; type: kotlin.CharSequence + + ;; Special Interface call: kotlin.CharSequence. + local.get $1_tmp0 + local.tee $2_this + local.get $2_this + struct.get $kotlin.Any___type_6 0 + struct.get $___type_5 0 + + struct.get $SpecialITable___type_2 17 + ref.cast $___type_75 + struct.get $___type_75 0 + call_ref (type $____type_24) + + i32.const 0 + i32.eq + br 0 + end + if ;; type: kotlin.String? + call $kotlin.wasm.internal.___fun_51 + return + + ;; Inlined call of `kotlin.String.chars` + end + local.get $0_x ;; type: kotlin.String + local.set $4_tmp0 + block (result (ref null $kotlin.wasm.internal.WasmCharArray___type_26)) ;; type: kotlin.String + nop + local.get $4_tmp0 + local.tee $5_this + call $kotlin.access$___fun_25 ;; type: kotlin.String + ref.is_null + i32.eqz + if ;; type: kotlin.Unit? ;; type: kotlin.String + local.get $5_this + call $kotlin.String.foldChars___fun_28 + end + + local.get $5_this + call $kotlin.access$___fun_26 ;; type: kotlin.wasm.internal.WasmCharArray + br 0 + end + local.tee $3_srcArray + array.len + + ;; Inlined call of `kotlin.wasm.unsafe.withScopedMemoryAllocator` + local.set $6_stringLength + i32.const 32768 + local.set $7_maxStringLength + block + nop + call $kotlin.wasm.unsafe.createAllocatorInTheNewScope___fun_97 + local.set $8_allocator + block (result (ref null $kotlin.Any___type_6)) ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + block (result externref) + block + + ;; Inlined call of `UNKNOWN` + try (result (ref null $kotlin.Throwable___type_32)) + local.get $8_allocator ;; type: kotlin.wasm.unsafe.MemoryAllocator + local.set $12_tmp0 + block (result (ref null $kotlin.Any___type_6)) ;; type: kotlin.wasm.unsafe.MemoryAllocator + nop ;; type: kotlin.Int + local.get $12_tmp0 ;; type: kotlin.Int + local.tee $13_allocator + local.get $6_stringLength + + ;; Class Virtual call: kotlin.wasm.unsafe.MemoryAllocator.allocate + local.get $7_maxStringLength ;; type: kotlin.wasm.unsafe.MemoryAllocator + call $kotlin.ranges.coerceAtMost___fun_13 + i32.const 2 + i32.mul + + local.get $13_allocator + struct.get $kotlin.wasm.unsafe.MemoryAllocator___type_66 0 + struct.get $___type_65 1 + + ;; Inlined call of `kotlin.UInt.toInt` + call_ref (type $____type_64) + call $kotlin.wasm.unsafe.-impl>___fun_91 ;; type: kotlin.UInt + local.set $15_tmp0 + block (result i32) ;; type: kotlin.UInt + nop + local.get $15_tmp0 + + local.tee $16_this + call $kotlin.-impl>___fun_15 + br 0 + end + local.set $14_memBuffer + ref.null noextern + local.set $17_result + i32.const 0 ;; type: kotlin.Int + local.set $18_srcStartIndex ;; type: kotlin.Int + loop ;; type: kotlin.Int + block + local.get $18_srcStartIndex + local.get $6_stringLength + local.get $7_maxStringLength + i32.sub ;; type: kotlin.wasm.internal.WasmCharArray + i32.lt_s ;; type: kotlin.Int + i32.eqz ;; type: kotlin.Int + br_if 0 ;; type: kotlin.Int + local.get $3_srcArray + local.get $18_srcStartIndex + local.get $7_maxStringLength ;; type: kotlin.Int ;; type: kotlin.Int + local.get $14_memBuffer ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.unsafeWasmCharArrayToRawMemory___fun_31 + local.get $14_memBuffer ;; type: kotlin.js.JsAny? + local.get $7_maxStringLength + local.get $17_result ;; type: kotlin.Int ;; type: kotlin.Int + call $kotlin.wasm.internal.importStringFromWasm__externalAdapter___fun_52 + local.set $17_result ;; type: kotlin.Int + local.get $18_srcStartIndex + local.get $7_maxStringLength + i32.add + local.set $18_srcStartIndex + br 1 ;; type: kotlin.wasm.internal.WasmCharArray ;; type: kotlin.Int + end ;; type: kotlin.Int + end ;; type: kotlin.Int + local.get $3_srcArray + local.get $18_srcStartIndex ;; type: kotlin.Int + local.get $6_stringLength + local.get $18_srcStartIndex + i32.sub ;; type: kotlin.Int ;; type: kotlin.Int + local.get $14_memBuffer ;; type: kotlin.Int + call $kotlin.wasm.internal.unsafeWasmCharArrayToRawMemory___fun_31 + local.get $14_memBuffer ;; type: kotlin.js.JsAny? + local.get $6_stringLength + local.get $18_srcStartIndex + i32.sub + + local.get $17_result + call $kotlin.wasm.internal.importStringFromWasm__externalAdapter___fun_52 + br 3 + end + br 3 + catch 0 + catch_all + ref.null extern ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + call $kotlin.wasm.internal.createJsException___fun_48 + end + local.set $19_t ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: parent, type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + local.get $8_allocator ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.destroy___fun_96 + local.get $8_allocator ;; type: kotlin.Throwable + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 4 + global.set $kotlin.wasm.unsafe.currentAllocator___g_9 + local.get $19_t + + throw 0 + end ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + unreachable + end + local.set $11_tmp ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: parent, type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + local.get $8_allocator ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.destroy___fun_96 + local.get $8_allocator ;; type: kotlin.js.JsString? + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 4 + + global.set $kotlin.wasm.unsafe.currentAllocator___g_9 + local.get $11_tmp ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + return + end + local.set $10_tmp ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: parent, type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + local.get $8_allocator ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.destroy___fun_96 + local.get $8_allocator ;; type: kotlin.Any? + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 4 ;; type: kotlin.Any? + global.set $kotlin.wasm.unsafe.currentAllocator___g_9 + + local.get $10_tmp + local.set $9_result + unreachable + end + unreachable) + (func $kotlin.wasm.internal.___fun_51 (type $____type_104) (result externref) + (local $0_value externref) ;; type: kotlin.js.JsString? ;; type: kotlin.js.JsString? + global.get $kotlin.wasm.internal._jsEmptyString___g_5 + local.tee $0_value ;; type: kotlin.js.JsString? + ref.is_null + if ;; type: kotlin.js.JsString? ;; type: kotlin.js.JsString? + call $kotlin.wasm.internal.getJsEmptyString__externalAdapter___fun_53 ;; type: kotlin.Unit? ;; type: kotlin.js.JsString? + local.tee $0_value + global.set $kotlin.wasm.internal._jsEmptyString___g_5 + end + local.get $0_value + return) + (func $kotlin.wasm.internal.importStringFromWasm__externalAdapter___fun_52 (type $____type_113) + (param $0_address i32) + (param $1_length i32) + (param $2_prefix externref) (result externref) + (local $3_tmp0 externref) ;; type: kotlin.Int ;; type: kotlin.Int ;; type: kotlin.js.JsAny? + local.get $0_address + local.get $1_length + local.get $2_prefix ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.importStringFromWasm___fun_4 + call $kotlin.wasm.internal.jsCheckIsNullOrUndefinedAdapter___fun_56 + local.tee $3_tmp0 + ref.is_null + if (result externref) ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.THROW_NPE___fun_33 + unreachable + else + local.get $3_tmp0 + end + return) + (func $kotlin.wasm.internal.getJsEmptyString__externalAdapter___fun_53 (type $____type_104) (result externref) + (local $0_tmp0 externref) ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.getJsEmptyString___fun_5 + call $kotlin.wasm.internal.jsCheckIsNullOrUndefinedAdapter___fun_56 + local.tee $0_tmp0 + ref.is_null + if (result externref) ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.THROW_NPE___fun_33 + unreachable + else + local.get $0_tmp0 + end + return) + (func $kotlin.wasm.internal.kotlinToJsAnyAdapter___fun_54 (type $____type_30) + (param $0_x (ref null $kotlin.Any___type_6)) (result externref) ;; type: kotlin.Any? + local.get $0_x + ref.is_null ;; type: kotlin.Any? + if (result externref) + ref.null noextern + else + local.get $0_x + call $kotlin.wasm.internal.anyToExternRef___fun_55 + end + return) + (func $kotlin.wasm.internal.anyToExternRef___fun_55 (type $____type_30) + (param $0_x (ref null $kotlin.Any___type_6)) (result externref) ;; type: kotlin.Any ;; type: kotlin.Any + local.get $0_x + ref.test $kotlin.wasm.internal.JsExternalBox___type_34 ;; name: ref, type: kotlin.js.JsAny + if (result externref) + local.get $0_x ;; type: kotlin.Any + ref.cast null $kotlin.wasm.internal.JsExternalBox___type_34 + struct.get $kotlin.wasm.internal.JsExternalBox___type_34 4 + else + local.get $0_x + extern.externalize + end + return) + (func $kotlin.wasm.internal.jsCheckIsNullOrUndefinedAdapter___fun_56 (type $____type_114) + (param $0_x externref) (result externref) ;; type: kotlin.js.JsAny? + local.get $0_x + call $kotlin.wasm.internal.isNullish___fun_6 ;; type: kotlin.js.JsAny? + if (result externref) + ref.null noextern + else + local.get $0_x + end + return) + (func $kotlin.wasm.internal.jsToKotlinAnyAdapter___fun_57 (type $____type_115) + (param $0_x externref) (result (ref null $kotlin.Any___type_6)) ;; type: kotlin.js.JsAny? + local.get $0_x + ref.is_null ;; type: kotlin.js.JsAny? + if (result (ref null $kotlin.Any___type_6)) + ref.null none + else + local.get $0_x + call $kotlin.wasm.internal.externRefToAny___fun_58 + end + return) + (func $kotlin.wasm.internal.externRefToAny___fun_58 (type $____type_115) + (param $0_ref externref) (result (ref null $kotlin.Any___type_6)) + block (result anyref) + local.get $0_ref + extern.internalize + br_on_cast_fail 3 0 any $kotlin.Any___type_6 + return ;; type: kotlin.js.JsAny + + ;; Any parameters + end + drop + local.get $0_ref + + global.get $___g_19 ;; type: kotlin.js.JsAny + ref.null none ;; @WasmPrimitiveConstructor ctor call: kotlin.wasm.internal.JsExternalBox + global.get $kotlin.wasm.internal.JsExternalBox_rtti___g_53 + i32.const 0 + local.get $0_ref + struct.new $kotlin.wasm.internal.JsExternalBox___type_34 + extern.externalize + call $kotlin.wasm.internal.getCachedJsObject_$external_fun__externalAdapter___fun_59 + call $kotlin.wasm.internal.jsToKotlinAnyAdapter___fun_57 + return) + (func $kotlin.wasm.internal.getCachedJsObject_$external_fun__externalAdapter___fun_59 (type $____type_116) + (param $0_ref externref) + (param $1_ifNotCached externref) (result externref) ;; type: kotlin.js.JsAny? ;; type: kotlin.js.JsAny? + local.get $0_ref + local.get $1_ifNotCached + call $kotlin.wasm.internal.getCachedJsObject_$external_fun___fun_7 + call $kotlin.wasm.internal.jsCheckIsNullOrUndefinedAdapter___fun_56 + return) + (func $kotlin.js.___fun_60 (type $____type_104) (result externref) ;; type: kotlin.js.JsAny + call $kotlin.js.___fun_69 + global.get $kotlin.js.stackPlaceHolder___g_6 + return) + (func $kotlin.js.stackPlaceHolder_js_code__externalAdapter___fun_61 (type $____type_104) (result externref) + (local $0_tmp0 externref) + call $kotlin.js.___fun_69 ;; type: kotlin.js.JsAny? + call $kotlin.js.stackPlaceHolder_js_code___fun_8 + call $kotlin.wasm.internal.jsCheckIsNullOrUndefinedAdapter___fun_56 + local.tee $0_tmp0 + ref.is_null + if (result externref) ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.THROW_NPE___fun_33 + unreachable + else + local.get $0_tmp0 + end + return) + (func $kotlin.js.JsException.___fun_62 (type $____type_117) + (param $0_ (ref null $kotlin.js.JsException___type_36)) + (param $1_thrownValue externref) (result (ref null $kotlin.js.JsException___type_36)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_20 + ref.null none + global.get $kotlin.js.JsException_rtti___g_60 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + ref.null $kotlin.Any___type_6 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null extern + struct.new $kotlin.js.JsException___type_36 + local.set $0_ + end + local.get $0_ + ref.null none + ref.null none ;; type: kotlin.js.JsException + call $kotlin.js.___fun_60 ;; type: kotlin.js.JsAny? + call $kotlin.Throwable.___fun_39 ;; name: thrownValue, type: kotlin.js.JsAny? + drop + local.get $0_ ;; type: kotlin.js.JsException + local.get $1_thrownValue ;; name: _message, type: kotlin.String? + struct.set $kotlin.js.JsException___type_36 9 + local.get $0_ ;; type: kotlin.js.JsException + ref.null none ;; name: _jsStack, type: kotlin.js.JsAny? + struct.set $kotlin.js.JsException___type_36 10 + local.get $0_ + ref.null noextern + struct.set $kotlin.js.JsException___type_36 11 + nop + local.get $0_ + return) + (func $kotlin.js.JsException.___fun_63 (type $____type_29) + (param $0_ (ref null $kotlin.Any___type_6)) (result (ref null $kotlin.String___type_27)) + (local $1_tmp0_ (ref null $kotlin.js.JsException___type_36)) + (local $2_value (ref null $kotlin.String___type_27)) + (local $3_tmp externref) ;; type: kotlin.Any ;; type: kotlin.js.JsException + local.get $0_ ;; name: _message, type: kotlin.String? + ref.cast null $kotlin.js.JsException___type_36 ;; type: kotlin.String? + local.tee $1_tmp0_ + struct.get $kotlin.js.JsException___type_36 10 ;; type: kotlin.js.JsException + local.tee $2_value ;; name: thrownValue, type: kotlin.js.JsAny? + ref.is_null + if ;; type: kotlin.js.JsAny? + local.get $1_tmp0_ + struct.get $kotlin.js.JsException___type_36 9 + local.tee $3_tmp + ref.is_null ;; type: kotlin.js.JsAny? + if (result i32) + i32.const 0 + else + local.get $3_tmp + call $kotlin.wasm.internal.jsToKotlinAnyAdapter___fun_57 ;; type: kotlin.js.JsException + call $kotlin.js.JsError_$external_class_instanceof__externalAdapter___fun_68 ;; name: thrownValue, type: kotlin.js.JsAny? + end + if (result (ref null $kotlin.String___type_27)) + + ;; const string: "Exception was thrown while running JavaScript code" + local.get $1_tmp0_ + struct.get $kotlin.js.JsException___type_36 9 + call $kotlin.js.message_$external_prop_getter__externalAdapter___fun_66 + else + + i32.const 14 + i32.const 234 ;; type: kotlin.String? + i32.const 50 + call $kotlin.stringLiteral___fun_29 ;; type: kotlin.js.JsException ;; type: kotlin.String? + end ;; name: _message, type: kotlin.String? + local.set $2_value + local.get $1_tmp0_ ;; type: kotlin.Unit? ;; type: kotlin.String? + local.get $2_value + struct.set $kotlin.js.JsException___type_36 10 + end + local.get $2_value + return) + (func $kotlin.js.JsException.___fun_64 (type $____type_29) + (param $0_ (ref null $kotlin.Any___type_6)) (result (ref null $kotlin.String___type_27)) ;; type: kotlin.Any + local.get $0_ + call $kotlin.js.JsException.___fun_63 + return) + (func $kotlin.js.JsException.___fun_65 (type $____type_30) + (param $0_ (ref null $kotlin.Any___type_6)) (result externref) + (local $1_tmp0_ (ref null $kotlin.js.JsException___type_36)) + (local $2_value externref) + (local $3_tmp externref) ;; type: kotlin.Any ;; type: kotlin.js.JsException + local.get $0_ ;; name: _jsStack, type: kotlin.js.JsAny? + ref.cast null $kotlin.js.JsException___type_36 ;; type: kotlin.js.JsAny? + local.tee $1_tmp0_ + struct.get $kotlin.js.JsException___type_36 11 ;; type: kotlin.js.JsException + local.tee $2_value ;; name: thrownValue, type: kotlin.js.JsAny? + ref.is_null + if ;; type: kotlin.js.JsAny? + local.get $1_tmp0_ + struct.get $kotlin.js.JsException___type_36 9 + local.tee $3_tmp + ref.is_null ;; type: kotlin.js.JsAny? + if (result i32) + i32.const 0 + else + local.get $3_tmp + call $kotlin.wasm.internal.jsToKotlinAnyAdapter___fun_57 ;; type: kotlin.js.JsException + call $kotlin.js.JsError_$external_class_instanceof__externalAdapter___fun_68 ;; name: thrownValue, type: kotlin.js.JsAny? + end + if (result externref) + local.get $1_tmp0_ + struct.get $kotlin.js.JsException___type_36 9 + call $kotlin.js.stack_$external_prop_getter__externalAdapter___fun_67 ;; type: kotlin.js.JsAny? + else + call $kotlin.js.___fun_60 ;; type: kotlin.js.JsException ;; type: kotlin.js.JsAny? + end ;; name: _jsStack, type: kotlin.js.JsAny? + local.set $2_value + local.get $1_tmp0_ ;; type: kotlin.Unit? ;; type: kotlin.js.JsAny? + local.get $2_value + struct.set $kotlin.js.JsException___type_36 11 + end + local.get $2_value + return) + (func $kotlin.js.message_$external_prop_getter__externalAdapter___fun_66 (type $____type_109) + (param $0__this externref) (result (ref null $kotlin.String___type_27)) + (local $1_tmp0 externref) ;; type: kotlin.js.JsError + call $kotlin.js.___fun_69 ;; type: kotlin.js.JsAny? + local.get $0__this + call $kotlin.js.message_$external_prop_getter___fun_9 + local.tee $1_tmp0 + ref.is_null + if (result (ref null $kotlin.String___type_27)) ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.THROW_NPE___fun_33 + unreachable + else + local.get $1_tmp0 + call $kotlin.wasm.internal.jsToKotlinStringAdapter___fun_49 + end + return) + (func $kotlin.js.stack_$external_prop_getter__externalAdapter___fun_67 (type $____type_114) + (param $0__this externref) (result externref) + (local $1_tmp0 externref) ;; type: kotlin.js.JsError + call $kotlin.js.___fun_69 + local.get $0__this ;; type: kotlin.js.JsAny? + call $kotlin.js.stack_$external_prop_getter___fun_10 + call $kotlin.wasm.internal.jsCheckIsNullOrUndefinedAdapter___fun_56 + local.tee $1_tmp0 + ref.is_null + if (result externref) ;; type: kotlin.js.JsAny? + call $kotlin.wasm.internal.THROW_NPE___fun_33 + unreachable + else + local.get $1_tmp0 + end + return) + (func $kotlin.js.JsError_$external_class_instanceof__externalAdapter___fun_68 (type $____type_24) + (param $0_x (ref null $kotlin.Any___type_6)) (result i32) ;; type: kotlin.Any + call $kotlin.js.___fun_69 + local.get $0_x + call $kotlin.wasm.internal.kotlinToJsAnyAdapter___fun_54 + call $kotlin.js.JsError_$external_class_instanceof___fun_11 + return) + (func $kotlin.js.___fun_69 (type $____type_95) ;; type: kotlin.Boolean + global.get $kotlin.js.properties_initialized_JsException.kt___g_7 ;; type: kotlin.Boolean + if + else ;; type: kotlin.js.JsAny + i32.const 1 + global.set $kotlin.js.properties_initialized_JsException.kt___g_7 + call $kotlin.js.stackPlaceHolder_js_code__externalAdapter___fun_61 + global.set $kotlin.js.stackPlaceHolder___g_6 + end + nop) + (func $kotlin.IllegalArgumentException.___fun_70 (type $____type_118) + (param $0_ (ref null $kotlin.IllegalArgumentException___type_42)) + (param $1_message (ref null $kotlin.String___type_27)) (result (ref null $kotlin.IllegalArgumentException___type_42)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_21 + ref.null none + global.get $kotlin.IllegalArgumentException_rtti___g_64 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.IllegalArgumentException___type_42 ;; type: kotlin.String? + local.set $0_ + end + local.get $0_ + local.get $1_message + call $kotlin.RuntimeException.___fun_77 + drop + local.get $0_ + call $kotlin.IllegalArgumentException.___fun_71 + drop + nop + local.get $0_ + return) + (func $kotlin.IllegalArgumentException.___fun_71 (type $____type_119) + (param $0_ (ref null $kotlin.IllegalArgumentException___type_42)) (result (ref null $kotlin.IllegalArgumentException___type_42)) + nop + local.get $0_ + return) + (func $kotlin.ArithmeticException.___fun_72 (type $____type_120) + (param $0_ (ref null $kotlin.ArithmeticException___type_44)) + (param $1_message (ref null $kotlin.String___type_27)) (result (ref null $kotlin.ArithmeticException___type_44)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_22 + ref.null none + global.get $kotlin.ArithmeticException_rtti___g_65 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.ArithmeticException___type_44 ;; type: kotlin.String? + local.set $0_ + end + local.get $0_ + local.get $1_message + call $kotlin.RuntimeException.___fun_77 + drop + local.get $0_ + call $kotlin.ArithmeticException.___fun_73 + drop + nop + local.get $0_ + return) + (func $kotlin.ArithmeticException.___fun_73 (type $____type_121) + (param $0_ (ref null $kotlin.ArithmeticException___type_44)) (result (ref null $kotlin.ArithmeticException___type_44)) + nop + local.get $0_ + return) + (func $kotlin.IndexOutOfBoundsException.___fun_74 (type $____type_122) + (param $0_ (ref null $kotlin.IndexOutOfBoundsException___type_47)) (result (ref null $kotlin.IndexOutOfBoundsException___type_47)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_23 + ref.null none + global.get $kotlin.IndexOutOfBoundsException_rtti___g_66 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.IndexOutOfBoundsException___type_47 + local.set $0_ + end + local.get $0_ + call $kotlin.RuntimeException.___fun_76 + drop + local.get $0_ + call $kotlin.IndexOutOfBoundsException.___fun_75 + drop + nop + local.get $0_ + return) + (func $kotlin.IndexOutOfBoundsException.___fun_75 (type $____type_122) + (param $0_ (ref null $kotlin.IndexOutOfBoundsException___type_47)) (result (ref null $kotlin.IndexOutOfBoundsException___type_47)) + nop + local.get $0_ + return) + (func $kotlin.RuntimeException.___fun_76 (type $____type_123) + (param $0_ (ref null $kotlin.RuntimeException___type_40)) (result (ref null $kotlin.RuntimeException___type_40)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_24 + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.RuntimeException___type_40 + local.set $0_ + end + local.get $0_ + call $kotlin.Exception.___fun_79 + drop + local.get $0_ + call $kotlin.RuntimeException.___fun_78 + drop + nop + local.get $0_ + return) + (func $kotlin.RuntimeException.___fun_77 (type $____type_124) + (param $0_ (ref null $kotlin.RuntimeException___type_40)) + (param $1_message (ref null $kotlin.String___type_27)) (result (ref null $kotlin.RuntimeException___type_40)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_24 + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.RuntimeException___type_40 ;; type: kotlin.String? + local.set $0_ + end + local.get $0_ + local.get $1_message + call $kotlin.Exception.___fun_80 + drop + local.get $0_ + call $kotlin.RuntimeException.___fun_78 + drop + nop + local.get $0_ + return) + (func $kotlin.RuntimeException.___fun_78 (type $____type_123) + (param $0_ (ref null $kotlin.RuntimeException___type_40)) (result (ref null $kotlin.RuntimeException___type_40)) + nop + local.get $0_ + return) + (func $kotlin.Exception.___fun_79 (type $____type_125) + (param $0_ (ref null $kotlin.Exception___type_38)) (result (ref null $kotlin.Exception___type_38)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_25 + ref.null none + global.get $kotlin.Exception_rtti___g_61 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.Exception___type_38 + local.set $0_ + end + local.get $0_ + call $kotlin.Throwable.___fun_44 + drop + local.get $0_ + call $kotlin.Exception.___fun_81 + drop + nop + local.get $0_ + return) + (func $kotlin.Exception.___fun_80 (type $____type_126) + (param $0_ (ref null $kotlin.Exception___type_38)) + (param $1_message (ref null $kotlin.String___type_27)) (result (ref null $kotlin.Exception___type_38)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_25 + ref.null none + global.get $kotlin.Exception_rtti___g_61 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.Exception___type_38 ;; type: kotlin.String? + local.set $0_ + end + local.get $0_ + local.get $1_message + call $kotlin.Throwable.___fun_43 + drop + local.get $0_ + call $kotlin.Exception.___fun_81 + drop + nop + local.get $0_ + return) + (func $kotlin.Exception.___fun_81 (type $____type_125) + (param $0_ (ref null $kotlin.Exception___type_38)) (result (ref null $kotlin.Exception___type_38)) + nop + local.get $0_ + return) + (func $kotlin.IllegalStateException.___fun_82 (type $____type_127) + (param $0_ (ref null $kotlin.IllegalStateException___type_50)) + (param $1_message (ref null $kotlin.String___type_27)) (result (ref null $kotlin.IllegalStateException___type_50)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_26 + ref.null none + global.get $kotlin.IllegalStateException_rtti___g_67 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.IllegalStateException___type_50 ;; type: kotlin.String? + local.set $0_ + end + local.get $0_ + local.get $1_message + call $kotlin.RuntimeException.___fun_77 + drop + local.get $0_ + call $kotlin.IllegalStateException.___fun_83 + drop + nop + local.get $0_ + return) + (func $kotlin.IllegalStateException.___fun_83 (type $____type_128) + (param $0_ (ref null $kotlin.IllegalStateException___type_50)) (result (ref null $kotlin.IllegalStateException___type_50)) + nop + local.get $0_ + return) + (func $kotlin.ClassCastException.___fun_84 (type $____type_129) + (param $0_ (ref null $kotlin.ClassCastException___type_53)) (result (ref null $kotlin.ClassCastException___type_53)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_27 + ref.null none + global.get $kotlin.ClassCastException_rtti___g_68 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.ClassCastException___type_53 + local.set $0_ + end + local.get $0_ + call $kotlin.RuntimeException.___fun_76 + drop + local.get $0_ + call $kotlin.ClassCastException.___fun_85 + drop + nop + local.get $0_ + return) + (func $kotlin.ClassCastException.___fun_85 (type $____type_129) + (param $0_ (ref null $kotlin.ClassCastException___type_53)) (result (ref null $kotlin.ClassCastException___type_53)) + nop + local.get $0_ + return) + (func $kotlin.NullPointerException.___fun_86 (type $____type_130) + (param $0_ (ref null $kotlin.NullPointerException___type_56)) (result (ref null $kotlin.NullPointerException___type_56)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_28 + ref.null none + global.get $kotlin.NullPointerException_rtti___g_69 + i32.const 0 + ref.null $kotlin.String___type_27 + ref.null $kotlin.Throwable___type_32 + ref.null extern + ref.null $kotlin.String___type_27 + + ref.null $kotlin.Any___type_6 + struct.new $kotlin.NullPointerException___type_56 + local.set $0_ + end + local.get $0_ + call $kotlin.RuntimeException.___fun_76 + drop + local.get $0_ + call $kotlin.NullPointerException.___fun_87 + drop + nop + local.get $0_ + return) + (func $kotlin.NullPointerException.___fun_87 (type $____type_130) + (param $0_ (ref null $kotlin.NullPointerException___type_56)) (result (ref null $kotlin.NullPointerException___type_56)) + nop + local.get $0_ + return) + (func $kotlin.Unit.___fun_88 (type $____type_131) + (param $0_ (ref null $kotlin.Unit___type_59)) (result (ref null $kotlin.Unit___type_59)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_29 + ref.null none + global.get $kotlin.Unit_rtti___g_54 + + i32.const 0 + struct.new $kotlin.Unit___type_59 + local.set $0_ + end + nop + local.get $0_ + return) + (func $kotlin.Unit_getInstance___fun_89 (type $____type_132) (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.Unit? + global.get $kotlin.Unit_instance___g_8 + return) + (func $kotlin.wasm.unsafe.-impl>___fun_90 (type $____type_81) + (param $0_address i32) (result i32) ;; type: kotlin.UInt + local.get $0_address + return) + (func $kotlin.wasm.unsafe.-impl>___fun_91 (type $____type_81) + (param $0_$this i32) (result i32) ;; type: kotlin.wasm.unsafe.Pointer + local.get $0_$this + return) + (func $kotlin.wasm.unsafe.MemoryAllocator.___fun_92 (type $____type_133) + (param $0_ (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)) (result (ref null $kotlin.wasm.unsafe.MemoryAllocator___type_66)) + nop + local.get $0_ + return) + (func $kotlin.wasm.unsafe.ScopedMemoryAllocator.___fun_93 (type $____type_134) + (param $0_ (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (param $1_startAddress i32) + (param $2_parent (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_31 + ref.null none + global.get $kotlin.wasm.unsafe.ScopedMemoryAllocator_rtti___g_62 + i32.const 0 + ref.null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 + i32.const 0 + i32.const 0 + + i32.const 0 + struct.new $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 + local.set $0_ + end ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.get $0_ ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + call $kotlin.wasm.unsafe.MemoryAllocator.___fun_92 ;; name: parent, type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + drop + local.get $0_ ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.get $2_parent ;; name: destroyed, type: kotlin.Boolean + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 4 + local.get $0_ ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + i32.const 0 ;; name: suspended, type: kotlin.Boolean + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 5 + local.get $0_ ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; type: kotlin.Int + i32.const 0 ;; name: availableAddress, type: kotlin.Int + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 6 + local.get $0_ + local.get $1_startAddress + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 + nop + local.get $0_ + return) + (func $kotlin.wasm.unsafe.ScopedMemoryAllocator.allocate___fun_94 (type $____type_64) + (param $0_ (ref null $kotlin.Any___type_6)) + (param $1_size i32) (result i32) + (local $2_tmp0_ (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $3_tmp0 i32) + (local $4_value i32) + (local $5_message (ref null $kotlin.String___type_27)) + (local $6_tmp0 i32) + (local $7_value i32) + (local $8_message (ref null $kotlin.String___type_27)) + (local $9_align i32) + (local $10_result i32) + (local $11_tmp0 i32) + (local $12_this i32) + (local $13_tmp0 i32) + (local $14_value i32) + (local $15_message (ref null $kotlin.String___type_27)) + (local $16_tmp0 (ref null $kotlin.String___type_27)) + (local $17_message (ref null $kotlin.String___type_27)) + (local $18_currentMaxSize i32) + (local $19_numPagesToGrow i32) + (local $20_tmp0 (ref null $kotlin.String___type_27)) + (local $21_message (ref null $kotlin.String___type_27)) + (local $22_tmp0 i32) + (local $23_value i32) + (local $24_tmp0 i32) + (local $25_this i32) ;; type: kotlin.Any ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.get $0_ ;; name: destroyed, type: kotlin.Boolean + ref.cast null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 + local.tee $2_tmp0_ + + ;; Inlined call of `kotlin.check` + struct.get_s $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 5 + i32.eqz ;; type: kotlin.Boolean + local.set $3_tmp0 + block (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.Boolean + nop + local.get $3_tmp0 + + ;; Inlined call of `UNKNOWN` + local.tee $4_value + + ;; const string: "ScopedMemoryAllocator is destroyed when out of scope" + i32.eqz + if + block (result (ref null $kotlin.String___type_27)) + nop + + i32.const 27 + i32.const 732 + + i32.const 52 + call $kotlin.stringLiteral___fun_29 + br 0 ;; type: kotlin.String + end + local.set $5_message + ref.null none + local.get $5_message ;; type: kotlin.Unit? + call $kotlin.IllegalStateException.___fun_82 + throw 0 + + end + global.get $kotlin.Unit_instance___g_8 ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + br 0 ;; name: suspended, type: kotlin.Boolean + end + drop + local.get $2_tmp0_ + + ;; Inlined call of `kotlin.check` + struct.get_s $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 6 + i32.eqz ;; type: kotlin.Boolean + local.set $6_tmp0 + block (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.Boolean + nop + local.get $6_tmp0 + + ;; Inlined call of `UNKNOWN` + local.tee $7_value + + ;; const string: "ScopedMemoryAllocator is suspended when nested allocators are used" + i32.eqz + if + block (result (ref null $kotlin.String___type_27)) + nop + + i32.const 28 + i32.const 836 + + i32.const 66 + call $kotlin.stringLiteral___fun_29 + br 0 ;; type: kotlin.String + end + local.set $8_message + ref.null none + local.get $8_message ;; type: kotlin.Unit? + call $kotlin.IllegalStateException.___fun_82 + throw 0 + + end + global.get $kotlin.Unit_instance___g_8 + br 0 + end ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + drop ;; name: availableAddress, type: kotlin.Int + i32.const 8 ;; type: kotlin.Int + local.set $9_align + local.get $2_tmp0_ + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 + local.get $9_align ;; type: kotlin.Int + i32.add + i32.const 1 + i32.sub + local.get $9_align + + ;; Inlined call of `kotlin.Int.inv` + i32.const 1 + i32.sub ;; type: kotlin.Int + local.set $11_tmp0 + block (result i32) ;; type: kotlin.Int + nop + local.get $11_tmp0 + local.tee $12_this + + i32.const -1 + i32.xor + br 0 ;; type: kotlin.Int + end + i32.and + local.tee $10_result ;; type: kotlin.Int + i32.const 0 ;; type: kotlin.Int + i32.ge_s + if (result i32) + local.get $10_result + local.get $9_align + call $kotlin.Int__rem-impl___fun_22 + i32.const 0 + i32.eq + else + + ;; Inlined call of `kotlin.check` + i32.const 0 + end ;; type: kotlin.Boolean + local.set $13_tmp0 + block (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.Boolean + nop + local.get $13_tmp0 + + ;; Inlined call of `UNKNOWN` + local.tee $14_value + + ;; const string: "result must be >= 0 and 8-byte aligned" + i32.eqz + if + block (result (ref null $kotlin.String___type_27)) + nop + + i32.const 29 + i32.const 968 + + i32.const 38 + call $kotlin.stringLiteral___fun_29 + br 0 ;; type: kotlin.String + end + local.set $15_message + ref.null none + local.get $15_message ;; type: kotlin.Unit? + call $kotlin.IllegalStateException.___fun_82 + throw 0 + + end + global.get $kotlin.Unit_instance___g_8 + br 0 ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + end ;; name: availableAddress, type: kotlin.Int + drop + i32.const 2147483647 ;; type: kotlin.Int + local.get $2_tmp0_ + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 + + ;; const string: "Out of linear memory. All available address space (2gb) is used." + i32.sub + local.get $1_size + i32.lt_s + if + + i32.const 30 + i32.const 1044 + + ;; Inlined call of `kotlin.error` + i32.const 64 + call $kotlin.stringLiteral___fun_29 ;; type: kotlin.String + local.set $16_tmp0 + block + nop ;; type: kotlin.String + local.get $16_tmp0 + local.set $17_message + ref.null none + + local.get $17_message + call $kotlin.IllegalStateException.___fun_82 + throw 0 ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + end ;; type: kotlin.Int + unreachable ;; type: kotlin.Int + end + local.get $2_tmp0_ ;; name: availableAddress, type: kotlin.Int + local.get $10_result + local.get $1_size + i32.add + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 + memory.size ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + i32.const 65536 ;; name: availableAddress, type: kotlin.Int + i32.mul ;; type: kotlin.Int + local.set $18_currentMaxSize + local.get $2_tmp0_ + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.get $18_currentMaxSize ;; name: availableAddress, type: kotlin.Int + i32.ge_s ;; type: kotlin.Int + if + local.get $2_tmp0_ + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 + local.get $18_currentMaxSize + i32.sub + i32.const 65536 + call $kotlin.Int__div-impl___fun_21 ;; type: kotlin.Int + i32.const 2 + i32.add + local.tee $19_numPagesToGrow + + ;; const string: "Out of linear memory. memory.grow returned -1" + memory.grow + i32.const -1 + i32.eq + if + + i32.const 31 + i32.const 1172 + + ;; Inlined call of `kotlin.error` + i32.const 45 + call $kotlin.stringLiteral___fun_29 ;; type: kotlin.String + local.set $20_tmp0 + block + nop ;; type: kotlin.String + local.get $20_tmp0 + local.set $21_message + ref.null none + + local.get $21_message + call $kotlin.IllegalStateException.___fun_82 + throw 0 + end ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + unreachable ;; name: availableAddress, type: kotlin.Int + end + end + local.get $2_tmp0_ + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 + memory.size + i32.const 65536 + + ;; Inlined call of `kotlin.check` + i32.mul + i32.lt_s ;; type: kotlin.Boolean + local.set $22_tmp0 + block (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.Boolean + nop + local.get $22_tmp0 + + ;; const string: "Check failed." + local.tee $23_value + i32.eqz + if + ref.null none + + i32.const 10 + i32.const 142 + i32.const 13 + call $kotlin.stringLiteral___fun_29 ;; type: kotlin.Unit? + call $kotlin.IllegalStateException.___fun_82 + throw 0 + + end + global.get $kotlin.Unit_instance___g_8 ;; type: kotlin.Int + br 0 + end + + ;; Inlined call of `kotlin.toUInt` + drop + local.get $10_result ;; type: kotlin.Int + local.set $24_tmp0 + block (result i32) ;; type: kotlin.Int + nop + local.get $24_tmp0 + + local.tee $25_this + call $kotlin.-impl>___fun_14 + br 0 + end + call $kotlin.wasm.unsafe.-impl>___fun_90 + return) + (func $kotlin.wasm.unsafe.ScopedMemoryAllocator.createChild___fun_95 (type $____type_135) + (param $0_ (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $1_child (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $2_tmp0 i32) + (local $3_this i32) ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: availableAddress, type: kotlin.Int + ref.null none + + ;; Inlined call of `kotlin.Int.toInt` + local.get $0_ + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 7 ;; type: kotlin.Int + local.set $2_tmp0 + block (result i32) ;; type: kotlin.Int + nop + local.get $2_tmp0 + ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.tee $3_this + br 0 + end ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.get $0_ + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.___fun_93 ;; name: suspended, type: kotlin.Boolean + local.set $1_child + local.get $0_ ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + i32.const 1 + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 6 + local.get $1_child + return) + (func $kotlin.wasm.unsafe.ScopedMemoryAllocator.destroy___fun_96 (type $____type_136) + (param $0_ (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $1_tmp0_safe_receiver (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: destroyed, type: kotlin.Boolean + local.get $0_ ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator ;; name: parent, type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + i32.const 1 + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 5 ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + local.get $0_ + struct.get $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 4 + local.tee $1_tmp0_safe_receiver ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + ref.is_null + if ;; name: suspended, type: kotlin.Boolean + else + local.get $1_tmp0_safe_receiver ;; type: kotlin.Unit? + i32.const 0 + struct.set $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68 6 + end + nop) + (func $kotlin.wasm.unsafe.createAllocatorInTheNewScope___fun_97 (type $____type_137) (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $0_allocator (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $1_tmp1_elvis_lhs (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + (local $2_tmp0_safe_receiver (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + global.get $kotlin.wasm.unsafe.currentAllocator___g_9 + local.tee $2_tmp0_safe_receiver + ref.is_null ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + if (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + ref.null none + else + local.get $2_tmp0_safe_receiver ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.createChild___fun_95 + end + local.tee $1_tmp1_elvis_lhs + ref.is_null + if (result (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + ref.null none + i32.const 0 ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + ref.null none + call $kotlin.wasm.unsafe.ScopedMemoryAllocator.___fun_93 + else ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.get $1_tmp1_elvis_lhs ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator? + end ;; type: kotlin.wasm.unsafe.ScopedMemoryAllocator + local.tee $0_allocator + global.set $kotlin.wasm.unsafe.currentAllocator___g_9 + local.get $0_allocator + return) + (func $___fun_98 (type $____type_138) (result (ref null $kotlin.Any___type_6)) ;; type: kotlin.Function1 + call $___fun_109 + global.get $x___g_35 + return) + (func $___fun_99 (type $____type_138) (result (ref null $kotlin.Any___type_6)) ;; type: kotlin.Function1 + call $___fun_109 + global.get $y___g_36 + return) + (func $lolkek___fun_100 (type $____type_139) + (param $0_x i32) + (param $1_f (ref null $kotlin.Any___type_6)) (result i32) ;; type: kotlin.Function1 + + ;; Any parameters + call $___fun_109 + local.get $1_f + + global.get $___g_15 ;; type: kotlin.Int + global.get $___g_33 ;; box + global.get $kotlin.Int_rtti___g_59 ;; type: kotlin.Function1 + + ;; Functional Interface call: kotlin.Function1.invoke + i32.const 0 + local.get $0_x + struct.new $kotlin.Int___type_20 + local.get $1_f + struct.get $kotlin.Any___type_6 0 + struct.get $___type_5 0 + struct.get $SpecialITable___type_2 22 + + i32.const 1 + array.get (type $FuncArray___type_1) ;; name: value, type: kotlin.Int + ref.cast $____type_69 + call_ref (type $____type_69) + ref.cast $kotlin.Int___type_20 + struct.get $kotlin.Int___type_20 4 + i32.const 20 + i32.add + return) + (func $box___fun_101 (type $____type_140) (result (ref null $kotlin.String___type_27)) + (local $0_inductionVariable i32) + (local $1_i i32) ;; type: kotlin.Int + call $___fun_109 + i32.const 0 + local.tee $0_inductionVariable + i32.const 100000 + i32.le_s + if ;; type: kotlin.Int + loop + block ;; type: kotlin.Int + block + local.get $0_inductionVariable + local.set $1_i ;; type: kotlin.Int + local.get $0_inductionVariable + i32.const 1 ;; type: kotlin.Int + i32.add + local.set $0_inductionVariable + local.get $1_i + i32.const 2 + call $kotlin.Int__rem-impl___fun_22 ;; type: kotlin.Int + i32.const 0 + i32.eq + if + local.get $1_i + call $___fun_98 ;; type: kotlin.Int + call $lolkek___fun_100 + drop + else + local.get $1_i + call $___fun_99 + call $lolkek___fun_100 ;; type: kotlin.Int + drop + end + end + local.get $0_inductionVariable + i32.const 100000 + i32.le_s + br_if 1 ;; type: kotlin.Unit? + + ;; const string: "OK" + end + end + end + + i32.const 32 + i32.const 1262 + i32.const 2 + call $kotlin.stringLiteral___fun_29 + return) + (func $box__JsExportAdapter___fun_102 (type $____type_104) (result externref) + (local $0_currentIsNotFirstWasmExportCall i32) + (local $1_tmp externref) + (local $2_e (ref null $kotlin.Throwable___type_32)) + (local $3_t (ref null $kotlin.Throwable___type_32)) ;; type: kotlin.Boolean + global.get $kotlin.wasm.internal.isNotFirstWasmExportCall___g_3 + local.set $0_currentIsNotFirstWasmExportCall + block (result (ref null $kotlin.Unit___type_59)) + block (result externref) + block + try (result (ref null $kotlin.Throwable___type_32)) ;; type: kotlin.Boolean + block + try (result (ref null $kotlin.Throwable___type_32)) + i32.const 1 + global.set $kotlin.wasm.internal.isNotFirstWasmExportCall___g_3 + call $box___fun_101 + call $kotlin.wasm.internal.kotlinToJsStringAdapter___fun_50 + br 4 + catch 0 + catch_all + ref.null extern ;; type: kotlin.Boolean + call $kotlin.wasm.internal.createJsException___fun_48 + end ;; type: kotlin.Throwable + local.set $2_e + local.get $0_currentIsNotFirstWasmExportCall + if (result (ref null $kotlin.Unit___type_59)) ;; type: kotlin.Throwable + local.get $2_e + throw 0 + else + local.get $2_e + call $kotlin.wasm.internal.throwAsJsException___fun_46 + unreachable + end + br 4 + end + unreachable + catch 0 + catch_all + ref.null extern ;; type: kotlin.Boolean + call $kotlin.wasm.internal.createJsException___fun_48 ;; type: kotlin.Boolean + end + local.set $3_t ;; type: kotlin.Throwable + local.get $0_currentIsNotFirstWasmExportCall + global.set $kotlin.wasm.internal.isNotFirstWasmExportCall___g_3 + local.get $3_t + + throw 0 + end ;; type: kotlin.Boolean + unreachable ;; type: kotlin.Boolean + end + local.set $1_tmp ;; type: kotlin.js.JsString? + local.get $0_currentIsNotFirstWasmExportCall + + global.set $kotlin.wasm.internal.isNotFirstWasmExportCall___g_3 + local.get $1_tmp ;; type: kotlin.Boolean + return ;; type: kotlin.Boolean + end + drop + local.get $0_currentIsNotFirstWasmExportCall + global.set $kotlin.wasm.internal.isNotFirstWasmExportCall___g_3 + unreachable) + (func $x$lambda.___fun_103 (type $____type_141) + (param $0_ (ref null $x$lambda___type_71)) (result (ref null $x$lambda___type_71)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_40 + global.get $___g_42 + global.get $x$lambda_rtti___g_57 + + i32.const 0 + struct.new $x$lambda___type_71 + local.set $0_ + end + nop + local.get $0_ + return) + (func $x$lambda.invoke___fun_104 (type $____type_64) + (param $0_ (ref null $kotlin.Any___type_6)) + (param $1_it i32) (result i32) ;; type: kotlin.Int + local.get $1_it + i32.const 42 + i32.add + return) + (func $x$lambda.invoke___fun_105 (type $____type_69) + (param $0_ (ref null $kotlin.Any___type_6)) + (param $1_p1 (ref null $kotlin.Any___type_6)) (result (ref null $kotlin.Any___type_6)) + + ;; Any parameters + + global.get $___g_15 ;; type: kotlin.Function1 + global.get $___g_33 ;; type: P1 of kotlin.Function1 + global.get $kotlin.Int_rtti___g_59 + i32.const 0 + local.get $0_ + local.get $1_p1 + ref.is_null ;; type: P1 of kotlin.Function1 + if (result i32) + i32.const 0 + else + local.get $1_p1 ;; type: P1 of kotlin.Function1 + ref.test $kotlin.Int___type_20 + end ;; name: value, type: kotlin.Int + if (result i32) + local.get $1_p1 + ref.cast $kotlin.Int___type_20 + struct.get $kotlin.Int___type_20 4 + else + call $kotlin.wasm.internal.THROW_CCE___fun_34 ;; box + unreachable + end + call $x$lambda.invoke___fun_104 + struct.new $kotlin.Int___type_20 + return) + (func $y$lambda.___fun_106 (type $____type_142) + (param $0_ (ref null $y$lambda___type_73)) (result (ref null $y$lambda___type_73)) + + ;; Object creation prefix + + ;; Any parameters + local.get $0_ + ref.is_null + if + + global.get $___g_41 + global.get $___g_43 + global.get $y$lambda_rtti___g_58 + + i32.const 0 + struct.new $y$lambda___type_73 + local.set $0_ + end + nop + local.get $0_ + return) + (func $y$lambda.invoke___fun_107 (type $____type_64) + (param $0_ (ref null $kotlin.Any___type_6)) + (param $1_it i32) (result i32) ;; type: kotlin.Int + local.get $1_it + i32.const 24 + i32.add + return) + (func $y$lambda.invoke___fun_108 (type $____type_69) + (param $0_ (ref null $kotlin.Any___type_6)) + (param $1_p1 (ref null $kotlin.Any___type_6)) (result (ref null $kotlin.Any___type_6)) + + ;; Any parameters + + global.get $___g_15 ;; type: kotlin.Function1 + global.get $___g_33 ;; type: P1 of kotlin.Function1 + global.get $kotlin.Int_rtti___g_59 + i32.const 0 + local.get $0_ + local.get $1_p1 + ref.is_null ;; type: P1 of kotlin.Function1 + if (result i32) + i32.const 0 + else + local.get $1_p1 ;; type: P1 of kotlin.Function1 + ref.test $kotlin.Int___type_20 + end ;; name: value, type: kotlin.Int + if (result i32) + local.get $1_p1 + ref.cast $kotlin.Int___type_20 + struct.get $kotlin.Int___type_20 4 + else + call $kotlin.wasm.internal.THROW_CCE___fun_34 ;; box + unreachable + end + call $y$lambda.invoke___fun_107 + struct.new $kotlin.Int___type_20 + return) + (func $___fun_109 (type $____type_95) ;; type: kotlin.Boolean + global.get $properties_initialized_equalsHashCode.kt___g_39 ;; type: kotlin.Boolean + if + else ;; type: .x$lambda? ;; type: kotlin.Function1 + i32.const 1 + global.set $properties_initialized_equalsHashCode.kt___g_39 ;; type: .y$lambda? ;; type: kotlin.Function1 + global.get $x$lambda_instance___g_37 + global.set $x___g_35 + global.get $y$lambda_instance___g_38 + global.set $y___g_36 + end + nop) + (func $_fieldInitialize___fun_110 (type $____type_143) + ref.null none + i32.const 35 + call $kotlin.Array.___fun_17 + global.set $kotlin.wasm.internal.stringPool___g_4 + ref.null none + call $y$lambda.___fun_106 + global.set $y$lambda_instance___g_38 + ref.null none + call $x$lambda.___fun_103 + global.set $x$lambda_instance___g_37 + ref.null none + call $kotlin.Unit.___fun_88 + global.set $kotlin.Unit_instance___g_8 + ref.null none + call $kotlin.Companion.___fun_24 + global.set $kotlin.Companion_instance___g_2 + ref.null none + call $kotlin.Companion.___fun_20 + global.set $kotlin.Companion_instance___g_1 + ref.null none + call $kotlin.Companion.___fun_16 + global.set $kotlin.Companion_instance___g_0) + (func $_initialize___fun_111 (type $____type_143) + call $kotlin.Unit_getInstance___fun_89 + call $_fieldInitialize___fun_110 + return) + (memory $____mem_0 0) + (global $kotlin.Companion_instance___g_0 (mut (ref null $kotlin.Companion___type_10)) + ref.null $kotlin.Companion___type_10) + (global $kotlin.Companion_instance___g_1 (mut (ref null $kotlin.Companion___type_17)) + ref.null $kotlin.Companion___type_17) + (global $kotlin.Companion_instance___g_2 (mut (ref null $kotlin.Companion___type_22)) + ref.null $kotlin.Companion___type_22) + (global $kotlin.wasm.internal.isNotFirstWasmExportCall___g_3 (mut i32) + i32.const 0) + (global $kotlin.wasm.internal.stringPool___g_4 (mut (ref null $kotlin.Array___type_15)) + ref.null $kotlin.Array___type_15) + (global $kotlin.wasm.internal._jsEmptyString___g_5 (mut externref) + ref.null noextern) + (global $kotlin.js.stackPlaceHolder___g_6 (mut externref) + ref.null extern) + (global $kotlin.js.properties_initialized_JsException.kt___g_7 (mut i32) + i32.const 0) + (global $kotlin.Unit_instance___g_8 (mut (ref null $kotlin.Unit___type_59)) + ref.null $kotlin.Unit___type_59) + (global $kotlin.wasm.unsafe.currentAllocator___g_9 (mut (ref null $kotlin.wasm.unsafe.ScopedMemoryAllocator___type_68)) + ref.null none) + (global $___g_10 (ref $___type_9) + ref.null none + struct.new $___type_9) + (global $___g_11 (ref $___type_11) + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + struct.new $___type_76 + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + struct.new $SpecialITable___type_2 + struct.new $___type_11) + (global $___g_12 (ref $___type_5) + ref.null none + struct.new $___type_5) + (global $___g_13 (ref $___type_13) + ref.null none + struct.new $___type_13) + (global $___g_14 (ref $___type_16) + ref.null none + struct.new $___type_16) + (global $___g_15 (ref $___type_19) + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + struct.new $___type_76 + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + struct.new $SpecialITable___type_2 + struct.new $___type_19) + (global $___g_16 (ref $___type_21) + ref.null none + struct.new $___type_21) + (global $___g_17 (ref $___type_25) + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + struct.new $___type_76 + ref.func $kotlin.String.___fun_27 + struct.new $___type_75 + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + struct.new $SpecialITable___type_2 + ref.func $kotlin.String.___fun_27 + struct.new $___type_25) + (global $___g_18 (ref $___type_31) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_31) + (global $___g_19 (ref $___type_33) + ref.null none + struct.new $___type_33) + (global $___g_20 (ref $___type_35) + ref.null none + ref.func $kotlin.js.JsException.___fun_64 + ref.func $kotlin.js.JsException.___fun_65 + ref.func $kotlin.js.JsException.___fun_63 + struct.new $___type_35) + (global $___g_21 (ref $___type_41) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_41) + (global $___g_22 (ref $___type_43) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_43) + (global $___g_23 (ref $___type_46) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_46) + (global $___g_24 (ref $___type_39) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_39) + (global $___g_25 (ref $___type_37) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_37) + (global $___g_26 (ref $___type_49) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_49) + (global $___g_27 (ref $___type_52) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_52) + (global $___g_28 (ref $___type_55) + ref.null none + ref.func $kotlin.Throwable.___fun_40 + ref.func $kotlin.Throwable.___fun_41 + struct.new $___type_55) + (global $___g_29 (ref $___type_58) + ref.null none + struct.new $___type_58) + (global $___g_30 (ref $___type_61) + ref.null none + struct.new $___type_61) + (global $___g_31 (ref $___type_67) + ref.null none + ref.func $kotlin.wasm.unsafe.ScopedMemoryAllocator.allocate___fun_94 + struct.new $___type_67) + (global $___g_32 (ref $AnyArray___type_0) + array.new_fixed $AnyArray___type_0 0) + (global $___g_33 (ref $AnyArray___type_0) + array.new_fixed $AnyArray___type_0 0) + (global $___g_34 (ref $AnyArray___type_0) + array.new_fixed $AnyArray___type_0 0) + (global $x___g_35 (mut (ref null $kotlin.Any___type_6)) + ref.null $kotlin.Any___type_6) + (global $y___g_36 (mut (ref null $kotlin.Any___type_6)) + ref.null $kotlin.Any___type_6) + (global $x$lambda_instance___g_37 (mut (ref null $x$lambda___type_71)) + ref.null $x$lambda___type_71) + (global $y$lambda_instance___g_38 (mut (ref null $y$lambda___type_73)) + ref.null $y$lambda___type_73) + (global $properties_initialized_equalsHashCode.kt___g_39 (mut i32) + i32.const 0) + (global $___g_40 (ref $___type_70) + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null func + ref.func $x$lambda.invoke___fun_105 + array.new_fixed $FuncArray___type_1 2 + struct.new $SpecialITable___type_2 + ref.func $x$lambda.invoke___fun_104 + ref.func $x$lambda.invoke___fun_105 + struct.new $___type_70) + (global $___g_41 (ref $___type_72) + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null none + ref.null func + ref.func $y$lambda.invoke___fun_108 + array.new_fixed $FuncArray___type_1 2 + struct.new $SpecialITable___type_2 + ref.func $y$lambda.invoke___fun_107 + ref.func $y$lambda.invoke___fun_108 + struct.new $___type_72) + (global $___g_42 (ref $AnyArray___type_0) + array.new_fixed $AnyArray___type_0 0) + (global $___g_43 (ref $AnyArray___type_0) + array.new_fixed $AnyArray___type_0 0) + (global $kotlin.Any_rtti___g_44 (ref $RTTI___type_4) + ref.null none + ref.null none + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 38 + i32.const 3 + i32.const 4 + i64.const 2798839509968575897 + struct.new $RTTI___type_4) + (global $kotlin.Number_rtti___g_45 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 6 + i32.const 1 + i64.const -8592449170174531932 + struct.new $RTTI___type_4) + (global $kotlin.Companion_rtti___g_46 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 12 + i32.const 9 + i32.const 2 + i64.const -6607763668320844268 + struct.new $RTTI___type_4) + (global $kotlin.UInt_rtti___g_47 (ref $RTTI___type_4) + i64.const 5954910402192883452 + array.new_fixed $kotlin.wasm.internal.WasmLongImmutableArray___type_28 1 + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 30 + i32.const 4 + i32.const 3 + i64.const 7083758452498518870 + struct.new $RTTI___type_4) + (global $kotlin.Array_rtti___g_48 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 44 + i32.const 5 + i32.const 5 + i64.const -8244439916257877247 + struct.new $RTTI___type_4) + (global $kotlin.Companion_rtti___g_49 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 12 + i32.const 9 + i32.const 2 + i64.const 7147592030385101646 + struct.new $RTTI___type_4) + (global $kotlin.Companion_rtti___g_50 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 12 + i32.const 9 + i32.const 2 + i64.const 4903249906481983065 + struct.new $RTTI___type_4) + (global $kotlin.String_rtti___g_51 (ref $RTTI___type_4) + i64.const 5954910402192883452 + i64.const 6370907013483330859 + array.new_fixed $kotlin.wasm.internal.WasmLongImmutableArray___type_28 2 + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 130 + i32.const 6 + i32.const 9 + i64.const -6333374602768427243 + struct.new $RTTI___type_4) + (global $kotlin.Throwable_rtti___g_52 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 168 + i32.const 9 + i32.const 11 + i64.const -6652194674597942208 + struct.new $RTTI___type_4) + (global $kotlin.wasm.internal.JsExternalBox_rtti___g_53 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 186 + i32.const 13 + i32.const 12 + i64.const -5257734225098662143 + struct.new $RTTI___type_4) + (global $kotlin.Unit_rtti___g_54 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 638 + i32.const 4 + i32.const 23 + i64.const 2747285998620027492 + struct.new $RTTI___type_4) + (global $kotlin.wasm.unsafe.Pointer_rtti___g_55 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 646 + i32.const 7 + i32.const 24 + i64.const -4487840357310797298 + struct.new $RTTI___type_4) + (global $kotlin.wasm.unsafe.MemoryAllocator_rtti___g_56 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 660 + i32.const 15 + i32.const 25 + i64.const 1654642677112532623 + struct.new $RTTI___type_4) + (global $x$lambda_rtti___g_57 (ref $RTTI___type_4) + i64.const 4865718197115112024 + i64.const 7218332242951333468 + array.new_fixed $kotlin.wasm.internal.WasmLongImmutableArray___type_28 2 + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 1266 + i32.const 8 + i32.const 33 + i64.const 2144703159167525795 + struct.new $RTTI___type_4) + (global $y$lambda_rtti___g_58 (ref $RTTI___type_4) + i64.const 4865718197115112024 + i64.const 7218332242951333468 + array.new_fixed $kotlin.wasm.internal.WasmLongImmutableArray___type_28 2 + global.get $kotlin.Any_rtti___g_44 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 1282 + i32.const 8 + i32.const 34 + i64.const 7523473610768890175 + struct.new $RTTI___type_4) + (global $kotlin.Int_rtti___g_59 (ref $RTTI___type_4) + i64.const 5954910402192883452 + array.new_fixed $kotlin.wasm.internal.WasmLongImmutableArray___type_28 1 + global.get $kotlin.Number_rtti___g_45 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 124 + i32.const 3 + i32.const 8 + i64.const 1189077720114019965 + struct.new $RTTI___type_4) + (global $kotlin.js.JsException_rtti___g_60 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Throwable_rtti___g_52 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 212 + i32.const 11 + i32.const 13 + i64.const 8788567566637533234 + struct.new $RTTI___type_4) + (global $kotlin.Exception_rtti___g_61 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Throwable_rtti___g_52 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 502 + i32.const 9 + i32.const 19 + i64.const 1817363542377701804 + struct.new $RTTI___type_4) + (global $kotlin.wasm.unsafe.ScopedMemoryAllocator_rtti___g_62 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.wasm.unsafe.MemoryAllocator_rtti___g_56 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 690 + i32.const 21 + i32.const 26 + i64.const -3385990925803172230 + struct.new $RTTI___type_4) + (global $kotlin.RuntimeException_rtti___g_63 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.Exception_rtti___g_61 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 470 + i32.const 16 + i32.const 18 + i64.const 8306083845140529227 + struct.new $RTTI___type_4) + (global $kotlin.IllegalArgumentException_rtti___g_64 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 334 + i32.const 24 + i32.const 15 + i64.const -7549230862210269749 + struct.new $RTTI___type_4) + (global $kotlin.ArithmeticException_rtti___g_65 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 382 + i32.const 19 + i32.const 16 + i64.const 5839956794142491588 + struct.new $RTTI___type_4) + (global $kotlin.IndexOutOfBoundsException_rtti___g_66 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 420 + i32.const 25 + i32.const 17 + i64.const 8218141595550395280 + struct.new $RTTI___type_4) + (global $kotlin.IllegalStateException_rtti___g_67 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 520 + i32.const 21 + i32.const 20 + i64.const 2722369505687500671 + struct.new $RTTI___type_4) + (global $kotlin.ClassCastException_rtti___g_68 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 562 + i32.const 18 + i32.const 21 + i64.const 171180164838119449 + struct.new $RTTI___type_4) + (global $kotlin.NullPointerException_rtti___g_69 (ref $RTTI___type_4) + ref.null none + global.get $kotlin.RuntimeException_rtti___g_63 + i32.const 0 + i32.const 0 + i32.const 0 + i32.const 598 + i32.const 20 + i32.const 22 + i64.const -1226160245839178222 + struct.new $RTTI___type_4) + (export "box" (func $box__JsExportAdapter___fun_102)) + (export "memory" (memory $____mem_0)) + (export "_initialize" (func $_initialize___fun_111)) + (data "\4e\00\75\00\6d\00\62\00\65\00\72\00\43\00\6f\00\6d\00\70\00\61\00\6e\00\69\00\6f\00\6e\00\55\00\49\00\6e\00\74\00\41\00\6e\00\79\00\41\00\72\00\72\00\61\00\79\00\4e\00\65\00\67\00\61\00\74\00\69\00\76\00\65\00\20\00\61\00\72\00\72\00\61\00\79\00\20\00\73\00\69\00\7a\00\65\00\44\00\69\00\76\00\69\00\73\00\69\00\6f\00\6e\00\20\00\62\00\79\00\20\00\7a\00\65\00\72\00\6f\00\49\00\6e\00\74\00\53\00\74\00\72\00\69\00\6e\00\67\00\43\00\68\00\65\00\63\00\6b\00\20\00\66\00\61\00\69\00\6c\00\65\00\64\00\2e\00\54\00\68\00\72\00\6f\00\77\00\61\00\62\00\6c\00\65\00\4a\00\73\00\45\00\78\00\74\00\65\00\72\00\6e\00\61\00\6c\00\42\00\6f\00\78\00\4a\00\73\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\20\00\77\00\61\00\73\00\20\00\74\00\68\00\72\00\6f\00\77\00\6e\00\20\00\77\00\68\00\69\00\6c\00\65\00\20\00\72\00\75\00\6e\00\6e\00\69\00\6e\00\67\00\20\00\4a\00\61\00\76\00\61\00\53\00\63\00\72\00\69\00\70\00\74\00\20\00\63\00\6f\00\64\00\65\00\49\00\6c\00\6c\00\65\00\67\00\61\00\6c\00\41\00\72\00\67\00\75\00\6d\00\65\00\6e\00\74\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\41\00\72\00\69\00\74\00\68\00\6d\00\65\00\74\00\69\00\63\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\49\00\6e\00\64\00\65\00\78\00\4f\00\75\00\74\00\4f\00\66\00\42\00\6f\00\75\00\6e\00\64\00\73\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\52\00\75\00\6e\00\74\00\69\00\6d\00\65\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\49\00\6c\00\6c\00\65\00\67\00\61\00\6c\00\53\00\74\00\61\00\74\00\65\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\43\00\6c\00\61\00\73\00\73\00\43\00\61\00\73\00\74\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\4e\00\75\00\6c\00\6c\00\50\00\6f\00\69\00\6e\00\74\00\65\00\72\00\45\00\78\00\63\00\65\00\70\00\74\00\69\00\6f\00\6e\00\55\00\6e\00\69\00\74\00\50\00\6f\00\69\00\6e\00\74\00\65\00\72\00\4d\00\65\00\6d\00\6f\00\72\00\79\00\41\00\6c\00\6c\00\6f\00\63\00\61\00\74\00\6f\00\72\00\53\00\63\00\6f\00\70\00\65\00\64\00\4d\00\65\00\6d\00\6f\00\72\00\79\00\41\00\6c\00\6c\00\6f\00\63\00\61\00\74\00\6f\00\72\00\53\00\63\00\6f\00\70\00\65\00\64\00\4d\00\65\00\6d\00\6f\00\72\00\79\00\41\00\6c\00\6c\00\6f\00\63\00\61\00\74\00\6f\00\72\00\20\00\69\00\73\00\20\00\64\00\65\00\73\00\74\00\72\00\6f\00\79\00\65\00\64\00\20\00\77\00\68\00\65\00\6e\00\20\00\6f\00\75\00\74\00\20\00\6f\00\66\00\20\00\73\00\63\00\6f\00\70\00\65\00\53\00\63\00\6f\00\70\00\65\00\64\00\4d\00\65\00\6d\00\6f\00\72\00\79\00\41\00\6c\00\6c\00\6f\00\63\00\61\00\74\00\6f\00\72\00\20\00\69\00\73\00\20\00\73\00\75\00\73\00\70\00\65\00\6e\00\64\00\65\00\64\00\20\00\77\00\68\00\65\00\6e\00\20\00\6e\00\65\00\73\00\74\00\65\00\64\00\20\00\61\00\6c\00\6c\00\6f\00\63\00\61\00\74\00\6f\00\72\00\73\00\20\00\61\00\72\00\65\00\20\00\75\00\73\00\65\00\64\00\72\00\65\00\73\00\75\00\6c\00\74\00\20\00\6d\00\75\00\73\00\74\00\20\00\62\00\65\00\20\00\3e\00\3d\00\20\00\30\00\20\00\61\00\6e\00\64\00\20\00\38\00\2d\00\62\00\79\00\74\00\65\00\20\00\61\00\6c\00\69\00\67\00\6e\00\65\00\64\00\4f\00\75\00\74\00\20\00\6f\00\66\00\20\00\6c\00\69\00\6e\00\65\00\61\00\72\00\20\00\6d\00\65\00\6d\00\6f\00\72\00\79\00\2e\00\20\00\41\00\6c\00\6c\00\20\00\61\00\76\00\61\00\69\00\6c\00\61\00\62\00\6c\00\65\00\20\00\61\00\64\00\64\00\72\00\65\00\73\00\73\00\20\00\73\00\70\00\61\00\63\00\65\00\20\00\28\00\32\00\67\00\62\00\29\00\20\00\69\00\73\00\20\00\75\00\73\00\65\00\64\00\2e\00\4f\00\75\00\74\00\20\00\6f\00\66\00\20\00\6c\00\69\00\6e\00\65\00\61\00\72\00\20\00\6d\00\65\00\6d\00\6f\00\72\00\79\00\2e\00\20\00\6d\00\65\00\6d\00\6f\00\72\00\79\00\2e\00\67\00\72\00\6f\00\77\00\20\00\72\00\65\00\74\00\75\00\72\00\6e\00\65\00\64\00\20\00\2d\00\31\00\4f\00\4b\00\78\00\24\00\6c\00\61\00\6d\00\62\00\64\00\61\00\79\00\24\00\6c\00\61\00\6d\00\62\00\64\00\61\00") + (tag $____tag_0 (param (ref null $kotlin.Throwable___type_32)))) \ No newline at end of file diff --git a/JSTests/wasm/stress/wasm-gc-ref-cast.mjs b/JSTests/wasm/stress/wasm-gc-ref-cast.mjs new file mode 100644 index 000000000000..232c797d288d --- /dev/null +++ b/JSTests/wasm/stress/wasm-gc-ref-cast.mjs @@ -0,0 +1,139 @@ +//@ skip if !$isSIMDPlatform + +async function instantiate(imports={}, runInitializer=true) { + const cachedJsObjects = new WeakMap(); + // ref must be non-null + function getCachedJsObject(ref, ifNotCached) { + if (typeof ref !== 'object' && typeof ref !== 'function') return ifNotCached; + const cached = cachedJsObjects.get(ref); + if (cached !== void 0) return cached; + cachedJsObjects.set(ref, ifNotCached); + return ifNotCached; + } + + + + const js_code = { + 'kotlin.captureStackTrace' : () => new Error().stack, + 'kotlin.wasm.internal.throwJsError' : (message, wasmTypeName, stack) => { + const error = new Error(); + error.message = message; + error.name = wasmTypeName; + error.stack = stack; + throw error; + }, + 'kotlin.wasm.internal.stringLength' : (x) => x.length, + 'kotlin.wasm.internal.jsExportStringToWasm' : (src, srcOffset, srcLength, dstAddr) => { + const mem16 = new Uint16Array(wasmExports.memory.buffer, dstAddr, srcLength); + let arrayIndex = 0; + let srcIndex = srcOffset; + while (arrayIndex < srcLength) { + mem16.set([src.charCodeAt(srcIndex)], arrayIndex); + srcIndex++; + arrayIndex++; + } + }, + 'kotlin.wasm.internal.importStringFromWasm' : (address, length, prefix) => { + const mem16 = new Uint16Array(wasmExports.memory.buffer, address, length); + const str = String.fromCharCode.apply(null, mem16); + return (prefix == null) ? str : prefix + str; + }, + 'kotlin.wasm.internal.getJsEmptyString' : () => '', + 'kotlin.wasm.internal.isNullish' : (ref) => ref == null, + 'kotlin.wasm.internal.getCachedJsObject_$external_fun' : (p0, p1) => getCachedJsObject(p0, p1), + 'kotlin.js.stackPlaceHolder_js_code' : () => (''), + 'kotlin.js.message_$external_prop_getter' : (_this) => _this.message, + 'kotlin.js.stack_$external_prop_getter' : (_this) => _this.stack, + 'kotlin.js.JsError_$external_class_instanceof' : (x) => x instanceof Error + } + + // Placed here to give access to it from externals (js_code) + let wasmInstance; + let require; + let wasmExports; + + const isNodeJs = (typeof process !== 'undefined') && (process.release.name === 'node'); + const isDeno = !isNodeJs && (typeof Deno !== 'undefined') + const isStandaloneJsVM = + !isDeno && !isNodeJs && ( + typeof d8 !== 'undefined' // V8 + || typeof inIon !== 'undefined' // SpiderMonkey + || typeof jscOptions !== 'undefined' // JavaScriptCore + ); + const isBrowser = !isNodeJs && !isDeno && !isStandaloneJsVM && (typeof window !== 'undefined' || typeof self !== 'undefined'); + + if (!isNodeJs && !isDeno && !isStandaloneJsVM && !isBrowser) { + throw "Supported JS engine not detected"; + } + + const wasmFilePath = './resources/wasm-gc-ref-cast.wasm'; + const importObject = { + js_code, + intrinsics: { + + }, + + }; + + if (isNodeJs) { + const module = await import(/* webpackIgnore: true */'node:module'); + const importMeta = import.meta; + require = module.default.createRequire(importMeta.url); + const fs = require('fs'); + const url = require('url'); + const filepath = import.meta.resolve(wasmFilePath); + const wasmBuffer = fs.readFileSync(url.fileURLToPath(filepath)); + const wasmModule = new WebAssembly.Module(wasmBuffer); + wasmInstance = new WebAssembly.Instance(wasmModule, importObject); + } + + if (isDeno) { + const path = await import(/* webpackIgnore: true */'https://deno.land/std/path/mod.ts'); + const binary = Deno.readFileSync(path.fromFileUrl(import.meta.resolve(wasmFilePath))); + const module = await WebAssembly.compile(binary); + wasmInstance = await WebAssembly.instantiate(module, importObject); + } + + if (isStandaloneJsVM) { + const wasmBuffer = read(wasmFilePath, 'binary'); + const wasmModule = new WebAssembly.Module(wasmBuffer); + wasmInstance = new WebAssembly.Instance(wasmModule, importObject); + } + + if (isBrowser) { + wasmInstance = (await WebAssembly.instantiateStreaming(fetch(new URL('./resources/wasm-gc-ref-cast.wasm',import.meta.url).href), importObject)).instance; + } + + wasmExports = wasmInstance.exports; + if (runInitializer) { + wasmExports._initialize(); + } + + return { instance: wasmInstance, exports: wasmExports }; +} + +globalThis.console = { + log: print +}; + +if ($vm.useJIT()) { + let actualResult; + try { + let jsModule = (await instantiate({ + })).exports; + actualResult = jsModule.box(); + } catch(e) { + if (e instanceof WebAssembly.CompileError) { + actualResult = "OK"; + } else { + console.log('Failed with exception!') + console.log('Message: ' + e.message) + console.log('Name: ' + e.name) + console.log('Stack:') + console.log(e.stack) + } + } + + if (actualResult !== "OK") + throw `Wrong box result '${actualResult}'; Expected "OK"`; +} diff --git a/Source/JavaScriptCore/wasm/WasmFormat.h b/Source/JavaScriptCore/wasm/WasmFormat.h index dd0324929c01..724f97344de4 100644 --- a/Source/JavaScriptCore/wasm/WasmFormat.h +++ b/Source/JavaScriptCore/wasm/WasmFormat.h @@ -809,7 +809,7 @@ struct WasmToWasmImportableFunction : public WasmCallableFunction { // FIXME: Pack type index and code pointer into one 64-bit value. See . TypeIndex typeIndex { TypeDefinition::invalidIndex }; // Used when GC proposal is enabled, otherwise can be null. - const RTT* rtt; + const RTT* rtt { nullptr }; }; using FunctionIndexSpace = Vector; diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp index 927b2825befa..6f2808e52796 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator.cpp @@ -3764,12 +3764,7 @@ void OMGIRGenerator::emitCheckOrBranchForCast(CastKind kind, Value* condition, c Value* OMGIRGenerator::emitLoadRTTFromFuncref(Value* funcref) { - PatchpointValue* patch = m_currentBlock->appendNew(m_proc, B3::Int64, Origin()); - patch->append(funcref, ValueRep::SomeRegister); - patch->setGenerator([](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { - jit.loadCompactPtr(CCallHelpers::Address(params[1].gpr(), WebAssemblyFunctionBase::offsetOfRTT()), params[0].gpr()); - }); - return patch; + return m_currentBlock->appendNew(m_proc, B3::Load, pointerType(), origin(), funcref, safeCast(WebAssemblyFunctionBase::offsetOfRTT())); } Value* OMGIRGenerator::emitLoadRTTFromObject(Value* reference) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index aa483aece5a2..a02b02499c2c 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -4077,12 +4077,7 @@ void OMGIRGenerator::emitCheckOrBranchForCast(CastKind kind, Value* condition, c Value* OMGIRGenerator::emitLoadRTTFromFuncref(Value* funcref) { - PatchpointValue* patch = append(m_proc, B3::Int64, Origin()); - patch->append(funcref, ValueRep::SomeRegister); - patch->setGenerator([](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { - jit.loadCompactPtr(CCallHelpers::Address(params[1].gpr(), WebAssemblyFunctionBase::offsetOfRTT()), params[0].gpr()); - }); - return patch; + return m_currentBlock->appendNew(m_proc, B3::Load, pointerType(), origin(), funcref, safeCast(WebAssemblyFunctionBase::offsetOfRTT())); } Value* OMGIRGenerator::emitLoadRTTFromObject(Value* reference) From 0414456da840ccb90e6ff8f0c2940d588549369e Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Tue, 9 Sep 2025 09:41:36 -0700 Subject: [PATCH 47/54] [ARMv7] Store CallSiteIndex when throwing exceptions in OMG https://bugs.webkit.org/show_bug.cgi?id=298604 Reviewed by Justin Michaud. Bring in the missing bits from https://commits.webkit.org/289952@main. Canonical link: https://commits.webkit.org/299756@main (cherry picked from commit 45e6922943c71b908f8c6fde447ef5810b0cd1fe) --- .../wasm/WasmOMGIRGenerator32_64.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index a02b02499c2c..5779060495a1 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -1575,6 +1575,10 @@ void OMGIRGenerator::reloadMemoryRegistersFromInstance(const MemoryInformation& void OMGIRGenerator::emitExceptionCheck(CCallHelpers& jit, ExceptionType type) { jit.move(CCallHelpers::TrustedImm32(static_cast(type)), GPRInfo::argumentGPR1); + if (auto* omgOrigin = origin.omgOrigin()) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::argumentGPR2); + jit.store32(GPRInfo::argumentGPR2, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } jit.jumpThunk(CodeLocationLabel(Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator).code())); } @@ -4852,6 +4856,10 @@ auto OMGIRGenerator::addThrow(unsigned exceptionIndex, ArgumentList& args, Stack patch->setGenerator([this, exceptionIndex, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); + if (auto* omgOrigin = origin.omgOrigin()) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); + jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } emitThrowImpl(jit, exceptionIndex); }); m_currentBlock->append(patch); @@ -4883,6 +4891,10 @@ auto WARN_UNUSED_RETURN OMGIRGenerator::addThrowRef(ExpressionType exn, Stack&) patch->setGenerator([this, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); + if (auto* omgOrigin = origin.omgOrigin()) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); + jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } emitThrowRefImpl(jit); }); m_currentBlock->append(patch); @@ -4904,6 +4916,10 @@ auto OMGIRGenerator::addRethrow(unsigned, ControlType& data) -> PartialResult patch->setGenerator([this, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); + if (auto* omgOrigin = origin.omgOrigin()) { + jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); + jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + } emitThrowRefImpl(jit); }); m_currentBlock->append(patch); From 1bc5fe0affb5e4aaaf3a9d4788f3e7f32510c7a4 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Fri, 19 Sep 2025 04:52:33 -0700 Subject: [PATCH 48/54] [ARMv7] OMG: clarify where the inputs into try_table catch handler blocks come from https://bugs.webkit.org/show_bug.cgi?id=298536 Reviewed by Yusuke Suzuki. Bring in https://commits.webkit.org/297341@main. Canonical link: https://commits.webkit.org/300220@main (cherry picked from commit b627e177be18f30eda11738c43f6fa97ccfebdcb) --- .../wasm/WasmOMGIRGenerator32_64.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index 5779060495a1..b9589edcb50e 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -1024,7 +1024,7 @@ class OMGIRGenerator { Value* loadFromScratchBuffer(OSRBufferMode, unsigned& indexInBuffer, Value* pointer, B3::Type); void connectControlAtEntrypoint(OSRBufferMode, unsigned& indexInBuffer, Value* pointer, ControlData&, Stack& expressionStack, ControlData& currentData, bool fillLoopPhis = false); Value* emitCatchImpl(CatchKind, ControlType&, unsigned exceptionIndex = 0); - void emitCatchTableImpl(ControlData& entryData, const ControlData::TryTableTarget&, const Stack&); + void emitCatchTableImpl(ControlData& entryData, const ControlData::TryTableTarget&); PatchpointExceptionHandle preparePatchpointForExceptions(BasicBlock*, PatchpointValue*); Origin origin(); @@ -4732,7 +4732,7 @@ Value* OMGIRGenerator::emitCatchImpl(CatchKind kind, ControlType& data, unsigned return buffer; } -auto OMGIRGenerator::emitCatchTableImpl(ControlData& data, const ControlData::TryTableTarget& target, const Stack& stack) -> void +auto OMGIRGenerator::emitCatchTableImpl(ControlData& data, const ControlData::TryTableTarget& target) -> void { auto block = m_proc.addBlock(); m_rootBlocks.append(block); @@ -4786,8 +4786,8 @@ auto OMGIRGenerator::emitCatchTableImpl(ControlData& data, const ControlData::Tr connectControlAtEntrypoint(SplitI64, indexInBuffer, pointer, topControlData, topExpressionStack, data); } - auto newStack = stack; + Stack resultStack; if (target.type == CatchKind::Catch || target.type == CatchKind::CatchRef) { unsigned offset = 0; for (unsigned i = 0; i < signature->template as()->argumentCount(); ++i) { @@ -4795,7 +4795,7 @@ auto OMGIRGenerator::emitCatchTableImpl(ControlData& data, const ControlData::Tr Variable* var = m_proc.addVariable(toB3Type(type)); Value* value = append(heapTop(), m_proc, Load, toB3Type(type), origin(), buffer, offset * sizeof(uint64_t)); set(var, value); - newStack.constructAndAppend(type, var); + resultStack.constructAndAppend(type, var); offset += type.kind == TypeKind::V128 ? 2 : 1; } } @@ -4807,11 +4807,11 @@ auto OMGIRGenerator::emitCatchTableImpl(ControlData& data, const ControlData::Tr m_currentBlock->appendNew(m_proc, Origin(), JSValue::CellTag)); set(var, exceptionWithTag); push(exceptionWithTag); - newStack.constructAndAppend(Type { TypeKind::RefNull, static_cast(TypeKind::Exn) }, var); + resultStack.constructAndAppend(Type { TypeKind::RefNull, static_cast(TypeKind::Exn) }, var); } auto& targetControl = m_parser->resolveControlRef(target.target).controlData; - unifyValuesWithBlock(newStack, targetControl); + unifyValuesWithBlock(resultStack, targetControl); m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), FrequentedBlock(targetControl.targetBlockForBranch(), FrequencyClass::Normal)); targetControl.targetBlockForBranch()->addPredecessor(block); @@ -5101,7 +5101,7 @@ auto OMGIRGenerator::addEndToUnreachable(ControlEntry& entry, const Stack& expre data.endTryTable(advanceCallSiteIndex()); auto targets = data.m_tryTableTargets; for (auto& target : targets) - emitCatchTableImpl(data, target, expressionStack); + emitCatchTableImpl(data, target); --m_tryCatchDepth; } From fe2165d5f2ae70f89412c60b158cd6270cfd2537 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 8 Jul 2026 22:52:46 -0600 Subject: [PATCH 49/54] [ARMv7] Sync prepareForTailCallImpl with upstream's final pre-deletion state Function-level transplant of prepareForTailCallImpl from upstream 9f179c4476dd (the last change before OMG-ARMv7 was removed upstream), replacing our re-land-era copy. This incorporates, in one verifiable step: - 11eaa3910d44 ([JSC] Fix spilling macro scratch reg in OMG tail calls) - 9f179c4476dd (Size in bytes to clobber is not aligned on 32 bit OMGIRGenerator's prepareForTailCallImpl, bug 302776) - the prepareForTailCallImpl portions of d934b72704ab (bug 294413), notably restoring srcOffset from the tmp spill when clobbered. The enclosing patchpoint/caller block is byte-identical between our tree and upstream at that commit, so the function body is the entire delta. Adapted rawReturnPC() to this tree's rawReturnPCForInspection(). Co-Authored-By: Claude Fable 5 --- .../wasm/WasmOMGIRGenerator32_64.cpp | 285 ++++++++++-------- 1 file changed, 152 insertions(+), 133 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index b9589edcb50e..10302a5d2ad5 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -5243,58 +5243,95 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& auto& functionSignature = *signature.as(); const Checked offsetOfFirstSlotFromFP = WTF::roundUpToMultipleOf(wasmCallerInfoAsCallee.headerAndArgumentStackSizeInBytes); JIT_COMMENT(jit, "Set up tail call, new FP offset from FP: ", newFPOffsetFromFP); - AllowMacroScratchRegisterUsage allowScratch(jit); + + const unsigned frameSize = params.code().frameSize(); + ASSERT(WTF::roundUpToMultipleOf(frameSize + sizeof(CallerFrameAndPC)) == frameSize + sizeof(CallerFrameAndPC)); + + auto fpOffsetToSPOffset = [frameSize](int32_t offset) { + return checkedSum(safeCast(frameSize), offset).value(); + }; + + auto newReturnPCOffset = fpOffsetToSPOffset(checkedSum(CallFrame::returnPCOffset(), newFPOffsetFromFP).value()); + + // We requested some extra stack space below via requestCallArgAreaSize + // ... FP [initial safe area][caller stack space ] [callArgSpace ] SP ... + // becomes + // ... FP [safe area growing -> ] [danger ] [ scratch ] SP ... + // This scratch space sits at the very bottom of the stack, near sp. + // AirLowerStackArgs takes care of adding callArgSpace to our total caller frame size. + // BUT, even though we have this extra space, the new frame might be bigger, so we can't + // use the new frame as scratch. The new return pc represents the lowest offset from SP we can use. + int spillPointer = 0; + const int scratchAreaUpperBound = std::min( + safeCast(WTF::roundUpToMultipleOf(static_cast(wasmCalleeInfoAsCallee.headerAndArgumentStackSizeInBytes))), + newReturnPCOffset); + auto allocateSpill = [&] (Width width) -> int { + int offset = spillPointer; + spillPointer += bytesForWidth(width); + ASSERT(spillPointer <= scratchAreaUpperBound); + ASSERT(offset < scratchAreaUpperBound); + return offset; + }; + + RegisterAtOffsetList calleeSaves = params.code().calleeSaveRegisterAtOffsetList(); // Be careful not to clobber this below. // We also need to make sure that we preserve this if it is used by the patchpoint body. - bool clobbersTmp = false; + AllowMacroScratchRegisterUsage allowScratch(jit); auto tmp = jit.scratchRegister(); - int tmpSpill = 0; + bool tmpNeedsSaving = false; + int tmpSpillOffsetRelativeToOriginalSP = 0; // If we pass a stack location to the patchpoint in arugmentCountIncludingThis, preserve it here. bool stackPatchArg[tailCallPatchpointScratchCount] = { false, false }; int stackPatchArgSpill[tailCallPatchpointScratchCount] = { 0, 0 }; - // Set up a valid frame so that we can clobber this one. - RegisterAtOffsetList calleeSaves = params.code().calleeSaveRegisterAtOffsetList(); - jit.emitRestore(calleeSaves); - - for (unsigned i = 0; i < params.size(); ++i) { - auto arg = params[i]; - if (arg.isGPR()) { - ASSERT(!calleeSaves.find(arg.gpr())); - if (arg.gpr() == tmp) - clobbersTmp = true; - continue; - } - if (arg.isFPR()) { - ASSERT(!calleeSaves.find(arg.fpr())); - continue; - } - } + // Nothing before saving tmp can use the scratch register since it might clobber an input. + { + DisallowMacroScratchRegisterUsage disallowScratch(jit); - for (unsigned i = lastPatchArg; i < params.size(); ++i) { - auto arg = params[i]; - if (arg.isStack()) { - unsigned scratch = -1; - for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { - if (!stackPatchArg[i]) { - scratch = i; - break; - } + // Set up a valid frame so that we can clobber this one. + jit.emitRestore(calleeSaves); + + for (unsigned i = 0; i < params.size(); ++i) { + auto arg = params[i]; + if (arg.isGPR()) { + ASSERT(!calleeSaves.find(arg.gpr())); + if (arg.gpr() == tmp) + tmpNeedsSaving = true; + continue; } - ASSERT(scratch >= 0 && !stackPatchArg[scratch]); - stackPatchArg[scratch] = true; - if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebug([arg] (Probe::Context& context) { - dataLogLn("patch arg spill: ", RawHex(context.gpr(MacroAssembler::framePointerRegister)[arg.offsetFromFP() / sizeof(uintptr_t)])); - }); + if (arg.isFPR()) { + ASSERT(!calleeSaves.find(arg.fpr())); + continue; } - // A convinent and save place to stash it. - jit.transferPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, arg.offsetFromFP()), - CCallHelpers::Address(MacroAssembler::framePointerRegister, tailCallPatchpointScratchOffsets[scratch])); - } else - ASSERT(arg.isGPR() || arg.isFPR()); + } + + for (unsigned i = lastPatchArg; i < params.size(); ++i) { + auto arg = params[i]; + if (arg.isStack()) { + unsigned scratch = -1; + for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { + if (!stackPatchArg[i]) { + scratch = i; + break; + } + } + ASSERT(scratch >= 0 && !stackPatchArg[scratch]); + stackPatchArg[scratch] = true; + if (WasmOMGIRGeneratorInternal::verboseTailCalls) { + jit.probeDebug([arg] (Probe::Context& context) { + dataLogLn("patch arg spill: ", RawHex(context.gpr(MacroAssembler::framePointerRegister)[arg.offsetFromFP() / sizeof(uintptr_t)])); + }); + } + // A convinent and save place to stash it. + jit.transferPtr(CCallHelpers::Address(MacroAssembler::framePointerRegister, arg.offsetFromFP()), + CCallHelpers::Address(MacroAssembler::framePointerRegister, tailCallPatchpointScratchOffsets[scratch])); + } else + ASSERT(arg.isGPR() || arg.isFPR()); + } + + ASSERT(!calleeSaves.find(tmp) || !tmpNeedsSaving); } #if ASSERT_ENABLED @@ -5307,18 +5344,9 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } #endif - ASSERT(!calleeSaves.find(tmp) || !clobbersTmp); - - const unsigned frameSize = params.code().frameSize(); - ASSERT(WTF::roundUpToMultipleOf(frameSize + sizeof(CallerFrameAndPC)) == frameSize + sizeof(CallerFrameAndPC)); - - auto fpOffsetToSPOffset = [frameSize](int32_t offset) { - return checkedSum(safeCast(frameSize), offset).value(); - }; - JIT_COMMENT(jit, "Let's use the caller's frame, so that we always have a valid frame."); if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebug([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, signature = Ref(signature), wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, params, functionIndex] (Probe::Context& context) { + jit.probeDebugSIMD([frameSize, fpOffsetToSPOffset, newFPOffsetFromFP, signature = Ref(signature), wasmCalleeInfoAsCallee, firstPatchArg, lastPatchArg, params, functionIndex] (Probe::Context& context) { auto& functionSignature = *signature->as(); auto sp = context.gpr(MacroAssembler::stackPointerRegister); auto fp = context.gpr(GPRInfo::callFrameRegister); @@ -5378,31 +5406,9 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& }); } - auto newReturnPCOffset = fpOffsetToSPOffset(checkedSum(CallFrame::returnPCOffset(), newFPOffsetFromFP).value()); - JIT_COMMENT(jit, "Copy over args if needed into their final position, clobbering everything."); // This code has a bunch of overlap with CallFrameShuffler and Shuffle in Air/BBQ - // We requested some extra stack space below via requestCallArgAreaSize - // ... FP [initial safe area][caller stack space ] [callArgSpace ] SP ... - // becomes - // ... FP [safe area growing -> ] [danger ] [ scratch ] SP ... - // This scratch space sits at the very bottom of the stack, near sp. - // AirLowerStackArgs takes care of adding callArgSpace to our total caller frame size. - // BUT, even though we have this extra space, the new frame might be bigger, so we can't - // use the new frame as scratch. The new return pc represents the lowest offset from SP we can use. - int spillPointer = 0; - const int scratchAreaUpperBound = std::min( - safeCast(WTF::roundUpToMultipleOf(static_cast(wasmCalleeInfoAsCallee.headerAndArgumentStackSizeInBytes))), - newReturnPCOffset); - auto allocateSpill = [&] (Width width) -> int { - int offset = spillPointer; - spillPointer += bytesForWidth(width); - ASSERT(spillPointer <= scratchAreaUpperBound); - ASSERT(offset < scratchAreaUpperBound); - return offset; - }; - auto doMove = [&jit, tmp] (int srcOffset, int dstOffset, Width width) { JIT_COMMENT(jit, "Do move ", srcOffset, " -> ", dstOffset); auto src = CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset); @@ -5417,7 +5423,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& } if (WasmOMGIRGeneratorInternal::verboseTailCalls) { jit.loadPtr(dst, tmp); - jit.probeDebug([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { + jit.probeDebugSIMD([tmp, srcOffset, dstOffset, width] (Probe::Context& context) { auto val = context.gpr(tmp); auto sp = context.gpr(MacroAssembler::stackPointerRegister); dataLogLn("Move value ", val, " / ", RawHex(val), " at ", RawHex(sp + srcOffset), " -> ", RawHex(sp + dstOffset), " width ", width); @@ -5433,6 +5439,18 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& JIT_COMMENT(jit, "SP[", safeAreaLowerBound, "] to SP[", stackUpperBound, "] form the safe portion of the stack to clobber; Scratches go from SP[0] to SP[", scratchAreaUpperBound, "]."); + if (tmpNeedsSaving) { + tmpSpillOffsetRelativeToOriginalSP = allocateSpill(WidthPtr); + jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpillOffsetRelativeToOriginalSP)); + } + + for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { + if (stackPatchArg[i]) { + stackPatchArgSpill[i] = allocateSpill(WidthPtr); + jit.transferPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, fpOffsetToSPOffset(tailCallPatchpointScratchOffsets[i])), CCallHelpers::Address(MacroAssembler::stackPointerRegister, stackPatchArgSpill[i])); + } + } + #if ASSERT_ENABLED // Clobber all safe values to make debugging easier. for (int i = safeAreaLowerBound; i < stackUpperBound; i += sizeof(Register)) { @@ -5446,19 +5464,6 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& Vector> spillsToMove; argsToMove.reserveInitialCapacity(wasmCalleeInfoAsCallee.params.size() + 1); - if (clobbersTmp) { - tmpSpill = allocateSpill(WidthPtr); - jit.storePtr(tmp, CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpill)); - } - - - for (unsigned i = 0; i < tailCallPatchpointScratchCount; ++i) { - if (stackPatchArg[i]) { - stackPatchArgSpill[i] = allocateSpill(WidthPtr); - jit.transferPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, fpOffsetToSPOffset(tailCallPatchpointScratchOffsets[i])), CCallHelpers::Address(MacroAssembler::stackPointerRegister, stackPatchArgSpill[i])); - } - } - // We will complete those moves who's source is closest to the danger frontier first. // That will move the danger frontier. unsigned currentPatchArg = firstPatchArg; @@ -5478,9 +5483,12 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& continue; } - auto saveSrc = [tmp, dstType, &allocateSpill, &jit, &fpOffsetToSPOffset](ValueRep src) -> std::tuple { + auto saveSrc = [tmp, tmpNeedsSaving, tmpSpillOffsetRelativeToOriginalSP, dstType, &allocateSpill, &jit, &fpOffsetToSPOffset](ValueRep src) -> std::tuple { int srcOffset = 0; - if (src.isGPR()) { + if (tmpNeedsSaving && src.isGPR() && src.gpr() == tmp) { + // Before tmp may have been clobbered, it was spilled to tmpSpillOffsetRelativeToOriginalSP. + srcOffset = tmpSpillOffsetRelativeToOriginalSP; + } else if (src.isGPR()) { srcOffset = allocateSpill(WidthPtr); jit.storePtr(src.gpr(), CCallHelpers::Address(MacroAssembler::stackPointerRegister, srcOffset)); return { srcOffset, WidthPtr }; @@ -5547,11 +5555,9 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& argsToMove.append({ stackPatchArgSpill[i], fpOffsetToSPOffset(tailCallPatchpointScratchOffsets[i] + newFPOffsetFromFP), WidthPtr }); } - std::sort( - argsToMove.begin(), argsToMove.end(), - [] (const auto& left, const auto& right) { - return std::get<0>(left) > std::get<0>(right); - }); + std::ranges::sort(argsToMove, [](const auto& left, const auto& right) { + return std::get<0>(left) > std::get<0>(right); + }); for (unsigned i = 0; i < argsToMove.size(); ++i) { auto [srcOffset, dstOffset, width] = argsToMove[i]; @@ -5626,53 +5632,66 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& #endif #endif - jit.addPtr(MacroAssembler::TrustedImm32(newSPAtPrologueOffsetFromSP), MacroAssembler::stackPointerRegister); + if (tmpNeedsSaving) + jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpillOffsetRelativeToOriginalSP), tmp); + + // Nothing after restoring tmp can use the scratch register since it might clobber an input. + { + DisallowMacroScratchRegisterUsage disallowScratch(jit); + + jit.addPtr(MacroAssembler::TrustedImm32(newSPAtPrologueOffsetFromSP), MacroAssembler::stackPointerRegister); #if CPU(X86_64) - if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebugSIMD([] (Probe::Context& context) { - dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); - }); - } + if (WasmOMGIRGeneratorInternal::verboseTailCalls) { + jit.probeDebugSIMD([] (Probe::Context& context) { + dataLogLn("return pc on the top of the stack: ", RawHex(*context.gpr(MacroAssembler::stackPointerRegister)), " at ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + }); + } #endif + JIT_COMMENT(jit, "OK, now we can jump."); + if (WasmOMGIRGeneratorInternal::verboseTailCalls) { + jit.probeDebugSIMD([wasmCalleeInfoAsCallee] (Probe::Context& context) { + dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); + auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uintptr_t); + dataLogLn("New (callee) FP at prologue will be at ", RawPointer(newFP)); + auto fpl = std::bit_cast(newFP); + auto fpi = std::bit_cast(newFP); + + for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { + auto arg = wasmCalleeInfoAsCallee.params[i]; + auto src = arg.location; + dataLog("Arg ", i, " located at ", arg.location, " = "); + if (arg.location.isGPR()) { + dataLog(context.gpr(arg.location.jsr().payloadGPR()), " / ", (int) context.gpr(arg.location.jsr().payloadGPR())); + if (src.jsr().tagGPR()) + dataLog(" Upper bits: ", context.gpr(src.jsr().tagGPR()), " / ", (int) context.gpr(src.jsr().tagGPR())); + } else if (arg.location.isFPR() && arg.width <= Width::Width64) + dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::DontSaveVectors)); + else if (arg.location.isFPR()) + RELEASE_ASSERT_NOT_REACHED(); + else + dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(*fpi)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(*fpi)])); + dataLogLn(); + } + }); + } + #if ASSERT_ENABLED - for (unsigned i = 2; i < 50; ++i) { - // Everthing after sp might be overwritten anyway. - jit.storePtr(MacroAssembler::TrustedImm32(0xBFFF), CCallHelpers::Address(MacroAssembler::stackPointerRegister, -i * sizeof(uintptr_t))); - } + // Everything in the old stack might be overwritten anyway. Clobber for easier debugging. + if (tmpNeedsSaving) + jit.pushPair(tmp, tmp); + jit.move(MacroAssembler::TrustedImm32(0xBFFF), tmp); + constexpr int stackSlotsToClobber = 3 * stackAlignmentBytes(); + constexpr int stackBytesToClobber = stackSlotsToClobber * registerSize(); + static_assert(!(stackBytesToClobber & (stackAlignmentBytes() - 1)), "Size in bytes to clobber on stack is aligned"); + for (int i = 0; i < stackSlotsToClobber / 2; ++i) + jit.pushPair(tmp, tmp); + jit.addPtr(MacroAssembler::TrustedImm32(stackBytesToClobber), MacroAssembler::stackPointerRegister); + if (tmpNeedsSaving) + jit.popPair(tmp, tmp); #endif - - JIT_COMMENT(jit, "OK, now we can jump."); - if (WasmOMGIRGeneratorInternal::verboseTailCalls) { - jit.probeDebug([wasmCalleeInfoAsCallee] (Probe::Context& context) { - dataLogLn("Can now jump: FP: ", RawHex(context.gpr(GPRInfo::callFrameRegister)), " SP: ", RawHex(context.gpr(MacroAssembler::stackPointerRegister))); - auto* newFP = context.gpr(MacroAssembler::stackPointerRegister) - prologueStackPointerDelta() / sizeof(uintptr_t); - dataLogLn("New (callee) FP at prologue will be at ", RawPointer(newFP)); - auto fpl = std::bit_cast(newFP); - auto fpi = std::bit_cast(newFP); - - for (unsigned i = 0; i < wasmCalleeInfoAsCallee.params.size(); ++i) { - auto arg = wasmCalleeInfoAsCallee.params[i]; - auto src = arg.location; - dataLog("Arg ", i, " located at ", arg.location, " = "); - if (arg.location.isGPR()) { - dataLog(context.gpr(arg.location.jsr().payloadGPR()), " / ", (int) context.gpr(arg.location.jsr().payloadGPR())); - if (src.jsr().tagGPR()) - dataLog(" Upper bits: ", context.gpr(src.jsr().tagGPR()), " / ", (int) context.gpr(src.jsr().tagGPR())); - } else if (arg.location.isFPR() && arg.width <= Width::Width64) - dataLog(context.fpr(arg.location.fpr(), SavedFPWidth::DontSaveVectors)); - else if (arg.location.isFPR()) - RELEASE_ASSERT_NOT_REACHED(); - else - dataLog(fpl[src.offsetFromFP() / sizeof(*fpl)], " / ", fpi[src.offsetFromFP() / sizeof(*fpi)], " / ", RawHex(fpi[src.offsetFromFP() / sizeof(*fpi)]), " / ", std::bit_cast(fpl[src.offsetFromFP() / sizeof(*fpl)]), " at ", RawPointer(&fpi[src.offsetFromFP() / sizeof(*fpi)])); - dataLogLn(); - } - }); } - - if (clobbersTmp) - jit.loadPtr(CCallHelpers::Address(MacroAssembler::stackPointerRegister, tmpSpill), tmp); } // See also: https://leaningtech.com/fantastic-tail-calls-and-how-to-implement-them/, a blog post about contributing this feature. From 2afec45d66a325ea0cad3363405729062c1a894a Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 8 Jul 2026 22:54:53 -0600 Subject: [PATCH 50/54] [ARMv7] Load RTT values as pointer-typed in WasmOMGIRGenerator32_64 Hand-applied 32-bit adaptation of ed72fde9f3fb (Correctly load RTT in WasmOMGIRGenerator32_64.cpp, bug 291513), required for coherence after taking f63d69092df2: emitLoadRTTFromFuncref now returns pointerType(), so emitLoadRTTFromObject must too (its RefPtr field is one pointer wide; the old code loaded 8 bytes as Types::Ref and truncated), and the shared use sites must stop wrapping rtt in truncate(), which is malformed B3 on an Int32 input. Co-Authored-By: Claude Fable 5 --- Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index 10302a5d2ad5..21ce52a6fe85 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -3993,7 +3993,7 @@ void OMGIRGenerator::emitRefTestOrCast(CastKind castKind, ExpressionType referen Value* jsType = append(heapTop(), m_proc, Load8Z, Int32, origin(), truncate(get(reference)), safeCast(JSCell::typeInfoTypeOffset())); emitCheckOrBranchForCast(castKind, append(m_proc, NotEqual, origin(), jsType, constant(Int32, JSType::WebAssemblyGCObjectType)), castFailure, falseBlock); Value* rtt = emitLoadRTTFromObject(truncate(get(reference))); - emitCheckOrBranchForCast(castKind, emitNotRTTKind(truncate(rtt), static_cast(heapType) == Wasm::TypeKind::Arrayref ? RTTKind::Array : RTTKind::Struct), castFailure, falseBlock); + emitCheckOrBranchForCast(castKind, emitNotRTTKind(rtt, static_cast(heapType) == Wasm::TypeKind::Arrayref ? RTTKind::Array : RTTKind::Struct), castFailure, falseBlock); break; } default: @@ -4013,12 +4013,12 @@ void OMGIRGenerator::emitRefTestOrCast(CastKind castKind, ExpressionType referen Value* jsType = append(heapTop(), m_proc, Load8Z, Int32, origin(), truncate(get(reference)), safeCast(JSCell::typeInfoTypeOffset())); emitCheckOrBranchForCast(castKind, append(m_proc, NotEqual, origin(), jsType, constant(Int32, JSType::WebAssemblyGCObjectType)), castFailure, falseBlock); rtt = emitLoadRTTFromObject(truncate(get(reference))); - emitCheckOrBranchForCast(castKind, emitNotRTTKind(truncate(rtt), signature.expand().is() ? RTTKind::Array : RTTKind::Struct), castFailure, falseBlock); + emitCheckOrBranchForCast(castKind, emitNotRTTKind(rtt, signature.expand().is() ? RTTKind::Array : RTTKind::Struct), castFailure, falseBlock); } Value* targetRTT = append(m_proc, origin(), m_info.rtts[heapType].get()); Value* rttsAreEqual = append(m_proc, Equal, origin(), - truncate(rtt), targetRTT); + rtt, targetRTT); BasicBlock* equalBlock; if (castKind == CastKind::Cast) equalBlock = continuation; @@ -4033,7 +4033,7 @@ void OMGIRGenerator::emitRefTestOrCast(CastKind castKind, ExpressionType referen // FIXME: It may be worthwhile to JIT inline this in the future. Value* isSubRTT = append(m_proc, B3::Int32, origin(), append(m_proc, origin(), tagCFunction(operationWasmIsSubRTT)), - truncate(rtt), targetRTT); + rtt, targetRTT); emitCheckOrBranchForCast(castKind, append(m_proc, Equal, origin(), isSubRTT, constant(Int32, 0)), castFailure, falseBlock); } @@ -4086,7 +4086,7 @@ Value* OMGIRGenerator::emitLoadRTTFromFuncref(Value* funcref) Value* OMGIRGenerator::emitLoadRTTFromObject(Value* reference) { - return append(heapTop(), m_proc, B3::Load, toB3Type(Types::Ref), origin(), reference, safeCast(WebAssemblyGCObjectBase::offsetOfRTT())); + return append(heapTop(), m_proc, B3::Load, pointerType(), origin(), reference, safeCast(WebAssemblyGCObjectBase::offsetOfRTT())); } Value* OMGIRGenerator::emitNotRTTKind(Value* rtt, RTTKind targetKind) From ed5806c5f4850191ff9b306a99affd562025c26f Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Wed, 8 Jul 2026 23:07:56 -0600 Subject: [PATCH 51/54] [ARMv7] Complete the no-stored-call-site-index conversion for OMG exception checks Finish what 287138@main (Do not use stored call-site-index for OMG) did for the shared generator: emitExceptionCheck now takes the B3::Origin, stores the OMGOrigin's CallSiteIndex at trap sites (this tree's bit_cast-of-Origin::data idiom, matching WasmOMGIRGenerator.cpp), and every generator lambda captures origin = this->origin() at emission time. Also add the missing DisallowMacroScratchRegisterUsage.h include needed by the synced prepareForTailCallImpl and adopt the returnPCForInspection() spelling. Co-Authored-By: Claude Fable 5 --- .../wasm/WasmOMGIRGenerator32_64.cpp | 237 +++++++++--------- 1 file changed, 119 insertions(+), 118 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index 21ce52a6fe85..c137a0542d69 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -30,6 +30,7 @@ #include "AirCode.h" #include "AllowMacroScratchRegisterUsageIf.h" +#include "DisallowMacroScratchRegisterUsage.h" #include "B3BasicBlockInlines.h" #include "B3CCallValue.h" #include "B3Const128Value.h" @@ -976,7 +977,7 @@ class OMGIRGenerator { return append(block, m_proc, resultType, origin(), operationValue, std::forward(args)...); } - void emitExceptionCheck(CCallHelpers&, ExceptionType); + void emitExceptionCheck(CCallHelpers&, Origin, ExceptionType); void emitWriteBarrierForJSWrapper(); void emitWriteBarrier(Value* cell, Value* instanceCell); @@ -1290,7 +1291,7 @@ void OMGIRGenerator::restoreWasmContextInstance(BasicBlock* block, Value* arg) patchpoint->effects = effects; patchpoint->clobberLate(RegisterSetBuilder(GPRInfo::wasmContextInstancePointer)); patchpoint->append(arg, ValueRep::SomeRegister); - patchpoint->setGenerator([](CCallHelpers& jit, const StackmapGenerationParams& param) { + patchpoint->setGenerator([, origin = this->origin()](CCallHelpers& jit, const StackmapGenerationParams& param) { jit.move(param[0].gpr(), GPRInfo::wasmContextInstancePointer); }); } @@ -1409,7 +1410,7 @@ OMGIRGenerator::OMGIRGenerator(CompilationContext& context, CalleeGroup& calleeG ASSERT_UNUSED(pinnedGPR, InvalidGPRReg == pinnedGPR); break; } - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -1558,7 +1559,7 @@ void OMGIRGenerator::reloadMemoryRegistersFromInstance(const MemoryInformation& patchpoint->numGPScratchRegisters = 1; patchpoint->append(instance, ValueRep::SomeRegister); - patchpoint->setGenerator([](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patchpoint->setGenerator([, origin = this->origin()](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); GPRReg scratch = params.gpScratch(0); jit.loadPairPtr(params[0].gpr(), CCallHelpers::TrustedImm32(JSWebAssemblyInstance::offsetOfCachedMemory()), GPRInfo::wasmBaseMemoryPointer, GPRInfo::wasmBoundsCheckingSizeRegister); @@ -1572,10 +1573,10 @@ void OMGIRGenerator::reloadMemoryRegistersFromInstance(const MemoryInformation& #endif // OMG_JSVALUE_32_64_PINNED_MEMORY_REGISTERS } -void OMGIRGenerator::emitExceptionCheck(CCallHelpers& jit, ExceptionType type) +void OMGIRGenerator::emitExceptionCheck(CCallHelpers& jit, Origin origin, ExceptionType type) { jit.move(CCallHelpers::TrustedImm32(static_cast(type)), GPRInfo::argumentGPR1); - if (auto* omgOrigin = origin.omgOrigin()) { + if (auto* omgOrigin = std::bit_cast(origin.data())) { jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::argumentGPR2); jit.store32(GPRInfo::argumentGPR2, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); } @@ -1840,8 +1841,8 @@ auto OMGIRGenerator::addTableGet(unsigned tableIndex, ExpressionType index, Expr CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1857,8 +1858,8 @@ auto OMGIRGenerator::addTableSet(unsigned tableIndex, ExpressionType index, Expr CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), shouldThrow, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1880,8 +1881,8 @@ auto OMGIRGenerator::addRefAsNonNull(ExpressionType reference, ExpressionType& r { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), get(reference), append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullRefAsNonNull); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullRefAsNonNull); }); } return { }; @@ -1904,8 +1905,8 @@ auto OMGIRGenerator::addTableInit(unsigned elementIndex, unsigned tableIndex, Ex CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1947,8 +1948,8 @@ auto OMGIRGenerator::addTableFill(unsigned tableIndex, ExpressionType offset, Ex CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1968,8 +1969,8 @@ auto OMGIRGenerator::addTableCopy(unsigned dstTableIndex, unsigned srcTableIndex CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTableAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTableAccess); }); } @@ -1987,8 +1988,8 @@ auto OMGIRGenerator::getLocal(uint32_t index, ExpressionType& result) -> Partial auto OMGIRGenerator::addUnreachable() -> PartialResult { B3::PatchpointValue* unreachable = append(m_proc, B3::Void, origin()); - unreachable->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::Unreachable); + unreachable->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::Unreachable); }); unreachable->effects.terminal = true; return { }; @@ -2220,8 +2221,8 @@ auto OMGIRGenerator::addMemoryFill(ExpressionType dstAddress, ExpressionType tar CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -2239,8 +2240,8 @@ auto OMGIRGenerator::addMemoryInit(unsigned dataSegmentIndex, ExpressionType dst CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -2257,8 +2258,8 @@ auto OMGIRGenerator::addMemoryCopy(ExpressionType dstAddress, ExpressionType src CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -2557,15 +2558,15 @@ inline Value* OMGIRGenerator::emitCheckAndPreparePointer(Value* pointer, uint32_ Value* highestAccess = append(m_proc, Add, origin(), pointerPlusOffset, sizeValue); // Test that we didn't overflow. CheckValue* checkOverflow = append(m_proc, Check, origin(), append(m_proc, AboveEqual, origin(), pointer, highestAccess)); - checkOverflow->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + checkOverflow->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); // Test that we're within bounds. Value* boundsCheckingSize = append(heapTop(), m_proc, Load, Int32, origin(), instanceValue(), safeCast(JSWebAssemblyInstance::offsetOfCachedBoundsCheckingSize())); Value* isWithinBounds = append(m_proc, Above, origin(), highestAccess, boundsCheckingSize); CheckValue* checkBounds = append(m_proc, Check, origin(), isWithinBounds); - checkBounds->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + checkBounds->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); break; } @@ -2694,8 +2695,8 @@ auto OMGIRGenerator::load(LoadOpType op, ExpressionType pointerVar, ExpressionTy // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = append(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (op) { @@ -2794,8 +2795,8 @@ auto OMGIRGenerator::store(StoreOpType op, ExpressionType pointerVar, Expression // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = append(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } else emitStoreOp(op, emitCheckAndPreparePointer(pointer, offset, sizeOfStoreOp(op)), value, offset); @@ -2847,8 +2848,8 @@ Value* OMGIRGenerator::fixupPointerPlusOffsetForAtomicOps(ExtAtomicOpType op, Va if (accessWidth(op) != Width8) { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, BitAnd, origin(), pointer, constant(pointerType(), sizeOfAtomicOpMemoryAccess(op) - 1))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::UnalignedMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::UnalignedMemoryAccess); }); } return pointer; @@ -2884,8 +2885,8 @@ auto OMGIRGenerator::atomicLoad(ExtAtomicOpType op, Type valueType, ExpressionTy // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = append(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (valueType.kind) { @@ -2922,8 +2923,8 @@ auto OMGIRGenerator::atomicStore(ExtAtomicOpType op, Type valueType, ExpressionT // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = append(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } else emitAtomicStoreOp(op, valueType, emitCheckAndPreparePointer(get(pointer), offset, sizeOfAtomicOpMemoryAccess(op)), get(value), offset); @@ -3010,8 +3011,8 @@ auto OMGIRGenerator::atomicBinaryRMW(ExtAtomicOpType op, Type valueType, Express // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = append(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (valueType.kind) { @@ -3123,8 +3124,8 @@ auto OMGIRGenerator::atomicCompareExchange(ExtAtomicOpType op, Type valueType, E // FIXME: Even though this is provably out of bounds, it's not a validation error, so we have to handle it // as a runtime exception. However, this may change: https://bugs.webkit.org/show_bug.cgi?id=166435 B3::PatchpointValue* throwException = append(m_proc, B3::Void, origin()); - throwException->setGenerator([this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + throwException->setGenerator([this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); switch (valueType.kind) { @@ -3163,8 +3164,8 @@ auto OMGIRGenerator::atomicWait(ExtAtomicOpType op, ExpressionType pointerVar, E CheckValue* check = append(m_proc, Check, origin(), append(m_proc, LessThan, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -3180,8 +3181,8 @@ auto OMGIRGenerator::atomicNotify(ExtAtomicOpType, ExpressionType pointer, Expre CheckValue* check = append(m_proc, Check, origin(), append(m_proc, LessThan, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -3337,8 +3338,8 @@ auto OMGIRGenerator::addI31GetS(ExpressionType ref, ExpressionType& result) -> P { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), get(ref), append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullI31Get); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullI31Get); }); } @@ -3353,8 +3354,8 @@ auto OMGIRGenerator::addI31GetU(ExpressionType ref, ExpressionType& result) -> P { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), get(ref), append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullI31Get); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullI31Get); }); } @@ -3380,8 +3381,8 @@ Variable* OMGIRGenerator::pushArrayNew(uint32_t typeIndex, Value* initValue, Exp CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadArrayNew); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadArrayNew); }); } @@ -3509,8 +3510,8 @@ auto OMGIRGenerator::addArrayGet(ExtGCOpType arrayGetKind, uint32_t typeIndex, E { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), get(arrayref), append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullArrayGet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullArrayGet); }); } @@ -3520,8 +3521,8 @@ auto OMGIRGenerator::addArrayGet(ExtGCOpType arrayGetKind, uint32_t typeIndex, E { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, AboveEqual, origin(), get(index), arraySize)); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayGet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayGet); }); } @@ -3571,8 +3572,8 @@ void OMGIRGenerator::emitArrayNullCheck(Value* arrayref, ExceptionType exception { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), arrayref, append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, exceptionType); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, exceptionType); }); } @@ -3626,8 +3627,8 @@ auto OMGIRGenerator::addArraySet(uint32_t typeIndex, ExpressionType arrayref, Ex { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, AboveEqual, origin(), get(index), arraySize)); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArraySet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArraySet); }); } @@ -3642,8 +3643,8 @@ auto OMGIRGenerator::addArrayLen(ExpressionType arrayref, ExpressionType& result { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), get(arrayref), append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullArrayLen); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullArrayLen); }); } @@ -3673,8 +3674,8 @@ auto OMGIRGenerator::addArrayFill(uint32_t typeIndex, ExpressionType arrayref, E CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayFill); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayFill); }); } @@ -3696,8 +3697,8 @@ auto OMGIRGenerator::addArrayCopy(uint32_t, ExpressionType dst, ExpressionType d CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayCopy); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayCopy); }); } @@ -3718,8 +3719,8 @@ auto OMGIRGenerator::addArrayInitElem(uint32_t, ExpressionType dst, ExpressionTy CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayInitElem); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayInitElem); }); } @@ -3740,8 +3741,8 @@ auto OMGIRGenerator::addArrayInitData(uint32_t, ExpressionType dst, ExpressionTy CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), resultValue, append(m_proc, origin(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsArrayInitData); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsArrayInitData); }); } @@ -3761,8 +3762,8 @@ auto OMGIRGenerator::addStructNew(uint32_t typeIndex, ArgumentList& args, Expres { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), structValue, append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadStructNew); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadStructNew); }); } @@ -3788,8 +3789,8 @@ auto OMGIRGenerator::addStructNewDefault(uint32_t typeIndex, ExpressionType& res { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), structValue, append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadStructNew); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadStructNew); }); } @@ -3818,8 +3819,8 @@ auto OMGIRGenerator::addStructGet(ExtGCOpType structGetKind, ExpressionType stru { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), get(structReference), append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullStructGet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullStructGet); }); } @@ -3865,8 +3866,8 @@ auto OMGIRGenerator::addStructSet(ExpressionType structReference, const StructTy { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), get(structReference), append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullStructSet); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullStructSet); }); } @@ -3900,7 +3901,7 @@ void OMGIRGenerator::emitRefTestOrCast(CastKind castKind, ExpressionType referen } auto castFailure = [this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::CastFailure); + this->emitExceptionCheck(jit, origin, ExceptionType::CastFailure); }; // Ensure reference nullness agrees with heap type. @@ -4853,10 +4854,10 @@ auto OMGIRGenerator::addThrow(unsigned exceptionIndex, ArgumentList& args, Stack m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, offset); patch->clobber(RegisterSetBuilder::registersToSaveForJSCall(m_proc.usesSIMD() ? RegisterSetBuilder::allRegisters() : RegisterSetBuilder::allScalarRegisters())); PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); - patch->setGenerator([this, exceptionIndex, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patch->setGenerator([this, exceptionIndex, handle, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); - if (auto* omgOrigin = origin.omgOrigin()) { + if (auto* omgOrigin = std::bit_cast(origin.data())) { jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); } @@ -4884,14 +4885,14 @@ auto WARN_UNUSED_RETURN OMGIRGenerator::addThrowRef(ExpressionType exn, Stack&) CheckValue* check = m_currentBlock->appendNew(m_proc, Check, origin(), m_currentBlock->appendNew(m_proc, Equal, origin(), exception, constant(Wasm::toB3Type(exnrefType()), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullExnReference); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullExnReference); }); PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); - patch->setGenerator([this, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patch->setGenerator([this, handle, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); - if (auto* omgOrigin = origin.omgOrigin()) { + if (auto* omgOrigin = std::bit_cast(origin.data())) { jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); } @@ -4913,10 +4914,10 @@ auto OMGIRGenerator::addRethrow(unsigned, ControlType& data) -> PartialResult patch->append(exception, ValueRep::reg(GPRInfo::argumentGPR2)); patch->append(constant(Int32, JSValue::CellTag), ValueRep::reg(GPRInfo::argumentGPR3)); PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); - patch->setGenerator([this, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patch->setGenerator([this, handle, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); handle.generate(jit, params, this); - if (auto* omgOrigin = origin.omgOrigin()) { + if (auto* omgOrigin = std::bit_cast(origin.data())) { jit.move(CCallHelpers::TrustedImm32(omgOrigin->m_callSiteIndex.bits()), GPRInfo::nonPreservedNonArgumentGPR0); jit.store32(GPRInfo::nonPreservedNonArgumentGPR0, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); } @@ -5356,7 +5357,7 @@ static inline void prepareForTailCallImpl(unsigned functionIndex, CCallHelpers& dataLogLn("callee original: ", RawPointer(fpp->callee().rawPtr())); auto& wasmCallee = context.gpr(GPRInfo::callFrameRegister)[CallFrameSlot::callee * 1]; dataLogLn("callee original: ", RawHex(wasmCallee), " at ", RawPointer(&wasmCallee)); - dataLogLn("retPC original: ", RawPointer(fpp->rawReturnPCForInspection())); + dataLogLn("retPC original: ", RawPointer(fpp->returnPCForInspection())); auto& retPC = context.gpr(GPRInfo::callFrameRegister)[CallFrame::returnPCOffset() / sizeof(uint64_t)]; dataLogLn("retPC original: ", RawHex(retPC), " at ", RawPointer(&retPC)); dataLogLn("callerFrame original: ", RawPointer(fpp->callerFrame())); @@ -6118,8 +6119,8 @@ auto OMGIRGenerator::addCallIndirect(unsigned tableIndex, const TypeDefinition& CheckValue* check = append(m_proc, Check, origin(), append(m_proc, AboveEqual, origin(), calleeIndex, callableFunctionBufferLength)); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsCallIndirect); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsCallIndirect); }); } @@ -6148,8 +6149,8 @@ auto OMGIRGenerator::addCallIndirect(unsigned tableIndex, const TypeDefinition& CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), calleeSignatureIndex, constant(pointerType(), 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullTableEntry); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullTableEntry); }); } @@ -6193,8 +6194,8 @@ auto OMGIRGenerator::addCallIndirect(unsigned tableIndex, const TypeDefinition& m_currentBlock = throwBlock; B3::PatchpointValue* throwException = append(m_proc, B3::Void, origin()); - throwException->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::BadSignature); + throwException->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::BadSignature); }); throwException->effects.terminal = true; @@ -6220,8 +6221,8 @@ auto OMGIRGenerator::addCallRef(const TypeDefinition& originalSignature, Argumen { CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), callee, append(m_proc, origin(), JSValue::encode(jsNull())))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::NullReference); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::NullReference); }); } @@ -6404,8 +6405,8 @@ void OMGIRGenerator::emitChecksForModOrDiv(B3::Opcode operation, Value* left, Va CheckValue* check = append(m_proc, Check, origin(), append(m_proc, Equal, origin(), right, constant(type, 0))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::DivisionByZero); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::DivisionByZero); }); } @@ -6417,8 +6418,8 @@ void OMGIRGenerator::emitChecksForModOrDiv(B3::Opcode operation, Value* left, Va append(m_proc, Equal, origin(), left, constant(type, min)), append(m_proc, Equal, origin(), right, constant(type, -1)))); - check->setGenerator([=, this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::IntegerOverflow); + check->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::IntegerOverflow); }); } } @@ -6661,8 +6662,8 @@ auto OMGIRGenerator::addI32TruncSF64(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = append(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6684,8 +6685,8 @@ auto OMGIRGenerator::addI32TruncSF32(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterEqual, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = append(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6708,8 +6709,8 @@ auto OMGIRGenerator::addI32TruncUF64(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = append(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6731,8 +6732,8 @@ auto OMGIRGenerator::addI32TruncUF32(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); PatchpointValue* patchpoint = append(m_proc, Int32, origin()); patchpoint->append(arg, ValueRep::SomeRegister); @@ -6754,8 +6755,8 @@ auto OMGIRGenerator::addI64TruncSF64(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterEqual, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); Value* call = append(m_proc, B3::Int64, origin(), append(m_proc, origin(), tagCFunction(Math::i64_trunc_s_f64)), @@ -6774,8 +6775,8 @@ auto OMGIRGenerator::addI64TruncUF64(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); Value* call = append(m_proc, B3::Int64, origin(), @@ -6795,8 +6796,8 @@ auto OMGIRGenerator::addI64TruncSF32(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterEqual, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); Value* call = append(m_proc, B3::Int64, origin(), append(m_proc, origin(), tagCFunction(Math::i64_trunc_s_f32)), @@ -6815,8 +6816,8 @@ auto OMGIRGenerator::addI64TruncUF32(ExpressionType argVar, ExpressionType& resu append(m_proc, GreaterThan, origin(), arg, min)); outOfBounds = append(m_proc, Equal, origin(), outOfBounds, constant(Int32, 0)); CheckValue* trap = append(m_proc, Check, origin(), outOfBounds); - trap->setGenerator([=, this] (CCallHelpers& jit, const StackmapGenerationParams&) { - this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsTrunc); + trap->setGenerator([=, this, origin = this->origin()] (CCallHelpers& jit, const StackmapGenerationParams&) { + this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsTrunc); }); Value* call = append(m_proc, B3::Int64, origin(), From c1c904375164d3be1c109453458471dc862bc2b2 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Thu, 9 Jul 2026 07:47:35 -0600 Subject: [PATCH 52/54] [ARMv7] Fix up exception-origin conversion in non-setGenerator lambdas Follow-up to the previous commit's mechanical transform, which only injected the origin init-capture into setGenerator([...]) lambdas: - restoreWasmContextInstance / memory-cage patchpoints: revert the spurious (and malformed, [,...]) capture injection; those bodies do not use origin. - setWasmBoundsCheckGenerator: name the WasmBoundsCheckValue parameter and use originValue->origin(), matching WasmOMGIRGenerator.cpp. - castFailure plain lambda: capture origin = this->origin(). Co-Authored-By: Claude Fable 5 --- Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index c137a0542d69..be93ea0bf317 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -1291,7 +1291,7 @@ void OMGIRGenerator::restoreWasmContextInstance(BasicBlock* block, Value* arg) patchpoint->effects = effects; patchpoint->clobberLate(RegisterSetBuilder(GPRInfo::wasmContextInstancePointer)); patchpoint->append(arg, ValueRep::SomeRegister); - patchpoint->setGenerator([, origin = this->origin()](CCallHelpers& jit, const StackmapGenerationParams& param) { + patchpoint->setGenerator([](CCallHelpers& jit, const StackmapGenerationParams& param) { jit.move(param[0].gpr(), GPRInfo::wasmContextInstancePointer); }); } @@ -1400,7 +1400,7 @@ OMGIRGenerator::OMGIRGenerator(CompilationContext& context, CalleeGroup& calleeG m_proc.pinRegister(GPRInfo::wasmBoundsCheckingSizeRegister); #endif if (info.memory) { - m_proc.setWasmBoundsCheckGenerator([=, this](CCallHelpers& jit, WasmBoundsCheckValue*, GPRReg pinnedGPR) { + m_proc.setWasmBoundsCheckGenerator([=, this](CCallHelpers& jit, WasmBoundsCheckValue* originValue, GPRReg pinnedGPR) { AllowMacroScratchRegisterUsage allowScratch(jit); switch (m_mode) { case MemoryMode::BoundsChecking: @@ -1410,7 +1410,7 @@ OMGIRGenerator::OMGIRGenerator(CompilationContext& context, CalleeGroup& calleeG ASSERT_UNUSED(pinnedGPR, InvalidGPRReg == pinnedGPR); break; } - this->emitExceptionCheck(jit, origin, ExceptionType::OutOfBoundsMemoryAccess); + this->emitExceptionCheck(jit, originValue->origin(), ExceptionType::OutOfBoundsMemoryAccess); }); } @@ -1559,7 +1559,7 @@ void OMGIRGenerator::reloadMemoryRegistersFromInstance(const MemoryInformation& patchpoint->numGPScratchRegisters = 1; patchpoint->append(instance, ValueRep::SomeRegister); - patchpoint->setGenerator([, origin = this->origin()](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { + patchpoint->setGenerator([](CCallHelpers& jit, const B3::StackmapGenerationParams& params) { AllowMacroScratchRegisterUsage allowScratch(jit); GPRReg scratch = params.gpScratch(0); jit.loadPairPtr(params[0].gpr(), CCallHelpers::TrustedImm32(JSWebAssemblyInstance::offsetOfCachedMemory()), GPRInfo::wasmBaseMemoryPointer, GPRInfo::wasmBoundsCheckingSizeRegister); @@ -3900,7 +3900,7 @@ void OMGIRGenerator::emitRefTestOrCast(CastKind castKind, ExpressionType referen falseBlock = m_proc.addBlock(); } - auto castFailure = [this] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { + auto castFailure = [this, origin = this->origin()] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { this->emitExceptionCheck(jit, origin, ExceptionType::CastFailure); }; From 54dc7795477f9bcf32d481a5fb1425936ccd2a91 Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Thu, 9 Jul 2026 07:57:29 -0600 Subject: [PATCH 53/54] [ARMv7] Include JSCJSValueInlines.h in WasmFaultSignalHandler for non-unified builds 287138@main's signal handler recovers the instance with jsSecureCast, which needs the inline JSCell::type(). Upstream relies on unified builds to supply it; under --no-unified-builds the definition is absent and the executable link fails with an undefined reference to JSC::JSCell::type(). Include the inlines header the way sibling wasm translation units do. Co-Authored-By: Claude Fable 5 --- Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp b/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp index 7114b819f92f..8cf9d1579aa9 100644 --- a/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp +++ b/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp @@ -29,6 +29,7 @@ #if ENABLE(WEBASSEMBLY) #include "ExecutableAllocator.h" +#include "JSCJSValueInlines.h" #include "JSWebAssemblyInstance.h" #include "LLIntData.h" #include "MachineContext.h" From 3cfae844d820ac922f85886816b9328449b3919f Mon Sep 17 00:00:00 2001 From: Justin Michaud Date: Fri, 10 Jul 2026 15:10:50 -0600 Subject: [PATCH 54/54] Wasm OMG + BBQ fixes Here are some minor workarounds for some crashes and hangs on 32-bit. I have also included a js3 cli wrapper with a subset of the tests that should work fine on 32-bit. This still needs to be reviewed, but should help with testing in the meantime. --- .../stress/bbq-i64-unaligned-load-store.js | 29 ++++++++ JSTests/wasm/stress/omg-array-new-i32-init.js | 31 ++++++++ PerformanceTests/JetStream3/js3-cli.js | 1 + PerformanceTests/JetStream3/js3-nosimd.js | 1 + .../assembler/MacroAssemblerARMv7.h | 26 ++----- Source/JavaScriptCore/wasm/WasmBBQJIT.cpp | 72 ++++++++++++------- .../wasm/WasmOMGIRGenerator32_64.cpp | 8 +-- 7 files changed, 118 insertions(+), 50 deletions(-) create mode 100644 JSTests/wasm/stress/bbq-i64-unaligned-load-store.js create mode 100644 JSTests/wasm/stress/omg-array-new-i32-init.js create mode 100644 PerformanceTests/JetStream3/js3-cli.js create mode 100644 PerformanceTests/JetStream3/js3-nosimd.js diff --git a/JSTests/wasm/stress/bbq-i64-unaligned-load-store.js b/JSTests/wasm/stress/bbq-i64-unaligned-load-store.js new file mode 100644 index 000000000000..dba14b4fa053 --- /dev/null +++ b/JSTests/wasm/stress/bbq-i64-unaligned-load-store.js @@ -0,0 +1,29 @@ +//@ requireOptions("--useConcurrentJIT=false") +// Regression test for unaligned i64 memory access under BBQ on ARMv7. +// BBQ compiled wasm i64.load/i64.store with ldrd/strd, which fault on unaligned +// addresses on ARMv7 -- but wasm permits unaligned memory access. Round-tripping an +// i64 through an unaligned address therefore crashed (SIGBUS) once BBQ kicked in. + +// (module +// (memory 1) +// (func (export "roundtrip") (param $off i32) (param $v i64) (result i64) +// local.get $off local.get $v i64.store +// local.get $off i64.load)) +const bytes = new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, // \0asm v1 + 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7e, 0x01, 0x7e, // type: (i32,i64)->i64 + 0x03, 0x02, 0x01, 0x00, // func 0 + 0x05, 0x03, 0x01, 0x00, 0x01, // memory: min 1 page + 0x07, 0x0d, 0x01, 0x09, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x74, 0x72, 0x69, 0x70, 0x00, 0x00, // export "roundtrip" + 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x20, 0x00, 0x20, 0x01, 0x37, 0x03, 0x00, 0x20, 0x00, 0x29, 0x03, 0x00, 0x0b, // code +]); + +const { roundtrip } = new WebAssembly.Instance(new WebAssembly.Module(bytes)).exports; + +const V = 0x1122334455667788n; +for (let i = 0; i < 100000; i++) { + // offset 1 is unaligned; ldrd/strd would fault on ARMv7 once BBQ-compiled. + const got = roundtrip(1, V); + if (got !== V) + throw new Error("unaligned i64 roundtrip at iteration " + i + ": got 0x" + got.toString(16)); +} diff --git a/JSTests/wasm/stress/omg-array-new-i32-init.js b/JSTests/wasm/stress/omg-array-new-i32-init.js new file mode 100644 index 000000000000..e5b815e865db --- /dev/null +++ b/JSTests/wasm/stress/omg-array-new-i32-init.js @@ -0,0 +1,31 @@ +//@ requireOptions("--useConcurrentJIT=false") +// Regression test for array.new with a 32-bit init value under OMG on ARMv7. +// operationWasmArrayNew() takes the init value as a uint64_t. The 32-bit OMG +// generator passed an i32 init as a single word, so the ABI put it in a register +// while the callee read the uint64_t from an uninitialized stack slot -- filling +// the array with a stray value instead of the requested init. + +// (module +// (type $arr (array (mut i32))) +// (func (export "f") (param i32) (result i32) +// local.get 0 +// i32.const 3 +// array.new $arr +// i32.const 1 +// array.get $arr)) +const bytes = new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, // \0asm v1 + 0x01, 0x09, 0x02, 0x5e, 0x7f, 0x01, 0x60, 0x01, 0x7f, 0x01, 0x7f, // type: array(mut i32); (i32)->i32 + 0x03, 0x02, 0x01, 0x01, // func 0 has type 1 + 0x07, 0x05, 0x01, 0x01, 0x66, 0x00, 0x00, // export "f" + 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x20, 0x00, 0x41, 0x03, 0xfb, 0x06, 0x00, 0x41, 0x01, 0xfb, 0x0b, 0x00, 0x0b, // code +]); + +const f = new WebAssembly.Instance(new WebAssembly.Module(bytes)).exports.f; + +for (let i = 0; i < 100000; i++) { + // f(v) allocates i32[3] filled with v and returns element 1, which must equal v. + const got = f(0x2a); + if (got !== 0x2a) + throw new Error("array.new i32 init: f(0x2a) should be 0x2a, got " + got + " at iteration " + i); +} diff --git a/PerformanceTests/JetStream3/js3-cli.js b/PerformanceTests/JetStream3/js3-cli.js new file mode 100644 index 000000000000..0e0ac842b96f --- /dev/null +++ b/PerformanceTests/JetStream3/js3-cli.js @@ -0,0 +1 @@ +testList=["8bitbench-wasm","ai-astar","Air","argon2-wasm","async-fs","Babylon","Basic","bigint-bigdenary","bigint-noble-bls12-381","bigint-noble-ed25519","bigint-noble-secp256k1","bigint-paillier","Box2D","cdjs","crypto","delta-blue","doxbee-async","doxbee-promise","earley-boyer","first-inspector-code-load","FlightPlanner","float-mm.c","gaussian-blur","gbemu","gcc-loops-wasm","hash-map","HashSet-wasm","json-parse-inspector","json-stringify-inspector","js-tokens","lazy-collections","mandreel","ML","multi-inspector-code-load","navier-stokes","octane-code-load","octane-zlib","OfflineAssembler","pdfjs","proxy-mobx","proxy-vue","quicksort-wasm","raytrace","raytrace-private-class-fields","raytrace-public-class-fields","regexp","richards","richards-wasm","splay","stanford-crypto-aes","stanford-crypto-pbkdf2","stanford-crypto-sha256","sync-fs","tfjs-wasm","tsf-wasm","typescript","UniPoker","WSL",]; diff --git a/PerformanceTests/JetStream3/js3-nosimd.js b/PerformanceTests/JetStream3/js3-nosimd.js new file mode 100644 index 000000000000..7365553d9947 --- /dev/null +++ b/PerformanceTests/JetStream3/js3-nosimd.js @@ -0,0 +1 @@ +testList=["8bitbench-wasm","ai-astar","Air","argon2-wasm","async-fs","Babylon","Basic","bigint-bigdenary","bigint-noble-bls12-381","bigint-noble-ed25519","bigint-noble-secp256k1","bigint-paillier","bomb-workers","Box2D","cdjs","crypto","delta-blue","doxbee-async","doxbee-promise","earley-boyer","first-inspector-code-load","FlightPlanner","float-mm.c","gaussian-blur","gbemu","gcc-loops-wasm","hash-map","HashSet-wasm","json-parse-inspector","json-stringify-inspector","js-tokens","lazy-collections","mandreel","ML","multi-inspector-code-load","navier-stokes","octane-code-load","octane-zlib","OfflineAssembler","pdfjs","proxy-mobx","proxy-vue","quicksort-wasm","raytrace","raytrace-private-class-fields","raytrace-public-class-fields","regexp","richards","richards-wasm","segmentation","splay","stanford-crypto-aes","stanford-crypto-pbkdf2","stanford-crypto-sha256","sync-fs","tfjs-wasm","tsf-wasm","typescript","UniPoker","WSL",]; diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 301b29fed204..47f449ffa961 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2009-2022 Apple Inc. All rights reserved. * Copyright (C) 2010 University of Szeged + * Copyright (C) 2026 Igalia S.L. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -1094,32 +1095,15 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { loadPair32(Address(scratch), dest1, dest2); } else { ASSERT(dest1 != dest2); // If it is the same, ldp becomes illegal instruction. - // Check if dest1 or dest2 aliases the base register to avoid UNPREDICTABLE ldrd behavior + // ldrd does not support unaligned accesses on some chips, so we avoid it. Order the + // two load32s so the base register is not overwritten before both words are read. + ArmAddress highAddress(address.base, address.u.offset + 4); if (address.base == dest1) { - // Load high word first to avoid clobbering base register - ArmAddress highAddress(address.base, address.u.offset + 4); load32(highAddress, dest2); load32(address, dest1); - } else if (address.base == dest2) { - // Load low word first to avoid clobbering base register + } else { load32(address, dest1); - ArmAddress highAddress(address.base, address.u.offset + 4); load32(highAddress, dest2); - } else { - int32_t absOffset = address.u.offset; - if (absOffset < 0) - absOffset = -absOffset; - if (!(absOffset & ~0x3fc)) { - if ((dest1 == addressTempRegister) || (dest2 == addressTempRegister)) - invalidateCachedAddressTempRegister(); - if ((dest1 == dataTempRegister) || (dest2 == dataTempRegister)) - cachedDataTempRegister().invalidate(); - m_assembler.ldrd(dest1, dest2, address.base, address.u.offset, /* index: */ true, /* wback: */ false); - } else { - load32(address, dest1); - ArmAddress highAddress(address.base, address.u.offset + 4); - load32(highAddress, dest2); - } } } } diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp b/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp index 4f4d9a1738b4..cb7b8e4ae562 100644 --- a/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp +++ b/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2019-2024 Apple Inc. All rights reserved. + * Copyright (C) 2026 Igalia S.L. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -1664,34 +1665,55 @@ PartialResult WARN_UNUSED_RETURN BBQJIT::addSelect(Value condition, Value lhs, V LOG_INSTRUCTION("Select", condition, lhs, lhsLocation, rhs, rhsLocation, RESULT(result)); LOG_INDENT(); - bool inverted = false; + if constexpr (is32Bit()) { + // On 32-bit an i64 occupies a register pair, and the result pair can + // partially overlap rhs (e.g. result's high half is rhs's low half). + // Moving lhs into result first, as the 64-bit path does, would then + // clobber rhs before the conditional move reads it, so branch and move + // only the selected operand -- a single move handles its own overlap. + Jump selectFalse = m_jit.branchTest32(ResultCondition::Zero, conditionLocation.asGPR(), conditionLocation.asGPR()); + consume(condition); + if (lhs.isConst()) + emitMoveConst(lhs, resultLocation); + else + emitMove(lhs.type(), lhsLocation, resultLocation); + Jump done = m_jit.jump(); + selectFalse.link(&m_jit); + if (rhs.isConst()) + emitMoveConst(rhs, resultLocation); + else + emitMove(rhs.type(), rhsLocation, resultLocation); + done.link(&m_jit); + } else { + bool inverted = false; - // If the operands or the result alias, we want the matching one to be on top. - if (rhsLocation == resultLocation) { - std::swap(lhs, rhs); - std::swap(lhsLocation, rhsLocation); - inverted = true; - } + // If the operands or the result alias, we want the matching one to be on top. + if (rhsLocation == resultLocation) { + std::swap(lhs, rhs); + std::swap(lhsLocation, rhsLocation); + inverted = true; + } - // If the condition location and the result alias, we want to make sure the condition is - // preserved no matter what. - if (conditionLocation == resultLocation) { - m_jit.move(conditionLocation.asGPR(), wasmScratchGPR); - conditionLocation = Location::fromGPR(wasmScratchGPR); - } + // If the condition location and the result alias, we want to make sure the condition is + // preserved no matter what. + if (conditionLocation == resultLocation) { + m_jit.move(conditionLocation.asGPR(), wasmScratchGPR); + conditionLocation = Location::fromGPR(wasmScratchGPR); + } - // Kind of gross isel, but it should handle all use/def aliasing cases correctly. - if (lhs.isConst()) - emitMoveConst(lhs, resultLocation); - else - emitMove(lhs.type(), lhsLocation, resultLocation); - Jump ifZero = m_jit.branchTest32(inverted ? ResultCondition::Zero : ResultCondition::NonZero, conditionLocation.asGPR(), conditionLocation.asGPR()); - consume(condition); - if (rhs.isConst()) - emitMoveConst(rhs, resultLocation); - else - emitMove(rhs.type(), rhsLocation, resultLocation); - ifZero.link(&m_jit); + // Kind of gross isel, but it should handle all use/def aliasing cases correctly. + if (lhs.isConst()) + emitMoveConst(lhs, resultLocation); + else + emitMove(lhs.type(), lhsLocation, resultLocation); + Jump ifZero = m_jit.branchTest32(inverted ? ResultCondition::Zero : ResultCondition::NonZero, conditionLocation.asGPR(), conditionLocation.asGPR()); + consume(condition); + if (rhs.isConst()) + emitMoveConst(rhs, resultLocation); + else + emitMove(rhs.type(), rhsLocation, resultLocation); + ifZero.link(&m_jit); + } LOG_DEDENT(); } diff --git a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp index be93ea0bf317..a1be1d717923 100644 --- a/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp +++ b/Source/JavaScriptCore/wasm/WasmOMGIRGenerator32_64.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2016-2024 Apple Inc. All rights reserved. + * Copyright (C) 2026 Igalia S.L. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -3422,11 +3423,10 @@ auto OMGIRGenerator::addArrayNew(uint32_t typeIndex, ExpressionType size, Expres #endif Value* initValue = get(value); - if (value->type() == B3::Float || value->type() == B3::Double) { + if (value->type() == B3::Float || value->type() == B3::Double) initValue = append(m_proc, BitwiseCast, origin(), initValue); - if (initValue->type() == B3::Int32) - initValue = append(m_proc, ZExt32, origin(), initValue); - } + if (initValue->type() == B3::Int32) + initValue = append(m_proc, ZExt32, origin(), initValue); result = pushArrayNew(typeIndex, initValue, size);