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

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

Reviewed by Eric (yay!).


  • Removed Context wrapper for ContextImp, renamed ContextImp to Context, split Context into its own file -- Context.cpp -- renamed _var to m_var, change ' *' to '* '.
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/Context.cpp: Added. (KJS::Context::Context): (KJS::Context::~Context): (KJS::Context::mark):
  • kjs/context.h: (KJS::Context::scopeChain): (KJS::Context::variableObject): (KJS::Context::setVariableObject): (KJS::Context::thisValue): (KJS::Context::callingContext): (KJS::Context::activationObject): (KJS::Context::currentBody): (KJS::Context::function): (KJS::Context::arguments): (KJS::Context::pushScope): (KJS::Context::seenLabels):
  • kjs/function.cpp: (KJS::FunctionImp::callAsFunction): (KJS::FunctionImp::processParameters): (KJS::FunctionImp::argumentsGetter): (KJS::GlobalFuncImp::callAsFunction):
  • kjs/internal.cpp: (KJS::InterpreterImp::evaluate):
  • kjs/internal.h: (KJS::InterpreterImp::setContext): (KJS::InterpreterImp::context):
  • kjs/interpreter.cpp:
  • kjs/interpreter.h: (KJS::ExecState::context): (KJS::ExecState::ExecState):
  • kjs/nodes.cpp: (currentSourceId): (currentSourceURL): (ThisNode::evaluate): (ResolveNode::evaluate): (FunctionCallResolveNode::evaluate): (PostfixResolveNode::evaluate): (DeleteResolveNode::evaluate): (TypeOfResolveNode::evaluate): (PrefixResolveNode::evaluate): (AssignResolveNode::evaluate): (VarDeclNode::evaluate): (VarDeclNode::processVarDecls): (DoWhileNode::execute): (WhileNode::execute): (ForNode::execute): (ForInNode::execute): (ContinueNode::execute): (BreakNode::execute): (ReturnNode::execute): (WithNode::execute): (SwitchNode::execute): (LabelNode::execute): (TryNode::execute): (FuncDeclNode::processFuncDecl): (FuncExprNode::evaluate):
  • Property svn:eol-style set to native
