Commit 82a000d6 authored by timothy@apple.com's avatar timothy@apple.com

Made the starting line number of scripts be 1-based throughout the engine.

JavaScriptCore:

2008-05-30  Timothy Hatcher  <timothy@apple.com>

        Made the starting line number of scripts be 1-based throughout the engine.
        This cleans up script line numbers so they are all consistent now and fixes
        some cases where script execution was shown as off by one line in the debugger.

        No change in SunSpider.

        Reviewed by Oliver Hunt.

        * API/minidom.c:
        (main): Pass a line number of 1 instead of 0 to parser().parse().
        * API/testapi.c:
        (main): Ditto. And removes a FIXME and changed an assertEqualsAsNumber
        to use 1 instead of 2 for the line number.
        * VM/Machine.cpp:
        (KJS::callEval): Pass a line number of 1 instead of 0.
        (KJS::Machine::debug): Use firstLine for WillExecuteProgram instead of
        lastLine. Use lastLine for DidExecuteProgram instead of firstLine.
        * kjs/DebuggerCallFrame.cpp:
        (KJS::DebuggerCallFrame::evaluate): Pass a line number of 1 instead of
        0 to parser().parse().
        * kjs/Parser.cpp:
        (KJS::Parser::parse): ASSERT startingLineNumber is greatter than 0. Change
        the startingLineNumber to be 1 if it was less than or equal to 0. This is needed
        for release builds to maintain compatibility with the JavaScriptCore API.
        * kjs/function.cpp:
        (KJS::globalFuncEval): Pass a line number of 1 instead of 0 to parser().parse().
        * kjs/function_object.cpp:
        (FunctionObjectImp::construct): Pass a line number of 1 instead of 0 to construct().
        * kjs/lexer.cpp:
        (Lexer::setCode): Made yylineno = startingLineNumber instead of adding 1.
        * kjs/testkjs.cpp:
        (functionRun): Pass a line number of 1 instead of 0 to Interpreter::evaluate().
        (functionLoad): Ditto.
        (prettyPrintScript): Ditto.
        (runWithScripts): Ditto.
        * profiler/Profiler.cpp:
        (WebCore::createCallIdentifier): Removed a plus 1 of startingLineNumber.

WebCore:

2008-05-30  Timothy Hatcher  <timothy@apple.com>

        Made the starting line number of scripts be 1-based throughout the engine.
        This cleans up script line numbers so they are all consistent now and fixes
        some cases where script execution was shown as off by one line in the debugger.

        Doing this also exposed a bug where JSLazyEventListener created in XHML or SVG
        documents would always have a line number of 0. So this change fixed that bug
        to pass all the SVG and XHTML tests.

        All layout tests pass.

        Reviewed by Oliver Hunt.

        * bindings/js/kjs_events.cpp:
        (WebCore::JSLazyEventListener::JSLazyEventListener): Set the line number to 1
        if it was passed in as 0. This can happen when listeners are created with
        a setAttribute call from JavaScript.
        (WebCore::JSLazyEventListener::parseCode): Add a FIXME about the URL being
        incorrect when listeners are created with a setAttribute call from JavaScript.
        * bindings/js/kjs_events.h: Remove the default value for lineNumber, since no
        callers need it.
        * bindings/objc/WebScriptObject.mm:
        (-[WebScriptObject evaluateWebScript:]): Pass a line number of 1 instead of 0
        to Interpreter::evaluate().
        * bridge/NP_jsobject.cpp:
        (_NPN_Evaluate): Ditto.
        * bridge/jni/jni_jsobject.mm:
        (JavaJSObject::eval): Ditto.
        * dom/XMLTokenizer.cpp:
        (WebCore::XMLTokenizer::startElementNs): Call KJSProxy::setEventHandlerLineno()
        around the call to handleElementAttributes, so any JSLazyEventListener created
        from those attributes have line numbers.
        (WebCore::XMLTokenizer::endElementNs): Remove a minus 1 of the line number.
        (WebCore::XMLTokenizer::notifyFinished): Pass a line number of 1 instead of 0.
        (WebCore::XMLTokenizer::parseEndElement): Remove a minus 1 of the line number.
        * html/HTMLScriptElement.cpp:
        (WebCore::HTMLScriptElement::evaluateScript): Add a FIXME about the starting
        line number being incorrect in some cases when this function is called.
        * html/HTMLTokenizer.cpp:
        (WebCore::HTMLTokenizer::parseSpecial): Add a plus 1 to the line number when
        setting scriptStartLineno so it is 1-based. Same for calling setEventHandlerLineno().
        (WebCore::HTMLTokenizer::processToken): Ditto.
        * html/HTMLTokenizer.h: Change the default line number on scriptExecution() to 1 from 0.
        * loader/FrameLoader.cpp:
        (FrameLoader::executeIfJavaScriptURL): Pass a line number of 1 instead of 0 to executeScript().

