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

Last change on this file since 27763 was 27763, checked in by [email protected], 18 years ago

JavaScriptCore:

Reviewed by Sam Weinig.

Moved Shared.h into wtf so it could be used in more places. Deployed
Shared in places where JSCore previously had hand-rolled ref-counting
classes.

  • API/JSClassRef.cpp: (OpaqueJSClass::OpaqueJSClass):
  • API/JSClassRef.h:
  • API/JSObjectRef.cpp: (JSClassRetain): (JSClassRelease):
  • JavaScriptCore.vcproj/WTF/WTF.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/interpreter.cpp: (KJS::Interpreter::init):
  • kjs/interpreter.h:
  • kjs/regexp.cpp: (KJS::RegExp::RegExp):
  • kjs/regexp.h:
  • wtf/Shared.h: Copied from WebCore/platform/Shared.h.

JavaScriptGlue:

Reviewed by Sam Weinig.

Moved Shared.h into wtf so it could be used in more places.

  • ForwardingHeaders/wtf/Shared.h: Added.

WebCore:

Reviewed by Sam Weinig.

Moved Shared.h into wtf so it could be used in more places. Retained
TreeShared, but moved it to its own file, TreeShared.h.

  • ForwardingHeaders/wtf/Shared.h: Added.
  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSSVGPODTypeWrapper.h:
  • css/CSSFontFace.h:
  • css/CSSRuleList.h:
  • css/Counter.h:
  • css/Pair.h:
  • css/Rect.h:
  • css/StyleBase.h:
  • css/StyleSheetList.h:
  • dom/Clipboard.h:
  • dom/DOMImplementation.h:
  • dom/Event.h:
  • dom/EventListener.h:
  • dom/NamedNodeMap.h:
  • dom/NodeFilterCondition.h:
  • dom/NodeList.h:
  • dom/Range.h:
  • dom/RangeException.h:
  • dom/RegisteredEventListener.h:
  • dom/Traversal.h:
  • history/BackForwardList.h:
  • history/CachedPage.h:
  • history/HistoryItem.h:
  • html/CanvasGradient.h:
  • html/CanvasPattern.h:
  • html/HTMLCollection.h:
  • html/MediaError.h:
  • html/TimeRanges.h:
  • html/VoidCallback.h:
  • ksvg2/css/SVGRenderStyleDefs.h:
  • ksvg2/svg/SVGAnimatedTemplate.h:
  • ksvg2/svg/SVGElementInstanceList.h:
  • ksvg2/svg/SVGList.h:
  • ksvg2/svg/SVGPathSeg.h:
  • ksvg2/svg/SVGPreserveAspectRatio.h:
  • ksvg2/svg/SVGRenderingIntent.h:
  • ksvg2/svg/SVGTransform.h:
  • ksvg2/svg/SVGUnitTypes.h:
  • loader/DocumentLoader.h:
  • loader/FormState.h:
  • loader/ResourceLoader.h:
  • loader/TextResourceDecoder.h:
  • loader/icon/IconRecord.h:
  • page/BarInfo.h:
  • page/Console.h:
  • page/DOMSelection.h:
  • page/DOMWindow.h:
  • page/History.h:
  • page/InspectorController.cpp:
  • page/Plugin.h:
  • page/Screen.h:
  • platform/ArrayImpl.h:
  • platform/CString.h:
  • platform/DeprecatedValueListImpl.cpp:
  • platform/FontFallbackList.h:
  • platform/FontFamily.h:
  • platform/FontSelector.h:
  • platform/GlyphPageTreeNode.h:
  • platform/PopupMenu.h:
  • platform/RegularExpression.cpp:
  • platform/ScrollBar.h:
  • platform/Shared.h: Removed.
  • platform/SharedBuffer.h:
  • platform/StringImpl.h:
  • platform/graphics/Icon.h:
  • platform/graphics/svg/SVGResource.h:
  • platform/network/FormData.h:
  • platform/network/ResourceHandleClient.h:
  • rendering/RenderStyle.h:
  • rendering/SVGCharacterLayoutInfo.h:
  • storage/SQLResultSetRowList.h:
  • xml/DOMParser.h:
  • xml/XMLSerializer.h:
  • xml/XPathEvaluator.h:
  • xml/XPathExpression.h:
  • xml/XPathNSResolver.h:
  • xml/XPathResult.h:

