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

Last change on this file since 15026 was 15026, checked in by thatcher, 19 years ago

JavaScriptCore:

Reviewed by Darin.

Bug 9574: Drosera should show inline scripts within the original HTML
http://bugzilla.opendarwin.org/show_bug.cgi?id=9574

Pass the starting line number and error message to the debugger.

  • kjs/debugger.cpp: (Debugger::sourceParsed):
  • kjs/debugger.h:
  • kjs/function.cpp: (KJS::GlobalFuncImp::callAsFunction):
  • kjs/function_object.cpp: (FunctionObjectImp::construct):
  • kjs/interpreter.cpp: (KJS::Interpreter::evaluate):

WebCore:

Reviewed by Darin.

Bug 9574: Drosera should show inline scripts within the original HTML
http://bugzilla.opendarwin.org/show_bug.cgi?id=9574

  • Pass the starting line number and error message to the debugger.
  • Call parsedSource even if there was a script parse error so the debugger can show the parse error.
  • Pass NSURL objects to the ObjC delegate for the script URLs.
  • bridge/mac/WebCoreScriptDebugger.h:
  • bridge/mac/WebCoreScriptDebugger.mm: (toNSURL): (WebCoreScriptDebuggerImp::sourceParsed):

WebKit:

Reviewed by Darin.

Bug 9574: Drosera should show inline scripts within the original HTML
http://bugzilla.opendarwin.org/show_bug.cgi?id=9574

  • Adds a new version of the didParseSource delegate callback with base line number.
  • Adds a new delegate callback for when a script fails to parse.
  • These new callbacks use NSURLs for the url parameter.
  • Adds a new script listener callback to notify when the main resource loads.
  • Adds a WebScriptErrorDomian and other keys for use with NSError.
  • DefaultDelegates/WebDefaultScriptDebugDelegate.m: (-[WebDefaultScriptDebugDelegate webView:didParseSource:baseLineNumber:fromURL:sourceId:forWebFrame:]): (-[WebDefaultScriptDebugDelegate webView:failedToParseSource:baseLineNumber:fromURL:withError:forWebFrame:]):
  • DefaultDelegates/WebScriptDebugServer.h:
  • DefaultDelegates/WebScriptDebugServer.m: (-[WebScriptDebugServer webView:didLoadMainResourceForDataSource:]): (-[WebScriptDebugServer webView:didParseSource:baseLineNumber:fromURL:sourceId:forWebFrame:]): (-[WebScriptDebugServer webView:failedToParseSource:baseLineNumber:fromURL:withError:forWebFrame:]):
  • DefaultDelegates/WebScriptDebugServerPrivate.h:
  • WebKit.exp:
  • WebView/WebDataSource.m: (-[WebDataSource _setPrimaryLoadComplete:]):
  • WebView/WebScriptDebugDelegate.h:
  • WebView/WebScriptDebugDelegate.m: (-[WebScriptCallFrame parsedSource:fromURL:sourceId:startLine:errorLine:errorMessage:]):

WebKitTools:

Reviewed by Darin.

Bug 9574: Drosera should show inline scripts within the original HTML
http://bugzilla.opendarwin.org/show_bug.cgi?id=9574

Refactor the JavaScript code to have a distinction between files
and scripts. Show the script in the context of the HTML file if
it's URL is the same as the frame's main resource. At the time of
the disParseScript callback the main resource might not be completely
loaded, but Drosera needs to show whatever we have at the time. Once
the main resource is finished, update the file source and reload the file.

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