WebKitTools:

2008-05-30  Timothy Hatcher  <timothy@apple.com>

        Made the starting line number of scripts be 1-based throughout the engine.
        This cleans up script line numbers so they are all consistent now.

        Reviewed by Oliver Hunt.

        * DumpRenderTree/mac/ObjCController.m:
        (runJavaScriptThread): Pass a line number of 1 instead of 0 to JSEvaluateScript.
        * DumpRenderTree/pthreads/JavaScriptThreadingPthreads.cpp:
        (runJavaScriptThread): Ditto.
        * DumpRenderTree/win/DumpRenderTree.cpp:
        (runJavaScriptThread): Ditto.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34273 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f8375ffb
...@@ -58,7 +58,7 @@ int main(int argc, char* argv[]) ...@@ -58,7 +58,7 @@ int main(int argc, char* argv[])
char* scriptUTF8 = createStringWithContentsOfFile(scriptPath); char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
JSStringRef script = JSStringCreateWithUTF8CString(scriptUTF8); JSStringRef script = JSStringCreateWithUTF8CString(scriptUTF8);
JSValueRef exception; JSValueRef exception;
JSValueRef result = JSEvaluateScript(context, script, NULL, NULL, 0, &exception); JSValueRef result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
if (result) if (result)
printf("PASS: Test script executed successfully.\n"); printf("PASS: Test script executed successfully.\n");
else { else {
......
...@@ -806,7 +806,7 @@ int main(int argc, char* argv[]) ...@@ -806,7 +806,7 @@ int main(int argc, char* argv[])
ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception)); ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
ASSERT(JSValueIsObject(context, exception)); ASSERT(JSValueIsObject(context, exception));
v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL); v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
assertEqualsAsNumber(v, 2); // FIXME: Lexer::setCode bumps startingLineNumber by 1 -- we need to change internal callers so that it doesn't have to (saying '0' to mean '1' in the API would be really confusing -- it's really confusing internally, in fact) assertEqualsAsNumber(v, 1);
JSStringRelease(functionBody); JSStringRelease(functionBody);
JSStringRelease(line); JSStringRelease(line);
...@@ -901,16 +901,16 @@ int main(int argc, char* argv[]) ...@@ -901,16 +901,16 @@ int main(int argc, char* argv[])
ASSERT(JSValueIsEqual(context, v, o, NULL)); ASSERT(JSValueIsEqual(context, v, o, NULL));
JSStringRef script = JSStringCreateWithUTF8CString("this;"); JSStringRef script = JSStringCreateWithUTF8CString("this;");
v = JSEvaluateScript(context, script, NULL, NULL, 0, NULL); v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
ASSERT(JSValueIsEqual(context, v, globalObject, NULL)); ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
v = JSEvaluateScript(context, script, o, NULL, 0, NULL); v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
ASSERT(JSValueIsEqual(context, v, o, NULL)); ASSERT(JSValueIsEqual(context, v, o, NULL));
JSStringRelease(script); JSStringRelease(script);
script = JSStringCreateWithUTF8CString("eval(this);"); script = JSStringCreateWithUTF8CString("eval(this);");
v = JSEvaluateScript(context, script, NULL, NULL, 0, NULL); v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
ASSERT(JSValueIsEqual(context, v, globalObject, NULL)); ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
v = JSEvaluateScript(context, script, o, NULL, 0, NULL); v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
ASSERT(JSValueIsEqual(context, v, o, NULL)); ASSERT(JSValueIsEqual(context, v, o, NULL));
JSStringRelease(script); JSStringRelease(script);
......
2008-05-30 Timothy Hatcher <timothy@apple.com>
Made the starting line number of scripts be 1-based throughout the engine.
This cleans up script line numbers so they are all consistent now and fixes
some cases where script execution was shown as off by one line in the debugger.
No change in SunSpider.
Reviewed by Oliver Hunt.
* API/minidom.c:
(main): Pass a line number of 1 instead of 0 to parser().parse().
* API/testapi.c:
(main): Ditto. And removes a FIXME and changed an assertEqualsAsNumber
to use 1 instead of 2 for the line number.
* VM/Machine.cpp:
(KJS::callEval): Pass a line number of 1 instead of 0.
(KJS::Machine::debug): Use firstLine for WillExecuteProgram instead of
lastLine. Use lastLine for DidExecuteProgram instead of firstLine.
* kjs/DebuggerCallFrame.cpp:
(KJS::DebuggerCallFrame::evaluate): Pass a line number of 1 instead of
0 to parser().parse().
* kjs/Parser.cpp:
(KJS::Parser::parse): ASSERT startingLineNumber is greatter than 0. Change
the startingLineNumber to be 1 if it was less than or equal to 0. This is needed
for release builds to maintain compatibility with the JavaScriptCore API.
* kjs/function.cpp:
(KJS::globalFuncEval): Pass a line number of 1 instead of 0 to parser().parse().
* kjs/function_object.cpp:
(FunctionObjectImp::construct): Pass a line number of 1 instead of 0 to construct().
* kjs/lexer.cpp:
(Lexer::setCode): Made yylineno = startingLineNumber instead of adding 1.
* kjs/testkjs.cpp:
(functionRun): Pass a line number of 1 instead of 0 to Interpreter::evaluate().
(functionLoad): Ditto.
(prettyPrintScript): Ditto.
(runWithScripts): Ditto.
* profiler/Profiler.cpp:
(WebCore::createCallIdentifier): Removed a plus 1 of startingLineNumber.
2008-05-30 Alexey Proskuryakov <ap@webkit.org> 2008-05-30 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin. Reviewed by Darin.
......
...@@ -533,7 +533,7 @@ ...@@ -533,7 +533,7 @@
931C6CEF038EE8DE008635CE /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = "<group>"; tabWidth = 8; }; 931C6CEF038EE8DE008635CE /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = "<group>"; tabWidth = 8; };
931C6CF0038EE8DE008635CE /* list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = list.cpp; sourceTree = "<group>"; tabWidth = 8; }; 931C6CF0038EE8DE008635CE /* list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = list.cpp; sourceTree = "<group>"; tabWidth = 8; };
9322A00306C341D3009067BB /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = /usr/lib/libicucore.dylib; sourceTree = "<absolute>"; }; 9322A00306C341D3009067BB /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = /usr/lib/libicucore.dylib; sourceTree = "<absolute>"; };
932F5BD80822A1C700736975 /* Info.plist */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; tabWidth = 8; usesTabs = 1; }; 932F5BD80822A1C700736975 /* Info.plist */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; tabWidth = 8; usesTabs = 1; };
932F5BD90822A1C700736975 /* JavaScriptCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 932F5BD90822A1C700736975 /* JavaScriptCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
932F5BE10822A1C700736975 /* testkjs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testkjs; sourceTree = BUILT_PRODUCTS_DIR; }; 932F5BE10822A1C700736975 /* testkjs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testkjs; sourceTree = BUILT_PRODUCTS_DIR; };
933A3499038AE7C6008635CE /* grammar.y */ = {isa = PBXFileReference; explicitFileType = sourcecode.yacc; fileEncoding = 4; indentWidth = 4; path = grammar.y; sourceTree = "<group>"; tabWidth = 8; }; 933A3499038AE7C6008635CE /* grammar.y */ = {isa = PBXFileReference; explicitFileType = sourcecode.yacc; fileEncoding = 4; indentWidth = 4; path = grammar.y; sourceTree = "<group>"; tabWidth = 8; };
......
...@@ -453,7 +453,7 @@ static NEVER_INLINE JSValue* callEval(ExecState* exec, JSObject* thisObj, ScopeC ...@@ -453,7 +453,7 @@ static NEVER_INLINE JSValue* callEval(ExecState* exec, JSObject* thisObj, ScopeC
int sourceId; int sourceId;
int errLine; int errLine;
UString errMsg; UString errMsg;
RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(exec, UString(), 0, UStringSourceProvider::create(static_cast<StringImp*>(program)->value()), &sourceId, &errLine, &errMsg); RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(static_cast<StringImp*>(program)->value()), &sourceId, &errLine, &errMsg);
if (!evalNode) { if (!evalNode) {
exceptionValue = Error::create(exec, SyntaxError, errMsg, errLine, sourceId, NULL); exceptionValue = Error::create(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
...@@ -852,11 +852,11 @@ NEVER_INLINE void Machine::debug(ExecState* exec, const Instruction* vPC, const ...@@ -852,11 +852,11 @@ NEVER_INLINE void Machine::debug(ExecState* exec, const Instruction* vPC, const
return; return;
} }
case WillExecuteProgram: { case WillExecuteProgram: {
debugger->willExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceId(), lastLine); debugger->willExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceId(), firstLine);
return; return;
} }
case DidExecuteProgram: { case DidExecuteProgram: {
debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceId(), firstLine); debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceId(), lastLine);
return; return;
} }
} }
......
...@@ -73,7 +73,7 @@ JSValue* DebuggerCallFrame::evaluate(const UString& script, JSValue*& exception) ...@@ -73,7 +73,7 @@ JSValue* DebuggerCallFrame::evaluate(const UString& script, JSValue*& exception)
int errLine; int errLine;
UString errMsg; UString errMsg;
RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(&newExec, UString(), 0, UStringSourceProvider::create(script), &sourceId, &errLine, &errMsg); RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(&newExec, UString(), 1, UStringSourceProvider::create(script), &sourceId, &errLine, &errMsg);
if (!evalNode) if (!evalNode)
return Error::create(&newExec, SyntaxError, errMsg, errLine, sourceId, 0); return Error::create(&newExec, SyntaxError, errMsg, errLine, sourceId, 0);
......
...@@ -67,6 +67,10 @@ void Parser::parse(ExecState* exec, const UString& sourceURL, int startingLineNu ...@@ -67,6 +67,10 @@ void Parser::parse(ExecState* exec, const UString& sourceURL, int startingLineNu
Lexer& lexer = KJS::lexer(); Lexer& lexer = KJS::lexer();
ASSERT(startingLineNumber > 0);
if (startingLineNumber <= 0)
startingLineNumber = 1;
lexer.setCode(startingLineNumber, source); lexer.setCode(startingLineNumber, source);
*sourceId = ++m_sourceId; *sourceId = ++m_sourceId;
......
...@@ -574,7 +574,7 @@ JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, J ...@@ -574,7 +574,7 @@ JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, J
int errLine; int errLine;
UString errMsg; UString errMsg;
RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(exec, UString(), 0, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg); RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
if (!evalNode) if (!evalNode)
return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL); return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
......
...@@ -217,7 +217,7 @@ JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args, const ...@@ -217,7 +217,7 @@ JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args, const
// ECMA 15.3.2 The Function Constructor // ECMA 15.3.2 The Function Constructor
JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args) JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args)
{ {
return construct(exec, args, "anonymous", UString(), 0); return construct(exec, args, "anonymous", UString(), 1);
} }
// ECMA 15.3.1 The Function Constructor Called as a Function // ECMA 15.3.1 The Function Constructor Called as a Function
......
...@@ -103,7 +103,7 @@ Lexer::~Lexer() ...@@ -103,7 +103,7 @@ Lexer::~Lexer()
void Lexer::setCode(int startingLineNumber, PassRefPtr<SourceProvider> source) void Lexer::setCode(int startingLineNumber, PassRefPtr<SourceProvider> source)
{ {
yylineno = 1 + startingLineNumber; yylineno = startingLineNumber;
restrKeyword = false; restrKeyword = false;
delimited = false; delimited = false;
eatNextIdentifier = false; eatNextIdentifier = false;
......
...@@ -195,7 +195,7 @@ JSValue* functionRun(ExecState* exec, JSObject*, const List& args) ...@@ -195,7 +195,7 @@ JSValue* functionRun(ExecState* exec, JSObject*, const List& args)
JSGlobalObject* globalObject = exec->dynamicGlobalObject(); JSGlobalObject* globalObject = exec->dynamicGlobalObject();
stopWatch.start(); stopWatch.start();
Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 0, script.data()); Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
stopWatch.stop(); stopWatch.stop();
return jsNumber(stopWatch.getElapsedMS()); return jsNumber(stopWatch.getElapsedMS());
...@@ -209,7 +209,7 @@ JSValue* functionLoad(ExecState* exec, JSObject*, const List& args) ...@@ -209,7 +209,7 @@ JSValue* functionLoad(ExecState* exec, JSObject*, const List& args)
return throwError(exec, GeneralError, "Could not open file."); return throwError(exec, GeneralError, "Could not open file.");
JSGlobalObject* globalObject = exec->dynamicGlobalObject(); JSGlobalObject* globalObject = exec->dynamicGlobalObject();
Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 0, script.data()); Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
return jsUndefined(); return jsUndefined();
} }
...@@ -275,7 +275,7 @@ static bool prettyPrintScript(ExecState* exec, const UString& fileName, const Ve ...@@ -275,7 +275,7 @@ static bool prettyPrintScript(ExecState* exec, const UString& fileName, const Ve
int errLine = 0; int errLine = 0;
UString errMsg; UString errMsg;
UString scriptUString(script.data()); UString scriptUString(script.data());
RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(exec, fileName, 0, UStringSourceProvider::create(scriptUString), 0, &errLine, &errMsg); RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(exec, fileName, 1, UStringSourceProvider::create(scriptUString), 0, &errLine, &errMsg);
if (!programNode) { if (!programNode) {
fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str()); fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
return false; return false;
...@@ -304,7 +304,7 @@ static bool runWithScripts(const Vector<UString>& fileNames, Vector<UString>& ar ...@@ -304,7 +304,7 @@ static bool runWithScripts(const Vector<UString>& fileNames, Vector<UString>& ar
if (prettyPrint) if (prettyPrint)
prettyPrintScript(globalObject->globalExec(), fileName, script); prettyPrintScript(globalObject->globalExec(), fileName, script);
else { else {
Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 0, script.data()); Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
success = success && completion.complType() != Throw; success = success && completion.complType() != Throw;
if (dump) { if (dump) {
if (success) if (success)
......
...@@ -148,7 +148,7 @@ CallIdentifier createCallIdentifier(JSObject* calledFunction) ...@@ -148,7 +148,7 @@ CallIdentifier createCallIdentifier(JSObject* calledFunction)
CallIdentifier createCallIdentifier(const UString& sourceURL, int startingLineNumber) CallIdentifier createCallIdentifier(const UString& sourceURL, int startingLineNumber)
{ {
return CallIdentifier(GlobalCodeExecution, sourceURL, (startingLineNumber + 1)); return CallIdentifier(GlobalCodeExecution, sourceURL, startingLineNumber);
} }
CallIdentifier createCallIdentifierFromFunctionImp(FunctionImp* functionImp) CallIdentifier createCallIdentifierFromFunctionImp(FunctionImp* functionImp)
......
2008-05-30 Timothy Hatcher <timothy@apple.com>
Made the starting line number of scripts be 1-based throughout the engine.
This cleans up script line numbers so they are all consistent now and fixes
some cases where script execution was shown as off by one line in the debugger.
Doing this also exposed a bug where JSLazyEventListener created in XHML or SVG
documents would always have a line number of 0. So this change fixed that bug
to pass all the SVG and XHTML tests.
All layout tests pass.
Reviewed by Oliver Hunt.
* bindings/js/kjs_events.cpp:
(WebCore::JSLazyEventListener::JSLazyEventListener): Set the line number to 1
if it was passed in as 0. This can happen when listeners are created with
a setAttribute call from JavaScript.
(WebCore::JSLazyEventListener::parseCode): Add a FIXME about the URL being
incorrect when listeners are created with a setAttribute call from JavaScript.
* bindings/js/kjs_events.h: Remove the default value for lineNumber, since no
callers need it.
* bindings/objc/WebScriptObject.mm:
(-[WebScriptObject evaluateWebScript:]): Pass a line number of 1 instead of 0
to Interpreter::evaluate().
* bridge/NP_jsobject.cpp:
(_NPN_Evaluate): Ditto.
* bridge/jni/jni_jsobject.mm:
(JavaJSObject::eval): Ditto.
* dom/XMLTokenizer.cpp:
(WebCore::XMLTokenizer::startElementNs): Call KJSProxy::setEventHandlerLineno()
around the call to handleElementAttributes, so any JSLazyEventListener created
from those attributes have line numbers.
(WebCore::XMLTokenizer::endElementNs): Remove a minus 1 of the line number.
(WebCore::XMLTokenizer::notifyFinished): Pass a line number of 1 instead of 0.
(WebCore::XMLTokenizer::parseEndElement): Remove a minus 1 of the line number.
* html/HTMLScriptElement.cpp:
(WebCore::HTMLScriptElement::evaluateScript): Add a FIXME about the starting
line number being incorrect in some cases when this function is called.
* html/HTMLTokenizer.cpp:
(WebCore::HTMLTokenizer::parseSpecial): Add a plus 1 to the line number when
setting scriptStartLineno so it is 1-based. Same for calling setEventHandlerLineno().
(WebCore::HTMLTokenizer::processToken): Ditto.
* html/HTMLTokenizer.h: Change the default line number on scriptExecution() to 1 from 0.
* loader/FrameLoader.cpp:
(FrameLoader::executeIfJavaScriptURL): Pass a line number of 1 instead of 0 to executeScript().
2008-05-30 Maciej Stachowiak <mjs@apple.com> 2008-05-30 Maciej Stachowiak <mjs@apple.com>
Reviewed by Oliver (earlier version reviewed by Alexey). Reviewed by Oliver (earlier version reviewed by Alexey).
...@@ -251,6 +251,11 @@ JSLazyEventListener::JSLazyEventListener(const String& functionName, const Strin ...@@ -251,6 +251,11 @@ JSLazyEventListener::JSLazyEventListener(const String& functionName, const Strin
// and we need to avoid a reference cycle. If JS transfers // and we need to avoid a reference cycle. If JS transfers
// this handler to another node, parseCode will be called and // this handler to another node, parseCode will be called and
// then originalNode is no longer needed. // then originalNode is no longer needed.
// A JSLazyEventListener can be created with a line number of zero when it is created with
// a setAttribute call from JavaScript, so make the line number 1 in that case.
if (m_lineNumber == 0)
m_lineNumber = 1;
} }
JSObject* JSLazyEventListener::listenerObj() const JSObject* JSLazyEventListener::listenerObj() const
...@@ -282,6 +287,9 @@ void JSLazyEventListener::parseCode() const ...@@ -282,6 +287,9 @@ void JSLazyEventListener::parseCode() const
UString sourceURL(frame->loader()->url().string()); UString sourceURL(frame->loader()->url().string());
args.append(eventParameterName()); args.append(eventParameterName());
args.append(jsString(m_code)); args.append(jsString(m_code));
// FIXME: Passing the document's URL to construct is not always correct, since this event listener might
// have been added with setAttribute from a script, and we should pass String() in that case.
m_listener = constr->construct(exec, args, m_functionName, sourceURL, m_lineNumber); // FIXME: is globalExec ok ? m_listener = constr->construct(exec, args, m_functionName, sourceURL, m_lineNumber); // FIXME: is globalExec ok ?
FunctionImp* listenerAsFunction = static_cast<FunctionImp*>(m_listener.get()); FunctionImp* listenerAsFunction = static_cast<FunctionImp*>(m_listener.get());
......
...@@ -76,7 +76,7 @@ namespace WebCore { ...@@ -76,7 +76,7 @@ namespace WebCore {
class JSLazyEventListener : public JSEventListener { class JSLazyEventListener : public JSEventListener {
public: public:
JSLazyEventListener(const String& functionName, const String& code, JSDOMWindow*, Node*, int lineNumber = 0); JSLazyEventListener(const String& functionName, const String& code, JSDOMWindow*, Node*, int lineNumber);
virtual KJS::JSObject* listenerObj() const; virtual KJS::JSObject* listenerObj() const;
private: private:
......
...@@ -333,7 +333,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root ...@@ -333,7 +333,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
JSLock lock; JSLock lock;
[self _rootObject]->globalObject()->startTimeoutCheck(); [self _rootObject]->globalObject()->startTimeoutCheck();
Completion completion = Interpreter::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), UString(), 0, String(script)); Completion completion = Interpreter::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), UString(), 1, String(script));
[self _rootObject]->globalObject()->stopTimeoutCheck(); [self _rootObject]->globalObject()->stopTimeoutCheck();
ComplType type = completion.complType(); ComplType type = completion.complType();
......
...@@ -196,7 +196,7 @@ bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant) ...@@ -196,7 +196,7 @@ bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant)
JSLock lock; JSLock lock;
String scriptString = convertNPStringToUTF16(s); String scriptString = convertNPStringToUTF16(s);
rootObject->globalObject()->startTimeoutCheck(); rootObject->globalObject()->startTimeoutCheck();
Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), UString(), 0, scriptString); Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), UString(), 1, scriptString);
rootObject->globalObject()->stopTimeoutCheck(); rootObject->globalObject()->stopTimeoutCheck();
ComplType type = completion.complType(); ComplType type = completion.complType();
......
...@@ -319,7 +319,7 @@ jobject JavaJSObject::eval(jstring script) const ...@@ -319,7 +319,7 @@ jobject JavaJSObject::eval(jstring script) const
return 0; return 0;
rootObject->globalObject()->startTimeoutCheck(); rootObject->globalObject()->startTimeoutCheck();
Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), UString(), 0, JavaString(script).ustring()); Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), UString(), 1, JavaString(script).ustring());
rootObject->globalObject()->stopTimeoutCheck(); rootObject->globalObject()->stopTimeoutCheck();
ComplType type = completion.complType(); ComplType type = completion.complType();
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "HTMLScriptElement.h" #include "HTMLScriptElement.h"
#include "HTMLStyleElement.h" #include "HTMLStyleElement.h"
#include "HTMLTokenizer.h" #include "HTMLTokenizer.h"
#include "kjs_proxy.h"
#include "ProcessingInstruction.h" #include "ProcessingInstruction.h"
#include "ResourceError.h" #include "ResourceError.h"
#include "ResourceHandle.h" #include "ResourceHandle.h"
...@@ -819,13 +820,20 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm ...@@ -819,13 +820,20 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
stopParsing(); stopParsing();
return; return;
} }
KJSProxy* jsProxy = m_doc->frame() ? m_doc->frame()->scriptProxy() : 0;
if (jsProxy && m_doc->frame()->scriptProxy()->isEnabled())
jsProxy->setEventHandlerLineno(lineNumber());
handleElementAttributes(newElement.get(), libxmlAttributes, nb_attributes, ec); handleElementAttributes(newElement.get(), libxmlAttributes, nb_attributes, ec);
if (ec) { if (ec) {
stopParsing(); stopParsing();
return; return;
} }
if (jsProxy)
jsProxy->setEventHandlerLineno(0);
newElement->beginParsingChildren(); newElement->beginParsingChildren();
if (newElement->hasTagName(scriptTag)) if (newElement->hasTagName(scriptTag))
...@@ -911,7 +919,7 @@ void XMLTokenizer::endElementNs() ...@@ -911,7 +919,7 @@ void XMLTokenizer::endElementNs()
if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE) if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE)
scriptCode += static_cast<CharacterData*>(child)->data(); scriptCode += static_cast<CharacterData*>(child)->data();
} }
m_view->frame()->loader()->executeScript(m_doc->url().string(), m_scriptStartLine - 1, scriptCode); m_view->frame()->loader()->executeScript(m_doc->url().string(), m_scriptStartLine, scriptCode);
} }
m_requestingScript = false; m_requestingScript = false;
...@@ -1478,7 +1486,7 @@ void XMLTokenizer::notifyFinished(CachedResource* finishedObj) ...@@ -1478,7 +1486,7 @@ void XMLTokenizer::notifyFinished(CachedResource* finishedObj)
if (errorOccurred) if (errorOccurred)
EventTargetNodeCast(e.get())->dispatchHTMLEvent(errorEvent, true, false); EventTargetNodeCast(e.get())->dispatchHTMLEvent(errorEvent, true, false);
else { else {
m_view->frame()->loader()->executeScript(cachedScriptUrl, 0, scriptSource); m_view->frame()->loader()->executeScript(cachedScriptUrl, 1, scriptSource);
EventTargetNodeCast(e.get())->dispatchHTMLEvent(loadEvent, false, false); EventTargetNodeCast(e.get())->dispatchHTMLEvent(loadEvent, false, false);
} }
...@@ -1948,7 +1956,7 @@ void XMLTokenizer::parseEndElement() ...@@ -1948,7 +1956,7 @@ void XMLTokenizer::parseEndElement()
if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE) if (child->isTextNode() || child->nodeType() == Node::CDATA_SECTION_NODE)
scriptCode += static_cast<CharacterData*>(child)->data(); scriptCode += static_cast<CharacterData*>(child)->data();
} }
m_view->frame()->loader()->executeScript(m_doc->url().string(), m_scriptStartLine - 1, scriptCode); m_view->frame()->loader()->executeScript(m_doc->url().string(), m_scriptStartLine, scriptCode);
} }
m_requestingScript = false; m_requestingScript = false;
} }
......
...@@ -230,7 +230,9 @@ void HTMLScriptElement::evaluateScript(const String& url, const String& script) ...@@ -230,7 +230,9 @@ void HTMLScriptElement::evaluateScript(const String& url, const String& script)
if (frame) { if (frame) {
if (frame->scriptProxy()->isEnabled()) { if (frame->scriptProxy()->isEnabled()) {
m_evaluated = true; m_evaluated = true;
frame->scriptProxy()->evaluate(url, 0, script); // FIXME: This starting line number will be incorrect for evaluation triggered
// from insertedIntoDocument or childrenChanged.
frame->scriptProxy()->evaluate(url, 1, script);
Document::updateDocumentsRendering(); Document::updateDocumentsRendering();
} }
} }
......
...@@ -307,7 +307,7 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta ...@@ -307,7 +307,7 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
ASSERT(!state.hasTagState()); ASSERT(!state.hasTagState());
ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() + state.inIFrame() == 1 ); ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() + state.inIFrame() == 1 );
if (state.inScript()) if (state.inScript())
scriptStartLineno = m_lineNumber; scriptStartLineno = m_lineNumber + 1; // Script line numbers are 1 based.
if (state.inComment()) if (state.inComment())
state = parseComment(src, state); state = parseComment(src, state);
...@@ -1873,7 +1873,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken() ...@@ -1873,7 +1873,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
{ {
KJSProxy* jsProxy = (!m_fragment && m_doc->frame()) ? m_doc->frame()->scriptProxy() : 0; KJSProxy* jsProxy = (!m_fragment && m_doc->frame()) ? m_doc->frame()->scriptProxy() : 0;
if (jsProxy && m_doc->frame()->scriptProxy()->isEnabled()) if (jsProxy && m_doc->frame()->scriptProxy()->isEnabled())
jsProxy->setEventHandlerLineno(tagStartLineno); jsProxy->setEventHandlerLineno(tagStartLineno + 1); // Script line numbers are 1 based.
if (dest > buffer) { if (dest > buffer) {
currToken.text = StringImpl::createStrippingNullCharacters(buffer, dest - buffer); currToken.text = StringImpl::createStrippingNullCharacters(buffer, dest - buffer);
if (currToken.tagName != commentAtom) if (currToken.tagName != commentAtom)
...@@ -1881,7 +1881,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken() ...@@ -1881,7 +1881,7 @@ PassRefPtr<Node> HTMLTokenizer::processToken()
} else if (currToken.tagName == nullAtom) { } else if (currToken.tagName == nullAtom) {
currToken.reset(); currToken.reset();
if (jsProxy) if (jsProxy)
jsProxy->setEventHandlerLineno(m_lineNumber); jsProxy->setEventHandlerLineno(m_lineNumber + 1); // Script line numbers are 1 based.
return 0; return 0;
} }
......
...@@ -171,7 +171,7 @@ private: ...@@ -171,7 +171,7 @@ private:
State parseEntity(SegmentedString&, UChar*& dest, State, unsigned& _cBufferPos, bool start, bool parsingTag); State parseEntity(SegmentedString&, UChar*& dest, State, unsigned& _cBufferPos, bool start, bool parsingTag);
State parseProcessingInstruction(SegmentedString&, State); State parseProcessingInstruction(SegmentedString&, State);
State scriptHandler(State); State scriptHandler(State);
State scriptExecution(const String& script, State, const String& scriptURL, int baseLine = 0); State scriptExecution(const String& script, State, const String& scriptURL, int baseLine = 1);
void setSrc(const SegmentedString&); void setSrc(const SegmentedString&);