From e14391e94c850b8bd03680c23b38978db68687a8 Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 4 Nov 2010 12:00:17 -0700 Subject: Merge Webkit at r70949: Initial merge by git. Change-Id: I77b8645c083b5d0da8dba73ed01d4014aab9848e --- JavaScriptCore/jit/JITArithmetic.cpp | 2 +- JavaScriptCore/jit/JITArithmetic32_64.cpp | 47 +++-- JavaScriptCore/jit/JITCode.h | 5 +- JavaScriptCore/jit/JITInlineMethods.h | 2 +- JavaScriptCore/jit/JITOpcodes.cpp | 15 +- JavaScriptCore/jit/JITOpcodes32_64.cpp | 34 ++-- JavaScriptCore/jit/JITPropertyAccess.cpp | 6 +- JavaScriptCore/jit/JITPropertyAccess32_64.cpp | 6 +- JavaScriptCore/jit/JITStubs.cpp | 259 +++++++++++--------------- JavaScriptCore/jit/JITStubs.h | 18 +- 10 files changed, 184 insertions(+), 210 deletions(-) (limited to 'JavaScriptCore/jit') diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp index d4fa12f..f0a049a 100644 --- a/JavaScriptCore/jit/JITArithmetic.cpp +++ b/JavaScriptCore/jit/JITArithmetic.cpp @@ -888,7 +888,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction) emitJumpSlowCaseIfNotImmediateInteger(regT0); emitJumpSlowCaseIfNotImmediateInteger(regT2); - addSlowCase(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0))))); + addSlowCase(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNumber(0))))); m_assembler.cdq(); m_assembler.idivl_r(regT2); emitFastArithReTagImmediate(regT1, regT0); diff --git a/JavaScriptCore/jit/JITArithmetic32_64.cpp b/JavaScriptCore/jit/JITArithmetic32_64.cpp index e53af77..e0b31f0 100644 --- a/JavaScriptCore/jit/JITArithmetic32_64.cpp +++ b/JavaScriptCore/jit/JITArithmetic32_64.cpp @@ -1293,7 +1293,7 @@ void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector /* ------------------------------ BEGIN: OP_MOD ------------------------------ */ -#if CPU(X86) || CPU(X86_64) +#if CPU(X86) || CPU(X86_64) || CPU(MIPS) void JIT::emit_op_mod(Instruction* currentInstruction) { @@ -1301,34 +1301,47 @@ void JIT::emit_op_mod(Instruction* currentInstruction) unsigned op1 = currentInstruction[2].u.operand; unsigned op2 = currentInstruction[3].u.operand; +#if CPU(X86) || CPU(X86_64) + // Make sure registers are correct for x86 IDIV instructions. + ASSERT(regT0 == X86Registers::eax); + ASSERT(regT1 == X86Registers::edx); + ASSERT(regT2 == X86Registers::ecx); + ASSERT(regT3 == X86Registers::ebx); +#endif + if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) { - emitLoad(op1, X86Registers::edx, X86Registers::eax); - move(Imm32(getConstantOperand(op2).asInt32()), X86Registers::ecx); - addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag))); + emitLoad(op1, regT1, regT0); + move(Imm32(getConstantOperand(op2).asInt32()), regT2); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); if (getConstantOperand(op2).asInt32() == -1) - addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC + addSlowCase(branch32(Equal, regT0, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC } else { - emitLoad2(op1, X86Registers::edx, X86Registers::eax, op2, X86Registers::ebx, X86Registers::ecx); - addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag))); - addSlowCase(branch32(NotEqual, X86Registers::ebx, Imm32(JSValue::Int32Tag))); + emitLoad2(op1, regT1, regT0, op2, regT3, regT2); + addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); + addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC - addSlowCase(branch32(Equal, X86Registers::ecx, Imm32(0))); // divide by 0 + addSlowCase(branch32(Equal, regT0, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC + addSlowCase(branch32(Equal, regT2, Imm32(0))); // divide by 0 } - move(X86Registers::eax, X86Registers::ebx); // Save dividend payload, in case of 0. + move(regT0, regT3); // Save dividend payload, in case of 0. +#if CPU(X86) || CPU(X86_64) m_assembler.cdq(); - m_assembler.idivl_r(X86Registers::ecx); + m_assembler.idivl_r(regT2); +#elif CPU(MIPS) + m_assembler.div(regT0, regT2); + m_assembler.mfhi(regT1); +#endif // If the remainder is zero and the dividend is negative, the result is -0. - Jump storeResult1 = branchTest32(NonZero, X86Registers::edx); - Jump storeResult2 = branchTest32(Zero, X86Registers::ebx, Imm32(0x80000000)); // not negative - emitStore(dst, jsNumber(m_globalData, -0.0)); + Jump storeResult1 = branchTest32(NonZero, regT1); + Jump storeResult2 = branchTest32(Zero, regT3, Imm32(0x80000000)); // not negative + emitStore(dst, jsNumber(-0.0)); Jump end = jump(); storeResult1.link(this); storeResult2.link(this); - emitStoreInt32(dst, X86Registers::edx, (op1 == dst || op2 == dst)); + emitStoreInt32(dst, regT1, (op1 == dst || op2 == dst)); end.link(this); } @@ -1355,7 +1368,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector stubCall.call(dst); } -#else // CPU(X86) || CPU(X86_64) +#else // CPU(X86) || CPU(X86_64) || CPU(MIPS) void JIT::emit_op_mod(Instruction* currentInstruction) { diff --git a/JavaScriptCore/jit/JITCode.h b/JavaScriptCore/jit/JITCode.h index 5d889b5..7346fd5 100644 --- a/JavaScriptCore/jit/JITCode.h +++ b/JavaScriptCore/jit/JITCode.h @@ -72,9 +72,10 @@ namespace JSC { } // Execute the code! - inline JSValue execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValue* exception) + inline JSValue execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData) { - return JSValue::decode(ctiTrampoline(m_ref.m_code.executableAddress(), registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData)); + JSValue result = JSValue::decode(ctiTrampoline(m_ref.m_code.executableAddress(), registerFile, callFrame, 0, Profiler::enabledProfilerReference(), globalData)); + return globalData->exception ? jsNull() : result; } void* start() diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h index 0fe9929..7611151 100644 --- a/JavaScriptCore/jit/JITInlineMethods.h +++ b/JavaScriptCore/jit/JITInlineMethods.h @@ -186,7 +186,7 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) ALWAYS_INLINE void JIT::restoreArgumentReference() { move(stackPointerRegister, firstArgumentRegister); - poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); + poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); } ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp index a468c18..1528b76 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/JavaScriptCore/jit/JITOpcodes.cpp @@ -198,6 +198,8 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon int executableOffsetToFunction = isConstruct ? OBJECT_OFFSETOF(NativeExecutable, m_constructor) : OBJECT_OFFSETOF(NativeExecutable, m_function); Label nativeCallThunk = align(); + + emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); #if CPU(X86_64) // Load caller frame's scope chain into this callframe so that whatever we call can @@ -711,7 +713,7 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction) unsigned target = currentInstruction[2].u.operand; emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target); + addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(0)))), target); Jump isNonZero = emitJumpIfImmediateInteger(regT0); addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target); @@ -831,7 +833,7 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction) unsigned target = currentInstruction[2].u.operand; emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); - Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); + Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(0)))); addJump(emitJumpIfImmediateInteger(regT0), target); addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); @@ -1062,7 +1064,10 @@ void JIT::emit_op_push_new_scope(Instruction* currentInstruction) void JIT::emit_op_catch(Instruction* currentInstruction) { killLastResultRegister(); // FIXME: Implicitly treat op_catch as a labeled statement, and remove this line of code. - peek(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*)); + move(regT0, callFrameRegister); + peek(regT3, OBJECT_OFFSETOF(struct JITStackFrame, globalData) / sizeof(void*)); + loadPtr(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception)), regT0); + storePtr(ImmPtr(JSValue::encode(JSValue())), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception))); emitPutVirtualRegister(currentInstruction[1].u.operand); } @@ -1284,7 +1289,7 @@ void JIT::emit_op_create_this(Instruction* currentInstruction) void JIT::emit_op_profile_will_call(Instruction* currentInstruction) { - peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*)); + peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*)); Jump noProfiler = branchTestPtr(Zero, Address(regT1)); JITStubCall stubCall(this, cti_op_profile_will_call); @@ -1296,7 +1301,7 @@ void JIT::emit_op_profile_will_call(Instruction* currentInstruction) void JIT::emit_op_profile_did_call(Instruction* currentInstruction) { - peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*)); + peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*)); Jump noProfiler = branchTestPtr(Zero, Address(regT1)); JITStubCall stubCall(this, cti_op_profile_did_call); diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp index c3b7ac2..0a3d69d 100644 --- a/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -198,6 +198,8 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon Label nativeCallThunk = align(); + emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + #if CPU(X86) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. @@ -312,6 +314,8 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr executa Call nativeCall; Label nativeCallThunk = align(); + emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + #if CPU(X86) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. @@ -923,11 +927,8 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction) // Now handle the immediate cases - undefined & null isImmediate.link(this); - set32(Equal, regT1, Imm32(JSValue::NullTag), regT2); - set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); - or32(regT2, regT1); - - addJump(branchTest32(NonZero, regT1), target); + ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1)); + addJump(branch32(AboveOrEqual, regT1, Imm32(JSValue::UndefinedTag)), target); wasNotImmediate.link(this); } @@ -950,11 +951,8 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) // Now handle the immediate cases - undefined & null isImmediate.link(this); - set32(Equal, regT1, Imm32(JSValue::NullTag), regT2); - set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1); - or32(regT2, regT1); - - addJump(branchTest32(Zero, regT1), target); + ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1)); + addJump(branch32(Below, regT1, Imm32(JSValue::UndefinedTag)), target); wasNotImmediate.link(this); } @@ -1388,15 +1386,17 @@ void JIT::emit_op_push_new_scope(Instruction* currentInstruction) void JIT::emit_op_catch(Instruction* currentInstruction) { - unsigned exception = currentInstruction[1].u.operand; - - // This opcode only executes after a return from cti_op_throw. - - // cti_op_throw may have taken us to a call frame further up the stack; reload - // the call frame pointer to adjust. - peek(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); + // cti_op_throw returns the callFrame for the handler. + move(regT0, callFrameRegister); // Now store the exception returned by cti_op_throw. + loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(struct JITStackFrame, globalData)), regT3); + load32(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); + load32(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); + store32(Imm32(JSValue().payload()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + store32(Imm32(JSValue().tag()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + + unsigned exception = currentInstruction[1].u.operand; emitStore(exception, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_catch), exception, regT1, regT0); } diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp index 2edc860..1b95eec 100644 --- a/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -585,10 +585,10 @@ void JIT::testPrototype(JSValue prototype, JumpList& failureCases) // values. In the non X86_64 case, the generated code is slightly more efficient because it uses // two less instructions and doesn't require any scratch registers. #if CPU(X86_64) - move(ImmPtr(asCell(prototype)->structure()), regT3); - failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(prototype)->m_structure), regT3)); + move(ImmPtr(prototype.asCell()->structure()), regT3); + failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), regT3)); #else - failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(prototype)->m_structure), ImmPtr(asCell(prototype)->structure()))); + failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), ImmPtr(prototype.asCell()->structure()))); #endif } diff --git a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index f6280ef..710a155 100644 --- a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -595,10 +595,10 @@ void JIT::testPrototype(JSValue prototype, JumpList& failureCases) // values. In the non X86_64 case, the generated code is slightly more efficient because it uses // two less instructions and doesn't require any scratch registers. #if CPU(X86_64) - move(ImmPtr(asCell(prototype)->structure()), regT3); - failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(prototype)->m_structure), regT3)); + move(ImmPtr(prototype.asCell()->structure()), regT3); + failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), regT3)); #else - failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(prototype)->m_structure), ImmPtr(asCell(prototype)->structure()))); + failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&prototype.asCell()->m_structure), ImmPtr(prototype.asCell()->structure()))); #endif } diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp index 8340211..c69a828 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -147,12 +147,7 @@ HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movl %esp, %ecx" "\n" "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" - "addl $0x3c, %esp" "\n" - "popl %ebx" "\n" - "popl %edi" "\n" - "popl %esi" "\n" - "popl %ebp" "\n" - "ret" "\n" + "int3" "\n" ); asm ( @@ -209,14 +204,7 @@ HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" - "addq $0x48, %rsp" "\n" - "popq %rbx" "\n" - "popq %r15" "\n" - "popq %r14" "\n" - "popq %r13" "\n" - "popq %r12" "\n" - "popq %rbp" "\n" - "ret" "\n" + "int3" "\n" ); asm ( @@ -261,7 +249,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_ extern "C" { - __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*) + __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*) { __asm { push ebp; @@ -373,12 +361,7 @@ HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movl %esp, %ecx" "\n" "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" - "addl $0x1c, %esp" "\n" - "popl %ebx" "\n" - "popl %edi" "\n" - "popl %esi" "\n" - "popl %ebp" "\n" - "ret" "\n" + "int3" "\n" ); asm ( @@ -442,14 +425,7 @@ HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "movq %rsp, %rdi" "\n" "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n" - "addq $0x78, %rsp" "\n" - "popq %rbx" "\n" - "popq %r15" "\n" - "popq %r14" "\n" - "popq %r13" "\n" - "popq %r12" "\n" - "popq %rbp" "\n" - "ret" "\n" + "int3" "\n" ); asm ( @@ -508,7 +484,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x1c, JITStackFrame_s extern "C" { - __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*) + __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*) { __asm { push ebp; @@ -763,7 +739,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" #elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL) -__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, JSValue*, Profiler**, JSGlobalData*) +__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*) { ARM stmdb sp!, {r1-r3} @@ -872,7 +848,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co return; } - JSCell* baseCell = asCell(baseValue); + JSCell* baseCell = baseValue.asCell(); Structure* structure = baseCell->structure(); if (structure->isUncacheableDictionary()) { @@ -940,7 +916,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co return; } - JSCell* baseCell = asCell(baseValue); + JSCell* baseCell = baseValue.asCell(); Structure* structure = baseCell->structure(); if (structure->isUncacheableDictionary()) { @@ -1087,6 +1063,25 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD } \ } while (0) +struct ExceptionHandler { + void* catchRoutine; + CallFrame* callFrame; +}; +static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation, bool explicitThrow) +{ + ASSERT(exceptionValue); + + unsigned vPCIndex = callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation); + globalData->exception = JSValue(); + HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, explicitThrow); // This may update callFrame & exceptionValue! + globalData->exception = exceptionValue; + + void* catchRoutine = handler ? handler->nativeCode.executableAddress() : FunctionPtr(ctiOpThrowNotCaught).value(); + ASSERT(catchRoutine); + ExceptionHandler exceptionHandler = { catchRoutine, callFrame }; + return exceptionHandler; +} + #if CPU(ARM_THUMB2) #define DEFINE_STUB_FUNCTION(rtype, op) \ @@ -1342,7 +1337,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) double left = 0.0, right; if (v1.getNumber(left) && v2.getNumber(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left + right)); + return JSValue::encode(jsNumber(left + right)); // All other cases are pretty uncommon JSValue result = jsAddSlowCase(callFrame, v1, v2); @@ -1357,7 +1352,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc) JSValue v = stackFrame.args[0].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, v.toNumber(callFrame) + 1); + JSValue result = jsNumber(v.toNumber(callFrame) + 1); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -1380,18 +1375,21 @@ DEFINE_STUB_FUNCTION(int, timeout_check) return timeoutChecker.ticksUntilNextCheck(); } -DEFINE_STUB_FUNCTION(void, register_file_check) +DEFINE_STUB_FUNCTION(void*, register_file_check) { STUB_INIT_STACK_FRAME(stackFrame); + CallFrame* callFrame = stackFrame.callFrame; - if (LIKELY(stackFrame.registerFile->grow(&stackFrame.callFrame->registers()[stackFrame.callFrame->codeBlock()->m_numCalleeRegisters]))) - return; + if (UNLIKELY(!stackFrame.registerFile->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) { + // Rewind to the previous call frame because op_call already optimistically + // moved the call frame forward. + CallFrame* oldCallFrame = callFrame->callerFrame(); + ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(oldCallFrame->returnPC()), false); + STUB_SET_RETURN_ADDRESS(handler.catchRoutine); + callFrame = handler.callFrame; + } - // Rewind to the previous call frame because op_call already optimistically - // moved the call frame forward. - CallFrame* oldCallFrame = stackFrame.callFrame->callerFrame(); - stackFrame.callFrame = oldCallFrame; - throwStackOverflowError(oldCallFrame, stackFrame.globalData, ReturnAddressPtr(oldCallFrame->returnPC()), STUB_RETURN_ADDRESS); + return callFrame; } DEFINE_STUB_FUNCTION(int, op_loop_if_lesseq) @@ -1563,7 +1561,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check) JSObject* slotBaseObject; if (baseValue.isCell() && slot.isCacheableValue() - && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary() + && !(structure = baseValue.asCell()->structure())->isUncacheableDictionary() && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific) && specific ) { @@ -1637,7 +1635,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) if (baseValue.isCell() && slot.isCacheable() - && !asCell(baseValue)->structure()->isUncacheableDictionary() + && !baseValue.asCell()->structure()->isUncacheableDictionary() && slot.slotBase() == baseValue) { CodeBlock* codeBlock = callFrame->codeBlock(); @@ -1658,7 +1656,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) } if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { stubInfo->u.getByIdSelfList.listSize++; - JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), ident, slot, slot.cachedOffset()); + JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, baseValue.asCell()->structure(), ident, slot, slot.cachedOffset()); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic)); @@ -1742,12 +1740,12 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) CHECK_FOR_EXCEPTION(); - if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) { + if (!baseValue.isCell() || !slot.isCacheable() || baseValue.asCell()->structure()->isDictionary()) { ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); return JSValue::encode(result); } - Structure* structure = asCell(baseValue)->structure(); + Structure* structure = baseValue.asCell()->structure(); CodeBlock* codeBlock = callFrame->codeBlock(); StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); @@ -1758,8 +1756,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) if (slot.slotBase() == baseValue) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); - else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) { - ASSERT(!asCell(baseValue)->structure()->isDictionary()); + else if (slot.slotBase() == baseValue.asCell()->structure()->prototypeForLookup(callFrame)) { + ASSERT(!baseValue.asCell()->structure()->isDictionary()); // Since we're accessing a prototype in a loop, it's a good bet that it // should not be treated as a dictionary. if (slotBaseObject->structure()->isDictionary()) { @@ -1776,7 +1774,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); } } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) { - ASSERT(!asCell(baseValue)->structure()->isDictionary()); + ASSERT(!baseValue.asCell()->structure()->isDictionary()); int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); @@ -1913,10 +1911,10 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul) double left; double right; if (src1.getNumber(left) && src2.getNumber(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left * right)); + return JSValue::encode(jsNumber(left * right)); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, src1.toNumber(callFrame) * src2.toNumber(callFrame)); + JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -1994,9 +1992,9 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck) if (!stackFrame.registerFile->grow(newEnd)) { // Rewind to the previous call frame because op_call already optimistically // moved the call frame forward. - stackFrame.callFrame = oldCallFrame; - throwStackOverflowError(oldCallFrame, stackFrame.globalData, pc, STUB_RETURN_ADDRESS); - return 0; + ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false); + STUB_SET_RETURN_ADDRESS(handler.catchRoutine); + return handler.callFrame; } Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount; @@ -2009,9 +2007,9 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck) if (!stackFrame.registerFile->grow(newEnd)) { // Rewind to the previous call frame because op_call already optimistically // moved the call frame forward. - stackFrame.callFrame = oldCallFrame; - throwStackOverflowError(oldCallFrame, stackFrame.globalData, pc, STUB_RETURN_ADDRESS); - return 0; + ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false); + STUB_SET_RETURN_ADDRESS(handler.catchRoutine); + return handler.callFrame; } Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; @@ -2053,9 +2051,9 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck) if (!stackFrame.registerFile->grow(newEnd)) { // Rewind to the previous call frame because op_call already optimistically // moved the call frame forward. - stackFrame.callFrame = oldCallFrame; - throwStackOverflowError(oldCallFrame, stackFrame.globalData, pc, STUB_RETURN_ADDRESS); - return 0; + ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false); + STUB_SET_RETURN_ADDRESS(handler.catchRoutine); + return handler.callFrame; } Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount; @@ -2068,9 +2066,9 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck) if (!stackFrame.registerFile->grow(newEnd)) { // Rewind to the previous call frame because op_call already optimistically // moved the call frame forward. - stackFrame.callFrame = oldCallFrame; - throwStackOverflowError(oldCallFrame, stackFrame.globalData, pc, STUB_RETURN_ADDRESS); - return 0; + ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false); + STUB_SET_RETURN_ADDRESS(handler.catchRoutine); + return handler.callFrame; } Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; @@ -2188,17 +2186,16 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction) throwStackOverflowError(previousCallFrame, stackFrame.globalData, callFrame->returnPC(), STUB_RETURN_ADDRESS); VM_THROW_EXCEPTION(); } + callFrame->init(0, static_cast((STUB_RETURN_ADDRESS).value()), previousCallFrame->scopeChain(), previousCallFrame, argCount, asObject(funcVal)); - stackFrame.callFrame = callFrame; EncodedJSValue returnValue; { SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); returnValue = callData.native.function(callFrame); } - stackFrame.callFrame = previousCallFrame; - CHECK_FOR_EXCEPTION(); + CHECK_FOR_EXCEPTION_AT_END(); return returnValue; } @@ -2234,8 +2231,10 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_activation) ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain()); JSValue activationValue = stackFrame.args[0].jsValue(); if (!activationValue) { - if (JSValue v = stackFrame.args[1].jsValue()) - asArguments(v)->copyRegisters(); + if (JSValue v = stackFrame.args[1].jsValue()) { + if (!stackFrame.callFrame->codeBlock()->isStrictMode()) + asArguments(v)->copyRegisters(); + } return; } JSActivation* activation = asActivation(stackFrame.args[0].jsValue()); @@ -2336,16 +2335,14 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct) } callFrame->init(0, static_cast((STUB_RETURN_ADDRESS).value()), previousCallFrame->scopeChain(), previousCallFrame, argCount, asObject(constrVal)); - stackFrame.callFrame = callFrame; EncodedJSValue returnValue; { SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); returnValue = constructData.native.function(callFrame); } - stackFrame.callFrame = previousCallFrame; - CHECK_FOR_EXCEPTION(); + CHECK_FOR_EXCEPTION_AT_END(); return returnValue; } @@ -2370,10 +2367,10 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val) if (LIKELY(baseValue.isCell() && subscript.isString())) { Identifier propertyName(callFrame, asString(subscript)->value(callFrame)); - PropertySlot slot(asCell(baseValue)); + PropertySlot slot(baseValue.asCell()); // JSString::value may have thrown, but we shouldn't find a property with a null identifier, // so we should miss this case and wind up in the CHECK_FOR_EXCEPTION_AT_END, below. - if (asCell(baseValue)->fastGetOwnPropertySlot(callFrame, propertyName, slot)) { + if (baseValue.asCell()->fastGetOwnPropertySlot(callFrame, propertyName, slot)) { JSValue result = slot.getValue(callFrame, propertyName); CHECK_FOR_EXCEPTION(); return JSValue::encode(result); @@ -2475,10 +2472,10 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub) double left; double right; if (src1.getNumber(left) && src2.getNumber(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left - right)); + return JSValue::encode(jsNumber(left - right)); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, src1.toNumber(callFrame) - src2.toNumber(callFrame)); + JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -2685,10 +2682,10 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_negate) double v; if (src.getNumber(v)) - return JSValue::encode(jsNumber(stackFrame.globalData, -v)); + return JSValue::encode(jsNumber(-v)); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, -src.toNumber(callFrame)); + JSValue result = jsNumber(-src.toNumber(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -2808,10 +2805,10 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_div) double left; double right; if (src1.getNumber(left) && src2.getNumber(right)) - return JSValue::encode(jsNumber(stackFrame.globalData, left / right)); + return JSValue::encode(jsNumber(left / right)); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, src1.toNumber(callFrame) / src2.toNumber(callFrame)); + JSValue result = jsNumber(src1.toNumber(callFrame) / src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -2823,7 +2820,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_dec) JSValue v = stackFrame.args[0].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, v.toNumber(callFrame) - 1); + JSValue result = jsNumber(v.toNumber(callFrame) - 1); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -2891,7 +2888,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc) JSValue number = v.toJSNumber(callFrame); CHECK_FOR_EXCEPTION_AT_END(); - callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(stackFrame.globalData, number.uncheckedGetNumber() + 1); + callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number.uncheckedGetNumber() + 1); return JSValue::encode(number); } @@ -2906,14 +2903,14 @@ DEFINE_STUB_FUNCTION(int, op_eq) start: if (src2.isUndefined()) { return src1.isNull() || - (src1.isCell() && asCell(src1)->structure()->typeInfo().masqueradesAsUndefined()) || - src1.isUndefined(); + (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined()) + || src1.isUndefined(); } if (src2.isNull()) { return src1.isUndefined() || - (src1.isCell() && asCell(src1)->structure()->typeInfo().masqueradesAsUndefined()) || - src1.isNull(); + (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined()) + || src1.isNull(); } if (src1.isInt32()) { @@ -2949,12 +2946,12 @@ DEFINE_STUB_FUNCTION(int, op_eq) } if (src1.isUndefined()) - return src2.isCell() && asCell(src2)->structure()->typeInfo().masqueradesAsUndefined(); + return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined(); if (src1.isNull()) - return src2.isCell() && asCell(src2)->structure()->typeInfo().masqueradesAsUndefined(); + return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined(); - JSCell* cell1 = asCell(src1); + JSCell* cell1 = src1.asCell(); if (cell1->isString()) { if (src2.isInt32()) @@ -2969,7 +2966,7 @@ DEFINE_STUB_FUNCTION(int, op_eq) if (src2.isFalse()) return jsToNumber(static_cast(cell1)->value(stackFrame.callFrame)) == 0.0; - JSCell* cell2 = asCell(src2); + JSCell* cell2 = src2.asCell(); if (cell2->isString()) return static_cast(cell1)->value(stackFrame.callFrame) == static_cast(cell2)->value(stackFrame.callFrame); @@ -3019,7 +3016,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift) JSValue shift = stackFrame.args[1].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f)); + JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -3033,7 +3030,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitand) ASSERT(!src1.isInt32() || !src2.isInt32()); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, src1.toInt32(callFrame) & src2.toInt32(callFrame)); + JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -3046,7 +3043,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift) JSValue shift = stackFrame.args[1].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); + JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); @@ -3060,7 +3057,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitnot) ASSERT(!src.isInt32()); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, ~src.toInt32(callFrame)); + JSValue result = jsNumber(~src.toInt32(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -3134,7 +3131,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod) CallFrame* callFrame = stackFrame.callFrame; double d = dividendValue.toNumber(callFrame); - JSValue result = jsNumber(stackFrame.globalData, fmod(d, divisorValue.toNumber(callFrame))); + JSValue result = jsNumber(fmod(d, divisorValue.toNumber(callFrame))); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -3160,7 +3157,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec) JSValue number = v.toJSNumber(callFrame); CHECK_FOR_EXCEPTION_AT_END(); - callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(stackFrame.globalData, number.uncheckedGetNumber() - 1); + callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number.uncheckedGetNumber() - 1); return JSValue::encode(number); } @@ -3172,7 +3169,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift) JSValue shift = stackFrame.args[1].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); + JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -3186,7 +3183,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor) CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, src1.toInt32(callFrame) ^ src2.toInt32(callFrame)); + JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -3207,7 +3204,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor) CallFrame* callFrame = stackFrame.callFrame; - JSValue result = jsNumber(stackFrame.globalData, src1.toInt32(callFrame) | src2.toInt32(callFrame)); + JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -3232,43 +3229,20 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval) JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject; if (baseValue == globalObject && funcVal == globalObject->evalFunction()) { - JSValue exceptionValue; - JSValue result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue); - if (UNLIKELY(exceptionValue)) { - stackFrame.globalData->exception = exceptionValue; - VM_THROW_EXCEPTION_AT_END(); - } + JSValue result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset); + CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } return JSValue::encode(JSValue()); } -DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw) +DEFINE_STUB_FUNCTION(void*, op_throw) { STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - CodeBlock* codeBlock = callFrame->codeBlock(); - - unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS); - - JSValue exceptionValue = stackFrame.args[0].jsValue(); - ASSERT(exceptionValue); - - HandlerInfo* handler = stackFrame.globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, true); - - if (!handler) { - *stackFrame.exception = exceptionValue; - STUB_SET_RETURN_ADDRESS(FunctionPtr(ctiOpThrowNotCaught).value()); - return JSValue::encode(jsNull()); - } - - stackFrame.callFrame = callFrame; - void* catchRoutine = handler->nativeCode.executableAddress(); - ASSERT(catchRoutine); - STUB_SET_RETURN_ADDRESS(catchRoutine); - return JSValue::encode(exceptionValue); + ExceptionHandler handler = jitThrow(stackFrame.globalData, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS, true); + STUB_SET_RETURN_ADDRESS(handler.catchRoutine); + return handler.callFrame; } DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames) @@ -3617,32 +3591,13 @@ DEFINE_STUB_FUNCTION(void, op_debug) stackFrame.globalData->interpreter->debug(callFrame, static_cast(debugHookID), firstLine, lastLine); } -DEFINE_STUB_FUNCTION(EncodedJSValue, vm_throw) +DEFINE_STUB_FUNCTION(void*, vm_throw) { STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - CodeBlock* codeBlock = callFrame->codeBlock(); JSGlobalData* globalData = stackFrame.globalData; - - unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, globalData->exceptionLocation); - - JSValue exceptionValue = globalData->exception; - ASSERT(exceptionValue); - globalData->exception = JSValue(); - - HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, false); - - if (!handler) { - *stackFrame.exception = exceptionValue; - return JSValue::encode(jsNull()); - } - - stackFrame.callFrame = callFrame; - void* catchRoutine = handler->nativeCode.executableAddress(); - ASSERT(catchRoutine); - STUB_SET_RETURN_ADDRESS(catchRoutine); - return JSValue::encode(exceptionValue); + ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation, false); + STUB_SET_RETURN_ADDRESS(handler.catchRoutine); + return handler.callFrame; } DEFINE_STUB_FUNCTION(EncodedJSValue, to_object) diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h index b91a074..c27ee52 100644 --- a/JavaScriptCore/jit/JITStubs.h +++ b/JavaScriptCore/jit/JITStubs.h @@ -97,7 +97,7 @@ namespace JSC { void* code; RegisterFile* registerFile; CallFrame* callFrame; - JSValue* exception; + void* unused1; Profiler** enabledProfilerReference; JSGlobalData* globalData; @@ -133,7 +133,7 @@ namespace JSC { void* code; RegisterFile* registerFile; CallFrame* callFrame; - JSValue* exception; + void* unused1; Profiler** enabledProfilerReference; JSGlobalData* globalData; @@ -161,7 +161,7 @@ namespace JSC { // These arguments passed in r1..r3 (r0 contained the entry code pointed, which is not preserved) RegisterFile* registerFile; CallFrame* callFrame; - JSValue* exception; + void* unused1; // These arguments passed on the stack. Profiler** enabledProfilerReference; @@ -189,7 +189,7 @@ namespace JSC { RegisterFile* registerFile; CallFrame* callFrame; - JSValue* exception; + void* unused1; // These arguments passed on the stack. Profiler** enabledProfilerReference; @@ -221,7 +221,7 @@ namespace JSC { // These arguments passed in a1..a3 (a0 contained the entry code pointed, which is not preserved) RegisterFile* registerFile; CallFrame* callFrame; - JSValue* exception; + void* unused1; // These arguments passed on the stack. Profiler** enabledProfilerReference; @@ -252,7 +252,7 @@ namespace JSC { extern "C" void ctiVMThrowTrampoline(); extern "C" void ctiOpThrowNotCaught(); - extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*); + extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*); class JITThunks { public: @@ -348,13 +348,11 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_to_jsnumber(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION); - EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION); JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION); @@ -395,7 +393,6 @@ extern "C" { void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION); void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION); - void JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION); void* JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION); void* JIT_STUB cti_op_construct_arityCheck(STUB_ARGS_DECLARATION); void* JIT_STUB cti_op_call_jitCompile(STUB_ARGS_DECLARATION); @@ -403,8 +400,11 @@ extern "C" { void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION); void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION); void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION); void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION); void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION); + void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION); } // extern "C" } // namespace JSC -- cgit v1.1