diff options
Diffstat (limited to 'Source/JavaScriptCore/jit/JITStubs.cpp')
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.cpp | 235 |
1 files changed, 162 insertions, 73 deletions
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index 74f505f..953bd11 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -40,7 +40,7 @@ #include "Debugger.h" #include "ExceptionHelpers.h" #include "GetterSetter.h" -#include "GlobalEvalFunction.h" +#include "Strong.h" #include "JIT.h" #include "JSActivation.h" #include "JSArray.h" @@ -67,7 +67,7 @@ using namespace std; namespace JSC { -#if OS(DARWIN) || OS(WINDOWS) +#if OS(DARWIN) || (OS(WINDOWS) && CPU(X86)) #define SYMBOL_STRING(name) "_" #name #else #define SYMBOL_STRING(name) #name @@ -81,7 +81,7 @@ namespace JSC { #if (OS(LINUX) || OS(FREEBSD)) && CPU(X86_64) #define SYMBOL_STRING_RELOCATION(name) #name "@plt" -#elif OS(DARWIN) +#elif OS(DARWIN) || (CPU(X86_64) && COMPILER(MINGW) && !GCC_VERSION_AT_LEAST(4, 5, 0)) #define SYMBOL_STRING_RELOCATION(name) "_" #name #elif CPU(X86) && COMPILER(MINGW) #define SYMBOL_STRING_RELOCATION(name) "@" #name "@4" @@ -314,7 +314,79 @@ extern "C" { #define ENABLE_PROFILER_REFERENCE_OFFSET 96 #define GLOBAL_DATA_OFFSET 100 #define STACK_LENGTH 104 +#elif CPU(SH4) +#define SYMBOL_STRING(name) #name +/* code (r4), RegisterFile* (r5), CallFrame* (r6), JSValue* exception (r7), Profiler**(sp), JSGlobalData (sp)*/ + +asm volatile ( +".text\n" +".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" +SYMBOL_STRING(ctiTrampoline) ":" "\n" + "mov.l r7, @-r15" "\n" + "mov.l r6, @-r15" "\n" + "mov.l r5, @-r15" "\n" + "mov.l r8, @-r15" "\n" + "mov #127, r8" "\n" + "mov.l r14, @-r15" "\n" + "sts.l pr, @-r15" "\n" + "mov.l r13, @-r15" "\n" + "mov.l r11, @-r15" "\n" + "mov.l r10, @-r15" "\n" + "add #-60, r15" "\n" + "mov r6, r14" "\n" + "jsr @r4" "\n" + "nop" "\n" + "add #60, r15" "\n" + "mov.l @r15+,r10" "\n" + "mov.l @r15+,r11" "\n" + "mov.l @r15+,r13" "\n" + "lds.l @r15+,pr" "\n" + "mov.l @r15+,r14" "\n" + "mov.l @r15+,r8" "\n" + "add #12, r15" "\n" + "rts" "\n" + "nop" "\n" +); + +asm volatile ( +".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" +SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" + "mov.l .L2"SYMBOL_STRING(cti_vm_throw)",r0" "\n" + "mov r15, r4" "\n" + "mov.l @(r0,r12),r11" "\n" + "jsr @r11" "\n" + "nop" "\n" + "add #60, r15" "\n" + "mov.l @r15+,r10" "\n" + "mov.l @r15+,r11" "\n" + "mov.l @r15+,r13" "\n" + "lds.l @r15+,pr" "\n" + "mov.l @r15+,r14" "\n" + "mov.l @r15+,r8" "\n" + "add #12, r15" "\n" + "rts" "\n" + "nop" "\n" + ".align 2" "\n" + ".L2"SYMBOL_STRING(cti_vm_throw)":.long " SYMBOL_STRING(cti_vm_throw)"@GOT \n" +); +asm volatile ( +".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" +SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" + "add #60, r15" "\n" + "mov.l @r15+,r10" "\n" + "mov.l @r15+,r11" "\n" + "mov.l @r15+,r13" "\n" + "lds.l @r15+,pr" "\n" + "mov.l @r15+,r14" "\n" + "mov.l @r15+,r8" "\n" + "add #12, r15" "\n" + "rts" "\n" + "nop" "\n" +); #else #error "JIT not supported on this platform." #endif @@ -680,6 +752,7 @@ __asm void ctiOpThrowNotCaught() #endif JITThunks::JITThunks(JSGlobalData* globalData) + : m_hostFunctionStubMap(new HostFunctionStubMap) { if (!globalData->executableAllocator.isValid()) return; @@ -717,7 +790,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_OFFSET); - ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == EXCEPTION_OFFSET); + ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, unused1) == EXCEPTION_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == ENABLE_PROFILER_REFERENCE_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == GLOBAL_DATA_OFFSET); @@ -770,12 +843,12 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co normalizePrototypeChain(callFrame, baseCell); StructureChain* prototypeChain = structure->prototypeChain(callFrame); - stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain); + stubInfo->initPutByIdTransition(callFrame->globalData(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain); JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct); return; } - stubInfo->initPutByIdReplace(structure); + stubInfo->initPutByIdReplace(callFrame->globalData(), codeBlock->ownerExecutable(), structure); JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct); } @@ -823,7 +896,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co if (slot.slotBase() == baseValue) { // set this up, so derefStructures can do it's job. - stubInfo->initGetByIdSelf(structure); + stubInfo->initGetByIdSelf(callFrame->globalData(), codeBlock->ownerExecutable(), structure); if (slot.cachedPropertyType() != PropertySlot::Value) ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail)); else @@ -846,10 +919,10 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co // should not be treated as a dictionary. if (slotBaseObject->structure()->isDictionary()) { slotBaseObject->flattenDictionaryObject(callFrame->globalData()); - offset = slotBaseObject->structure()->get(propertyName); + offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName); } - stubInfo->initGetByIdProto(structure, slotBaseObject->structure()); + stubInfo->initGetByIdProto(callFrame->globalData(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure()); ASSERT(!structure->isDictionary()); ASSERT(!slotBaseObject->structure()->isDictionary()); @@ -865,7 +938,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co } StructureChain* prototypeChain = structure->prototypeChain(callFrame); - stubInfo->initGetByIdChain(structure, prototypeChain); + stubInfo->initGetByIdChain(callFrame->globalData(), codeBlock->ownerExecutable(), structure, prototypeChain); JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress); } @@ -942,17 +1015,17 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD #define CHECK_FOR_EXCEPTION() \ do { \ - if (UNLIKELY(stackFrame.globalData->exception.get())) \ + if (UNLIKELY(stackFrame.globalData->exception)) \ VM_THROW_EXCEPTION(); \ } while (0) #define CHECK_FOR_EXCEPTION_AT_END() \ do { \ - if (UNLIKELY(stackFrame.globalData->exception.get())) \ + if (UNLIKELY(stackFrame.globalData->exception)) \ VM_THROW_EXCEPTION_AT_END(); \ } while (0) #define CHECK_FOR_EXCEPTION_VOID() \ do { \ - if (UNLIKELY(stackFrame.globalData->exception.get())) { \ + if (UNLIKELY(stackFrame.globalData->exception)) { \ VM_THROW_EXCEPTION_AT_END(); \ return; \ } \ @@ -977,7 +1050,7 @@ static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame, return exceptionHandler; } -#if CPU(ARM_THUMB2) +#if CPU(ARM_THUMB2) && COMPILER(GCC) #define DEFINE_STUB_FUNCTION(rtype, op) \ extern "C" { \ @@ -1073,7 +1146,7 @@ static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame, ); \ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) -#elif CPU(ARM_TRADITIONAL) && COMPILER(RVCT) +#elif (CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL)) && COMPILER(RVCT) #define DEFINE_STUB_FUNCTION(rtype, op) rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) @@ -1086,7 +1159,7 @@ static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame, RVCT(extern "C" #rtype# JITStubThunked_#op#(STUB_ARGS_DECLARATION);) RVCT(__asm #rtype# cti_#op#(STUB_ARGS_DECLARATION)) RVCT({) -RVCT( ARM) +RVCT( PRESERVE8) RVCT( IMPORT JITStubThunked_#op#) RVCT( str lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET]) RVCT( bl JITStubThunked_#op#) @@ -1155,6 +1228,29 @@ MSVC() MSVC_END( END) */ +#elif CPU(SH4) +#define DEFINE_STUB_FUNCTION(rtype, op) \ + extern "C" { \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \ + }; \ + asm volatile( \ + ".align 2" "\n" \ + ".globl " SYMBOL_STRING(cti_##op) "\n" \ + SYMBOL_STRING(cti_##op) ":" "\n" \ + "sts pr, r11" "\n" \ + "mov.l r11, @(0x38, r15)" "\n" \ + "mov.l .L2"SYMBOL_STRING(JITStubThunked_##op)",r0" "\n" \ + "mov.l @(r0,r12),r11" "\n" \ + "jsr @r11" "\n" \ + "nop" "\n" \ + "mov.l @(0x38, r15), r11 " "\n" \ + "lds r11, pr " "\n" \ + "rts" "\n" \ + "nop" "\n" \ + ".align 2" "\n" \ + ".L2"SYMBOL_STRING(JITStubThunked_##op)":.long " SYMBOL_STRING(JITStubThunked_##op)"@GOT \n" \ + ); \ + rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) #else #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION) #endif @@ -1173,10 +1269,10 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this) Structure* structure; JSValue proto = stackFrame.args[0].jsValue(); if (proto.isObject()) - structure = asObject(proto)->inheritorID(); + structure = asObject(proto)->inheritorID(*stackFrame.globalData); else - structure = constructor->scope().node()->globalObject->emptyObjectStructure(); - JSValue result = new (&callFrame->globalData()) JSObject(structure); + structure = constructor->scope()->globalObject->emptyObjectStructure(); + JSValue result = constructEmptyObject(callFrame, structure); return JSValue::encode(result); } @@ -1205,15 +1301,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this_strict) return JSValue::encode(result); } -DEFINE_STUB_FUNCTION(void, op_end) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - ScopeChainNode* scopeChain = stackFrame.callFrame->scopeChain(); - ASSERT(scopeChain->refCount > 1); - scopeChain->deref(); -} - DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) { STUB_INIT_STACK_FRAME(stackFrame); @@ -1473,7 +1560,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check) // Check to see if the function is on the object's prototype. Patch up the code to optimize. if (slot.slotBase() == structure->prototypeForLookup(callFrame)) { - JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS); + JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS); return JSValue::encode(result); } @@ -1484,7 +1571,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check) // for now. For now it performs a check on a special object on the global object only used for this // purpose. The object is in no way exposed, and as such the check will always pass. if (slot.slotBase() == baseValue) { - JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS); + JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS); return JSValue::encode(result); } } @@ -1543,7 +1630,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) if (stubInfo->accessType == access_get_by_id_self) { ASSERT(!stubInfo->stubRoutine); - polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure); + polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure.get()); stubInfo->initGetByIdSelfList(polymorphicStructureList, 1); } else { polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList; @@ -1561,19 +1648,19 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) return JSValue::encode(result); } -static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex) +static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSGlobalData& globalData, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex) { PolymorphicAccessStructureList* prototypeStructureList = 0; listIndex = 1; switch (stubInfo->accessType) { case access_get_by_id_proto: - prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure); + prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get()); stubInfo->stubRoutine = CodeLocationLabel(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; case access_get_by_id_chain: - prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain); + prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get()); stubInfo->stubRoutine = CodeLocationLabel(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; @@ -1657,11 +1744,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) // should not be treated as a dictionary. if (slotBaseObject->structure()->isDictionary()) { slotBaseObject->flattenDictionaryObject(callFrame->globalData()); - offset = slotBaseObject->structure()->get(propertyName); + offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName); } int listIndex; - PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex); if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset); @@ -1671,7 +1758,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) { ASSERT(!baseValue.asCell()->structure()->isDictionary()); int listIndex; - PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex); if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { StructureChain* protoChain = structure->prototypeChain(callFrame); @@ -1848,7 +1935,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_jitCompile) JSFunction* function = asFunction(stackFrame.callFrame->callee()); ASSERT(!function->isHostFunction()); FunctionExecutable* executable = function->jsExecutable(); - ScopeChainNode* callDataScopeChain = function->scope().node(); + ScopeChainNode* callDataScopeChain = function->scope(); JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain); if (error) { stackFrame.callFrame->globalData().exception = error; @@ -1869,7 +1956,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile) JSFunction* function = asFunction(stackFrame.callFrame->callee()); ASSERT(!function->isHostFunction()); FunctionExecutable* executable = function->jsExecutable(); - ScopeChainNode* callDataScopeChain = function->scope().node(); + ScopeChainNode* callDataScopeChain = function->scope(); JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain); if (error) { stackFrame.callFrame->globalData().exception = error; @@ -1930,7 +2017,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck) callFrame->setCallerFrame(oldCallFrame); callFrame->setArgumentCountIncludingThis(argCount); callFrame->setCallee(callee); - callFrame->setScopeChain(callee->scope().node()); + callFrame->setScopeChain(callee->scope()); callFrame->setReturnPC(pc.value()); ASSERT((void*)callFrame <= stackFrame.registerFile->end()); @@ -1989,7 +2076,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck) callFrame->setCallerFrame(oldCallFrame); callFrame->setArgumentCountIncludingThis(argCount); callFrame->setCallee(callee); - callFrame->setScopeChain(callee->scope().node()); + callFrame->setScopeChain(callee->scope()); callFrame->setReturnPC(pc.value()); ASSERT((void*)callFrame <= stackFrame.registerFile->end()); @@ -2010,7 +2097,7 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall) codePtr = executable->generatedJITCodeForCall().addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); - JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope().node()); + JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope()); if (error) { callFrame->globalData().exception = createStackOverflowError(callFrame); return 0; @@ -2044,7 +2131,7 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct) codePtr = executable->generatedJITCodeForConstruct().addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); - JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope().node()); + JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope()); if (error) { throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS); return 0; @@ -2071,7 +2158,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_push_activation) STUB_INIT_STACK_FRAME(stackFrame); JSActivation* activation = new (stackFrame.globalData) JSActivation(stackFrame.callFrame, static_cast<FunctionExecutable*>(stackFrame.callFrame->codeBlock()->ownerExecutable())); - stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->copy()->push(activation)); + stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(activation)); return activation; } @@ -2139,12 +2226,12 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_activation) if (!activationValue) { if (JSValue v = stackFrame.args[1].jsValue()) { if (!stackFrame.callFrame->codeBlock()->isStrictMode()) - asArguments(v)->copyRegisters(); + asArguments(v)->copyRegisters(*stackFrame.globalData); } return; } JSActivation* activation = asActivation(stackFrame.args[0].jsValue()); - activation->copyRegisters(); + activation->copyRegisters(*stackFrame.globalData); if (JSValue v = stackFrame.args[1].jsValue()) { if (!stackFrame.callFrame->codeBlock()->isStrictMode()) asArguments(v)->setActivation(*stackFrame.globalData, activation); @@ -2156,7 +2243,7 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_arguments) STUB_INIT_STACK_FRAME(stackFrame); ASSERT(stackFrame.callFrame->codeBlock()->usesArguments() && !stackFrame.callFrame->codeBlock()->needsFullScopeChain()); - asArguments(stackFrame.args[0].jsValue())->copyRegisters(); + asArguments(stackFrame.args[0].jsValue())->copyRegisters(*stackFrame.globalData); } DEFINE_STUB_FUNCTION(void, op_profile_will_call) @@ -2175,14 +2262,6 @@ DEFINE_STUB_FUNCTION(void, op_profile_did_call) (*stackFrame.enabledProfilerReference)->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue()); } -DEFINE_STUB_FUNCTION(void, op_ret_scopeChain) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain()); - stackFrame.callFrame->scopeChain()->deref(); -} - DEFINE_STUB_FUNCTION(JSObject*, op_new_array) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2525,7 +2604,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) stackFrame.globalData->exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments); VM_THROW_EXCEPTION(); } - if (asObject(arguments)->classInfo() == &Arguments::info) { + if (asObject(arguments)->classInfo() == &Arguments::s_info) { Arguments* argsObject = asArguments(arguments); argCount = argsObject->numProvidedArguments(callFrame); argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); @@ -2547,7 +2626,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) VM_THROW_EXCEPTION(); } array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); - } else if (asObject(arguments)->inherits(&JSArray::info)) { + } else if (asObject(arguments)->inherits(&JSArray::s_info)) { JSObject* argObject = asObject(arguments); argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments)); @@ -2674,10 +2753,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global) JSValue result = slot.getValue(callFrame, ident); if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { GlobalResolveInfo& globalResolveInfo = codeBlock->globalResolveInfo(globalResolveInfoIndex); - if (globalResolveInfo.structure) - globalResolveInfo.structure->deref(); - globalObject->structure()->ref(); - globalResolveInfo.structure = globalObject->structure(); + globalResolveInfo.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure()); globalResolveInfo.offset = slot.cachedOffset(); return JSValue::encode(result); } @@ -3009,7 +3085,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp) */ if (!function->name().isNull()) { JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete); - func->scope().push(functionScopeObject); + func->setScope(callFrame->globalData(), func->scope()->push(functionScopeObject)); } return func; @@ -3085,7 +3161,15 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp) { STUB_INIT_STACK_FRAME(stackFrame); - return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), stackFrame.args[0].regExp()); + CallFrame* callFrame = stackFrame.callFrame; + + RegExp* regExp = stackFrame.args[0].regExp(); + if (!regExp->isValid()) { + stackFrame.globalData->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor."); + VM_THROW_EXCEPTION(); + } + + return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp); } DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor) @@ -3119,7 +3203,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval) Register* newCallFrame = callFrame->registers() + registerOffset; Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount; JSValue baseValue = argv[0].jsValue(); - JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject; + JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject.get(); if (baseValue == globalObject && funcVal == globalObject->evalFunction()) { JSValue result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset); @@ -3480,7 +3564,7 @@ DEFINE_STUB_FUNCTION(void*, vm_throw) { STUB_INIT_STACK_FRAME(stackFrame); JSGlobalData* globalData = stackFrame.globalData; - ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception.get(), globalData->exceptionLocation); + ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation); STUB_SET_RETURN_ADDRESS(handler.catchRoutine); return handler.callFrame; } @@ -3501,22 +3585,27 @@ MacroAssemblerCodePtr JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerato return entry.first->second; } -PassRefPtr<NativeExecutable> JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function) +NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function) { - std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap.add(function, 0); + std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Strong<NativeExecutable>()); if (entry.second) - entry.first->second = NativeExecutable::create(JIT::compileCTINativeCall(globalData, m_executablePool, function), function, ctiNativeConstruct(), callHostFunctionAsConstructor); - return entry.first->second; + entry.first->second.set(*globalData, NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, m_executablePool, function), function, ctiNativeConstruct(), callHostFunctionAsConstructor)); + return entry.first->second.get(); } -PassRefPtr<NativeExecutable> JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator) +NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator) { - std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap.add(function, 0); + std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Strong<NativeExecutable>()); if (entry.second) { MacroAssemblerCodePtr code = globalData->canUseJIT() ? generator(globalData, m_executablePool.get()) : MacroAssemblerCodePtr(); - entry.first->second = NativeExecutable::create(code, function, ctiNativeConstruct(), callHostFunctionAsConstructor); + entry.first->second.set(*globalData, NativeExecutable::create(*globalData, code, function, ctiNativeConstruct(), callHostFunctionAsConstructor)); } - return entry.first->second; + return entry.first->second.get(); +} + +void JITThunks::clearHostFunctionStubs() +{ + m_hostFunctionStubMap.clear(); } } // namespace JSC |