source: webkit/trunk/JavaScriptCore/kjs/interpreter.cpp@ 32687

Last change on this file since 32687 was 31949, checked in by [email protected], 17 years ago

2008-04-16 Kevin McCullough <[email protected]>

Reviewed by Sam and Geoff.

-<rdar://problem/5770054> JavaScript profiler (10928)
Inital profiler prototype

  • GNUmakefile.am: Added new files to project
  • JavaScriptCore.pri: Ditto
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto
  • JavaScriptCore.xcodeproj/project.pbxproj: Ditto
  • JavaScriptCoreSources.bkl: Ditto
  • kjs/config.h: Put compiling flag in here.
  • kjs/function.cpp: Instrument calling the function eval(). (KJS::eval):
  • kjs/interpreter.cpp: Instrument evaluating global scopes. (KJS::Interpreter::evaluate):
  • kjs/object.cpp: Instrument JS function calls. (KJS::JSObject::call):
  • profiler: Added.
  • profiler/FunctionCallProfile.cpp: Added. (KJS::FunctionCallProfile::FunctionCallProfile): (KJS::FunctionCallProfile::~FunctionCallProfile): (KJS::FunctionCallProfile::willExecute): Call right before the JS function or executing context is executed to start the profiler's timer. (KJS::FunctionCallProfile::didExecute): Call right after the JS function or executing context is executed to stop the profiler's timer. (KJS::FunctionCallProfile::addChild): Add a child to the current FunctionCallProfile if it isn't already a child of the current FunctionalCallProfile. (KJS::FunctionCallProfile::findChild): Return the child that matches the given name if there is one. (KJS::FunctionCallProfile::printDataSampleStyle): Print the current profiled information in a format that matches sample's output.
  • profiler/FunctionCallProfile.h: Added. (KJS::FunctionCallProfile::FunctionCallProfile): (KJS::FunctionCallProfile::~FunctionCallProfile): (KJS::FunctionCallProfile::functionName): (KJS::FunctionCallProfile::microSecs):
  • profiler/Profiler.cpp: Added. (KJS::Profiler::profiler): (KJS::Profiler::sharedProfiler): Return global singleton (may change due to multi-threading concerns) (KJS::Profiler::startProfiling): Don't start collecting profiling information until the user starts the profiler. Also don't clear old prfiled data until the profiler is restarted. (KJS::Profiler::stopProfiling): Stop collecting profile information. (KJS::Profiler::willExecute): Same as above. (KJS::Profiler::didExecute): Same as above. (KJS::Profiler::insertStackNamesInTree): Follow the stack of the given names and if a sub-stack is not in the current tree, add it. (KJS::Profiler::getStackNames): Get the names from the different passed in parameters and order them as a stack. (KJS::Profiler::getFunctionName): Get the function name from the given parameter. (KJS::Profiler::printDataSampleStyle): Print the current profiled information in a format that matches sample's output. (KJS::Profiler::debugLog):
  • profiler/Profiler.h: Added. (KJS::Profiler::Profiler):
  • Property svn:eol-style set to native
File size: 4.9 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2007 Apple Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24#include "interpreter.h"
25
26#include "ExecState.h"
27#include "JSGlobalObject.h"
28#include "Parser.h"
29#include "debugger.h"
30#include <profiler/Profiler.h>
31#include <stdio.h>
32
33#if !PLATFORM(WIN_OS)
34#include <unistd.h>
35#endif
36
37namespace KJS {
38
39Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code)
40{
41 return checkSyntax(exec, sourceURL, startingLineNumber, code.data(), code.size());
42}
43
44Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength)
45{
46 JSLock lock;
47
48 int errLine;
49 UString errMsg;
50 RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
51 if (!progNode)
52 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, 0, sourceURL));
53 return Completion(Normal);
54}
55
56Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
57{
58 return evaluate(exec, sourceURL, startingLineNumber, code.data(), code.size(), thisV);
59}
60
61Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
62{
63 JSLock lock;
64
65 JSGlobalObject* globalObject = exec->dynamicGlobalObject();
66
67 if (globalObject->recursion() >= 20)
68 return Completion(Throw, Error::create(exec, GeneralError, "Recursion too deep"));
69
70 // parse the source code
71 int sourceId;
72 int errLine;
73 UString errMsg;
74
75#if JAVASCRIPT_PROFILING
76 Profiler::profiler()->willExecute(exec, sourceURL, startingLineNumber);
77#endif
78
79 RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg);
80
81 // notify debugger that source has been parsed
82 if (globalObject->debugger()) {
83 bool cont = globalObject->debugger()->sourceParsed(exec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
84 if (!cont)
85 return Completion(Break);
86 }
87
88 // no program node means a syntax error occurred
89 if (!progNode)
90 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL));
91
92 exec->clearException();
93
94 globalObject->incRecursion();
95
96 JSObject* thisObj = globalObject;
97
98 // "this" must be an object... use same rules as Function.prototype.apply()
99 if (thisV && !thisV->isUndefinedOrNull())
100 thisObj = thisV->toObject(exec);
101
102 Completion res;
103 if (exec->hadException())
104 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
105 res = Completion(Throw, exec->exception());
106 else {
107 // execute the code
108 InterpreterExecState newExec(globalObject, thisObj, progNode.get());
109 JSValue* value = progNode->execute(&newExec);
110 res = Completion(newExec.completionType(), value);
111 }
112
113#if JAVASCRIPT_PROFILING
114 Profiler::profiler()->didExecute(exec, sourceURL, startingLineNumber);
115#endif
116
117 globalObject->decRecursion();
118
119 if (shouldPrintExceptions() && res.complType() == Throw) {
120 JSLock lock;
121 ExecState* exec = globalObject->globalExec();
122 CString f = sourceURL.UTF8String();
123 CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
124 int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
125#if PLATFORM(WIN_OS)
126 printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
127#else
128 printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
129#endif
130 }
131
132 return res;
133}
134
135static bool printExceptions = false;
136
137bool Interpreter::shouldPrintExceptions()
138{
139 return printExceptions;
140}
141
142void Interpreter::setShouldPrintExceptions(bool print)
143{
144 printExceptions = print;
145}
146
147} // namespace KJS
Note: See TracBrowser for help on using the repository browser.