Warning, /graphics/krita/3rdparty/ext_qt/0137-masm-Add-error-handling-for-failed-mprotect.patch is written in an unsupported language. File is not indexed.
0001 From 4b7586b88b7bb611f72c0a1cfca9b2c257da84a2 Mon Sep 17 00:00:00 2001 0002 From: Ulf Hermann <ulf.hermann@qt.io> 0003 Date: Mon, 11 Jan 2021 11:33:26 +0100 0004 Subject: [PATCH 137/139] masm: Add error handling for failed mprotect() 0005 0006 If we cannot mprotect() we have to abort the JIT compilation. Delete 0007 RepatchBuffer.h as it is unfixable in that regard. Luckily we don't use 0008 it. 0009 0010 Task-number: QTBUG-89659 0011 Change-Id: Ic5ddbdf51b471db4ddeaa75aab48b24c1f7ced56 0012 Reviewed-by: Lars Knoll <lars.knoll@qt.io> 0013 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> 0014 (cherry picked from commit 131e2c81d40e3d324c62e113749a08e7993d008f) 0015 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> 0016 (cherry picked from commit ab15d9a547dbd83bec99366e7f7b0449fdcdb6ef) 0017 Signed-off-by: L. E. Segovia <amy@amyspark.me> 0018 --- 0019 .../masm/assembler/AbstractMacroAssembler.h | 2 - 0020 src/3rdparty/masm/assembler/AssemblerBuffer.h | 3 +- 0021 src/3rdparty/masm/assembler/LinkBuffer.h | 19 +- 0022 .../masm/assembler/MacroAssemblerARMv7.h | 1 - 0023 .../masm/assembler/MacroAssemblerMIPS.h | 1 - 0024 .../masm/assembler/MacroAssemblerX86.h | 1 - 0025 .../masm/assembler/MacroAssemblerX86_64.h | 1 - 0026 src/3rdparty/masm/assembler/RepatchBuffer.h | 181 ------------------ 0027 src/3rdparty/masm/stubs/ExecutableAllocator.h | 14 +- 0028 src/3rdparty/masm/yarr/YarrJIT.cpp | 3 +- 0029 src/qml/jit/qv4assemblercommon.cpp | 3 +- 0030 src/qml/jsruntime/qv4vme_moth.cpp | 5 +- 0031 12 files changed, 29 insertions(+), 205 deletions(-) 0032 delete mode 100644 src/3rdparty/masm/assembler/RepatchBuffer.h 0033 0034 diff --git a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h 0035 index d0c1c461..9bafa243 100644 0036 --- a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h 0037 +++ b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h 0038 @@ -51,7 +51,6 @@ template <typename, template <typename> class> 0039 class LinkBufferBase; 0040 template <typename> 0041 class BranchCompactingLinkBuffer; 0042 -class RepatchBuffer; 0043 class Watchpoint; 0044 namespace DFG { 0045 struct OSRExit; 0046 @@ -831,7 +830,6 @@ protected: 0047 0048 template <typename, template <typename> class> friend class LinkBufferBase; 0049 template <typename> friend class BranchCompactingLinkBuffer; 0050 - friend class RepatchBuffer; 0051 0052 static void linkJump(void* code, Jump jump, CodeLocationLabel target) 0053 { 0054 diff --git a/src/3rdparty/masm/assembler/AssemblerBuffer.h b/src/3rdparty/masm/assembler/AssemblerBuffer.h 0055 index 2292a4c2..58ecac2a 100644 0056 --- a/src/3rdparty/masm/assembler/AssemblerBuffer.h 0057 +++ b/src/3rdparty/masm/assembler/AssemblerBuffer.h 0058 @@ -140,7 +140,8 @@ namespace JSC { 0059 if (!result) 0060 return 0; 0061 0062 - ExecutableAllocator::makeWritable(result->memoryStart(), result->memorySize()); 0063 + if (Q_UNLIKELY(!ExecutableAllocator::makeWritable(result->memoryStart(), result->memorySize()))) 0064 + return 0; 0065 0066 memcpy(result->codeStart(), m_buffer, m_index); 0067 0068 diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h 0069 index aef35662..d9b5959f 100644 0070 --- a/src/3rdparty/masm/assembler/LinkBuffer.h 0071 +++ b/src/3rdparty/masm/assembler/LinkBuffer.h 0072 @@ -228,7 +228,7 @@ public: 0073 return m_size; 0074 } 0075 0076 - inline void makeExecutable(); 0077 + inline bool makeExecutable(); 0078 0079 private: 0080 template <typename T> T applyOffset(T src) 0081 @@ -358,10 +358,10 @@ void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performFinaliza 0082 } 0083 0084 template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator> 0085 -inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable() 0086 +inline bool LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable() 0087 { 0088 - ExecutableAllocator::makeExecutable(m_executableMemory->memoryStart(), 0089 - m_executableMemory->memorySize()); 0090 + return ExecutableAllocator::makeExecutable(m_executableMemory->memoryStart(), 0091 + m_executableMemory->memorySize()); 0092 } 0093 0094 template <typename MacroAssembler> 0095 @@ -397,7 +397,7 @@ public: 0096 } 0097 0098 virtual void performFinalization() override final; 0099 - inline void makeExecutable(); 0100 + inline bool makeExecutable(); 0101 0102 inline void linkCode(void* ownerUID, JITCompilationEffort); 0103 0104 @@ -433,9 +433,9 @@ void BranchCompactingLinkBuffer<MacroAssembler>::performFinalization() 0105 } 0106 0107 template <typename MacroAssembler> 0108 -inline void BranchCompactingLinkBuffer<MacroAssembler>::makeExecutable() 0109 +inline bool BranchCompactingLinkBuffer<MacroAssembler>::makeExecutable() 0110 { 0111 - ExecutableAllocator::makeExecutable(code(), m_initialSize); 0112 + return ExecutableAllocator::makeExecutable(code(), m_initialSize); 0113 } 0114 0115 template <typename MacroAssembler> 0116 @@ -448,9 +448,12 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID, 0117 m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort); 0118 if (!m_executableMemory) 0119 return; 0120 + if (Q_UNLIKELY(!ExecutableAllocator::makeWritable(m_executableMemory->memoryStart(), m_executableMemory->memorySize()))) { 0121 + m_executableMemory = {}; 0122 + return; 0123 + } 0124 m_code = (uint8_t*)m_executableMemory->codeStart(); 0125 ASSERT(m_code); 0126 - ExecutableAllocator::makeWritable(m_executableMemory->memoryStart(), m_executableMemory->memorySize()); 0127 uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode(); 0128 uint8_t* outData = reinterpret_cast<uint8_t*>(m_code); 0129 int readPtr = 0; 0130 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h 0131 index 99801a0e..dd66eefb 100644 0132 --- a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h 0133 +++ b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h 0134 @@ -2022,7 +2022,6 @@ protected: 0135 0136 private: 0137 template <typename, template <typename> class> friend class LinkBufferBase; 0138 - friend class RepatchBuffer; 0139 0140 #if !defined(V4_BOOTSTRAP) 0141 static void linkCall(void* code, Call call, FunctionPtr function) 0142 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h b/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h 0143 index 07f0ec62..6dfc1048 100644 0144 --- a/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h 0145 +++ b/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h 0146 @@ -2818,7 +2818,6 @@ private: 0147 bool m_fixedWidth; 0148 0149 template <typename, template <typename> class> friend class LinkBufferBase; 0150 - friend class RepatchBuffer; 0151 0152 static void linkCall(void* code, Call call, FunctionPtr function) 0153 { 0154 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86.h b/src/3rdparty/masm/assembler/MacroAssemblerX86.h 0155 index e3e0bfe5..bf5deeb1 100644 0156 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86.h 0157 +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86.h 0158 @@ -345,7 +345,6 @@ public: 0159 0160 private: 0161 template <typename, template <typename> class> friend class LinkBufferBase; 0162 - friend class RepatchBuffer; 0163 0164 static void linkCall(void* code, Call call, FunctionPtr function) 0165 { 0166 diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h 0167 index f4349e1f..c419bcd7 100644 0168 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h 0169 +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h 0170 @@ -743,7 +743,6 @@ public: 0171 0172 private: 0173 template <typename, template <typename> class> friend class LinkBufferBase; 0174 - friend class RepatchBuffer; 0175 0176 static void linkCall(void* code, Call call, FunctionPtr function) 0177 { 0178 diff --git a/src/3rdparty/masm/assembler/RepatchBuffer.h b/src/3rdparty/masm/assembler/RepatchBuffer.h 0179 deleted file mode 100644 0180 index dbb56f9a..00000000 0181 --- a/src/3rdparty/masm/assembler/RepatchBuffer.h 0182 +++ /dev/null 0183 @@ -1,181 +0,0 @@ 0184 -/* 0185 - * Copyright (C) 2009 Apple Inc. All rights reserved. 0186 - * 0187 - * Redistribution and use in source and binary forms, with or without 0188 - * modification, are permitted provided that the following conditions 0189 - * are met: 0190 - * 1. Redistributions of source code must retain the above copyright 0191 - * notice, this list of conditions and the following disclaimer. 0192 - * 2. Redistributions in binary form must reproduce the above copyright 0193 - * notice, this list of conditions and the following disclaimer in the 0194 - * documentation and/or other materials provided with the distribution. 0195 - * 0196 - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 0197 - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0198 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 0199 - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 0200 - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 0201 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 0202 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 0203 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 0204 - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0205 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0206 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0207 - */ 0208 - 0209 -#ifndef RepatchBuffer_h 0210 -#define RepatchBuffer_h 0211 - 0212 -#if ENABLE(JIT) 0213 - 0214 -#include "CodeBlock.h" 0215 -#include <MacroAssembler.h> 0216 -#include <wtf/Noncopyable.h> 0217 - 0218 -namespace JSC { 0219 - 0220 -// RepatchBuffer: 0221 -// 0222 -// This class is used to modify code after code generation has been completed, 0223 -// and after the code has potentially already been executed. This mechanism is 0224 -// used to apply optimizations to the code. 0225 -// 0226 -class RepatchBuffer { 0227 - typedef MacroAssemblerCodePtr CodePtr; 0228 - 0229 -public: 0230 - RepatchBuffer(CodeBlock* codeBlock) 0231 - { 0232 - JITCode& code = codeBlock->getJITCode(); 0233 - m_start = code.start(); 0234 - m_size = code.size(); 0235 - 0236 - ExecutableAllocator::makeWritable(m_start, m_size); 0237 - } 0238 - 0239 - ~RepatchBuffer() 0240 - { 0241 - ExecutableAllocator::makeExecutable(m_start, m_size); 0242 - } 0243 - 0244 - void relink(CodeLocationJump jump, CodeLocationLabel destination) 0245 - { 0246 - MacroAssembler::repatchJump(jump, destination); 0247 - } 0248 - 0249 - void relink(CodeLocationCall call, CodeLocationLabel destination) 0250 - { 0251 - MacroAssembler::repatchCall(call, destination); 0252 - } 0253 - 0254 - void relink(CodeLocationCall call, FunctionPtr destination) 0255 - { 0256 - MacroAssembler::repatchCall(call, destination); 0257 - } 0258 - 0259 - void relink(CodeLocationNearCall nearCall, CodePtr destination) 0260 - { 0261 - MacroAssembler::repatchNearCall(nearCall, CodeLocationLabel(destination)); 0262 - } 0263 - 0264 - void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination) 0265 - { 0266 - MacroAssembler::repatchNearCall(nearCall, destination); 0267 - } 0268 - 0269 - void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value) 0270 - { 0271 - MacroAssembler::repatchInt32(dataLabel32, value); 0272 - } 0273 - 0274 - void repatch(CodeLocationDataLabelCompact dataLabelCompact, int32_t value) 0275 - { 0276 - MacroAssembler::repatchCompact(dataLabelCompact, value); 0277 - } 0278 - 0279 - void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value) 0280 - { 0281 - MacroAssembler::repatchPointer(dataLabelPtr, value); 0282 - } 0283 - 0284 - void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 0285 - { 0286 - relink(CodeLocationCall(CodePtr(returnAddress)), label); 0287 - } 0288 - 0289 - void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction) 0290 - { 0291 - relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction)); 0292 - } 0293 - 0294 - void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function) 0295 - { 0296 - relink(CodeLocationCall(CodePtr(returnAddress)), function); 0297 - } 0298 - 0299 - void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 0300 - { 0301 - relink(CodeLocationNearCall(CodePtr(returnAddress)), label); 0302 - } 0303 - 0304 - void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction) 0305 - { 0306 - relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction)); 0307 - } 0308 - 0309 - void replaceWithLoad(CodeLocationConvertibleLoad label) 0310 - { 0311 - MacroAssembler::replaceWithLoad(label); 0312 - } 0313 - 0314 - void replaceWithAddressComputation(CodeLocationConvertibleLoad label) 0315 - { 0316 - MacroAssembler::replaceWithAddressComputation(label); 0317 - } 0318 - 0319 - void setLoadInstructionIsActive(CodeLocationConvertibleLoad label, bool isActive) 0320 - { 0321 - if (isActive) 0322 - replaceWithLoad(label); 0323 - else 0324 - replaceWithAddressComputation(label); 0325 - } 0326 - 0327 - static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label) 0328 - { 0329 - return MacroAssembler::startOfBranchPtrWithPatchOnRegister(label); 0330 - } 0331 - 0332 - static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr label) 0333 - { 0334 - return MacroAssembler::startOfPatchableBranchPtrWithPatchOnAddress(label); 0335 - } 0336 - 0337 - void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination) 0338 - { 0339 - MacroAssembler::replaceWithJump(instructionStart, destination); 0340 - } 0341 - 0342 - // This is a *bit* of a silly API, since we currently always also repatch the 0343 - // immediate after calling this. But I'm fine with that, since this just feels 0344 - // less yucky. 0345 - void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, MacroAssembler::RegisterID reg, void* value) 0346 - { 0347 - MacroAssembler::revertJumpReplacementToBranchPtrWithPatch(instructionStart, reg, value); 0348 - } 0349 - 0350 - void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel instructionStart, MacroAssembler::Address address, void* value) 0351 - { 0352 - MacroAssembler::revertJumpReplacementToPatchableBranchPtrWithPatch(instructionStart, address, value); 0353 - } 0354 - 0355 -private: 0356 - void* m_start; 0357 - size_t m_size; 0358 -}; 0359 - 0360 -} // namespace JSC 0361 - 0362 -#endif // ENABLE(ASSEMBLER) 0363 - 0364 -#endif // RepatchBuffer_h 0365 diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h 0366 index f9847040..515285a7 100644 0367 --- a/src/3rdparty/masm/stubs/ExecutableAllocator.h 0368 +++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h 0369 @@ -109,7 +109,7 @@ struct ExecutableAllocator { 0370 return adoptRef(new ExecutableMemoryHandle(realAllocator, size)); 0371 } 0372 0373 - static void makeWritable(void* addr, size_t size) 0374 + static bool makeWritable(void* addr, size_t size) 0375 { 0376 quintptr pageSize = WTF::pageSize(); 0377 quintptr iaddr = reinterpret_cast<quintptr>(addr); 0378 @@ -125,7 +125,7 @@ struct ExecutableAllocator { 0379 # else 0380 bool hr = VirtualProtectFromApp(addr, size, PAGE_READWRITE, &oldProtect); 0381 if (!hr) { 0382 - Q_UNREACHABLE(); 0383 + return false; 0384 } 0385 # endif 0386 # elif OS(INTEGRITY) 0387 @@ -134,7 +134,7 @@ struct ExecutableAllocator { 0388 int mode = PROT_READ | PROT_WRITE; 0389 if (mprotect(addr, size, mode) != 0) { 0390 perror("mprotect failed in ExecutableAllocator::makeWritable"); 0391 - Q_UNREACHABLE(); 0392 + return false; 0393 } 0394 # endif 0395 #else 0396 @@ -142,9 +142,10 @@ struct ExecutableAllocator { 0397 (void)addr; // suppress unused parameter warning 0398 (void)size; // suppress unused parameter warning 0399 #endif 0400 + return true; 0401 } 0402 0403 - static void makeExecutable(void* addr, size_t size) 0404 + static bool makeExecutable(void* addr, size_t size) 0405 { 0406 quintptr pageSize = WTF::pageSize(); 0407 quintptr iaddr = reinterpret_cast<quintptr>(addr); 0408 @@ -161,7 +162,7 @@ struct ExecutableAllocator { 0409 # else 0410 bool hr = VirtualProtectFromApp(addr, size, PAGE_EXECUTE_READ, &oldProtect); 0411 if (!hr) { 0412 - Q_UNREACHABLE(); 0413 + return false; 0414 } 0415 # endif 0416 # elif OS(INTEGRITY) 0417 @@ -170,7 +171,7 @@ struct ExecutableAllocator { 0418 int mode = PROT_READ | PROT_EXEC; 0419 if (mprotect(addr, size, mode) != 0) { 0420 perror("mprotect failed in ExecutableAllocator::makeExecutable"); 0421 - Q_UNREACHABLE(); 0422 + return false; 0423 } 0424 # endif 0425 #else 0426 @@ -180,6 +181,7 @@ struct ExecutableAllocator { 0427 (void)addr; // suppress unused parameter warning 0428 (void)size; // suppress unused parameter warning 0429 #endif 0430 + return true; 0431 } 0432 0433 QV4::ExecutableAllocator *realAllocator; 0434 diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp 0435 index 98e4ade5..92706ffb 100644 0436 --- a/src/3rdparty/masm/yarr/YarrJIT.cpp 0437 +++ b/src/3rdparty/masm/yarr/YarrJIT.cpp 0438 @@ -3553,7 +3553,8 @@ public: 0439 } 0440 QV4::generateFunctionTable(nullptr, &codeRef); 0441 0442 - linkBuffer.makeExecutable(); 0443 + if (Q_UNLIKELY(!linkBuffer.makeExecutable())) 0444 + m_failureReason = JITFailureReason::ExecutableMemoryAllocationFailure; 0445 0446 if (m_failureReason) 0447 codeBlock.setFallBackWithFailureReason(*m_failureReason); 0448 diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp 0449 index 6dc40ad8..45ff79c9 100644 0450 --- a/src/qml/jit/qv4assemblercommon.cpp 0451 +++ b/src/qml/jit/qv4assemblercommon.cpp 0452 @@ -153,7 +153,8 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind) 0453 0454 generateFunctionTable(function, &codeRef); 0455 0456 - linkBuffer.makeExecutable(); 0457 + if (Q_UNLIKELY(!linkBuffer.makeExecutable())) 0458 + function->jittedCode = nullptr; // The function is not executable, but the coderef exists. 0459 } 0460 0461 void PlatformAssemblerCommon::prepareCallWithArgCount(int argc) 0462 diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp 0463 index 47ad22f4..9d8a1c5a 100644 0464 --- a/src/qml/jsruntime/qv4vme_moth.cpp 0465 +++ b/src/qml/jsruntime/qv4vme_moth.cpp 0466 @@ -429,7 +429,10 @@ ReturnedValue VME::exec(CppStackFrame *frame, ExecutionEngine *engine) 0467 0468 #ifdef V4_ENABLE_JIT 0469 if (debugger == nullptr) { 0470 - if (function->jittedCode == nullptr) { 0471 + // Check for codeRef here. In rare cases the JIT compilation may fail, which leaves us 0472 + // with a (useless) codeRef, but no jittedCode. In that case, don't try to JIT again every 0473 + // time we execute the function, but just interpret instead. 0474 + if (function->codeRef == nullptr) { 0475 if (engine->canJIT(function)) 0476 QV4::JIT::BaselineJIT(function).generate(); 0477 else 0478 -- 0479 2.37.3 0480