Changeset 63548 in webkit
- Timestamp:
- Jul 16, 2010 8:30:32 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r63543 r63548 1 2010-07-16 Yury Semikhatsky <yurys@chromium.org> 2 3 Reviewed by Pavel Feldman. 4 5 console.trace should show file and line number for each function in the stack 6 https://bugs.webkit.org/show_bug.cgi?id=21180 7 8 * http/tests/inspector/console-tests.js: 9 (frontend_dumpConsoleMessages): 10 * inspector/console-trace-expected.txt: Added. 11 * inspector/console-trace.html: Added. 12 1 13 2010-07-16 Pavel Podivilov <podivilov@chromium.org> 2 14 -
trunk/LayoutTests/http/tests/inspector/console-tests.js
r58403 r63548 40 40 return result; 41 41 } 42 // Inspected Page functions.43 42 44 function dumpConsoleMessages(noNotifyDone) {45 function callback(result)46 {47 for (var i = 0; i < result.length; ++i)48 output(result[i].text);49 if (!noNotifyDone)50 notifyDone();51 }52 evaluateInWebInspector("frontend_dumpConsoleMessages", callback);53 }54 55 function dumpConsoleMessagesWithClasses(sortMessages) {56 function callback(result)57 {58 var messages = [];59 for (var i = 0; i < result.length; ++i)60 messages.push(result[i].text + " " + result[i].clazz);61 if (sortMessages)62 messages.sort();63 for (var i = 0; i < messages.length; ++i)64 output(messages[i]);65 notifyDone();66 }67 evaluateInWebInspector("frontend_dumpConsoleMessages", callback);68 }69 70 71 // Frontend functions.72 73 function frontend_dumpConsoleMessages()74 {75 var result = [];76 var messages = WebInspector.console.messages;77 for (var i = 0; i < messages.length; ++i) {78 var element = messages[i].toMessageElement();79 result.push({ text: element.textContent.replace(/\u200b/g, ""), clazz: element.getAttribute("class")});80 }81 return result;82 }83 // Inspected Page functions.84 85 function dumpConsoleMessages(noNotifyDone) {86 function callback(result)87 {88 for (var i = 0; i < result.length; ++i)89 output(result[i].text);90 if (!noNotifyDone)91 notifyDone();92 }93 evaluateInWebInspector("frontend_dumpConsoleMessages", callback);94 }95 96 function dumpConsoleMessagesWithClasses(sortMessages) {97 function callback(result)98 {99 var messages = [];100 for (var i = 0; i < result.length; ++i)101 messages.push(result[i].text + " " + result[i].clazz);102 if (sortMessages)103 messages.sort();104 for (var i = 0; i < messages.length; ++i)105 output(messages[i]);106 notifyDone();107 }108 evaluateInWebInspector("frontend_dumpConsoleMessages", callback);109 }110 111 112 // Frontend functions.113 114 function frontend_dumpConsoleMessages()115 {116 var result = [];117 var messages = WebInspector.console.messages;118 for (var i = 0; i < messages.length; ++i) {119 var element = messages[i].toMessageElement();120 result.push({ text: element.textContent.replace(/\u200b/g, ""), clazz: element.getAttribute("class")});121 }122 return result;123 } -
trunk/WebCore/ChangeLog
r63546 r63548 1 2010-07-16 Yury Semikhatsky <yurys@chromium.org> 2 3 Reviewed by Pavel Feldman. 4 5 console.trace should show file and line number for each function in the stack 6 https://bugs.webkit.org/show_bug.cgi?id=21180 7 8 Test: inspector/console-trace.html 9 10 * bindings/js/ScriptCallStack.cpp: 11 (WebCore::ScriptCallStack::initialize): 12 * bindings/v8/ScriptCallFrame.cpp: 13 (WebCore::ScriptCallFrame::ScriptCallFrame): 14 * bindings/v8/ScriptCallFrame.h: 15 * bindings/v8/ScriptCallStack.cpp: 16 (WebCore::getFrameLocation): 17 (WebCore::toScriptCallFrame): 18 (WebCore::ScriptCallStack::create): 19 (WebCore::ScriptCallStack::ScriptCallStack): 20 (WebCore::ScriptCallStack::at): 21 (WebCore::ScriptCallStack::size): 22 * bindings/v8/ScriptCallStack.h: 23 * bindings/v8/custom/V8ConsoleCustom.cpp: 24 (WebCore::V8Console::traceCallback): 25 * inspector/ConsoleMessage.cpp: 26 (WebCore::ConsoleMessage::CallFrame::CallFrame): 27 (WebCore::ConsoleMessage::CallFrame::isEqual): 28 (WebCore::ConsoleMessage::CallFrame::createFrontendObject): 29 (WebCore::ConsoleMessage::ConsoleMessage): 30 (WebCore::ConsoleMessage::addToFrontend): 31 (WebCore::ConsoleMessage::isEqual): 32 * inspector/ConsoleMessage.h: 33 * inspector/front-end/ConsoleView.js: 34 (WebInspector.ConsoleMessage.prototype._formatMessage): 35 (WebInspector.ConsoleMessage.prototype._createStackTraceElement): 36 (WebInspector.ConsoleMessage.prototype._createSourceUrlLink): 37 * inspector/front-end/inspector.css: 38 (.console-message.expandable > .console-message-text::before): 39 (.console-message.expandable.collapsed > .console-message-text::before): 40 (.console-message.expandable.collapsed > ol.stack-trace): 41 (.console-message > ol.stack-trace): 42 (.console-message.repeated-message > ol.stack-trace): 43 (.console-message.repeated-message > ol.stack-trace.trace-message): 44 * page/Console.idl: 45 1 46 2010-07-16 Lucas De Marchi <lucas.demarchi@profusion.mobi> 2 47 -
trunk/WebCore/bindings/js/ScriptCallStack.cpp
r62542 r63548 92 92 return; 93 93 94 JSValue func = m_exec->interpreter()->retrieveCaller(m_exec, m_caller); 95 while (!func.isNull()) { 96 JSFunction* jsFunction = asFunction(func); 97 m_frames.append(ScriptCallFrame(jsFunction->name(m_exec), UString(), 0, 0, 0)); 98 func = m_exec->interpreter()->retrieveCaller(m_exec, jsFunction); 94 int signedLineNumber; 95 intptr_t sourceID; 96 UString urlString; 97 JSValue function; 98 // callFrame must exist if m_caller is not null. 99 CallFrame* callFrame = m_exec->callerFrame(); 100 while (true) { 101 ASSERT(callFrame); 102 m_exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function); 103 if (!function) 104 break; 105 JSFunction* jsFunction = asFunction(function); 106 unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; 107 m_frames.append(ScriptCallFrame(jsFunction->name(m_exec), urlString, lineNumber, m_exec, 0)); 108 callFrame = callFrame->callerFrame(); 99 109 } 100 110 m_initialized = true; -
trunk/WebCore/bindings/v8/ScriptCallFrame.cpp
r47912 r63548 46 46 , m_lineNumber(lineNumber) 47 47 { 48 for (int i = 0; i < arguments.Length(); ++i)48 for (int i = skipArgumentCount; i < arguments.Length(); ++i) 49 49 m_arguments.append(ScriptValue(arguments[i])); 50 } 51 52 ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber) 53 : m_functionName(functionName) 54 , m_sourceURL(ParsedURLString, urlString) 55 , m_lineNumber(lineNumber) 56 { 50 57 } 51 58 -
trunk/WebCore/bindings/v8/ScriptCallFrame.h
r41159 r63548 51 51 public: 52 52 ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments&, unsigned skipArgumentCount); 53 ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber); 53 54 ~ScriptCallFrame(); 54 55 -
trunk/WebCore/bindings/v8/ScriptCallStack.cpp
r62542 r63548 33 33 34 34 #include "InspectorValues.h" 35 #include "ScriptScope.h"36 35 #include "ScriptController.h" 37 36 #include "ScriptDebugServer.h" 37 #include "ScriptScope.h" 38 38 #include "V8Binding.h" 39 39 … … 42 42 namespace WebCore { 43 43 44 ScriptCallStack* ScriptCallStack::create(const v8::Arguments& arguments, unsigned skipArgumentCount) { 45 String sourceName; 46 int sourceLineNumber; 47 String funcName; 48 if (!callLocation(&sourceName, &sourceLineNumber, &funcName)) 49 return 0; 50 return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber, funcName); 51 } 52 53 bool ScriptCallStack::callLocation(String* sourceName, int* sourceLineNumber, String* functionName) 44 static void getFrameLocation(v8::Handle<v8::StackFrame> frame, String* sourceName, int* sourceLineNumber, String* functionName) 54 45 { 55 v8::HandleScope scope;56 v8::Context::Scope contextScope(v8::Context::GetCurrent());57 v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(1));58 if (stackTrace.IsEmpty())59 return false;60 if (stackTrace->GetFrameCount() <= 0) {61 // Successfully grabbed stack trace, but there are no frames.62 // Fallback to setting lineNumber to 0, and source and function name to "undefined".63 *sourceName = toWebCoreString(v8::Undefined());64 *sourceLineNumber = 0;65 *functionName = toWebCoreString(v8::Undefined());66 return true;67 }68 v8::Handle<v8::StackFrame> frame = stackTrace->GetFrame(0);69 // There must be at least one valid frame.70 46 ASSERT(!frame.IsEmpty()); 71 47 v8::Local<v8::String> sourceNameValue(frame->GetScriptName()); … … 74 50 *functionName = functionNameValue.IsEmpty() ? "" : toWebCoreString(functionNameValue); 75 51 *sourceLineNumber = frame->GetLineNumber(); 76 return true; 52 } 53 54 static PassOwnPtr<ScriptCallFrame> toScriptCallFrame(v8::Handle<v8::StackFrame> frame) 55 { 56 String sourceName; 57 int sourceLineNumber; 58 String functionName; 59 getFrameLocation(frame, &sourceName, &sourceLineNumber, &functionName); 60 return new ScriptCallFrame(functionName, sourceName, sourceLineNumber); 61 } 62 63 PassOwnPtr<ScriptCallStack> ScriptCallStack::create(const v8::Arguments& arguments, unsigned skipArgumentCount) 64 { 65 v8::HandleScope scope; 66 v8::Context::Scope contextScope(v8::Context::GetCurrent()); 67 v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(1)); 68 69 if (stackTrace.IsEmpty()) 70 return 0; 71 72 String sourceName; 73 int sourceLineNumber; 74 String functionName; 75 if (stackTrace->GetFrameCount() <= 0) { 76 // Successfully grabbed stack trace, but there are no frames. 77 // Fallback to setting lineNumber to 0, and source and function name to "undefined". 78 sourceName = toWebCoreString(v8::Undefined()); 79 sourceLineNumber = 0; 80 functionName = toWebCoreString(v8::Undefined()); 81 } else { 82 v8::Handle<v8::StackFrame> frame = stackTrace->GetFrame(0); 83 getFrameLocation(frame, &sourceName, &sourceLineNumber, &functionName); 84 } 85 return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber, functionName); 86 } 87 88 PassOwnPtr<ScriptCallStack> ScriptCallStack::create(ScriptState* state, v8::Handle<v8::StackTrace> stackTrace) 89 { 90 return new ScriptCallStack(state, stackTrace); 77 91 } 78 92 79 93 ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber, String functionName) 80 : m_ lastCaller(functionName, sourceName, sourceLineNumber, arguments, skipArgumentCount)94 : m_topFrame(new ScriptCallFrame(functionName, sourceName, sourceLineNumber, arguments, skipArgumentCount)) 81 95 , m_scriptState(ScriptState::current()) 82 96 { 97 } 98 99 ScriptCallStack::ScriptCallStack(ScriptState* scriptState, v8::Handle<v8::StackTrace> stackTrace) 100 : m_scriptState(scriptState) 101 { 102 v8::HandleScope handleScope; 103 v8::Context::Scope contextScope(m_scriptState->context()); 104 int frameCount = stackTrace->GetFrameCount(); 105 for (int i = 0; i < frameCount; i++) { 106 v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i); 107 m_scriptCallFrames.append(toScriptCallFrame(stackFrame)); 108 } 83 109 } 84 110 … … 87 113 } 88 114 89 const ScriptCallFrame& ScriptCallStack::at(unsigned index) const115 const ScriptCallFrame& ScriptCallStack::at(unsigned index) 90 116 { 91 // Currently, only one ScriptCallFrame is supported. When we can get 92 // a full stack trace from V8, we can do this right. 93 ASSERT(index == 0); 94 return m_lastCaller; 117 if (!index && m_topFrame) 118 return *m_topFrame; 119 return *m_scriptCallFrames.at(index); 95 120 } 121 122 unsigned ScriptCallStack::size() 123 { 124 if (m_scriptCallFrames.isEmpty()) 125 return 1; 126 return m_scriptCallFrames.size(); 127 } 128 96 129 97 130 bool ScriptCallStack::stackTrace(int frameLimit, const RefPtr<InspectorArray>& stackTrace) -
trunk/WebCore/bindings/v8/ScriptCallStack.h
r62542 r63548 49 49 class ScriptCallStack : public Noncopyable { 50 50 public: 51 static ScriptCallStack* create(const v8::Arguments&, unsigned skipArgumentCount = 0); 51 static PassOwnPtr<ScriptCallStack> create(const v8::Arguments&, unsigned skipArgumentCount = 0); 52 static PassOwnPtr<ScriptCallStack> create(ScriptState*, v8::Handle<v8::StackTrace>); 52 53 ~ScriptCallStack(); 53 54 … … 63 64 static bool stackTrace(int frameLimit, const RefPtr<InspectorArray>& stackTrace); 64 65 65 const ScriptCallFrame& at(unsigned) const; 66 // FIXME: implement retrieving and storing call stack trace 67 unsigned size() const { return 1; } 66 const ScriptCallFrame& at(unsigned); 67 unsigned size(); 68 68 69 69 ScriptState* state() const { return m_scriptState; } … … 72 72 private: 73 73 ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber, String funcName); 74 ScriptCallStack(ScriptState* scriptState, v8::Handle<v8::StackTrace> stackTrace); 74 75 75 static bool callLocation(String* sourceName, int* sourceLineNumber, String* functionName); 76 77 ScriptCallFrame m_lastCaller; 76 OwnPtr<ScriptCallFrame> m_topFrame; 78 77 ScriptState* m_scriptState; 78 Vector<OwnPtr<ScriptCallFrame> > m_scriptCallFrames; 79 79 }; 80 80 -
trunk/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp
r63537 r63548 34 34 35 35 #include "Console.h" 36 #include "ScriptCallStack.h" 36 37 #include "ScriptProfile.h" 37 38 #include "V8Binding.h" … … 58 59 #endif 59 60 61 v8::Handle<v8::Value> V8Console::traceCallback(const v8::Arguments& args) 62 { 63 INC_STATS("DOM.Console.traceCallback"); 64 Console* imp = V8Console::toNative(args.Holder()); 65 v8::HandleScope handleScope; 66 ScriptState* scriptState = ScriptState::current(); 67 v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(200); 68 OwnPtr<ScriptCallStack> callStack(ScriptCallStack::create(scriptState, stackTrace)); 69 imp->trace(callStack.get()); 70 return v8::Handle<v8::Value>(); 71 } 60 72 } // namespace WebCore -
trunk/WebCore/inspector/ConsoleMessage.cpp
r63427 r63548 41 41 namespace WebCore { 42 42 43 ConsoleMessage::CallFrame::CallFrame(const ScriptCallFrame& frame) 44 : m_functionName(frame.functionName()) 45 , m_sourceURL(frame.sourceURL()) 46 , m_lineNumber(frame.lineNumber()) 47 { 48 } 49 50 ConsoleMessage::CallFrame::CallFrame() 51 : m_lineNumber(0) 52 { 53 } 54 55 bool ConsoleMessage::CallFrame::isEqual(const ConsoleMessage::CallFrame& o) const 56 { 57 return m_functionName == o.m_functionName 58 && m_sourceURL == o.m_sourceURL 59 && m_lineNumber == o.m_lineNumber; 60 } 61 62 ScriptObject ConsoleMessage::CallFrame::buildObject(InspectorFrontend* frontend) const 63 { 64 ScriptObject frame = frontend->newScriptObject(); 65 frame.set("functionName", m_functionName); 66 frame.set("sourceURL", m_sourceURL.string()); 67 frame.set("lineNumber", m_lineNumber); 68 return frame; 69 } 70 43 71 ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g) 44 72 : m_source(s) … … 74 102 if (storeTrace) { 75 103 for (unsigned i = 0; i < callStack->size(); ++i) 76 m_frames[i] = callStack->at(i).functionName();104 m_frames[i] = ConsoleMessage::CallFrame(callStack->at(i)); 77 105 } 78 106 … … 108 136 } 109 137 if (!m_frames.isEmpty()) { 110 ScriptArray jsonFrames = frontend->newScriptArray();111 for (unsigned i = 0; i < m_frames.size(); ++i)112 jsonFrames.set(i, m_frames[i]);113 jsonObj.set("stackTrace", jsonFrames);138 ScriptArray frames = frontend->newScriptArray(); 139 for (unsigned i = 0; i < m_frames.size(); i++) 140 frames.set(i, m_frames.at(i).buildObject(frontend)); 141 jsonObj.set("stackTrace", frames); 114 142 } 115 143 frontend->addConsoleMessage(jsonObj); … … 145 173 146 174 for (size_t i = 0; i < frameCount; ++i) { 147 if ( m_frames[i] != msg->m_frames[i])175 if (!m_frames[i].isEqual(msg->m_frames[i])) 148 176 return false; 149 177 } -
trunk/WebCore/inspector/ConsoleMessage.h
r56708 r63548 41 41 class InjectedScriptHost; 42 42 class InspectorFrontend; 43 class ScriptCallFrame; 43 44 class ScriptCallStack; 44 45 class ScriptString; … … 46 47 class ConsoleMessage : public Noncopyable { 47 48 public: 48 ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, unsigned li, const String& u, unsigned g); 49 ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, unsigned li, const String& u, unsigned g); 49 50 ConsoleMessage(MessageSource, MessageType, MessageLevel, ScriptCallStack*, unsigned g, bool storeTrace = false); 50 51 … … 60 61 61 62 private: 63 class CallFrame { 64 public: 65 explicit CallFrame(const ScriptCallFrame& frame); 66 CallFrame(); 67 bool isEqual(const CallFrame& o) const; 68 ScriptObject buildObject(InspectorFrontend* frontend) const; 69 70 private: 71 String m_functionName; 72 KURL m_sourceURL; 73 unsigned m_lineNumber; 74 }; 75 62 76 MessageSource m_source; 63 77 MessageType m_type; … … 68 82 ScriptStateProtectedPtr m_scriptState; 69 83 #endif 70 Vector< ScriptString> m_frames;84 Vector<CallFrame> m_frames; 71 85 unsigned m_line; 72 86 String m_url; -
trunk/WebCore/inspector/front-end/ConsoleView.js
r63427 r63548 674 674 switch (this.type) { 675 675 case WebInspector.ConsoleMessage.MessageType.Trace: 676 var span = document.createElement("span"); 677 span.className = "console-formatted-trace source-code"; 678 var funcNames = this._stackTrace.map(function(f) { 679 return f || WebInspector.UIString("(anonymous function)"); 680 }); 681 span.appendChild(document.createTextNode(funcNames.join("\n"))); 682 this.formattedMessage = span; 676 this.formattedMessage = this._createStackTraceElement(); 677 this.formattedMessage.addStyleClass("trace-message"); 683 678 break; 684 679 case WebInspector.ConsoleMessage.MessageType.Object: … … 831 826 } 832 827 833 if (this.url && this.url !== "undefined") { 834 var urlElement = document.createElement("a"); 835 urlElement.className = "console-message-url webkit-html-resource-link"; 836 urlElement.href = this.url; 837 urlElement.lineNumber = this.line; 838 839 if (this.source === WebInspector.ConsoleMessage.MessageSource.JS) 840 urlElement.preferredPanel = "scripts"; 841 842 if (this.line > 0) 843 urlElement.textContent = WebInspector.displayNameForURL(this.url) + ":" + this.line; 844 else 845 urlElement.textContent = WebInspector.displayNameForURL(this.url); 846 847 element.appendChild(urlElement); 848 } 849 850 var messageTextElement = document.createElement("span"); 851 messageTextElement.className = "console-message-text source-code"; 852 if (this.type === WebInspector.ConsoleMessage.MessageType.Assert) 853 messageTextElement.appendChild(document.createTextNode(WebInspector.UIString("Assertion failed: "))); 854 messageTextElement.appendChild(this.formattedMessage); 855 element.appendChild(messageTextElement); 828 if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) { 829 element.appendChild(this.formattedMessage); 830 } else { 831 if (this.url && this.url !== "undefined") { 832 var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url"); 833 element.appendChild(urlElement); 834 } 835 836 var messageTextElement = document.createElement("span"); 837 messageTextElement.className = "console-message-text source-code"; 838 if (this.type === WebInspector.ConsoleMessage.MessageType.Assert) 839 messageTextElement.appendChild(document.createTextNode(WebInspector.UIString("Assertion failed: "))); 840 messageTextElement.appendChild(this.formattedMessage); 841 element.appendChild(messageTextElement); 842 843 if (this._stackTrace) { 844 var ol = this._createStackTraceElement(); 845 element.appendChild(ol); 846 } 847 } 856 848 857 849 if (this.repeatCount > 1) … … 859 851 860 852 return element; 853 }, 854 855 _createStackTraceElement: function() 856 { 857 var ol = document.createElement("ol"); 858 ol.addStyleClass("stack-trace"); 859 var treeOutline = new TreeOutline(ol); 860 for (var i = 0; i < this._stackTrace.length; i++) { 861 var frame = this._stackTrace[i]; 862 863 var li = document.createElement("li"); 864 var messageTextElement = document.createElement("span"); 865 messageTextElement.className = "console-message-text source-code"; 866 var functionName = frame.functionName || WebInspector.UIString("(anonymous function)"); 867 messageTextElement.appendChild(document.createTextNode(functionName)); 868 li.appendChild(messageTextElement); 869 870 var urlElement = WebInspector.linkifyResourceAsNode(frame.sourceURL, "scripts", frame.lineNumber, "console-message-url"); 871 li.appendChild(urlElement); 872 873 874 var treeElement = new TreeElement(li.innerHTML); 875 treeOutline.appendChild(treeElement); 876 } 877 return ol; 861 878 }, 862 879 -
trunk/WebCore/inspector/front-end/inspector.css
r62535 r63548 712 712 } 713 713 714 .console-message > ol.stack-trace { 715 margin: 5px 0 5px -30px; 716 list-style: none; 717 } 718 719 .console-message.repeated-message > ol.stack-trace.trace-message { 720 margin-top: -9px; 721 margin-left: -12px; 722 } 723 714 724 .console-group-messages .section .header .title { 715 725 color: black; -
trunk/WebCore/page/Console.idl
r63537 r63548 42 42 [CustomArgumentHandling] void dir(); 43 43 [CustomArgumentHandling] void dirxml(); 44 [ CustomArgumentHandling] void trace();44 [V8Custom, CustomArgumentHandling] void trace(); 45 45 [CustomArgumentHandling, ImplementationFunction=assertCondition] void assert(in boolean condition); 46 46 [CustomArgumentHandling] void count();
Note: See TracChangeset
for help on using the changeset viewer.