Changeset 42337 in webkit for trunk/JavaScriptCore/interpreter/Interpreter.cpp
- Timestamp:
- Apr 8, 2009, 4:08:28 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r42065 r42337 2973 2973 goto vm_throw; 2974 2974 } 2975 DEFINE_OPCODE(op_load_varargs) { 2976 int argCountDst = (++vPC)->u.operand; 2977 int argsOffset = (++vPC)->u.operand; 2978 2979 JSValuePtr arguments = callFrame[argsOffset].jsValue(callFrame); 2980 uint32_t argCount = 0; 2981 if (!arguments.isUndefinedOrNull()) { 2982 if (!arguments.isObject()) { 2983 exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock()); 2984 goto vm_throw; 2985 } 2986 if (asObject(arguments)->classInfo() == &Arguments::info) { 2987 Arguments* args = asArguments(arguments); 2988 argCount = args->numProvidedArguments(callFrame); 2989 int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 2990 Register* newEnd = callFrame->registers() + sizeDelta; 2991 if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 2992 exceptionValue = createStackOverflowError(callFrame); 2993 goto vm_throw; 2994 } 2995 args->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); 2996 } else if (isJSArray(&callFrame->globalData(), arguments)) { 2997 JSArray* array = asArray(arguments); 2998 argCount = array->length(); 2999 int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 3000 Register* newEnd = callFrame->registers() + sizeDelta; 3001 if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 3002 exceptionValue = createStackOverflowError(callFrame); 3003 goto vm_throw; 3004 } 3005 array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); 3006 } else if (asObject(arguments)->inherits(&JSArray::info)) { 3007 JSObject* argObject = asObject(arguments); 3008 argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); 3009 int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 3010 Register* newEnd = callFrame->registers() + sizeDelta; 3011 if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 3012 exceptionValue = createStackOverflowError(callFrame); 3013 goto vm_throw; 3014 } 3015 Register* argsBuffer = callFrame->registers() + argsOffset; 3016 for (unsigned i = 0; i < argCount; ++i) { 3017 argsBuffer[i] = asObject(arguments)->get(callFrame, i); 3018 CHECK_FOR_EXCEPTION(); 3019 } 3020 } else { 3021 if (!arguments.isObject()) { 3022 exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock()); 3023 goto vm_throw; 3024 } 3025 } 3026 } 3027 CHECK_FOR_EXCEPTION(); 3028 callFrame[argCountDst] = argCount + 1; 3029 ++vPC; 3030 NEXT_INSTRUCTION(); 3031 } 3032 DEFINE_OPCODE(op_call_varargs) { 3033 /* call_varargs dst(r) func(r) argCountReg(r) baseRegisterOffset(n) 3034 3035 Perform a function call with a dynamic set of arguments. 3036 3037 registerOffset is the distance the callFrame pointer should move 3038 before the VM initializes the new call frame's header, excluding 3039 space for arguments. 3040 3041 dst is where op_ret should store its result. 3042 */ 3043 3044 int dst = vPC[1].u.operand; 3045 int func = vPC[2].u.operand; 3046 int argCountReg = vPC[3].u.operand; 3047 int registerOffset = vPC[4].u.operand; 3048 3049 JSValuePtr v = callFrame[func].jsValue(callFrame); 3050 int argCount = callFrame[argCountReg].i(); 3051 registerOffset += argCount; 3052 CallData callData; 3053 CallType callType = v.getCallData(callData); 3054 3055 if (callType == CallTypeJS) { 3056 ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 3057 FunctionBodyNode* functionBodyNode = callData.js.functionBody; 3058 CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain); 3059 3060 CallFrame* previousCallFrame = callFrame; 3061 3062 callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 3063 if (UNLIKELY(!callFrame)) { 3064 callFrame = previousCallFrame; 3065 exceptionValue = createStackOverflowError(callFrame); 3066 goto vm_throw; 3067 } 3068 3069 callFrame->init(newCodeBlock, vPC + 5, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v)); 3070 vPC = newCodeBlock->instructions().begin(); 3071 3072 #if ENABLE(OPCODE_STATS) 3073 OpcodeStats::resetLastInstruction(); 3074 #endif 3075 3076 NEXT_INSTRUCTION(); 3077 } 3078 3079 if (callType == CallTypeHost) { 3080 ScopeChainNode* scopeChain = callFrame->scopeChain(); 3081 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 3082 newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, 0); 3083 3084 Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount; 3085 ArgList args(thisRegister + 1, argCount - 1); 3086 3087 // FIXME: All host methods should be calling toThisObject, but this is not presently the case. 3088 JSValuePtr thisValue = thisRegister->jsValue(callFrame); 3089 if (thisValue == jsNull()) 3090 thisValue = callFrame->globalThisValue(); 3091 3092 JSValuePtr returnValue; 3093 { 3094 SamplingTool::HostCallRecord callRecord(m_sampler); 3095 returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args); 3096 } 3097 CHECK_FOR_EXCEPTION(); 3098 3099 callFrame[dst] = JSValuePtr(returnValue); 3100 3101 vPC += 5; 3102 NEXT_INSTRUCTION(); 3103 } 3104 3105 ASSERT(callType == CallTypeNone); 3106 3107 exceptionValue = createNotAFunctionError(callFrame, v, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock()); 3108 goto vm_throw; 3109 } 2975 3110 DEFINE_OPCODE(op_tear_off_activation) { 2976 3111 /* tear_off_activation activation(r)
Note:
See TracChangeset
for help on using the changeset viewer.