]> git.saurik.com Git - apple/javascriptcore.git/blob - kjs/interpreter.cpp
JavaScriptCore-466.1.6.tar.gz
[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 SourceCode& source)
58 {
59 JSLock lock;
60
61 int errLine;
62 UString errMsg;
63 RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(source, &errLine, &errMsg);
64 if (!progNode)
65 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
66 return Completion(Normal);
67 }
68
69 Completion Interpreter::evaluate(ExecState* exec, const SourceCode& source, JSValue* thisV)
70 {
71 JSLock lock;
72
73 JSGlobalObject* globalObject = exec->dynamicGlobalObject();
74
75 if (globalObject->recursion() >= 20)
76 return Completion(Throw, Error::create(exec, GeneralError, "Recursion too deep"));
77
78 // parse the source code
79 int errLine;
80 UString errMsg;
81 RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(source, &errLine, &errMsg);
82
83 // removed debugger support
84
85 // no program node means a syntax error occurred
86 if (!progNode)
87 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
88
89 exec->clearException();
90
91 globalObject->incRecursion();
92
93 JSObject* thisObj = globalObject;
94
95 // "this" must be an object... use same rules as Function.prototype.apply()
96 if (thisV && !thisV->isUndefinedOrNull())
97 thisObj = thisV->toObject(exec);
98
99 Completion res;
100 if (exec->hadException())
101 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
102 res = Completion(Throw, exec->exception());
103 else {
104 // execute the code
105 InterpreterExecState newExec(globalObject, thisObj, progNode.get());
106 JSValue* value = progNode->execute(&newExec);
107 res = Completion(newExec.completionType(), value);
108 }
109
110 globalObject->decRecursion();
111
112 if (shouldPrintExceptions() && res.complType() == Throw) {
113 JSLock lock;
114 ExecState* exec = globalObject->globalExec();
115 CString f = source.provider()->url().UTF8String();
116 CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
117 int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
118 #if PLATFORM(WIN_OS)
119 printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
120 #else
121 printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
122 #endif
123 }
124
125 return res;
126 }
127
128 static bool printExceptions = false;
129
130 bool Interpreter::shouldPrintExceptions()
131 {
132 return printExceptions;
133 }
134
135 void Interpreter::setShouldPrintExceptions(bool print)
136 {
137 printExceptions = print;
138 }
139
140 } // namespace KJS