diff --git a/docs/webkit.md b/docs/webkit.md index 0719c8ac7..b3062c187 100644 --- a/docs/webkit.md +++ b/docs/webkit.md @@ -5,476 +5,16 @@ * Apply tmm1's patch (found at end of this document) `patch -p1 < tmm1.patch` -* Build webkit (~2 hours) - `Tools/Scripts/build-webkit` +* Build webkit (~2 hours, don't let your computer go to sleep) + `Tools/Scripts/build-webkit --release` +* Copy WebKit.framework, WebCore.framework and JavaScript.framework from `webkit/WebKitBuild/Release` to +`atom/frameworks` + +* Fix the dynamic library linking problems + `rake webkit-fix` # tmm1's patch ``` - -diff --git a/LayoutTests/fast/js/exception-properties-expected.txt b/LayoutTests/fast/js/exception-properties-expected.txt -index 36d7e84..573ef10 100644 ---- a/LayoutTests/fast/js/exception-properties-expected.txt -+++ b/LayoutTests/fast/js/exception-properties-expected.txt -@@ -4,7 +4,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE - - - PASS enumerableProperties(error) is [] --PASS enumerableProperties(nativeError) is ["line", "sourceId", "sourceURL"] -+PASS enumerableProperties(nativeError) is ["line", "sourceId", "sourceURL", "stack"] - PASS Object.getPrototypeOf(nativeError).name is "RangeError" - PASS Object.getPrototypeOf(nativeError).message is "" - PASS successfullyParsed is true -diff --git a/LayoutTests/fast/js/script-tests/exception-properties.js b/LayoutTests/fast/js/script-tests/exception-properties.js -index 30789a0..f7c2871 100644 ---- a/LayoutTests/fast/js/script-tests/exception-properties.js -+++ b/LayoutTests/fast/js/script-tests/exception-properties.js -@@ -16,7 +16,7 @@ try { - var error = new Error("message"); - - shouldBe('enumerableProperties(error)', '[]'); -- shouldBe('enumerableProperties(nativeError)', '["line", "sourceId", "sourceURL"]'); -+ shouldBe('enumerableProperties(nativeError)', '["line", "sourceId", "sourceURL", "jscStack"]'); - - shouldBe('Object.getPrototypeOf(nativeError).name', '"RangeError"'); - shouldBe('Object.getPrototypeOf(nativeError).message', '""'); -diff --git a/LayoutTests/platform/chromium/test_expectations.txt b/LayoutTests/platform/chromium/test_expectations.txt -index f6e35e0..e6d0b90 100644 ---- a/LayoutTests/platform/chromium/test_expectations.txt -+++ b/LayoutTests/platform/chromium/test_expectations.txt -@@ -518,6 +518,10 @@ WONTFIX SKIP : fast/frames/cross-site-this.html = FAIL - // throw. V8 follows the spec. - WONTFIX SKIP : fast/js/reparsing-semicolon-insertion.html = FAIL - -+// This tests stack-traces that are generated by JSC. This test should -+// fail since it is specific to jsc. -+WONTFIX SKIP : fast/js/stack-trace.html = FAIL -+ - // Rubber-banding is currently a CG only feature. - WONTFIX : platform/chromium/rubberbanding = FAIL - WONTFIX : platform/chromium/compositing/rubberbanding = IMAGE -diff --git a/Source/JavaScriptCore/JavaScriptCore.exp b/Source/JavaScriptCore/JavaScriptCore.exp -index 4bf3ed9..1d11aea 100644 ---- a/Source/JavaScriptCore/JavaScriptCore.exp -+++ b/Source/JavaScriptCore/JavaScriptCore.exp -@@ -117,6 +117,7 @@ __ZN3JSC10JSFunction6s_infoE - __ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE - __ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE - __ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE -+__ZN3JSC11Interpreter13getStackTraceEPNS_12JSGlobalDataEiRN3WTF6VectorINS_10StackFrameELm0EEE - __ZN3JSC11JSByteArray10putByIndexEPNS_6JSCellEPNS_9ExecStateEjNS_7JSValueE - __ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataEPNS_14JSGlobalObjectENS_7JSValueEPKNS_9ClassInfoE - __ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def -index 5095d5c..13ee907 100644 ---- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def -+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def -@@ -208,6 +208,7 @@ EXPORTS - ?getPropertyDescriptor@JSObject@JSC@@QAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?getPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z - ?getSlice@ArgList@JSC@@QBEXHAAV12@@Z -+ ?getStackTrace@Interpreter@JSC@@SAXPAVJSGlobalData@2@HAAV?$Vector@UStackFrame@JSC@@$0A@@WTF@@@Z - ?getString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z - ?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVUString@2@@Z - ?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ -diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp -index 4194901..b9d07dd 100644 ---- a/Source/JavaScriptCore/interpreter/Interpreter.cpp -+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp -@@ -45,7 +45,6 @@ - #include "JSActivation.h" - #include "JSArray.h" - #include "JSByteArray.h" --#include "JSFunction.h" - #include "JSNotAnObject.h" - #include "JSPropertyNameIterator.h" - #include "LiteralParser.h" -@@ -790,6 +789,95 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, - exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message)); - } - -+static void getCallerLine(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber) -+{ -+ (void)globalData; -+ unsigned bytecodeOffset; -+ lineNumber = -1; -+ callFrame = callFrame->removeHostCallFrameFlag(); -+ -+ if (callFrame->callerFrame() == CallFrame::noCaller() || callFrame->callerFrame()->hasHostCallFrameFlag()) -+ return; -+ -+ CodeBlock* callerCodeBlock = callFrame->callerFrame()->removeHostCallFrameFlag()->codeBlock(); -+ -+#if ENABLE(INTERPRETER) -+ if (!globalData->canUseJIT()) -+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC()); -+#if ENABLE(JIT) -+ else -+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC()); -+#endif -+#else -+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC()); -+#endif -+ -+ lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1); -+} -+ -+static ALWAYS_INLINE const UString getSourceURLFromCallFrame(CallFrame* callFrame) -+{ -+ if (callFrame->hasHostCallFrameFlag()) -+ return UString(); -+#if ENABLE(INTERPRETER) -+ if (!callFrame->globalData().canUseJIT()) -+ return callFrame->codeBlock()->source()->url(); -+#if ENABLE(JIT) -+ return callFrame->codeBlock()->ownerExecutable()->sourceURL(); -+#endif -+#else -+ return callFrame->codeBlock()->ownerExecutable()->sourceURL(); -+#endif -+} -+ -+static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame) -+{ -+ if (callFrame->hasHostCallFrameFlag()) -+ return StackFrameNativeCode; -+ -+ switch (callFrame->codeBlock()->codeType()) { -+ case EvalCode: -+ return StackFrameEvalCode; -+ case FunctionCode: -+ return StackFrameFunctionCode; -+ case GlobalCode: -+ return StackFrameGlobalCode; -+ } -+ ASSERT_NOT_REACHED(); -+ return StackFrameGlobalCode; -+} -+ -+void Interpreter::getStackTrace(JSGlobalData* globalData, int line, Vector& results) -+{ -+ int stackLimit = 32; -+ CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag(); -+ if (!callFrame || callFrame == CallFrame::noCaller() || !callFrame->codeBlock()) -+ return; -+ UString sourceURL; -+ UString traceLevel; -+ -+ for (int i = 0; i < stackLimit; ++i) { -+ if (!callFrame || callFrame == CallFrame::noCaller()) -+ break; -+ if (callFrame->codeBlock()) { -+ sourceURL = getSourceURLFromCallFrame(callFrame); -+ -+ StackFrame s = { -+ Strong(*globalData, callFrame->callee()), -+ Strong(*globalData, callFrame), -+ getStackFrameCodeType(callFrame), -+ Strong(*globalData, callFrame->codeBlock()->ownerExecutable()), -+ line, -+ sourceURL -+ }; -+ -+ results.append(s); -+ } -+ getCallerLine(globalData, callFrame, line); -+ callFrame = callFrame->callerFrame()->removeHostCallFrameFlag(); -+ } -+} -+ - NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset) - { - CodeBlock* codeBlock = callFrame->codeBlock(); -@@ -808,7 +896,9 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV - - // FIXME: should only really be adding these properties to VM generated exceptions, - // but the inspector currently requires these for all thrown objects. -- addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source()); -+ Vector stackTrace; -+ getStackTrace(&callFrame->globalData(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), stackTrace); -+ addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source(), stackTrace); - } - - isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception); -diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h -index 6dfd331..748e8fb 100644 ---- a/Source/JavaScriptCore/interpreter/Interpreter.h -+++ b/Source/JavaScriptCore/interpreter/Interpreter.h -@@ -31,10 +31,12 @@ - - #include "ArgList.h" - #include "JSCell.h" -+#include "JSFunction.h" - #include "JSValue.h" - #include "JSObject.h" - #include "Opcode.h" - #include "RegisterFile.h" -+#include "StrongInlines.h" - - #include - -@@ -42,8 +44,8 @@ namespace JSC { - - class CodeBlock; - class EvalExecutable; -+ class ExecutableBase; - class FunctionExecutable; -- class JSFunction; - class JSGlobalObject; - class ProgramExecutable; - class Register; -@@ -62,16 +64,79 @@ namespace JSC { - WillExecuteStatement - }; - -+ enum StackFrameCodeType { -+ StackFrameGlobalCode, -+ StackFrameEvalCode, -+ StackFrameFunctionCode, -+ StackFrameNativeCode -+ }; -+ -+ struct StackFrame { -+ Strong callee; -+ Strong callFrame; -+ StackFrameCodeType codeType; -+ Strong executable; -+ int line; -+ UString sourceURL; -+ UString toString() const -+ { -+ bool hasSourceURLInfo = !sourceURL.isNull() && !sourceURL.isEmpty(); -+ bool hasLineInfo = line > -1; -+ String traceLine; -+ String sourceInfo; -+ JSObject* stackFrameCallee = callee.get(); -+ UString functionName = ""; -+ -+ if (hasSourceURLInfo) -+ sourceInfo = hasLineInfo ? String::format("%s:%d", sourceURL.ascii().data(), line) -+ : String::format("%s", sourceURL.ascii().data()); -+ -+ if (stackFrameCallee && stackFrameCallee->inherits(&JSFunction::s_info)) -+ functionName = asFunction(stackFrameCallee)->name(callFrame.get()); -+ -+ switch (codeType) { -+ case StackFrameEvalCode: -+ if (hasSourceURLInfo && !functionName.isEmpty()) -+ traceLine = String::format("at eval at %s (%s)", functionName.ascii().data(), sourceInfo.ascii().data()); -+ else if (hasSourceURLInfo) -+ traceLine = String::format("at eval at (%s)", sourceInfo.ascii().data()); -+ else if (!functionName.isEmpty()) -+ traceLine = String::format("at eval at %s", functionName.ascii().data()); -+ else -+ traceLine = String::format("at eval"); -+ break; -+ case StackFrameNativeCode: -+ if (!functionName.isEmpty()) -+ traceLine = String::format("at %s (native)", functionName.ascii().data()); -+ else -+ traceLine = "at (native)"; -+ break; -+ case StackFrameFunctionCode: -+ case StackFrameGlobalCode: -+ if (hasSourceURLInfo && !functionName.isEmpty()) -+ traceLine = String::format("at %s (%s)", functionName.ascii().data(), sourceInfo.ascii().data()); -+ else if (hasSourceURLInfo) -+ traceLine = String::format("at %s", sourceInfo.ascii().data()); -+ else if (!functionName.isEmpty()) -+ traceLine = String::format("at %s", functionName.ascii().data()); -+ else -+ traceLine = String::format("at unknown source"); -+ break; -+ } -+ return traceLine.impl(); -+ } -+ }; -+ - class TopCallFrameSetter { - public: - TopCallFrameSetter(JSGlobalData& global, CallFrame* callFrame) - : globalData(global) -- , oldCallFrame(global.topCallFrame) -+ , oldCallFrame(global.topCallFrame) - { - global.topCallFrame = callFrame; - } -- -- ~TopCallFrameSetter() -+ -+ ~TopCallFrameSetter() - { - globalData.topCallFrame = oldCallFrame; - } -@@ -141,6 +206,8 @@ namespace JSC { - - NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset); - NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine); -+ static const UString getTraceLine(CallFrame*, StackFrameCodeType, const UString&, int); -+ static void getStackTrace(JSGlobalData*, int line, Vector& results); - - void dumpSampleData(ExecState* exec); - void startSampling(); -diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp -index 47ec8c6..6d82f54 100644 ---- a/Source/JavaScriptCore/jsc.cpp -+++ b/Source/JavaScriptCore/jsc.cpp -@@ -27,6 +27,7 @@ - #include "CurrentTime.h" - #include "ExceptionHelpers.h" - #include "InitializeThreading.h" -+#include "Interpreter.h" - #include "JSArray.h" - #include "JSFunction.h" - #include "JSLock.h" -@@ -78,6 +79,7 @@ static bool fillBufferWithContentsOfFile(const UString& fileName, Vector& - - static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*); - static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*); -+static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*); - static EncodedJSValue JSC_HOST_CALL functionGC(ExecState*); - #ifndef NDEBUG - static EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState*); -@@ -184,6 +186,7 @@ protected: - addFunction(globalData, "run", functionRun, 1); - addFunction(globalData, "load", functionLoad, 1); - addFunction(globalData, "checkSyntax", functionCheckSyntax, 1); -+ addFunction(globalData, "jscStack", functionJSCStack, 1); - addFunction(globalData, "readline", functionReadline, 0); - addFunction(globalData, "preciseTime", functionPreciseTime, 0); - #if ENABLE(SAMPLING_FLAGS) -@@ -252,6 +255,22 @@ EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec) - return JSValue::encode(jsUndefined()); - } - -+EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState* exec) -+{ -+ String trace = "--> Stack trace:\n"; -+ Vector stackTrace; -+ Interpreter::getStackTrace(&exec->globalData(), -1, stackTrace); -+ int i = 0; -+ -+ for (Vector::iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) { -+ StackFrame level = *iter; -+ trace += String::format(" %i %s\n", i, level.toString().utf8().data()); -+ i++; -+ } -+ fprintf(stderr, "%s", trace.utf8().data()); -+ return JSValue::encode(jsUndefined()); -+} -+ - EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec) - { - JSLock lock(SilenceAssertionsOnly); -diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h -index f3d96ff..27dafae 100644 ---- a/Source/JavaScriptCore/parser/Parser.h -+++ b/Source/JavaScriptCore/parser/Parser.h -@@ -1016,7 +1016,7 @@ PassRefPtr Parser::parse(JSGlobalObject* lexicalGlobalObj - else if (isEvalNode()) - *exception = createSyntaxError(lexicalGlobalObject, errMsg); - else -- *exception = addErrorInfo(&lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, *m_source); -+ *exception = addErrorInfo(&lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, *m_source, Vector()); - } - - if (debugger && !ParsedNode::scopeIsFunction) -diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h -index 08d8644..ce11730 100644 ---- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h -+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h -@@ -52,6 +52,7 @@ - macro(input) \ - macro(isArray) \ - macro(isPrototypeOf) \ -+ macro(stack) \ - macro(length) \ - macro(message) \ - macro(multiline) \ -diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp -index c3f2878..9b4af6f 100644 ---- a/Source/JavaScriptCore/runtime/Error.cpp -+++ b/Source/JavaScriptCore/runtime/Error.cpp -@@ -27,6 +27,7 @@ - #include "ConstructData.h" - #include "ErrorConstructor.h" - #include "FunctionPrototype.h" -+#include "JSArray.h" - #include "JSFunction.h" - #include "JSGlobalObject.h" - #include "JSObject.h" -@@ -39,6 +40,8 @@ namespace JSC { - static const char* linePropertyName = "line"; - static const char* sourceIdPropertyName = "sourceId"; - static const char* sourceURLPropertyName = "sourceURL"; -+static const char* stackPropertyName = "stack"; -+static const char* messagePropertyName = "message"; - - JSObject* createError(JSGlobalObject* globalObject, const UString& message) - { -@@ -117,7 +120,7 @@ JSObject* createURIError(ExecState* exec, const UString& message) - return createURIError(exec->lexicalGlobalObject(), message); - } - --JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, const SourceCode& source) -+JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, const SourceCode& source, const Vector& stackTrace) - { - intptr_t sourceID = source.provider()->asID(); - const UString& sourceURL = source.provider()->url(); -@@ -128,13 +131,29 @@ JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, cons - error->putDirect(*globalData, Identifier(globalData, sourceIdPropertyName), jsNumber((double)sourceID), ReadOnly | DontDelete); - if (!sourceURL.isNull()) - error->putDirect(*globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete); -+ if (!stackTrace.isEmpty()) { -+ String trace = String::format("%s: ", JSObject::className(error).ascii().data()); -+ trace += asString(error->getDirect(*globalData, Identifier(globalData, messagePropertyName)))->tryGetValue().ascii().data(); -+ trace += "\n"; -+ //JSArray* stackTraceArray = JSArray::create(*globalData, globalData->dynamicGlobalObject->arrayStructure()); -+ for (unsigned i = 0; i < stackTrace.size(); i++) { -+ UString stackLevel = stackTrace[i].toString(); -+ trace += " "; -+ trace += stackLevel.ascii().data(); -+ if (i < stackTrace.size() - 1) -+ trace += "\n"; -+ //stackTraceArray->push(globalData->topCallFrame, jsString(globalData, stackLevel)); -+ } -+ //error->putDirect(*globalData, Identifier(globalData, stackPropertyName), stackTraceArray, ReadOnly | DontDelete); -+ error->putDirect(*globalData, Identifier(globalData, stackPropertyName), jsString(globalData, UString(trace.impl())), ReadOnly | DontDelete); -+ } - - return error; - } - --JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source) -+JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source, const Vector& stackTrace) - { -- return addErrorInfo(&exec->globalData(), error, line, source); -+ return addErrorInfo(&exec->globalData(), error, line, source, stackTrace); - } - - bool hasErrorInfo(ExecState* exec, JSObject* error) -diff --git a/Source/JavaScriptCore/runtime/Error.h b/Source/JavaScriptCore/runtime/Error.h -index 88b540a..59b3949 100644 ---- a/Source/JavaScriptCore/runtime/Error.h -+++ b/Source/JavaScriptCore/runtime/Error.h -@@ -24,6 +24,7 @@ - #define Error_h - - #include "InternalFunction.h" -+#include "Interpreter.h" - #include "JSObject.h" - #include - -@@ -56,9 +57,9 @@ namespace JSC { - - // Methods to add - bool hasErrorInfo(ExecState*, JSObject* error); -- JSObject* addErrorInfo(JSGlobalData*, JSObject* error, int line, const SourceCode&); -+ JSObject* addErrorInfo(JSGlobalData*, JSObject* error, int line, const SourceCode&, const Vector&); - // ExecState wrappers. -- JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&); -+ JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&, const Vector&); - - // Methods to throw Errors. - JS_EXPORT_PRIVATE JSValue throwError(ExecState*, JSValue); +Corey needs to go on the mini server and create the patch based on tmm1's changes ```