1 // -*- c-basic-offset: 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 Apple Computer, Inc.
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.
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.
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., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
32 #include "interpreter.h"
33 #include "scope_chain.h"
35 #define I18N_NOOP(s) s
39 static const double D16 = 65536.0;
40 static const double D32 = 4294967296.0;
43 class FunctionBodyNode;
44 class FunctionPrototypeImp;
48 // ---------------------------------------------------------------------------
50 // ---------------------------------------------------------------------------
52 class UndefinedImp : public ValueImp {
54 Type type() const { return UndefinedType; }
56 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
57 bool toBoolean(ExecState *exec) const;
58 double toNumber(ExecState *exec) const;
59 UString toString(ExecState *exec) const;
60 Object toObject(ExecState *exec) const;
62 static UndefinedImp *staticUndefined;
65 inline Undefined::Undefined(UndefinedImp *imp) : Value(imp) { }
67 class NullImp : public ValueImp {
69 Type type() const { return NullType; }
71 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
72 bool toBoolean(ExecState *exec) const;
73 double toNumber(ExecState *exec) const;
74 UString toString(ExecState *exec) const;
75 Object toObject(ExecState *exec) const;
77 static NullImp *staticNull;
80 inline Null::Null(NullImp *imp) : Value(imp) { }
82 class BooleanImp : public ValueImp {
84 BooleanImp(bool v = false) : val(v) { }
85 bool value() const { return val; }
87 Type type() const { return BooleanType; }
89 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
90 bool toBoolean(ExecState *exec) const;
91 double toNumber(ExecState *exec) const;
92 UString toString(ExecState *exec) const;
93 Object toObject(ExecState *exec) const;
95 static BooleanImp *staticTrue;
96 static BooleanImp *staticFalse;
101 inline Boolean::Boolean(BooleanImp *imp) : Value(imp) { }
103 class StringImp : public ValueImp {
105 StringImp(const UString& v) : val(v) { }
106 UString value() const { return val; }
108 Type type() const { return StringType; }
110 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
111 bool toBoolean(ExecState *exec) const;
112 double toNumber(ExecState *exec) const;
113 UString toString(ExecState *exec) const;
114 Object toObject(ExecState *exec) const;
120 inline String::String(StringImp *imp) : Value(imp) { }
122 class NumberImp : public ValueImp {
124 friend class InterpreterImp;
126 static ValueImp *create(int);
127 static ValueImp *create(double);
128 static ValueImp *zero() { return SimpleNumber::make(0); }
129 static ValueImp *one() { return SimpleNumber::make(1); }
130 static ValueImp *two() { return SimpleNumber::make(2); }
132 double value() const { return val; }
134 Type type() const { return NumberType; }
136 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
137 bool toBoolean(ExecState *exec) const;
138 double toNumber(ExecState *exec) const;
139 UString toString(ExecState *exec) const;
140 Object toObject(ExecState *exec) const;
142 static NumberImp *staticNaN;
145 NumberImp(double v) : val(v) { }
147 virtual bool toUInt32(unsigned&) const;
152 inline Number::Number(NumberImp *imp) : Value(imp) { }
155 * @short The "label set" in Ecma-262 spec
159 LabelStack(): tos(0L) {}
162 LabelStack(const LabelStack &other);
163 LabelStack &operator=(const LabelStack &other);
166 * If id is not empty and is not in the stack already, puts it on top of
167 * the stack and returns true, otherwise returns false
169 bool push(const Identifier &id);
171 * Is the id in the stack?
173 bool contains(const Identifier &id) const;
175 * Removes from the stack the last pushed id (what else?)
189 // ---------------------------------------------------------------------------
190 // Parsing & evaluateion
191 // ---------------------------------------------------------------------------
193 enum CodeType { GlobalCode,
201 * Parses ECMAScript source code and converts into ProgramNode objects, which
202 * represent the root of a parse tree. This class provides a conveniant workaround
203 * for the problem of the bison parser working in a static context.
207 static ProgramNode *parse(const UString &sourceURL, int startingLineNumber,
208 const UChar *code, unsigned int length, int *sourceId = 0,
209 int *errLine = 0, UString *errMsg = 0);
211 static ProgramNode *progNode;
215 class SavedBuiltinsInternal {
216 friend class InterpreterImp;
218 ProtectedObject b_Object;
219 ProtectedObject b_Function;
220 ProtectedObject b_Array;
221 ProtectedObject b_Boolean;
222 ProtectedObject b_String;
223 ProtectedObject b_Number;
224 ProtectedObject b_Date;
225 ProtectedObject b_RegExp;
226 ProtectedObject b_Error;
228 ProtectedObject b_ObjectPrototype;
229 ProtectedObject b_FunctionPrototype;
230 ProtectedObject b_ArrayPrototype;
231 ProtectedObject b_BooleanPrototype;
232 ProtectedObject b_StringPrototype;
233 ProtectedObject b_NumberPrototype;
234 ProtectedObject b_DatePrototype;
235 ProtectedObject b_RegExpPrototype;
236 ProtectedObject b_ErrorPrototype;
238 ProtectedObject b_evalError;
239 ProtectedObject b_rangeError;
240 ProtectedObject b_referenceError;
241 ProtectedObject b_syntaxError;
242 ProtectedObject b_typeError;
243 ProtectedObject b_uriError;
245 ProtectedObject b_evalErrorPrototype;
246 ProtectedObject b_rangeErrorPrototype;
247 ProtectedObject b_referenceErrorPrototype;
248 ProtectedObject b_syntaxErrorPrototype;
249 ProtectedObject b_typeErrorPrototype;
250 ProtectedObject b_uriErrorPrototype;
253 class InterpreterImp {
254 friend class Collector;
256 static void globalInit();
257 static void globalClear();
259 InterpreterImp(Interpreter *interp, const Object &glob);
262 ProtectedObject &globalObject() const { return const_cast<ProtectedObject &>(global); }
263 Interpreter* interpreter() const { return m_interpreter; }
265 void initGlobalObject();
267 static void unlock();
268 static int lockCount();
272 ExecState *globalExec() { return globExec; }
273 bool checkSyntax(const UString &code);
274 Completion evaluate(const UString &code, const Value &thisV, const UString &sourceURL, int startingLineNumber);
275 Debugger *debugger() const { return dbg; }
276 void setDebugger(Debugger *d);
278 Object builtinObject() const { return b_Object; }
279 Object builtinFunction() const { return b_Function; }
280 Object builtinArray() const { return b_Array; }
281 Object builtinBoolean() const { return b_Boolean; }
282 Object builtinString() const { return b_String; }
283 Object builtinNumber() const { return b_Number; }
284 Object builtinDate() const { return b_Date; }
285 Object builtinRegExp() const { return b_RegExp; }
286 Object builtinError() const { return b_Error; }
288 Object builtinObjectPrototype() const { return b_ObjectPrototype; }
289 Object builtinFunctionPrototype() const { return b_FunctionPrototype; }
290 Object builtinArrayPrototype() const { return b_ArrayPrototype; }
291 Object builtinBooleanPrototype() const { return b_BooleanPrototype; }
292 Object builtinStringPrototype() const { return b_StringPrototype; }
293 Object builtinNumberPrototype() const { return b_NumberPrototype; }
294 Object builtinDatePrototype() const { return b_DatePrototype; }
295 Object builtinRegExpPrototype() const { return b_RegExpPrototype; }
296 Object builtinErrorPrototype() const { return b_ErrorPrototype; }
298 Object builtinEvalError() const { return b_evalError; }
299 Object builtinRangeError() const { return b_rangeError; }
300 Object builtinReferenceError() const { return b_referenceError; }
301 Object builtinSyntaxError() const { return b_syntaxError; }
302 Object builtinTypeError() const { return b_typeError; }
303 Object builtinURIError() const { return b_uriError; }
305 Object builtinEvalErrorPrototype() const { return b_evalErrorPrototype; }
306 Object builtinRangeErrorPrototype() const { return b_rangeErrorPrototype; }
307 Object builtinReferenceErrorPrototype() const { return b_referenceErrorPrototype; }
308 Object builtinSyntaxErrorPrototype() const { return b_syntaxErrorPrototype; }
309 Object builtinTypeErrorPrototype() const { return b_typeErrorPrototype; }
310 Object builtinURIErrorPrototype() const { return b_uriErrorPrototype; }
312 void setCompatMode(Interpreter::CompatMode mode) { m_compatMode = mode; }
313 Interpreter::CompatMode compatMode() const { return m_compatMode; }
315 // Chained list of interpreters (ring)
316 static InterpreterImp* firstInterpreter() { return s_hook; }
317 InterpreterImp *nextInterpreter() const { return next; }
318 InterpreterImp *prevInterpreter() const { return prev; }
320 static InterpreterImp *interpreterWithGlobalObject(ObjectImp *);
322 void setContext(ContextImp *c) { _context = c; }
323 ContextImp *context() const { return _context; }
325 void saveBuiltins (SavedBuiltins &builtins) const;
326 void restoreBuiltins (const SavedBuiltins &builtins);
330 Interpreter *m_interpreter;
331 ProtectedObject global;
334 // Built-in properties of the object prototype. These are accessible
335 // from here even if they are replaced by js code (e.g. assigning to
338 ProtectedObject b_Object;
339 ProtectedObject b_Function;
340 ProtectedObject b_Array;
341 ProtectedObject b_Boolean;
342 ProtectedObject b_String;
343 ProtectedObject b_Number;
344 ProtectedObject b_Date;
345 ProtectedObject b_RegExp;
346 ProtectedObject b_Error;
348 ProtectedObject b_ObjectPrototype;
349 ProtectedObject b_FunctionPrototype;
350 ProtectedObject b_ArrayPrototype;
351 ProtectedObject b_BooleanPrototype;
352 ProtectedObject b_StringPrototype;
353 ProtectedObject b_NumberPrototype;
354 ProtectedObject b_DatePrototype;
355 ProtectedObject b_RegExpPrototype;
356 ProtectedObject b_ErrorPrototype;
358 ProtectedObject b_evalError;
359 ProtectedObject b_rangeError;
360 ProtectedObject b_referenceError;
361 ProtectedObject b_syntaxError;
362 ProtectedObject b_typeError;
363 ProtectedObject b_uriError;
365 ProtectedObject b_evalErrorPrototype;
366 ProtectedObject b_rangeErrorPrototype;
367 ProtectedObject b_referenceErrorPrototype;
368 ProtectedObject b_syntaxErrorPrototype;
369 ProtectedObject b_typeErrorPrototype;
370 ProtectedObject b_uriErrorPrototype;
373 Interpreter::CompatMode m_compatMode;
375 // Chained list of interpreters (ring) - for collector
376 static InterpreterImp* s_hook;
377 InterpreterImp *next, *prev;
379 ContextImp *_context;
384 class AttachedInterpreter;
393 void abort() { isAborted = true; }
394 bool aborted() const { return isAborted; }
396 AttachedInterpreter *interps;
402 class InternalFunctionImp : public ObjectImp {
404 InternalFunctionImp(FunctionPrototypeImp *funcProto);
405 bool implementsHasInstance() const;
406 Boolean hasInstance(ExecState *exec, const Value &value);
408 virtual const ClassInfo *classInfo() const { return &info; }
409 static const ClassInfo info;
412 // helper function for toInteger, toInt32, toUInt32 and toUInt16
413 double roundValue(ExecState *exec, const Value &v);
416 void printInfo(ExecState *exec, const char *s, const Value &o, int lineno = -1);
422 #endif // _INTERNAL_H_