void JITCompiler::exceptionCheck() { // It's important that we use origin.forExit here. Consider if we hoist string // addition outside a loop, and that we exit at the point of that concatenation // from an out of memory exception. // If the original loop had a try/catch around string concatenation, if we "catch" // that exception inside the loop, then the loops induction variable will be undefined // in the OSR exit value recovery. It's more defensible for the string concatenation, // then, to not be caught by the for loops' try/catch. // Here is the program I'm speaking about: // // >>>> lets presume "c = a + b" gets hoisted here. // for (var i = 0; i < length; i++) { // try { // c = a + b // } catch(e) { // If we threw an out of memory error, and we cought the exception // right here, then "i" would almost certainly be undefined, which // would make no sense. // ... // } // } CodeOrigin opCatchOrigin; HandlerInfo* exceptionHandler; bool willCatchException = m_graph.willCatchExceptionInMachineFrame(m_speculative->m_currentNode->origin.forExit, opCatchOrigin, exceptionHandler); if (willCatchException) { unsigned streamIndex = m_speculative->m_outOfLineStreamIndex != UINT_MAX ? m_speculative->m_outOfLineStreamIndex : m_speculative->m_stream->size(); MacroAssembler::Jump hadException = emitNonPatchableExceptionCheck(); // We assume here that this is called after callOpeartion()/appendCall() is called. appendExceptionHandlingOSRExit(ExceptionCheck, streamIndex, opCatchOrigin, exceptionHandler, m_jitCode->common.lastCallSite(), hadException); } else m_exceptionChecks.append(emitExceptionCheck()); }
void JIT::compileCallEval(Instruction* instruction) { addPtr(TrustedImm32(-static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC))), stackPointerRegister, regT1); callOperationNoExceptionCheck(operationCallEval, regT1); Jump noException = emitExceptionCheck(InvertedExceptionCheck); addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister); exceptionCheck(jump()); noException.link(this); addSlowCase(branch64(Equal, regT0, TrustedImm64(JSValue::encode(JSValue())))); addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister); checkStackPointerAlignment(); sampleCodeBlock(m_codeBlock); emitPutCallResult(instruction); }