Changeset 14799 in webkit for trunk/JavaScriptCore/kjs/Context.cpp
- Timestamp:
- Jun 9, 2006, 8:57:13 PM (19 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/Context.cpp
r14797 r14799 1 // -*- c-basic-offset: 2 -*- 1 2 /* 2 3 * This file is part of the KDE libraries 3 * Copyright (C) 1999-200 2Harri Porten ([email protected])4 * Copyright (C) 1999-2001 Harri Porten ([email protected]) 4 5 * Copyright (C) 2001 Peter Kelly ([email protected]) 5 * Copyright (C) 200 4Apple Computer, Inc.6 * Copyright (C) 2003, 2006 Apple Computer, Inc. 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 22 23 */ 23 24 24 #include "config.h"25 #include "internal.h"26 27 #include "array_object.h"28 #include "bool_object.h"29 #include "collector.h"30 25 #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 26 51 27 namespace KJS { 52 28 53 #if PLATFORM(WIN_OS)54 #define copysign _copysign55 #endif56 57 // ------------------------------ StringImp ------------------------------------58 59 JSValue *StringImp::toPrimitive(ExecState *, JSType) const60 {61 return const_cast<StringImp *>(this);62 }63 64 bool StringImp::toBoolean(ExecState *) const65 {66 return (val.size() > 0);67 }68 69 double StringImp::toNumber(ExecState *) const70 {71 return val.toDouble();72 }73 74 UString StringImp::toString(ExecState *) const75 {76 return val;77 }78 79 JSObject *StringImp::toObject(ExecState *exec) const80 {81 return new StringInstance(exec->lexicalInterpreter()->builtinStringPrototype(), val);82 }83 84 // ------------------------------ NumberImp ------------------------------------85 86 JSValue *NumberImp::toPrimitive(ExecState *, JSType) const87 {88 return const_cast<NumberImp *>(this);89 }90 91 bool NumberImp::toBoolean(ExecState *) const92 {93 return val < 0.0 || val > 0.0; // false for NaN94 }95 96 double NumberImp::toNumber(ExecState *) const97 {98 return val;99 }100 101 UString NumberImp::toString(ExecState *) const102 {103 if (val == 0.0) // +0.0 or -0.0104 return "0";105 return UString::from(val);106 }107 108 JSObject *NumberImp::toObject(ExecState *exec) const109 {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 now116 // because it never shows up on profiles.117 bool NumberImp::getUInt32(uint32_t& uint32) const118 {119 uint32 = (uint32_t)val;120 return (double)uint32 == val;121 }122 123 // --------------------------- GetterSetterImp ---------------------------------124 void 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 134 JSValue *GetterSetterImp::toPrimitive(ExecState*, JSType) const135 {136 assert(false);137 return jsNull();138 }139 140 bool GetterSetterImp::toBoolean(ExecState*) const141 {142 assert(false);143 return false;144 }145 146 double GetterSetterImp::toNumber(ExecState *) const147 {148 assert(false);149 return 0.0;150 }151 152 UString GetterSetterImp::toString(ExecState *) const153 {154 assert(false);155 return UString::null();156 }157 158 JSObject *GetterSetterImp::toObject(ExecState *exec) const159 {160 assert(false);161 return jsNull()->toObject(exec);162 }163 164 // ------------------------------ LabelStack -----------------------------------165 166 bool 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 178 bool LabelStack::contains(const Identifier &id) const179 {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 29 // ECMA 10.2 193 Context Imp::ContextImp(JSObject *glob, InterpreterImp *interpreter, JSObject *thisV, FunctionBodyNode* currentBody,194 195 CodeType type, ContextImp *callingCon, FunctionImp *func, const List *args)196 : _interpreter(interpreter)30 Context::Context(JSObject* glob, InterpreterImp* interpreter, JSObject* thisV, 31 FunctionBodyNode* currentBody, CodeType type, Context* callingCon, 32 FunctionImp* func, const List* args) 33 : m_interpreter(interpreter) 197 34 , m_currentBody(currentBody) 198 , _function(func)199 , _arguments(args)35 , m_function(func) 36 , m_arguments(args) 200 37 , m_iterationDepth(0) 201 38 , m_switchDepth(0) 202 39 { 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.2216 switch(type) {40 m_codeType = type; 41 m_callingContext = callingCon; 42 43 // create and initialize activation object (ECMA 10.1.6) 44 if (type == FunctionCode || type == AnonymousCode ) { 45 m_activation = new ActivationImp(func, *args); 46 m_variable = m_activation; 47 } else { 48 m_activation = 0; 49 m_variable = glob; 50 } 51 52 // ECMA 10.2 53 switch(type) { 217 54 case EvalCode: 218 if (_callingContext) { 219 scope = _callingContext->scopeChain(); 220 variable = _callingContext->variableObject(); 221 thisVal = _callingContext->thisValue(); 55 if (m_callingContext) { 56 scope = m_callingContext->scopeChain(); 57 m_variable = m_callingContext->variableObject(); 58 m_thisVal = m_callingContext->thisValue(); 59 break; 60 } // else same as GlobalCode 61 case GlobalCode: 62 scope.clear(); 63 scope.push(glob); 64 m_thisVal = static_cast<JSObject*>(glob); 222 65 break; 223 } // else same as GlobalCode224 case GlobalCode:225 scope.clear();226 scope.push(glob);227 thisVal = static_cast<JSObject*>(glob);228 break;229 66 case FunctionCode: 230 67 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;68 if (type == FunctionCode) { 69 scope = func->scope(); 70 scope.push(m_activation); 71 } else { 72 scope.clear(); 73 scope.push(glob); 74 scope.push(m_activation); 75 } 76 m_variable = m_activation; // TODO: DontDelete ? (ECMA 10.2.3) 77 m_thisVal = thisV; 78 break; 242 79 } 243 244 _interpreter->setContext(this);80 81 m_interpreter->setContext(this); 245 82 } 246 83 247 Context Imp::~ContextImp()84 Context::~Context() 248 85 { 249 _interpreter->setContext(_callingContext);86 m_interpreter->setContext(m_callingContext); 250 87 } 251 88 252 void Context Imp::mark()89 void Context::mark() 253 90 { 254 for (ContextImp *context = this; context; context = context->_callingContext) { 255 context->scope.mark(); 256 } 91 for (Context* context = this; context; context = context->m_callingContext) 92 context->scope.mark(); 257 93 } 258 94 259 // ------------------------------ InterpreterImp ------------------------------- 260 261 InterpreterImp* InterpreterImp::s_hook = 0L; 262 263 typedef HashMap<JSObject *, InterpreterImp *> InterpreterMap; 264 265 static inline InterpreterMap &interpreterMap() 266 { 267 static InterpreterMap *map = new InterpreterMap; 268 return *map; 269 } 270 271 InterpreterImp::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 302 void 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 424 InterpreterImp::~InterpreterImp() 425 { 426 if (dbg) 427 dbg->detach(m_interpreter); 428 clear(); 429 } 430 431 void 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 448 void InterpreterImp::mark(bool currentThreadIsMainThread) 449 { 450 if (m_interpreter) 451 m_interpreter->mark(currentThreadIsMainThread); 452 if (_context) 453 _context->mark(); 454 if (global) 455 global->mark(); 456 if (globExec.exception()) 457 globExec.exception()->mark(); 458 } 459 460 bool 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 469 Completion 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 522 void 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 563 void 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 604 InterpreterImp *InterpreterImp::interpreterWithGlobalObject(JSObject *global) 605 { 606 return interpreterMap().get(global); 607 } 608 609 610 // ------------------------------ InternalFunctionImp -------------------------- 611 612 const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0}; 613 614 InternalFunctionImp::InternalFunctionImp() 615 { 616 } 617 618 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto) 619 : JSObject(funcProto) 620 { 621 } 622 623 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name) 624 : JSObject(funcProto) 625 , m_name(name) 626 { 627 } 628 629 bool InternalFunctionImp::implementsCall() const 630 { 631 return true; 632 } 633 634 bool InternalFunctionImp::implementsHasInstance() const 635 { 636 return true; 637 } 638 639 bool 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 660 double 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> 671 void 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 } 95 } // namespace KJS
Note:
See TracChangeset
for help on using the changeset viewer.