static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSGlobalData* globalData = &exec->globalData(); if (kind == CodeForCall) { CallData callData; CallType callType = getCallData(callee, callData); ASSERT(callType != CallTypeJS); if (callType == CallTypeHost) { if (!globalData->interpreter->registerFile().grow(execCallee->registers())) { globalData->exception = createStackOverflowError(exec); return 0; } execCallee->setScopeChain(exec->scopeChain()); globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); if (globalData->exception) return 0; return reinterpret_cast<void*>(getHostCallReturnValue); } ASSERT(callType == CallTypeNone); exec->globalData().exception = createNotAFunctionError(exec, callee); return 0; } ASSERT(kind == CodeForConstruct); ConstructData constructData; ConstructType constructType = getConstructData(callee, constructData); ASSERT(constructType != ConstructTypeJS); if (constructType == ConstructTypeHost) { if (!globalData->interpreter->registerFile().grow(execCallee->registers())) { globalData->exception = createStackOverflowError(exec); return 0; } execCallee->setScopeChain(exec->scopeChain()); globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee)); if (globalData->exception) return 0; return reinterpret_cast<void*>(getHostCallReturnValue); } ASSERT(constructType == ConstructTypeNone); exec->globalData().exception = createNotAConstructorError(exec, callee); return 0; }
inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) return handleHostCall(execCallee, calleeAsValue, kind); JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScopeChain(callee->scopeUnchecked()); ExecutableBase* executable = callee->executable(); MacroAssemblerCodePtr codePtr; CodeBlock* codeBlock = 0; if (executable->isHostFunction()) codePtr = executable->generatedJITCodeFor(kind).addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind); if (error) { globalData->exception = createStackOverflowError(exec); return 0; } codeBlock = &functionExecutable->generatedBytecodeFor(kind); if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); else codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall(); } CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress); if (!callLinkInfo.seenOnce()) callLinkInfo.setSeen(); else dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); return codePtr.executableAddress(); }
inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); VM* vm = &exec->vm(); NativeCallFrameTracer tracer(vm, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind)); JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScope(callee->scopeUnchecked()); ExecutableBase* executable = callee->executable(); MacroAssemblerCodePtr codePtr; CodeBlock* codeBlock = 0; if (executable->isHostFunction()) codePtr = executable->generatedJITCodeFor(kind)->addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); if (error) { vm->throwException(exec, createStackOverflowError(exec)); return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); } codeBlock = functionExecutable->codeBlockFor(kind); if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); else codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall(); } CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC()); if (!callLinkInfo.seenOnce()) callLinkInfo.setSeen(); else linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); return reinterpret_cast<char*>(codePtr.executableAddress()); }
JSObject* throwStackOverflowError(ExecState* exec) { return throwError(exec, createStackOverflowError(exec)); }
JSObject* throwStackOverflowError(ExecState* exec) { VM& vm = exec->vm(); ErrorHandlingScope errorScope(vm); return vm.throwException(exec, createStackOverflowError(exec)); }
JSObject* throwStackOverflowError(ExecState* exec) { Interpreter::ErrorHandlingMode mode(exec); return exec->vm().throwException(exec, createStackOverflowError(exec)); }
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); bool isRealArray = isJSArray(&exec->globalData(), thisValue); if (!isRealArray && !thisValue.inherits(&JSArray::info)) return throwVMTypeError(exec); JSArray* thisObj = asArray(thisValue); HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) { if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth) return throwVMError(exec, createStackOverflowError(exec)); } bool alreadyVisited = !arrayVisitedElements.add(thisObj).second; if (alreadyVisited) return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoiding infinite recursion. //FYWEBKITMOD begin: setting up StringJoiner (while integrating r148721 due to fix of bug 114779). But not using 'ConstructFromLiteral' optimization which we dont have in our webkit. unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); //WebCore::String separator(",", WebCore::String::ConstructFromLiteral); //JSStringJoiner stringJoiner(separator, length); JSStringJoiner stringJoiner(",", length); //FYWEBKITMOD end unsigned totalSize = length ? length - 1 : 0; Vector<RefPtr<UString::Rep>, 256> strBuffer(length); for (unsigned k = 0; k < length; k++) { JSValue element; if (isRealArray && thisObj->canGetIndex(k)) element = thisObj->getIndex(k); else { element = thisObj->get(exec, k); //FYWEBKITMOD begin: added while integrating r148721 due to fix of bug 114779 if (exec->hadException()) return JSValue::encode(jsUndefined()); //FYWEBKITMOD end } //FYWEBKITMOD begin: removed (USE_FIX 1) old implementation which joined the strings manually and added usage of JSStringJoiner (while integrating r148721 due to fix of bug 114779) #define USE_FIX 1 //keep this defined!!! #ifdef USE_FIX if (element.isUndefinedOrNull()) stringJoiner.append(WebCore::String()); //FYWEBKITMOD: else stringJoiner.append(element.toString(exec).rep()); //FYWEBKITMOD: using toString() instead of new toWTFString(). Only difference is an optimization used in the toWTFString() case. if (exec->hadException()) return JSValue::encode(jsUndefined()); } arrayVisitedElements.remove(thisObj); return JSValue::encode(stringJoiner.build(exec)); #else if (element.isUndefinedOrNull()) continue; UString str = element.toString(exec); strBuffer[k] = str.rep(); totalSize += str.size(); if (!strBuffer.data()) { throwOutOfMemoryError(exec); } if (exec->hadException()) break; }