WebKit/mac:

Reviewed by Sam Weinig.

Moved Shared.h into wtf so it could be used in more places.

  • ChangeLog:
  • WebCoreSupport/WebContextMenuClient.h:
  • Property svn:eol-style set to native
File size: 27.7 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2001 Harri Porten ([email protected])
5 * Copyright (C) 2001 Peter Kelly ([email protected])
6 * Copyright (C) 2003 Apple Computer, 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 "SavedBuiltins.h"
31#include "array_object.h"
32#include "bool_object.h"
33#include "collector.h"
34#include "date_object.h"
35#include "debugger.h"
36#include "error_object.h"
37#include "function_object.h"
38#include "internal.h"
39#include "math_object.h"
40#include "nodes.h"
41#include "number_object.h"
42#include "object.h"
43#include "object_object.h"
44#include "operations.h"
45#include "regexp_object.h"
46#include "runtime.h"
47#include "string_object.h"
48#include "types.h"
49#include "value.h"
50#include <math.h>
51#include <signal.h>
52#include <stdio.h>
53#include <wtf/Assertions.h>
54
55#if HAVE(SYS_TIME_H)
56#include <sys/time.h>
57#endif
58
59#if PLATFORM(WIN_OS)
60#include <windows.h>
61#endif
62
63#if PLATFORM(QT)
64#include <QDateTime>
65#endif
66
67namespace KJS {
68
69// Default number of ticks before a timeout check should be done.
70static const int initialTickCountThreshold = 255;
71
72// Preferred number of milliseconds between each timeout check
73static const int preferredScriptCheckTimeInterval = 1000;
74
75Interpreter* Interpreter::s_hook = 0;
76
77typedef HashMap<JSObject*, Interpreter*> InterpreterMap;
78static inline InterpreterMap &interpreterMap()
79{
80 static InterpreterMap* map = new InterpreterMap;
81 return* map;
82}
83
84Interpreter::Interpreter(JSGlobalObject* globalObject)
85 : m_currentExec(0)
86 , m_globalObject(globalObject)
87 , m_globalExec(this, globalObject, globalObject, 0)
88{
89 init();
90}
91
92Interpreter::Interpreter()
93 : m_currentExec(0)
94 , m_globalObject(new JSGlobalObject())
95 , m_globalExec(this, m_globalObject, m_globalObject, 0)
96{
97 init();
98}
99
100void Interpreter::init()
101{
102 JSLock lock;
103
104 m_timeoutTime = 0;
105 m_recursion = 0;
106 m_debugger= 0;
107
108 resetTimeoutCheck();
109 m_timeoutCheckCount = 0;
110
111 m_compatMode = NativeMode;
112
113 if (s_hook) {
114 prev = s_hook;
115 next = s_hook->next;
116 s_hook->next->prev = this;
117 s_hook->next = this;
118 } else {
119 // This is the first interpreter
120 s_hook = next = prev = this;
121 }
122
123 initGlobalObject();
124}
125
126Interpreter::~Interpreter()
127{
128 JSLock lock;
129
130 if (m_debugger)
131 m_debugger->detach(this);
132
133 next->prev = prev;
134 prev->next = next;
135 s_hook = next;
136 if (s_hook == this) {
137 // This was the last interpreter
138 s_hook = 0;
139 }
140}
141
142JSGlobalObject* Interpreter::globalObject() const
143{
144 return m_globalObject;
145}
146
147void Interpreter::initGlobalObject()
148{
149 m_globalObject->setInterpreter(this);
150
151 // Clear before inititalizing, to avoid marking uninitialized (dangerous) or
152 // stale (wasteful) pointers during initialization.
153
154 // Prototypes
155 m_FunctionPrototype = 0;
156 m_ObjectPrototype = 0;
157
158 m_ArrayPrototype = 0;
159 m_StringPrototype = 0;
160 m_BooleanPrototype = 0;
161 m_NumberPrototype = 0;
162 m_DatePrototype = 0;
163 m_RegExpPrototype = 0;
164 m_ErrorPrototype = 0;
165
166 m_EvalErrorPrototype = 0;
167 m_RangeErrorPrototype = 0;
168 m_ReferenceErrorPrototype = 0;
169 m_SyntaxErrorPrototype = 0;
170 m_TypeErrorPrototype = 0;
171 m_UriErrorPrototype = 0;
172
173 // Constructors
174 m_Object = 0;
175 m_Function = 0;
176 m_Array = 0;
177 m_String = 0;
178 m_Boolean = 0;
179 m_Number = 0;
180 m_Date = 0;
181 m_RegExp = 0;
182 m_Error = 0;
183
184 m_EvalError = 0;
185 m_RangeError = 0;
186 m_ReferenceError = 0;
187 m_SyntaxError = 0;
188 m_TypeError = 0;
189 m_UriError = 0;
190
191 // Prototypes
192 m_FunctionPrototype = new FunctionPrototype(&m_globalExec);
193 m_ObjectPrototype = new ObjectPrototype(&m_globalExec, m_FunctionPrototype);
194 m_FunctionPrototype->setPrototype(m_ObjectPrototype);
195
196 m_ArrayPrototype = new ArrayPrototype(&m_globalExec, m_ObjectPrototype);
197 m_StringPrototype = new StringPrototype(&m_globalExec, m_ObjectPrototype);
198 m_BooleanPrototype = new BooleanPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype);
199 m_NumberPrototype = new NumberPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype);
200 m_DatePrototype = new DatePrototype(&m_globalExec, m_ObjectPrototype);
201 m_RegExpPrototype = new RegExpPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype);;
202 m_ErrorPrototype = new ErrorPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype);
203
204 m_EvalErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, EvalError, "EvalError", "EvalError");
205 m_RangeErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, RangeError, "RangeError", "RangeError");
206 m_ReferenceErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, ReferenceError, "ReferenceError", "ReferenceError");
207 m_SyntaxErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, SyntaxError, "SyntaxError", "SyntaxError");
208 m_TypeErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, TypeError, "TypeError", "TypeError");
209 m_UriErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, URIError, "URIError", "URIError");
210
211 // Constructors
212 m_Object = new ObjectObjectImp(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype);
213 m_Function = new FunctionObjectImp(&m_globalExec, m_FunctionPrototype);
214 m_Array = new ArrayObjectImp(&m_globalExec, m_FunctionPrototype, m_ArrayPrototype);
215 m_String = new StringObjectImp(&m_globalExec, m_FunctionPrototype, m_StringPrototype);
216 m_Boolean = new BooleanObjectImp(&m_globalExec, m_FunctionPrototype, m_BooleanPrototype);
217 m_Number = new NumberObjectImp(&m_globalExec, m_FunctionPrototype, m_NumberPrototype);
218 m_Date = new DateObjectImp(&m_globalExec, m_FunctionPrototype, m_DatePrototype);
219 m_RegExp = new RegExpObjectImp(&m_globalExec, m_FunctionPrototype, m_RegExpPrototype);
220 m_Error = new ErrorObjectImp(&m_globalExec, m_FunctionPrototype, m_ErrorPrototype);
221
222 m_EvalError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_EvalErrorPrototype);
223 m_RangeError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_RangeErrorPrototype);
224 m_ReferenceError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_ReferenceErrorPrototype);
225 m_SyntaxError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_SyntaxErrorPrototype);
226 m_TypeError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_TypeErrorPrototype);
227 m_UriError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_UriErrorPrototype);
228
229 m_FunctionPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum);
230 m_ObjectPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Object, DontEnum | DontDelete | ReadOnly);
231 m_FunctionPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum | DontDelete | ReadOnly);
232 m_ArrayPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Array, DontEnum | DontDelete | ReadOnly);
233 m_BooleanPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Boolean, DontEnum | DontDelete | ReadOnly);
234 m_StringPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_String, DontEnum | DontDelete | ReadOnly);
235 m_NumberPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Number, DontEnum | DontDelete | ReadOnly);
236 m_DatePrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Date, DontEnum | DontDelete | ReadOnly);
237 m_RegExpPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RegExp, DontEnum | DontDelete | ReadOnly);
238 m_ErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Error, DontEnum | DontDelete | ReadOnly);
239 m_EvalErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_EvalError, DontEnum | DontDelete | ReadOnly);
240 m_RangeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RangeError, DontEnum | DontDelete | ReadOnly);
241 m_ReferenceErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_ReferenceError, DontEnum | DontDelete | ReadOnly);
242 m_SyntaxErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_SyntaxError, DontEnum | DontDelete | ReadOnly);
243 m_TypeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_TypeError, DontEnum | DontDelete | ReadOnly);
244 m_UriErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_UriError, DontEnum | DontDelete | ReadOnly);
245
246 // Set global object prototype
247 JSObject* o = m_globalObject;
248 while (o->prototype()->isObject())
249 o = static_cast<JSObject*>(o->prototype());
250 o->setPrototype(m_ObjectPrototype);
251
252 // Set global constructors
253 // FIXME: kjs_window.cpp checks Internal/DontEnum as a performance hack, to
254 // see that these values can be put directly without a check for override
255 // properties. Maybe we should call putDirect instead, for better encapsulation.
256 m_globalObject->put(&m_globalExec, "Object", m_Object, DontEnum);
257 m_globalObject->put(&m_globalExec, "Function", m_Function, DontEnum);
258 m_globalObject->put(&m_globalExec, "Array", m_Array, DontEnum);
259 m_globalObject->put(&m_globalExec, "Boolean", m_Boolean, DontEnum);
260 m_globalObject->put(&m_globalExec, "String", m_String, DontEnum);
261 m_globalObject->put(&m_globalExec, "Number", m_Number, DontEnum);
262 m_globalObject->put(&m_globalExec, "Date", m_Date, DontEnum);
263 m_globalObject->put(&m_globalExec, "RegExp", m_RegExp, DontEnum);
264 m_globalObject->put(&m_globalExec, "Error", m_Error, DontEnum);
265 m_globalObject->put(&m_globalExec, "EvalError",m_EvalError, Internal);
266 m_globalObject->put(&m_globalExec, "RangeError",m_RangeError, Internal);
267 m_globalObject->put(&m_globalExec, "ReferenceError",m_ReferenceError, Internal);
268 m_globalObject->put(&m_globalExec, "SyntaxError",m_SyntaxError, Internal);
269 m_globalObject->put(&m_globalExec, "TypeError",m_TypeError, Internal);
270 m_globalObject->put(&m_globalExec, "URIError",m_UriError, Internal);
271
272 // Set global values
273 m_globalObject->put(&m_globalExec, "Math", new MathObjectImp(&m_globalExec, m_ObjectPrototype), DontEnum);
274 m_globalObject->put(&m_globalExec, "NaN", jsNaN(), DontEnum|DontDelete);
275 m_globalObject->put(&m_globalExec, "Infinity", jsNumber(Inf), DontEnum|DontDelete);
276 m_globalObject->put(&m_globalExec, "undefined", jsUndefined(), DontEnum|DontDelete);
277
278 // Set global functions
279 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
280 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
281 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
282 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
283 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
284 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
285 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
286 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
287 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
288 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
289 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
290#ifndef NDEBUG
291 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
292#endif
293}
294
295ExecState* Interpreter::globalExec()
296{
297 return &m_globalExec;
298}
299
300Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UString& code)
301{
302 return checkSyntax(sourceURL, startingLineNumber, code.data(), code.size());
303}
304
305Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength)
306{
307 JSLock lock;
308
309 int errLine;
310 UString errMsg;
311 RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
312 if (!progNode)
313 return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, 0, sourceURL));
314 return Completion(Normal);
315}
316
317Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
318{
319 return evaluate(sourceURL, startingLineNumber, code.data(), code.size(), thisV);
320}
321
322Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
323{
324 JSLock lock;
325
326 // prevent against infinite recursion
327 if (m_recursion >= 20)
328 return Completion(Throw, Error::create(&m_globalExec, GeneralError, "Recursion too deep"));
329
330 // parse the source code
331 int sid;
332 int errLine;
333 UString errMsg;
334 RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
335
336 // notify debugger that source has been parsed
337 if (m_debugger) {
338 bool cont = m_debugger->sourceParsed(&m_globalExec, sid, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
339 if (!cont)
340 return Completion(Break);
341 }
342
343 // no program node means a syntax error occurred
344 if (!progNode)
345 return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, sid, sourceURL));
346
347 m_globalExec.clearException();
348
349 m_recursion++;
350
351 JSGlobalObject* globalObj = m_globalObject;
352 JSObject* thisObj = globalObj;
353
354 // "this" must be an object... use same rules as Function.prototype.apply()
355 if (thisV && !thisV->isUndefinedOrNull())
356 thisObj = thisV->toObject(&m_globalExec);
357
358 Completion res;
359 if (m_globalExec.hadException())
360 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
361 res = Completion(Throw, m_globalExec.exception());
362 else {
363 // execute the code
364 ExecState newExec(this, globalObj, thisObj, progNode.get());
365 res = progNode->execute(&newExec);
366 }
367
368 m_recursion--;
369
370 if (shouldPrintExceptions() && res.complType() == Throw) {
371 JSLock lock;
372 ExecState* exec = globalExec();
373 CString f = sourceURL.UTF8String();
374 CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
375 int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
376#if PLATFORM(WIN_OS)
377 printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
378#else
379 printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
380#endif
381 }
382
383 return res;
384}
385
386JSObject *Interpreter::builtinObject() const
387{
388 return m_Object;
389}
390
391JSObject *Interpreter::builtinFunction() const
392{
393 return m_Function;
394}
395
396JSObject *Interpreter::builtinArray() const
397{
398 return m_Array;
399}
400
401JSObject *Interpreter::builtinBoolean() const
402{
403 return m_Boolean;
404}
405
406JSObject *Interpreter::builtinString() const
407{
408 return m_String;
409}
410
411JSObject *Interpreter::builtinNumber() const
412{
413 return m_Number;
414}
415
416JSObject *Interpreter::builtinDate() const
417{
418 return m_Date;
419}
420
421JSObject *Interpreter::builtinError() const
422{
423 return m_Error;
424}
425
426JSObject *Interpreter::builtinObjectPrototype() const
427{
428 return m_ObjectPrototype;
429}
430
431JSObject *Interpreter::builtinFunctionPrototype() const
432{
433 return m_FunctionPrototype;
434}
435
436JSObject *Interpreter::builtinArrayPrototype() const
437{
438 return m_ArrayPrototype;
439}
440
441JSObject *Interpreter::builtinBooleanPrototype() const
442{
443 return m_BooleanPrototype;
444}
445
446JSObject *Interpreter::builtinStringPrototype() const
447{
448 return m_StringPrototype;
449}
450
451JSObject *Interpreter::builtinNumberPrototype() const
452{
453 return m_NumberPrototype;
454}
455
456JSObject *Interpreter::builtinDatePrototype() const
457{
458 return m_DatePrototype;
459}
460
461JSObject *Interpreter::builtinRegExpPrototype() const
462{
463 return m_RegExpPrototype;
464}
465
466JSObject *Interpreter::builtinErrorPrototype() const
467{
468 return m_ErrorPrototype;
469}
470
471JSObject *Interpreter::builtinEvalError() const
472{
473 return m_EvalError;
474}
475
476JSObject *Interpreter::builtinRangeError() const
477{
478 return m_RangeError;
479}
480
481JSObject *Interpreter::builtinReferenceError() const
482{
483 return m_ReferenceError;
484}
485
486JSObject *Interpreter::builtinSyntaxError() const
487{
488 return m_SyntaxError;
489}
490
491JSObject *Interpreter::builtinTypeError() const
492{
493 return m_TypeError;
494}
495
496JSObject *Interpreter::builtinURIError() const
497{
498 return m_UriError;
499}
500
501JSObject *Interpreter::builtinEvalErrorPrototype() const
502{
503 return m_EvalErrorPrototype;
504}
505
506JSObject *Interpreter::builtinRangeErrorPrototype() const
507{
508 return m_RangeErrorPrototype;
509}
510
511JSObject *Interpreter::builtinReferenceErrorPrototype() const
512{
513 return m_ReferenceErrorPrototype;
514}
515
516JSObject *Interpreter::builtinSyntaxErrorPrototype() const
517{
518 return m_SyntaxErrorPrototype;
519}
520
521JSObject *Interpreter::builtinTypeErrorPrototype() const
522{
523 return m_TypeErrorPrototype;
524}
525
526JSObject *Interpreter::builtinURIErrorPrototype() const
527{
528 return m_UriErrorPrototype;
529}
530
531void Interpreter::mark()
532{
533 if (m_currentExec)
534 m_currentExec->mark();
535
536 if (m_globalExec.exception() && !m_globalExec.exception()->marked())
537 m_globalExec.exception()->mark();
538
539 if (m_globalObject && !m_globalObject->marked())
540 m_globalObject->mark();
541
542 if (m_Object && !m_Object->marked())
543 m_Object->mark();
544 if (m_Function && !m_Function->marked())
545 m_Function->mark();
546 if (m_Array && !m_Array->marked())
547 m_Array->mark();
548 if (m_Boolean && !m_Boolean->marked())
549 m_Boolean->mark();
550 if (m_String && !m_String->marked())
551 m_String->mark();
552 if (m_Number && !m_Number->marked())
553 m_Number->mark();
554 if (m_Date && !m_Date->marked())
555 m_Date->mark();
556 if (m_RegExp && !m_RegExp->marked())
557 m_RegExp->mark();
558 if (m_Error && !m_Error->marked())
559 m_Error->mark();
560
561 if (m_ObjectPrototype && !m_ObjectPrototype->marked())
562 m_ObjectPrototype->mark();
563 if (m_FunctionPrototype && !m_FunctionPrototype->marked())
564 m_FunctionPrototype->mark();
565 if (m_ArrayPrototype && !m_ArrayPrototype->marked())
566 m_ArrayPrototype->mark();
567 if (m_BooleanPrototype && !m_BooleanPrototype->marked())
568 m_BooleanPrototype->mark();
569 if (m_StringPrototype && !m_StringPrototype->marked())
570 m_StringPrototype->mark();
571 if (m_NumberPrototype && !m_NumberPrototype->marked())
572 m_NumberPrototype->mark();
573 if (m_DatePrototype && !m_DatePrototype->marked())
574 m_DatePrototype->mark();
575 if (m_RegExpPrototype && !m_RegExpPrototype->marked())
576 m_RegExpPrototype->mark();
577 if (m_ErrorPrototype && !m_ErrorPrototype->marked())
578 m_ErrorPrototype->mark();
579
580 if (m_EvalError && !m_EvalError->marked())
581 m_EvalError->mark();
582 if (m_RangeError && !m_RangeError->marked())
583 m_RangeError->mark();
584 if (m_ReferenceError && !m_ReferenceError->marked())
585 m_ReferenceError->mark();
586 if (m_SyntaxError && !m_SyntaxError->marked())
587 m_SyntaxError->mark();
588 if (m_TypeError && !m_TypeError->marked())
589 m_TypeError->mark();
590 if (m_UriError && !m_UriError->marked())
591 m_UriError->mark();
592
593 if (m_EvalErrorPrototype && !m_EvalErrorPrototype->marked())
594 m_EvalErrorPrototype->mark();
595 if (m_RangeErrorPrototype && !m_RangeErrorPrototype->marked())
596 m_RangeErrorPrototype->mark();
597 if (m_ReferenceErrorPrototype && !m_ReferenceErrorPrototype->marked())
598 m_ReferenceErrorPrototype->mark();
599 if (m_SyntaxErrorPrototype && !m_SyntaxErrorPrototype->marked())
600 m_SyntaxErrorPrototype->mark();
601 if (m_TypeErrorPrototype && !m_TypeErrorPrototype->marked())
602 m_TypeErrorPrototype->mark();
603 if (m_UriErrorPrototype && !m_UriErrorPrototype->marked())
604 m_UriErrorPrototype->mark();
605}
606
607#ifdef KJS_DEBUG_MEM
608#include "lexer.h"
609void Interpreter::finalCheck()
610{
611 fprintf(stderr,"Interpreter::finalCheck()\n");
612 Collector::collect();
613
614 Node::finalCheck();
615 Collector::finalCheck();
616 Lexer::globalClear();
617 UString::globalClear();
618}
619#endif
620
621static bool printExceptions = false;
622
623bool Interpreter::shouldPrintExceptions()
624{
625 return printExceptions;
626}
627
628void Interpreter::setShouldPrintExceptions(bool print)
629{
630 printExceptions = print;
631}
632
633void Interpreter::saveBuiltins (SavedBuiltins& builtins) const
634{
635 if (!builtins._internal)
636 builtins._internal = new SavedBuiltinsInternal;
637
638 builtins._internal->m_Object = m_Object;
639 builtins._internal->m_Function = m_Function;
640 builtins._internal->m_Array = m_Array;
641 builtins._internal->m_Boolean = m_Boolean;
642 builtins._internal->m_String = m_String;
643 builtins._internal->m_Number = m_Number;
644 builtins._internal->m_Date = m_Date;
645 builtins._internal->m_RegExp = m_RegExp;
646 builtins._internal->m_Error = m_Error;
647
648 builtins._internal->m_ObjectPrototype = m_ObjectPrototype;
649 builtins._internal->m_FunctionPrototype = m_FunctionPrototype;
650 builtins._internal->m_ArrayPrototype = m_ArrayPrototype;
651 builtins._internal->m_BooleanPrototype = m_BooleanPrototype;
652 builtins._internal->m_StringPrototype = m_StringPrototype;
653 builtins._internal->m_NumberPrototype = m_NumberPrototype;
654 builtins._internal->m_DatePrototype = m_DatePrototype;
655 builtins._internal->m_RegExpPrototype = m_RegExpPrototype;
656 builtins._internal->m_ErrorPrototype = m_ErrorPrototype;
657
658 builtins._internal->m_EvalError = m_EvalError;
659 builtins._internal->m_RangeError = m_RangeError;
660 builtins._internal->m_ReferenceError = m_ReferenceError;
661 builtins._internal->m_SyntaxError = m_SyntaxError;
662 builtins._internal->m_TypeError = m_TypeError;
663 builtins._internal->m_UriError = m_UriError;
664
665 builtins._internal->m_EvalErrorPrototype = m_EvalErrorPrototype;
666 builtins._internal->m_RangeErrorPrototype = m_RangeErrorPrototype;
667 builtins._internal->m_ReferenceErrorPrototype = m_ReferenceErrorPrototype;
668 builtins._internal->m_SyntaxErrorPrototype = m_SyntaxErrorPrototype;
669 builtins._internal->m_TypeErrorPrototype = m_TypeErrorPrototype;
670 builtins._internal->m_UriErrorPrototype = m_UriErrorPrototype;
671}
672
673void Interpreter::restoreBuiltins (const SavedBuiltins& builtins)
674{
675 if (!builtins._internal)
676 return;
677
678 m_Object = builtins._internal->m_Object;
679 m_Function = builtins._internal->m_Function;
680 m_Array = builtins._internal->m_Array;
681 m_Boolean = builtins._internal->m_Boolean;
682 m_String = builtins._internal->m_String;
683 m_Number = builtins._internal->m_Number;
684 m_Date = builtins._internal->m_Date;
685 m_RegExp = builtins._internal->m_RegExp;
686 m_Error = builtins._internal->m_Error;
687
688 m_ObjectPrototype = builtins._internal->m_ObjectPrototype;
689 m_FunctionPrototype = builtins._internal->m_FunctionPrototype;
690 m_ArrayPrototype = builtins._internal->m_ArrayPrototype;
691 m_BooleanPrototype = builtins._internal->m_BooleanPrototype;
692 m_StringPrototype = builtins._internal->m_StringPrototype;
693 m_NumberPrototype = builtins._internal->m_NumberPrototype;
694 m_DatePrototype = builtins._internal->m_DatePrototype;
695 m_RegExpPrototype = builtins._internal->m_RegExpPrototype;
696 m_ErrorPrototype = builtins._internal->m_ErrorPrototype;
697
698 m_EvalError = builtins._internal->m_EvalError;
699 m_RangeError = builtins._internal->m_RangeError;
700 m_ReferenceError = builtins._internal->m_ReferenceError;
701 m_SyntaxError = builtins._internal->m_SyntaxError;
702 m_TypeError = builtins._internal->m_TypeError;
703 m_UriError = builtins._internal->m_UriError;
704
705 m_EvalErrorPrototype = builtins._internal->m_EvalErrorPrototype;
706 m_RangeErrorPrototype = builtins._internal->m_RangeErrorPrototype;
707 m_ReferenceErrorPrototype = builtins._internal->m_ReferenceErrorPrototype;
708 m_SyntaxErrorPrototype = builtins._internal->m_SyntaxErrorPrototype;
709 m_TypeErrorPrototype = builtins._internal->m_TypeErrorPrototype;
710 m_UriErrorPrototype = builtins._internal->m_UriErrorPrototype;
711}
712
713void Interpreter::startTimeoutCheck()
714{
715 if (m_timeoutCheckCount == 0)
716 resetTimeoutCheck();
717
718 m_timeoutCheckCount++;
719}
720
721void Interpreter::stopTimeoutCheck()
722{
723 m_timeoutCheckCount--;
724}
725
726void Interpreter::resetTimeoutCheck()
727{
728 m_tickCount = 0;
729 m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
730 m_timeAtLastCheckTimeout = 0;
731 m_timeExecuting = 0;
732}
733
734// Returns the current time in milliseconds
735// It doesn't matter what "current time" is here, just as long as
736// it's possible to measure the time difference correctly.
737static inline unsigned getCurrentTime() {
738#if HAVE(SYS_TIME_H)
739 struct timeval tv;
740 gettimeofday(&tv, 0);
741 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
742#elif PLATFORM(QT)
743 QDateTime t = QDateTime::currentDateTime();
744 return t.toTime_t() * 1000 + t.time().msec();
745#elif PLATFORM(WIN_OS)
746 return timeGetTime();
747#else
748#error Platform does not have getCurrentTime function
749#endif
750}
751
752bool Interpreter::checkTimeout()
753{
754 m_tickCount = 0;
755
756 unsigned currentTime = getCurrentTime();
757
758 if (!m_timeAtLastCheckTimeout) {
759 // Suspicious amount of looping in a script -- start timing it
760 m_timeAtLastCheckTimeout = currentTime;
761 return false;
762 }
763
764 unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout;
765
766 if (timeDiff == 0)
767 timeDiff = 1;
768
769 m_timeExecuting += timeDiff;
770 m_timeAtLastCheckTimeout = currentTime;
771
772 // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in
773 // preferredScriptCheckTimeInterval
774 m_ticksUntilNextTimeoutCheck = (unsigned)((float)preferredScriptCheckTimeInterval / timeDiff) * m_ticksUntilNextTimeoutCheck;
775
776 // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
777 // preferred script check time interval.
778 if (m_ticksUntilNextTimeoutCheck == 0)
779 m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
780
781 if (m_timeoutTime && m_timeExecuting > m_timeoutTime) {
782 if (shouldInterruptScript())
783 return true;
784
785 resetTimeoutCheck();
786 }
787
788 return false;
789}
790
791
792SavedBuiltins::SavedBuiltins() :
793 _internal(0)
794{
795}
796
797SavedBuiltins::~SavedBuiltins()
798{
799 delete _internal;
800}
801
802}
Note: See TracBrowser for help on using the repository browser.