JSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec, JSObject* constructor, JSValue, const ArgList&) { CodeBlock* codeBlock = exec->callerFrame()->codeBlock(); unsigned vPCIndex = codeBlock->bytecodeOffset(exec, exec->returnPC()); exec->setException(createNotAConstructorError(exec, constructor, vPCIndex, codeBlock)); return JSValue(); }
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; }
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); VM* vm = &exec->vm(); execCallee->setScope(exec->scope()); execCallee->setCodeBlock(0); if (kind == CodeForCall) { CallData callData; CallType callType = getCallData(callee, callData); ASSERT(callType != CallTypeJS); if (callType == CallTypeHost) { NativeCallFrameTracer tracer(vm, execCallee); execCallee->setCallee(asObject(callee)); vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); if (vm->exception()) return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); return reinterpret_cast<void*>(getHostCallReturnValue); } ASSERT(callType == CallTypeNone); exec->vm().throwException(exec, createNotAFunctionError(exec, callee)); return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); } ASSERT(kind == CodeForConstruct); ConstructData constructData; ConstructType constructType = getConstructData(callee, constructData); ASSERT(constructType != ConstructTypeJS); if (constructType == ConstructTypeHost) { NativeCallFrameTracer tracer(vm, execCallee); execCallee->setCallee(asObject(callee)); vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee)); if (vm->exception()) return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); return reinterpret_cast<void*>(getHostCallReturnValue); } ASSERT(constructType == ConstructTypeNone); exec->vm().throwException(exec, createNotAConstructorError(exec, callee)); return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(); }
JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, unsigned bytecodeOffset, CodeBlock* codeBlock) { // Both op_create_this and op_instanceof require a use of op_get_by_id to get // the prototype property from an object. The exception messages for exceptions // thrown by these instances op_get_by_id need to reflect this. OpcodeID followingOpcodeID; if (codeBlock->getByIdExceptionInfoForBytecodeOffset(exec, bytecodeOffset, followingOpcodeID)) { ASSERT(followingOpcodeID == op_create_this || followingOpcodeID == op_instanceof); if (followingOpcodeID == op_create_this) return createNotAConstructorError(exec, error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock); return createInvalidParamError(exec, "instanceof", error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock); } int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object"); JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset); return exception; }
JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, unsigned bytecodeOffset, CodeBlock* codeBlock) { // Both op_construct and op_instanceof require a use of op_get_by_id to get // the prototype property from an object. The exception messages for exceptions // thrown by these instances op_get_by_id need to reflect this. OpcodeID followingOpcodeID; if (codeBlock->getByIdExceptionInfoForBytecodeOffset(exec, bytecodeOffset, followingOpcodeID)) { ASSERT(followingOpcodeID == op_construct || followingOpcodeID == op_instanceof); if (followingOpcodeID == op_construct) return createNotAConstructorError(exec, error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock); return createInvalidParamError(exec, "instanceof", error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock); } int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object"); JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); return exception; }
EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec) { return throwVMError(exec, createNotAConstructorError(exec, exec->callee())); }
EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec) { CodeBlock* codeBlock = exec->callerFrame()->codeBlock(); unsigned vPCIndex = codeBlock->bytecodeOffset(exec, exec->returnPC()); return throwVMError(exec, createNotAConstructorError(exec, exec->callee(), vPCIndex, codeBlock)); }