]> git.saurik.com Git - apple/javascriptcore.git/blob - kjs/interpreter.cpp
f7ea2c55a9abd40d3166e9c57a349db78b7fe214
[apple/javascriptcore.git] / kjs / interpreter.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
5 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
6 * Copyright (C) 2003, 2007 Apple Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25 #include "config.h"
26 #include "interpreter.h"
27
28 #include "ExecState.h"
29 #include "JSGlobalObject.h"
30 #include "Parser.h"
31 #include "SavedBuiltins.h"
32 #include "array_object.h"
33 #include "bool_object.h"
34 #include "collector.h"
35 #include "date_object.h"
36 #include "debugger.h"
37 #include "error_object.h"
38 #include "function_object.h"
39 #include "internal.h"
40 #include "math_object.h"
41 #include "nodes.h"
42 #include "number_object.h"
43 #include "object.h"
44 #include "object_object.h"
45 #include "operations.h"
46 #include "regexp_object.h"
47 #include "runtime.h"
48 #include "string_object.h"
49 #include "types.h"
50 #include "value.h"
51 #include <math.h>
52 #include <stdio.h>
53 #include <wtf/Assertions.h>
54
55 namespace KJS {
56
57 Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code)
58 {
59 return checkSyntax(exec, sourceURL, startingLineNumber, code.data(), code.size());
60 }
61
62 Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength)
63 {
64 JSLock lock;
65
66 int errLine;
67 UString errMsg;
68 RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
69 if (!progNode)
70 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, 0, sourceURL));
71 return Completion(Normal);
72 }
73
74 Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
75 {
76 return evaluate(exec, sourceURL, startingLineNumber, code.data(), code.size(), thisV);
77 }
78
79 Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
80 {
81 JSLock lock;
82
83 JSGlobalObject* globalObject = exec->dynamicGlobalObject();
84
85 if (globalObject->recursion() >= 20)
86 return Completion(Throw, Error::create(exec, GeneralError, "Recursion too deep"));
87
88 // parse the source code
89 int sourceId;
90 int errLine;
91 UString errMsg;
92 RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg);
93
94 // notify debugger that source has been parsed
95 if (globalObject->debugger()) {
96 bool cont = globalObject->debugger()->sourceParsed(exec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
97 if (!cont)
98 return Completion(Break);
99 }
100
101 // no program node means a syntax error occurred
102 if (!progNode)
103 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL));
104
105 exec->clearException();
106
107 globalObject->incRecursion();
108
109 JSObject* thisObj = globalObject;
110
111 // "this" must be an object... use same rules as Function.prototype.apply()
112 if (thisV && !thisV->isUndefinedOrNull())
113 thisObj = thisV->toObject(exec);
114
115 Completion res;
116 if (exec->hadException())
117 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
118 res = Completion(Throw, exec->exception());
119 else {
120 // execute the code
121 InterpreterExecState newExec(globalObject, thisObj, progNode.get());
122 JSValue* value = progNode->execute(&newExec);
123 res = Completion(newExec.completionType(), value);
124 }
125
126 globalObject->decRecursion();
127
128 if (shouldPrintExceptions() && res.complType() == Throw) {
129 JSLock lock;
130 ExecState* exec = globalObject->globalExec();
131 CString f = sourceURL.UTF8String();
132 CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
133 int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
134 #if PLATFORM(WIN_OS)
135 printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
136 #else
137 printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
138 #endif
139 }
140
141 return res;
142 }
143
144 static bool printExceptions = false;
145
146 bool Interpreter::shouldPrintExceptions()
147 {
148 return printExceptions;
149 }
150
151 void Interpreter::setShouldPrintExceptions(bool print)
152 {
153 printExceptions = print;
154 }
155
156 } // namespace KJS