JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString message(makeUString("Can't find variable: ", ident.ustring())); JSObject* exception = addErrorInfo(exec, createReferenceError(exec, message), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset); return exception; }
JSValue createNotAFunctionError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* 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, value, "not a function"); JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset); return exception; }
JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* 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, divotPoint + endOffset, value, makeUString("not a valid argument for '", op, "'")); JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset); return exception; }
JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source) { JSGlobalData* globalData = &exec->globalData(); addErrorInfo(globalData, error, line, source); JSArray* stack = constructEmptyArray(exec); CallFrame* frame = exec; JSObject* stackFrame; CodeBlock* codeBlock; UString sourceURL; UString functionName; ReturnAddressPtr pc; while (!frame->hasHostCallFrameFlag()) { stackFrame = constructEmptyObject(exec); codeBlock = frame->codeBlock(); // sourceURL sourceURL = codeBlock->ownerExecutable()->sourceURL(); stackFrame->putWithAttributes( globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete ); // line if (frame != exec) { line = codeBlock->lineNumberForBytecodeOffset(codeBlock->bytecodeOffset(pc)); } stackFrame->putWithAttributes( globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete ); // function JSObject* function = frame->callee(); if (function && function->inherits(&JSFunction::s_info)) { functionName = asFunction(function)->calculatedDisplayName(exec); stackFrame->putWithAttributes( globalData, Identifier(globalData, functionPropertyName), jsString(globalData, functionName), ReadOnly | DontDelete ); } stack->push(exec, JSValue(stackFrame)); pc = frame->returnPC(); frame = frame->callerFrame(); } error->putWithAttributes(globalData, Identifier(globalData, stackPropertyName), stack, ReadOnly | DontDelete); return error; }
JSObject* ProgramExecutable::checkSyntax(ExecState* exec) { int errLine; UString errMsg; JSGlobalData* globalData = &exec->globalData(); JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject->debugger(), exec, m_source, &errLine, &errMsg); if (!programNode) return addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, m_source); return 0; }
JSObject* createNotAConstructorError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); // We're in a "new" expression, so we need to skip over the "new.." part int startPoint = divotPoint - (startOffset ? startOffset - 4 : 0); // -4 for "new " const UChar* data = codeBlock->source()->data(); while (startPoint < divotPoint && isStrWhiteSpace(data[startPoint])) startPoint++; UString errorMessage = createErrorMessage(exec, codeBlock, line, startPoint, divotPoint, value, "not a constructor"); 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_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* ProgramExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode) { int errLine; UString errMsg; JSGlobalData* globalData = &exec->globalData(); JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject->debugger(), exec, m_source, &errLine, &errMsg); if (!programNode) return addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, m_source); recordParse(programNode->features(), programNode->lineNo(), programNode->lastLine()); ScopeChain scopeChain(scopeChainNode); JSGlobalObject* globalObject = scopeChain.globalObject(); ASSERT(!m_programCodeBlock); m_programCodeBlock = new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()); OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(programNode.get(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock)); generator->generate(); programNode->destroyData(); return 0; }
TiObject* addErrorInfo(TiExcState* exec, TiObject* error, int line, const SourceCode& source) { return addErrorInfo(&exec->globalData(), error, line, source); }
JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source) { JSGlobalData* globalData = &exec->globalData(); addErrorInfo(globalData, error, line, source); UStringBuilder stackString; JSArray* stackArray = constructEmptyArray(exec); CallFrame* frame = exec; stackString.append(error->toString(exec)); bool functionKnown; ReturnAddressPtr pc; while (!frame->hasHostCallFrameFlag()) { CodeBlock* codeBlock = frame->codeBlock(); JSObject* arrayItem = constructEmptyObject(exec); stackString.append("\n at "); JSObject* callee = frame->callee(); UString functionName; if (callee && callee->inherits(&JSFunction::s_info)) { functionName = asFunction(callee)->calculatedDisplayName(exec); functionKnown = !functionName.isEmpty(); } else { functionKnown = false; } if (functionKnown) { stackString.append(functionName); stackString.append(" ("); arrayItem->putWithAttributes( globalData, Identifier(globalData, functionPropertyName), jsString(globalData, functionName), ReadOnly | DontDelete ); } UString sourceURL = codeBlock->ownerExecutable()->sourceURL(); arrayItem->putWithAttributes( globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete ); stackString.append(sourceURL); stackString.append(":"); if (frame != exec) { line = codeBlock->lineNumberForBytecodeOffset(codeBlock->bytecodeOffset(pc)); } arrayItem->putWithAttributes( globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete ); stackString.append(UString::number(line)); if (functionKnown) { stackString.append(")"); } stackArray->push(exec, JSValue(arrayItem)); pc = frame->returnPC(); frame = frame->callerFrame(); } error->putWithAttributes( globalData, Identifier(globalData, stackPropertyName), jsString(globalData, stackString.toUString()), ReadOnly | DontDelete ); error->putWithAttributes( globalData, Identifier(globalData, "stackArray"), stackArray, ReadOnly | DontDelete ); return error; }