source: webkit/trunk/JavaScriptCore/kjs/internal.cpp@ 13865

Last change on this file since 13865 was 13865, checked in by ggaren, 19 years ago

JavaScriptCore:

Reviewed by Darin.

  • kjs/internal.cpp: (KJS::InterpreterImp::initGlobalObject): Add the built-in object prototype to the end of the global object's prototype chain instead of just blowing away its existing prototype. We need to do this because the window object has a meaningful prototype now.

LayoutTests:

Layout test for document.defaultView

  • fast/dom/defaultView-expected.txt: Added.
  • fast/dom/defaultView.html: Added.
  • fast/events/event-view-toString-expected.txt: Updated to reflect new prototype chain for defaultView.

WebCore:

Reviewed by Darin.

  • Fixed <rdar://problem/4478467> document.defaultView should return the window object


Also made part of the window object autogenerated by IDL file.


  • DerivedSources.make: Added /page to IDL file search path, added JSDOMWindow.h, removed kjs_views.lut.h
  • WebCore.xcodeproj/project.pbxproj: Added missing files, removed obsolete files
  • bindings/js/kjs_dom.cpp:
  • bindings/js/kjs_events.cpp:
  • bindings/js/kjs_proxy.cpp: (WebCore::KJSProxy::initScriptIfNeeded):
  • bindings/js/kjs_views.cpp: Removed.
  • bindings/js/kjs_views.h: Removed.
  • bindings/js/kjs_window.cpp: Removed document property -- it now belongs to JSDOMWindow. Added toJS and toDOMWindow. (KJS::Window::Window): (KJS::Window::impl): (KJS::Window::getValueProperty): (KJS::Window::clear): Added call to setPrototype to ensure that the prototype gets cleared during navigation. (Previously this wasn't an issue because the window object had no real prototype.) (WebCore::toJS): (WebCore::toDOMWindow):
  • bindings/js/kjs_window.h: (KJS::Window::):
  • bindings/objc/DOMCSS.mm: Added NULL checks for the AbstractView (Presumably this is an issue after the window is closed.) Typedef-ed AbstractView as DOMWindow. I could have just replaced AbstractView with DOMWindow, but I think it's clearer to say, "There's this thing called the AbstractView, but really it's just the window." (-[DOMDocument getComputedStyle::]): (-[DOMDocument getMatchedCSSRules::]):
  • bindings/objc/DOMViews.mm:
  • bindings/objc/DOMViewsInternal.h:
  • bindings/scripts/CodeGeneratorJS.pm: Removed unused GetLegacyImplementationIncludes. Added support for DOMWindow and new "DoNotCache" attribute. Replaced C macros with text because (1) it makes the generated source easier to read and debug and (2) it made it much easier to implement the DoNotCache attribute.
  • bindings/scripts/IDLParser.pm: Return a hash reference instead of a hash, because otherwise an interface with more than one attribute returns too many arguments to be processed.
  • bridge/mac/FrameMac.mm:
  • dom/AbstractView.cpp: Removed.
  • dom/AbstractView.h: Removed.
  • dom/Document.cpp: (WebCore::Document::Document): (WebCore::Document::defaultView):
  • dom/Document.h:
  • dom/Document.idl:
  • dom/KeyboardEvent.idl:
  • dom/MouseEvent.idl:
  • dom/Position.cpp:
  • dom/UIEvent.idl:
  • dom/dom2_eventsimpl.h:
  • page/DOMWindow.cpp: Added. (WebCore::DOMWindow::DOMWindow): (WebCore::DOMWindow::frame): (WebCore::DOMWindow::disconnectFrame): (WebCore::DOMWindow::document): (WebCore::DOMWindow::getComputedStyle): (WebCore::DOMWindow::getMatchedCSSRules):
  • page/DOMWindow.h: Added.
  • page/DOMWindow.idl: Added.
  • page/Frame.cpp: (WebCore::Frame::~Frame): Disconnect the new DOMWindow object in addition to the Window object. Maybe we can unify this in the future. (WebCore::Frame::tree): (WebCore::Frame::domWindow):
  • page/Frame.h:
  • page/FramePrivate.h:
  • Property svn:eol-style set to native
File size: 23.4 KB
Line 
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1999-2002 Harri Porten ([email protected])
4 * Copyright (C) 2001 Peter Kelly ([email protected])
5 * Copyright (C) 2004 Apple Computer, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25#include "internal.h"
26
27#include "array_object.h"
28#include "bool_object.h"
29#include "collector.h"
30#include "context.h"
31#include "date_object.h"
32#include "debugger.h"
33#include "error_object.h"
34#include "function_object.h"
35#include "lexer.h"
36#include "math_object.h"
37#include "nodes.h"
38#include "number_object.h"
39#include "object.h"
40#include "object_object.h"
41#include "operations.h"
42#include "regexp_object.h"
43#include "string_object.h"
44#include <assert.h>
45#include <kxmlcore/HashMap.h>
46#include <kxmlcore/HashSet.h>
47#include <kxmlcore/Vector.h>
48#include <math.h>
49#include <stdio.h>
50
51namespace KJS {
52
53#if PLATFORM(WIN_OS)
54#define copysign _copysign
55#endif
56
57// ------------------------------ StringImp ------------------------------------
58
59JSValue *StringImp::toPrimitive(ExecState *, JSType) const
60{
61 return const_cast<StringImp *>(this);
62}
63
64bool StringImp::toBoolean(ExecState *) const
65{
66 return (val.size() > 0);
67}
68
69double StringImp::toNumber(ExecState *) const
70{
71 return val.toDouble();
72}
73
74UString StringImp::toString(ExecState *) const
75{
76 return val;
77}
78
79JSObject *StringImp::toObject(ExecState *exec) const
80{
81 return new StringInstance(exec->lexicalInterpreter()->builtinStringPrototype(), val);
82}
83
84// ------------------------------ NumberImp ------------------------------------
85
86JSValue *NumberImp::toPrimitive(ExecState *, JSType) const
87{
88 return const_cast<NumberImp *>(this);
89}
90
91bool NumberImp::toBoolean(ExecState *) const
92{
93 return val < 0.0 || val > 0.0; // false for NaN
94}
95
96double NumberImp::toNumber(ExecState *) const
97{
98 return val;
99}
100
101UString NumberImp::toString(ExecState *) const
102{
103 if (val == 0.0) // +0.0 or -0.0
104 return "0";
105 return UString::from(val);
106}
107
108JSObject *NumberImp::toObject(ExecState *exec) const
109{
110 List args;
111 args.append(const_cast<NumberImp*>(this));
112 return static_cast<JSObject *>(exec->lexicalInterpreter()->builtinNumber()->construct(exec,args));
113}
114
115// FIXME: We can optimize this to work like JSValue::getUInt32. I'm ignoring it for now
116// because it never shows up on profiles.
117bool NumberImp::getUInt32(uint32_t& uint32) const
118{
119 uint32 = (uint32_t)val;
120 return (double)uint32 == val;
121}
122
123// --------------------------- GetterSetterImp ---------------------------------
124void GetterSetterImp::mark()
125{
126 JSCell::mark();
127
128 if (getter && !getter->marked())
129 getter->mark();
130 if (setter && !setter->marked())
131 setter->mark();
132}
133
134JSValue *GetterSetterImp::toPrimitive(ExecState*, JSType) const
135{
136 assert(false);
137 return jsNull();
138}
139
140bool GetterSetterImp::toBoolean(ExecState*) const
141{
142 assert(false);
143 return false;
144}
145
146double GetterSetterImp::toNumber(ExecState *) const
147{
148 assert(false);
149 return 0.0;
150}
151
152UString GetterSetterImp::toString(ExecState *) const
153{
154 assert(false);
155 return UString::null();
156}
157
158JSObject *GetterSetterImp::toObject(ExecState *exec) const
159{
160 assert(false);
161 return jsNull()->toObject(exec);
162}
163
164// ------------------------------ LabelStack -----------------------------------
165
166bool LabelStack::push(const Identifier &id)
167{
168 if (contains(id))
169 return false;
170
171 StackElem *newtos = new StackElem;
172 newtos->id = id;
173 newtos->prev = tos;
174 tos = newtos;
175 return true;
176}
177
178bool LabelStack::contains(const Identifier &id) const
179{
180 if (id.isEmpty())
181 return true;
182
183 for (StackElem *curr = tos; curr; curr = curr->prev)
184 if (curr->id == id)
185 return true;
186
187 return false;
188}
189
190// ------------------------------ ContextImp -----------------------------------
191
192// ECMA 10.2
193ContextImp::ContextImp(JSObject *glob, InterpreterImp *interpreter, JSObject *thisV, FunctionBodyNode* currentBody,
194
195 CodeType type, ContextImp *callingCon, FunctionImp *func, const List *args)
196 : _interpreter(interpreter)
197 , m_currentBody(currentBody)
198 , _function(func)
199 , _arguments(args)
200 , m_iterationDepth(0)
201 , m_switchDepth(0)
202{
203 m_codeType = type;
204 _callingContext = callingCon;
205
206 // create and initialize activation object (ECMA 10.1.6)
207 if (type == FunctionCode || type == AnonymousCode ) {
208 activation = new ActivationImp(func, *args);
209 variable = activation;
210 } else {
211 activation = NULL;
212 variable = glob;
213 }
214
215 // ECMA 10.2
216 switch(type) {
217 case EvalCode:
218 if (_callingContext) {
219 scope = _callingContext->scopeChain();
220 variable = _callingContext->variableObject();
221 thisVal = _callingContext->thisValue();
222 break;
223 } // else same as GlobalCode
224 case GlobalCode:
225 scope.clear();
226 scope.push(glob);
227 thisVal = static_cast<JSObject*>(glob);
228 break;
229 case FunctionCode:
230 case AnonymousCode:
231 if (type == FunctionCode) {
232 scope = func->scope();
233 scope.push(activation);
234 } else {
235 scope.clear();
236 scope.push(glob);
237 scope.push(activation);
238 }
239 variable = activation; // TODO: DontDelete ? (ECMA 10.2.3)
240 thisVal = thisV;
241 break;
242 }
243
244 _interpreter->setContext(this);
245}
246
247ContextImp::~ContextImp()
248{
249 _interpreter->setContext(_callingContext);
250}
251
252void ContextImp::mark()
253{
254 for (ContextImp *context = this; context; context = context->_callingContext) {
255 context->scope.mark();
256 }
257}
258
259// ------------------------------ InterpreterImp -------------------------------
260
261InterpreterImp* InterpreterImp::s_hook = 0L;
262
263typedef HashMap<JSObject *, InterpreterImp *> InterpreterMap;
264
265static inline InterpreterMap &interpreterMap()
266{
267 static InterpreterMap *map = new InterpreterMap;
268 return *map;
269}
270
271InterpreterImp::InterpreterImp(Interpreter *interp, JSObject *glob)
272 : globExec(interp, 0)
273 , _context(0)
274{
275 // add this interpreter to the global chain
276 // as a root set for garbage collection
277 JSLock lock;
278
279 m_interpreter = interp;
280 if (s_hook) {
281 prev = s_hook;
282 next = s_hook->next;
283 s_hook->next->prev = this;
284 s_hook->next = this;
285 } else {
286 // This is the first interpreter
287 s_hook = next = prev = this;
288 }
289
290 interpreterMap().set(glob, this);
291
292 global = glob;
293 dbg = 0;
294 m_compatMode = Interpreter::NativeMode;
295
296 // initialize properties of the global object
297 initGlobalObject();
298
299 recursion = 0;
300}
301
302void InterpreterImp::initGlobalObject()
303{
304 Identifier::init();
305
306 // Contructor prototype objects (Object.prototype, Array.prototype etc)
307
308 FunctionPrototype *funcProto = new FunctionPrototype(&globExec);
309 b_FunctionPrototype = funcProto;
310 ObjectPrototype *objProto = new ObjectPrototype(&globExec, funcProto);
311 b_ObjectPrototype = objProto;
312 funcProto->setPrototype(b_ObjectPrototype);
313
314 ArrayPrototype *arrayProto = new ArrayPrototype(&globExec, objProto);
315 b_ArrayPrototype = arrayProto;
316 StringPrototype *stringProto = new StringPrototype(&globExec, objProto);
317 b_StringPrototype = stringProto;
318 BooleanPrototype *booleanProto = new BooleanPrototype(&globExec, objProto, funcProto);
319 b_BooleanPrototype = booleanProto;
320 NumberPrototype *numberProto = new NumberPrototype(&globExec, objProto, funcProto);
321 b_NumberPrototype = numberProto;
322 DatePrototype *dateProto = new DatePrototype(&globExec, objProto);
323 b_DatePrototype = dateProto;
324 RegExpPrototype *regexpProto = new RegExpPrototype(&globExec, objProto, funcProto);
325 b_RegExpPrototype = regexpProto;
326 ErrorPrototype *errorProto = new ErrorPrototype(&globExec, objProto, funcProto);
327 b_ErrorPrototype = errorProto;
328
329 JSObject* o = global;
330 while (o->prototype()->isObject())
331 o = static_cast<JSObject*>(o->prototype());
332 o->setPrototype(b_ObjectPrototype);
333
334 // Constructors (Object, Array, etc.)
335 b_Object = new ObjectObjectImp(&globExec, objProto, funcProto);
336 b_Function = new FunctionObjectImp(&globExec, funcProto);
337 b_Array = new ArrayObjectImp(&globExec, funcProto, arrayProto);
338 b_String = new StringObjectImp(&globExec, funcProto, stringProto);
339 b_Boolean = new BooleanObjectImp(&globExec, funcProto, booleanProto);
340 b_Number = new NumberObjectImp(&globExec, funcProto, numberProto);
341 b_Date = new DateObjectImp(&globExec, funcProto, dateProto);
342 b_RegExp = new RegExpObjectImp(&globExec, funcProto, regexpProto);
343 b_Error = new ErrorObjectImp(&globExec, funcProto, errorProto);
344
345 // Error object prototypes
346 b_evalErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, EvalError, "EvalError", "EvalError");
347 b_rangeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, RangeError, "RangeError", "RangeError");
348 b_referenceErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
349 b_syntaxErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
350 b_typeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, TypeError, "TypeError", "TypeError");
351 b_uriErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, URIError, "URIError", "URIError");
352
353 // Error objects
354 b_evalError = new NativeErrorImp(&globExec, funcProto, b_evalErrorPrototype);
355 b_rangeError = new NativeErrorImp(&globExec, funcProto, b_rangeErrorPrototype);
356 b_referenceError = new NativeErrorImp(&globExec, funcProto, b_referenceErrorPrototype);
357 b_syntaxError = new NativeErrorImp(&globExec, funcProto, b_syntaxErrorPrototype);
358 b_typeError = new NativeErrorImp(&globExec, funcProto, b_typeErrorPrototype);
359 b_uriError = new NativeErrorImp(&globExec, funcProto, b_uriErrorPrototype);
360
361 // ECMA 15.3.4.1
362 funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum);
363
364 global->put(&globExec, "Object", b_Object, DontEnum);
365 global->put(&globExec, "Function", b_Function, DontEnum);
366 global->put(&globExec, "Array", b_Array, DontEnum);
367 global->put(&globExec, "Boolean", b_Boolean, DontEnum);
368 global->put(&globExec, "String", b_String, DontEnum);
369 global->put(&globExec, "Number", b_Number, DontEnum);
370 global->put(&globExec, "Date", b_Date, DontEnum);
371 global->put(&globExec, "RegExp", b_RegExp, DontEnum);
372 global->put(&globExec, "Error", b_Error, DontEnum);
373 // Using Internal for those to have something != 0
374 // (see kjs_window). Maybe DontEnum would be ok too ?
375 global->put(&globExec, "EvalError",b_evalError, Internal);
376 global->put(&globExec, "RangeError",b_rangeError, Internal);
377 global->put(&globExec, "ReferenceError",b_referenceError, Internal);
378 global->put(&globExec, "SyntaxError",b_syntaxError, Internal);
379 global->put(&globExec, "TypeError",b_typeError, Internal);
380 global->put(&globExec, "URIError",b_uriError, Internal);
381
382 // Set the constructorPropertyName property of all builtin constructors
383 objProto->put(&globExec, constructorPropertyName, b_Object, DontEnum | DontDelete | ReadOnly);
384 funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum | DontDelete | ReadOnly);
385 arrayProto->put(&globExec, constructorPropertyName, b_Array, DontEnum | DontDelete | ReadOnly);
386 booleanProto->put(&globExec, constructorPropertyName, b_Boolean, DontEnum | DontDelete | ReadOnly);
387 stringProto->put(&globExec, constructorPropertyName, b_String, DontEnum | DontDelete | ReadOnly);
388 numberProto->put(&globExec, constructorPropertyName, b_Number, DontEnum | DontDelete | ReadOnly);
389 dateProto->put(&globExec, constructorPropertyName, b_Date, DontEnum | DontDelete | ReadOnly);
390 regexpProto->put(&globExec, constructorPropertyName, b_RegExp, DontEnum | DontDelete | ReadOnly);
391 errorProto->put(&globExec, constructorPropertyName, b_Error, DontEnum | DontDelete | ReadOnly);
392 b_evalErrorPrototype->put(&globExec, constructorPropertyName, b_evalError, DontEnum | DontDelete | ReadOnly);
393 b_rangeErrorPrototype->put(&globExec, constructorPropertyName, b_rangeError, DontEnum | DontDelete | ReadOnly);
394 b_referenceErrorPrototype->put(&globExec, constructorPropertyName, b_referenceError, DontEnum | DontDelete | ReadOnly);
395 b_syntaxErrorPrototype->put(&globExec, constructorPropertyName, b_syntaxError, DontEnum | DontDelete | ReadOnly);
396 b_typeErrorPrototype->put(&globExec, constructorPropertyName, b_typeError, DontEnum | DontDelete | ReadOnly);
397 b_uriErrorPrototype->put(&globExec, constructorPropertyName, b_uriError, DontEnum | DontDelete | ReadOnly);
398
399 // built-in values
400 global->put(&globExec, "NaN", jsNaN(), DontEnum|DontDelete);
401 global->put(&globExec, "Infinity", jsNumber(Inf), DontEnum|DontDelete);
402 global->put(&globExec, "undefined", jsUndefined(), DontEnum|DontDelete);
403
404 // built-in functions
405 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
406 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
407 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
408 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
409 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
410 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
411 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
412 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
413 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
414 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
415 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
416#ifndef NDEBUG
417 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
418#endif
419
420 // built-in objects
421 global->put(&globExec, "Math", new MathObjectImp(&globExec, objProto), DontEnum);
422}
423
424InterpreterImp::~InterpreterImp()
425{
426 if (dbg)
427 dbg->detach(m_interpreter);
428 clear();
429}
430
431void InterpreterImp::clear()
432{
433 //fprintf(stderr,"InterpreterImp::clear\n");
434 // remove from global chain (see init())
435 JSLock lock;
436
437 next->prev = prev;
438 prev->next = next;
439 s_hook = next;
440 if (s_hook == this)
441 {
442 // This was the last interpreter
443 s_hook = 0L;
444 }
445 interpreterMap().remove(global);
446}
447
448void InterpreterImp::mark()
449{
450 if (m_interpreter)
451 m_interpreter->mark();
452 if (_context)
453 _context->mark();
454 if (global)
455 global->mark();
456 if (globExec.exception())
457 globExec.exception()->mark();
458}
459
460bool InterpreterImp::checkSyntax(const UString &code)
461{
462 JSLock lock;
463
464 // Parser::parse() returns 0 in a syntax error occurs, so we just check for that
465 RefPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(), code.size(), 0, 0, 0);
466 return progNode;
467}
468
469Completion InterpreterImp::evaluate(const UChar* code, int codeLength, JSValue* thisV, const UString& sourceURL, int startingLineNumber)
470{
471 JSLock lock;
472
473 // prevent against infinite recursion
474 if (recursion >= 20)
475 return Completion(Throw, Error::create(&globExec, GeneralError, "Recursion too deep"));
476
477 // parse the source code
478 int sid;
479 int errLine;
480 UString errMsg;
481 RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
482
483 // notify debugger that source has been parsed
484 if (dbg) {
485 bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, UString(code, codeLength), errLine);
486 if (!cont)
487 return Completion(Break);
488 }
489
490 // no program node means a syntax error occurred
491 if (!progNode)
492 return Completion(Throw, Error::create(&globExec, SyntaxError, errMsg, errLine, sid, &sourceURL));
493
494 globExec.clearException();
495
496 recursion++;
497
498 JSObject* globalObj = globalObject();
499 JSObject* thisObj = globalObj;
500
501 // "this" must be an object... use same rules as Function.prototype.apply()
502 if (thisV && !thisV->isUndefinedOrNull())
503 thisObj = thisV->toObject(&globExec);
504
505 Completion res;
506 if (globExec.hadException())
507 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
508 res = Completion(Throw, globExec.exception());
509 else {
510 // execute the code
511 ContextImp ctx(globalObj, this, thisObj, progNode.get());
512 ExecState newExec(m_interpreter, &ctx);
513 progNode->processVarDecls(&newExec);
514 res = progNode->execute(&newExec);
515 }
516
517 recursion--;
518
519 return res;
520}
521
522void InterpreterImp::saveBuiltins (SavedBuiltins &builtins) const
523{
524 if (!builtins._internal) {
525 builtins._internal = new SavedBuiltinsInternal;
526 }
527
528 builtins._internal->b_Object = b_Object;
529 builtins._internal->b_Function = b_Function;
530 builtins._internal->b_Array = b_Array;
531 builtins._internal->b_Boolean = b_Boolean;
532 builtins._internal->b_String = b_String;
533 builtins._internal->b_Number = b_Number;
534 builtins._internal->b_Date = b_Date;
535 builtins._internal->b_RegExp = b_RegExp;
536 builtins._internal->b_Error = b_Error;
537
538 builtins._internal->b_ObjectPrototype = b_ObjectPrototype;
539 builtins._internal->b_FunctionPrototype = b_FunctionPrototype;
540 builtins._internal->b_ArrayPrototype = b_ArrayPrototype;
541 builtins._internal->b_BooleanPrototype = b_BooleanPrototype;
542 builtins._internal->b_StringPrototype = b_StringPrototype;
543 builtins._internal->b_NumberPrototype = b_NumberPrototype;
544 builtins._internal->b_DatePrototype = b_DatePrototype;
545 builtins._internal->b_RegExpPrototype = b_RegExpPrototype;
546 builtins._internal->b_ErrorPrototype = b_ErrorPrototype;
547
548 builtins._internal->b_evalError = b_evalError;
549 builtins._internal->b_rangeError = b_rangeError;
550 builtins._internal->b_referenceError = b_referenceError;
551 builtins._internal->b_syntaxError = b_syntaxError;
552 builtins._internal->b_typeError = b_typeError;
553 builtins._internal->b_uriError = b_uriError;
554
555 builtins._internal->b_evalErrorPrototype = b_evalErrorPrototype;
556 builtins._internal->b_rangeErrorPrototype = b_rangeErrorPrototype;
557 builtins._internal->b_referenceErrorPrototype = b_referenceErrorPrototype;
558 builtins._internal->b_syntaxErrorPrototype = b_syntaxErrorPrototype;
559 builtins._internal->b_typeErrorPrototype = b_typeErrorPrototype;
560 builtins._internal->b_uriErrorPrototype = b_uriErrorPrototype;
561}
562
563void InterpreterImp::restoreBuiltins (const SavedBuiltins &builtins)
564{
565 if (!builtins._internal) {
566 return;
567 }
568
569 b_Object = builtins._internal->b_Object;
570 b_Function = builtins._internal->b_Function;
571 b_Array = builtins._internal->b_Array;
572 b_Boolean = builtins._internal->b_Boolean;
573 b_String = builtins._internal->b_String;
574 b_Number = builtins._internal->b_Number;
575 b_Date = builtins._internal->b_Date;
576 b_RegExp = builtins._internal->b_RegExp;
577 b_Error = builtins._internal->b_Error;
578
579 b_ObjectPrototype = builtins._internal->b_ObjectPrototype;
580 b_FunctionPrototype = builtins._internal->b_FunctionPrototype;
581 b_ArrayPrototype = builtins._internal->b_ArrayPrototype;
582 b_BooleanPrototype = builtins._internal->b_BooleanPrototype;
583 b_StringPrototype = builtins._internal->b_StringPrototype;
584 b_NumberPrototype = builtins._internal->b_NumberPrototype;
585 b_DatePrototype = builtins._internal->b_DatePrototype;
586 b_RegExpPrototype = builtins._internal->b_RegExpPrototype;
587 b_ErrorPrototype = builtins._internal->b_ErrorPrototype;
588
589 b_evalError = builtins._internal->b_evalError;
590 b_rangeError = builtins._internal->b_rangeError;
591 b_referenceError = builtins._internal->b_referenceError;
592 b_syntaxError = builtins._internal->b_syntaxError;
593 b_typeError = builtins._internal->b_typeError;
594 b_uriError = builtins._internal->b_uriError;
595
596 b_evalErrorPrototype = builtins._internal->b_evalErrorPrototype;
597 b_rangeErrorPrototype = builtins._internal->b_rangeErrorPrototype;
598 b_referenceErrorPrototype = builtins._internal->b_referenceErrorPrototype;
599 b_syntaxErrorPrototype = builtins._internal->b_syntaxErrorPrototype;
600 b_typeErrorPrototype = builtins._internal->b_typeErrorPrototype;
601 b_uriErrorPrototype = builtins._internal->b_uriErrorPrototype;
602}
603
604InterpreterImp *InterpreterImp::interpreterWithGlobalObject(JSObject *global)
605{
606 return interpreterMap().get(global);
607}
608
609
610// ------------------------------ InternalFunctionImp --------------------------
611
612const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};
613
614InternalFunctionImp::InternalFunctionImp()
615{
616}
617
618InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto)
619 : JSObject(funcProto)
620{
621}
622
623InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name)
624 : JSObject(funcProto)
625 , m_name(name)
626{
627}
628
629bool InternalFunctionImp::implementsCall() const
630{
631 return true;
632}
633
634bool InternalFunctionImp::implementsHasInstance() const
635{
636 return true;
637}
638
639bool InternalFunctionImp::hasInstance(ExecState *exec, JSValue *value)
640{
641 if (!value->isObject())
642 return false;
643
644 JSValue *prot = get(exec,prototypePropertyName);
645 if (!prot->isObject() && !prot->isNull()) {
646 throwError(exec, TypeError, "Invalid prototype encountered in instanceof operation.");
647 return false;
648 }
649
650 JSObject *v = static_cast<JSObject *>(value);
651 while ((v = v->prototype()->getObject())) {
652 if (v == prot)
653 return true;
654 }
655 return false;
656}
657
658// ------------------------------ global functions -----------------------------
659
660double roundValue(ExecState *exec, JSValue *v)
661{
662 double d = v->toNumber(exec);
663 double ad = fabs(d);
664 if (ad == 0 || isNaN(d) || isInf(d))
665 return d;
666 return copysign(floor(ad), d);
667}
668
669#ifndef NDEBUG
670#include <stdio.h>
671void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
672{
673 if (!o)
674 fprintf(stderr, "KJS: %s: (null)", s);
675 else {
676 JSValue *v = o;
677
678 UString name;
679 switch (v->type()) {
680 case UnspecifiedType:
681 name = "Unspecified";
682 break;
683 case UndefinedType:
684 name = "Undefined";
685 break;
686 case NullType:
687 name = "Null";
688 break;
689 case BooleanType:
690 name = "Boolean";
691 break;
692 case StringType:
693 name = "String";
694 break;
695 case NumberType:
696 name = "Number";
697 break;
698 case ObjectType:
699 name = static_cast<JSObject *>(v)->className();
700 if (name.isNull())
701 name = "(unknown class)";
702 break;
703 case GetterSetterType:
704 name = "GetterSetter";
705 break;
706 }
707 UString vString = v->toString(exec);
708 if ( vString.size() > 50 )
709 vString = vString.substr( 0, 50 ) + "...";
710 // Can't use two UString::ascii() in the same fprintf call
711 CString tempString( vString.cstring() );
712
713 fprintf(stderr, "KJS: %s: %s : %s (%p)",
714 s, tempString.c_str(), name.ascii(), (void*)v);
715
716 if (lineno >= 0)
717 fprintf(stderr, ", line %d\n",lineno);
718 else
719 fprintf(stderr, "\n");
720 }
721}
722#endif
723
724}
Note: See TracBrowser for help on using the repository browser.