File size: 21.6 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 <wtf/HashMap.h>
46#include <wtf/HashSet.h>
47#include <wtf/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// ------------------------------ InterpreterImp -------------------------------
191
192InterpreterImp* InterpreterImp::s_hook = 0L;
193
194typedef HashMap<JSObject *, InterpreterImp *> InterpreterMap;
195
196static inline InterpreterMap &interpreterMap()
197{
198 static InterpreterMap *map = new InterpreterMap;
199 return *map;
200}
201
202InterpreterImp::InterpreterImp(Interpreter *interp, JSObject *glob)
203 : globExec(interp, 0)
204 , _context(0)
205{
206 // add this interpreter to the global chain
207 // as a root set for garbage collection
208 JSLock lock;
209
210 m_interpreter = interp;
211 if (s_hook) {
212 prev = s_hook;
213 next = s_hook->next;
214 s_hook->next->prev = this;
215 s_hook->next = this;
216 } else {
217 // This is the first interpreter
218 s_hook = next = prev = this;
219 }
220
221 interpreterMap().set(glob, this);
222
223 global = glob;
224 dbg = 0;
225 m_compatMode = Interpreter::NativeMode;
226
227 // initialize properties of the global object
228 initGlobalObject();
229
230 recursion = 0;
231}
232
233void InterpreterImp::initGlobalObject()
234{
235 Identifier::init();
236
237 // Contructor prototype objects (Object.prototype, Array.prototype etc)
238
239 FunctionPrototype *funcProto = new FunctionPrototype(&globExec);
240 b_FunctionPrototype = funcProto;
241 ObjectPrototype *objProto = new ObjectPrototype(&globExec, funcProto);
242 b_ObjectPrototype = objProto;
243 funcProto->setPrototype(b_ObjectPrototype);
244
245 ArrayPrototype *arrayProto = new ArrayPrototype(&globExec, objProto);
246 b_ArrayPrototype = arrayProto;
247 StringPrototype *stringProto = new StringPrototype(&globExec, objProto);
248 b_StringPrototype = stringProto;
249 BooleanPrototype *booleanProto = new BooleanPrototype(&globExec, objProto, funcProto);
250 b_BooleanPrototype = booleanProto;
251 NumberPrototype *numberProto = new NumberPrototype(&globExec, objProto, funcProto);
252 b_NumberPrototype = numberProto;
253 DatePrototype *dateProto = new DatePrototype(&globExec, objProto);
254 b_DatePrototype = dateProto;
255 RegExpPrototype *regexpProto = new RegExpPrototype(&globExec, objProto, funcProto);
256 b_RegExpPrototype = regexpProto;
257 ErrorPrototype *errorProto = new ErrorPrototype(&globExec, objProto, funcProto);
258 b_ErrorPrototype = errorProto;
259
260 JSObject* o = global;
261 while (o->prototype()->isObject())
262 o = static_cast<JSObject*>(o->prototype());
263 o->setPrototype(b_ObjectPrototype);
264
265 // Constructors (Object, Array, etc.)
266 b_Object = new ObjectObjectImp(&globExec, objProto, funcProto);
267 b_Function = new FunctionObjectImp(&globExec, funcProto);
268 b_Array = new ArrayObjectImp(&globExec, funcProto, arrayProto);
269 b_String = new StringObjectImp(&globExec, funcProto, stringProto);
270 b_Boolean = new BooleanObjectImp(&globExec, funcProto, booleanProto);
271 b_Number = new NumberObjectImp(&globExec, funcProto, numberProto);
272 b_Date = new DateObjectImp(&globExec, funcProto, dateProto);
273 b_RegExp = new RegExpObjectImp(&globExec, funcProto, regexpProto);
274 b_Error = new ErrorObjectImp(&globExec, funcProto, errorProto);
275
276 // Error object prototypes
277 b_evalErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, EvalError, "EvalError", "EvalError");
278 b_rangeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, RangeError, "RangeError", "RangeError");
279 b_referenceErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
280 b_syntaxErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
281 b_typeErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, TypeError, "TypeError", "TypeError");
282 b_uriErrorPrototype = new NativeErrorPrototype(&globExec, errorProto, URIError, "URIError", "URIError");
283
284 // Error objects
285 b_evalError = new NativeErrorImp(&globExec, funcProto, b_evalErrorPrototype);
286 b_rangeError = new NativeErrorImp(&globExec, funcProto, b_rangeErrorPrototype);
287 b_referenceError = new NativeErrorImp(&globExec, funcProto, b_referenceErrorPrototype);
288 b_syntaxError = new NativeErrorImp(&globExec, funcProto, b_syntaxErrorPrototype);
289 b_typeError = new NativeErrorImp(&globExec, funcProto, b_typeErrorPrototype);
290 b_uriError = new NativeErrorImp(&globExec, funcProto, b_uriErrorPrototype);
291
292 // ECMA 15.3.4.1
293 funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum);
294
295 global->put(&globExec, "Object", b_Object, DontEnum);
296 global->put(&globExec, "Function", b_Function, DontEnum);
297 global->put(&globExec, "Array", b_Array, DontEnum);
298 global->put(&globExec, "Boolean", b_Boolean, DontEnum);
299 global->put(&globExec, "String", b_String, DontEnum);
300 global->put(&globExec, "Number", b_Number, DontEnum);
301 global->put(&globExec, "Date", b_Date, DontEnum);
302 global->put(&globExec, "RegExp", b_RegExp, DontEnum);
303 global->put(&globExec, "Error", b_Error, DontEnum);
304 // Using Internal for those to have something != 0
305 // (see kjs_window). Maybe DontEnum would be ok too ?
306 global->put(&globExec, "EvalError",b_evalError, Internal);
307 global->put(&globExec, "RangeError",b_rangeError, Internal);
308 global->put(&globExec, "ReferenceError",b_referenceError, Internal);
309 global->put(&globExec, "SyntaxError",b_syntaxError, Internal);
310 global->put(&globExec, "TypeError",b_typeError, Internal);
311 global->put(&globExec, "URIError",b_uriError, Internal);
312
313 // Set the constructorPropertyName property of all builtin constructors
314 objProto->put(&globExec, constructorPropertyName, b_Object, DontEnum | DontDelete | ReadOnly);
315 funcProto->put(&globExec, constructorPropertyName, b_Function, DontEnum | DontDelete | ReadOnly);
316 arrayProto->put(&globExec, constructorPropertyName, b_Array, DontEnum | DontDelete | ReadOnly);
317 booleanProto->put(&globExec, constructorPropertyName, b_Boolean, DontEnum | DontDelete | ReadOnly);
318 stringProto->put(&globExec, constructorPropertyName, b_String, DontEnum | DontDelete | ReadOnly);
319 numberProto->put(&globExec, constructorPropertyName, b_Number, DontEnum | DontDelete | ReadOnly);
320 dateProto->put(&globExec, constructorPropertyName, b_Date, DontEnum | DontDelete | ReadOnly);
321 regexpProto->put(&globExec, constructorPropertyName, b_RegExp, DontEnum | DontDelete | ReadOnly);
322 errorProto->put(&globExec, constructorPropertyName, b_Error, DontEnum | DontDelete | ReadOnly);
323 b_evalErrorPrototype->put(&globExec, constructorPropertyName, b_evalError, DontEnum | DontDelete | ReadOnly);
324 b_rangeErrorPrototype->put(&globExec, constructorPropertyName, b_rangeError, DontEnum | DontDelete | ReadOnly);
325 b_referenceErrorPrototype->put(&globExec, constructorPropertyName, b_referenceError, DontEnum | DontDelete | ReadOnly);
326 b_syntaxErrorPrototype->put(&globExec, constructorPropertyName, b_syntaxError, DontEnum | DontDelete | ReadOnly);
327 b_typeErrorPrototype->put(&globExec, constructorPropertyName, b_typeError, DontEnum | DontDelete | ReadOnly);
328 b_uriErrorPrototype->put(&globExec, constructorPropertyName, b_uriError, DontEnum | DontDelete | ReadOnly);
329
330 // built-in values
331 global->put(&globExec, "NaN", jsNaN(), DontEnum|DontDelete);
332 global->put(&globExec, "Infinity", jsNumber(Inf), DontEnum|DontDelete);
333 global->put(&globExec, "undefined", jsUndefined(), DontEnum|DontDelete);
334
335 // built-in functions
336 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
337 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
338 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
339 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
340 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
341 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
342 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
343 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
344 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
345 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
346 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
347#ifndef NDEBUG
348 global->putDirectFunction(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
349#endif
350
351 // built-in objects
352 global->put(&globExec, "Math", new MathObjectImp(&globExec, objProto), DontEnum);
353}
354
355InterpreterImp::~InterpreterImp()
356{
357 if (dbg)
358 dbg->detach(m_interpreter);
359 clear();
360}
361
362void InterpreterImp::clear()
363{
364 //fprintf(stderr,"InterpreterImp::clear\n");
365 // remove from global chain (see init())
366 JSLock lock;
367
368 next->prev = prev;
369 prev->next = next;
370 s_hook = next;
371 if (s_hook == this)
372 {
373 // This was the last interpreter
374 s_hook = 0L;
375 }
376 interpreterMap().remove(global);
377}
378
379void InterpreterImp::mark(bool currentThreadIsMainThread)
380{
381 if (m_interpreter)
382 m_interpreter->mark(currentThreadIsMainThread);
383 if (_context)
384 _context->mark();
385 if (global)
386 global->mark();
387 if (globExec.exception())
388 globExec.exception()->mark();
389}
390
391bool InterpreterImp::checkSyntax(const UString &code)
392{
393 JSLock lock;
394
395 // Parser::parse() returns 0 in a syntax error occurs, so we just check for that
396 RefPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(), code.size(), 0, 0, 0);
397 return progNode;
398}
399
400Completion InterpreterImp::evaluate(const UChar* code, int codeLength, JSValue* thisV, const UString& sourceURL, int startingLineNumber)
401{
402 JSLock lock;
403
404 // prevent against infinite recursion
405 if (recursion >= 20)
406 return Completion(Throw, Error::create(&globExec, GeneralError, "Recursion too deep"));
407
408 // parse the source code
409 int sid;
410 int errLine;
411 UString errMsg;
412 RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
413
414 // notify debugger that source has been parsed
415 if (dbg) {
416 bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, UString(code, codeLength), errLine);
417 if (!cont)
418 return Completion(Break);
419 }
420
421 // no program node means a syntax error occurred
422 if (!progNode)
423 return Completion(Throw, Error::create(&globExec, SyntaxError, errMsg, errLine, sid, &sourceURL));
424
425 globExec.clearException();
426
427 recursion++;
428
429 JSObject* globalObj = globalObject();
430 JSObject* thisObj = globalObj;
431
432 // "this" must be an object... use same rules as Function.prototype.apply()
433 if (thisV && !thisV->isUndefinedOrNull())
434 thisObj = thisV->toObject(&globExec);
435
436 Completion res;
437 if (globExec.hadException())
438 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
439 res = Completion(Throw, globExec.exception());
440 else {
441 // execute the code
442 Context ctx(globalObj, this, thisObj, progNode.get());
443 ExecState newExec(m_interpreter, &ctx);
444 progNode->processVarDecls(&newExec);
445 res = progNode->execute(&newExec);
446 }
447
448 recursion--;
449
450 return res;
451}
452
453void InterpreterImp::saveBuiltins (SavedBuiltins &builtins) const
454{
455 if (!builtins._internal) {
456 builtins._internal = new SavedBuiltinsInternal;
457 }
458
459 builtins._internal->b_Object = b_Object;
460 builtins._internal->b_Function = b_Function;
461 builtins._internal->b_Array = b_Array;
462 builtins._internal->b_Boolean = b_Boolean;
463 builtins._internal->b_String = b_String;
464 builtins._internal->b_Number = b_Number;
465 builtins._internal->b_Date = b_Date;
466 builtins._internal->b_RegExp = b_RegExp;
467 builtins._internal->b_Error = b_Error;
468
469 builtins._internal->b_ObjectPrototype = b_ObjectPrototype;
470 builtins._internal->b_FunctionPrototype = b_FunctionPrototype;
471 builtins._internal->b_ArrayPrototype = b_ArrayPrototype;
472 builtins._internal->b_BooleanPrototype = b_BooleanPrototype;
473 builtins._internal->b_StringPrototype = b_StringPrototype;
474 builtins._internal->b_NumberPrototype = b_NumberPrototype;
475 builtins._internal->b_DatePrototype = b_DatePrototype;
476 builtins._internal->b_RegExpPrototype = b_RegExpPrototype;
477 builtins._internal->b_ErrorPrototype = b_ErrorPrototype;
478
479 builtins._internal->b_evalError = b_evalError;
480 builtins._internal->b_rangeError = b_rangeError;
481 builtins._internal->b_referenceError = b_referenceError;
482 builtins._internal->b_syntaxError = b_syntaxError;
483 builtins._internal->b_typeError = b_typeError;
484 builtins._internal->b_uriError = b_uriError;
485
486 builtins._internal->b_evalErrorPrototype = b_evalErrorPrototype;
487 builtins._internal->b_rangeErrorPrototype = b_rangeErrorPrototype;
488 builtins._internal->b_referenceErrorPrototype = b_referenceErrorPrototype;
489 builtins._internal->b_syntaxErrorPrototype = b_syntaxErrorPrototype;
490 builtins._internal->b_typeErrorPrototype = b_typeErrorPrototype;
491 builtins._internal->b_uriErrorPrototype = b_uriErrorPrototype;
492}
493
494void InterpreterImp::restoreBuiltins (const SavedBuiltins &builtins)
495{
496 if (!builtins._internal) {
497 return;
498 }
499
500 b_Object = builtins._internal->b_Object;
501 b_Function = builtins._internal->b_Function;
502 b_Array = builtins._internal->b_Array;
503 b_Boolean = builtins._internal->b_Boolean;
504 b_String = builtins._internal->b_String;
505 b_Number = builtins._internal->b_Number;
506 b_Date = builtins._internal->b_Date;
507 b_RegExp = builtins._internal->b_RegExp;
508 b_Error = builtins._internal->b_Error;
509
510 b_ObjectPrototype = builtins._internal->b_ObjectPrototype;
511 b_FunctionPrototype = builtins._internal->b_FunctionPrototype;
512 b_ArrayPrototype = builtins._internal->b_ArrayPrototype;
513 b_BooleanPrototype = builtins._internal->b_BooleanPrototype;
514 b_StringPrototype = builtins._internal->b_StringPrototype;
515 b_NumberPrototype = builtins._internal->b_NumberPrototype;
516 b_DatePrototype = builtins._internal->b_DatePrototype;
517 b_RegExpPrototype = builtins._internal->b_RegExpPrototype;
518 b_ErrorPrototype = builtins._internal->b_ErrorPrototype;
519
520 b_evalError = builtins._internal->b_evalError;
521 b_rangeError = builtins._internal->b_rangeError;
522 b_referenceError = builtins._internal->b_referenceError;
523 b_syntaxError = builtins._internal->b_syntaxError;
524 b_typeError = builtins._internal->b_typeError;
525 b_uriError = builtins._internal->b_uriError;
526
527 b_evalErrorPrototype = builtins._internal->b_evalErrorPrototype;
528 b_rangeErrorPrototype = builtins._internal->b_rangeErrorPrototype;
529 b_referenceErrorPrototype = builtins._internal->b_referenceErrorPrototype;
530 b_syntaxErrorPrototype = builtins._internal->b_syntaxErrorPrototype;
531 b_typeErrorPrototype = builtins._internal->b_typeErrorPrototype;
532 b_uriErrorPrototype = builtins._internal->b_uriErrorPrototype;
533}
534
535InterpreterImp *InterpreterImp::interpreterWithGlobalObject(JSObject *global)
536{
537 return interpreterMap().get(global);
538}
539
540
541// ------------------------------ InternalFunctionImp --------------------------
542
543const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};
544
545InternalFunctionImp::InternalFunctionImp()
546{
547}
548
549InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto)
550 : JSObject(funcProto)
551{
552}
553
554InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name)
555 : JSObject(funcProto)
556 , m_name(name)
557{
558}
559
560bool InternalFunctionImp::implementsCall() const
561{
562 return true;
563}
564
565bool InternalFunctionImp::implementsHasInstance() const
566{
567 return true;
568}
569
570bool InternalFunctionImp::hasInstance(ExecState *exec, JSValue *value)
571{
572 if (!value->isObject())
573 return false;
574
575 JSValue *prot = get(exec,prototypePropertyName);
576 if (!prot->isObject() && !prot->isNull()) {
577 throwError(exec, TypeError, "Invalid prototype encountered in instanceof operation.");
578 return false;
579 }
580
581 JSObject *v = static_cast<JSObject *>(value);
582 while ((v = v->prototype()->getObject())) {
583 if (v == prot)
584 return true;
585 }
586 return false;
587}
588
589// ------------------------------ global functions -----------------------------
590
591double roundValue(ExecState *exec, JSValue *v)
592{
593 double d = v->toNumber(exec);
594 double ad = fabs(d);
595 if (ad == 0 || isNaN(d) || isInf(d))
596 return d;
597 return copysign(floor(ad), d);
598}
599
600#ifndef NDEBUG
601#include <stdio.h>
602void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
603{
604 if (!o)
605 fprintf(stderr, "KJS: %s: (null)", s);
606 else {
607 JSValue *v = o;
608
609 UString name;
610 switch (v->type()) {
611 case UnspecifiedType:
612 name = "Unspecified";
613 break;
614 case UndefinedType:
615 name = "Undefined";
616 break;
617 case NullType:
618 name = "Null";
619 break;
620 case BooleanType:
621 name = "Boolean";
622 break;
623 case StringType:
624 name = "String";
625 break;
626 case NumberType:
627 name = "Number";
628 break;
629 case ObjectType:
630 name = static_cast<JSObject *>(v)->className();
631 if (name.isNull())
632 name = "(unknown class)";
633 break;
634 case GetterSetterType:
635 name = "GetterSetter";
636 break;
637 }
638 UString vString = v->toString(exec);
639 if ( vString.size() > 50 )
640 vString = vString.substr( 0, 50 ) + "...";
641 // Can't use two UString::ascii() in the same fprintf call
642 CString tempString( vString.cstring() );
643
644 fprintf(stderr, "KJS: %s: %s : %s (%p)",
645 s, tempString.c_str(), name.ascii(), (void*)v);
646
647 if (lineno >= 0)
648 fprintf(stderr, ", line %d\n",lineno);
649 else
650 fprintf(stderr, "\n");
651 }
652}
653#endif
654
655}
Note: See TracBrowser for help on using the repository browser.