Changeset 28468 in webkit for trunk/JavaScriptCore/kjs/interpreter.cpp
- Timestamp:
- Dec 5, 2007, 6:31:41 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/interpreter.cpp
r28328 r28468 4 4 * Copyright (C) 1999-2001 Harri Porten ([email protected]) 5 5 * Copyright (C) 2001 Peter Kelly ([email protected]) 6 * Copyright (C) 2003 Apple Computer,Inc.6 * Copyright (C) 2003, 2007 Apple Inc. 7 7 * 8 8 * This library is free software; you can redistribute it and/or … … 67 67 namespace KJS { 68 68 69 // Default number of ticks before a timeout check should be done. 70 static const int initialTickCountThreshold = 255; 71 72 // Preferred number of milliseconds between each timeout check 73 static const int preferredScriptCheckTimeInterval = 1000; 74 75 Interpreter* Interpreter::s_hook = 0; 76 77 typedef HashMap<JSObject*, Interpreter*> InterpreterMap; 78 static inline InterpreterMap &interpreterMap() 69 Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code) 79 70 { 80 static InterpreterMap* map = new InterpreterMap; 81 return* map; 71 return checkSyntax(exec, sourceURL, startingLineNumber, code.data(), code.size()); 82 72 } 83 73 84 Interpreter::Interpreter() 85 : m_globalExec(this, 0, 0, 0) 86 , m_currentExec(0) 87 , m_globalObject(0) 88 { 89 init(); 90 } 91 92 void Interpreter::init() 93 { 94 JSLock lock; 95 96 m_timeoutTime = 0; 97 m_recursion = 0; 98 m_debugger= 0; 99 100 resetTimeoutCheck(); 101 m_timeoutCheckCount = 0; 102 103 m_compatMode = NativeMode; 104 105 if (s_hook) { 106 prev = s_hook; 107 next = s_hook->next; 108 s_hook->next->prev = this; 109 s_hook->next = this; 110 } else { 111 // This is the first interpreter 112 s_hook = next = prev = this; 113 } 114 115 createObjectsForGlobalObjectProperties(); 116 } 117 118 Interpreter::~Interpreter() 119 { 120 JSLock lock; 121 122 if (m_debugger) 123 m_debugger->detach(this); 124 125 next->prev = prev; 126 prev->next = next; 127 s_hook = next; 128 if (s_hook == this) { 129 // This was the last interpreter 130 s_hook = 0; 131 } 132 } 133 134 JSGlobalObject* Interpreter::globalObject() const 135 { 136 // Now that we delay setting of the global object, people retrieving it before it is set may be in for a nasty surprise 137 ASSERT(m_globalObject); 138 return m_globalObject; 139 } 140 141 void Interpreter::setGlobalObject(JSGlobalObject* globalObject) 142 { 143 ASSERT(!m_globalObject); 144 ASSERT(globalObject); 145 m_globalObject = globalObject; 146 m_globalExec.setGlobalObject(globalObject); 147 148 setGlobalObjectProperties(); 149 } 150 151 void Interpreter::resetGlobalObjectProperties() 152 { 153 ASSERT(m_globalObject); 154 createObjectsForGlobalObjectProperties(); 155 setGlobalObjectProperties(); 156 } 157 158 void Interpreter::createObjectsForGlobalObjectProperties() 159 { 160 // Clear before inititalizing, to avoid marking uninitialized (dangerous) or 161 // stale (wasteful) pointers during initialization. 162 163 // Prototypes 164 m_FunctionPrototype = 0; 165 m_ObjectPrototype = 0; 166 167 m_ArrayPrototype = 0; 168 m_StringPrototype = 0; 169 m_BooleanPrototype = 0; 170 m_NumberPrototype = 0; 171 m_DatePrototype = 0; 172 m_RegExpPrototype = 0; 173 m_ErrorPrototype = 0; 174 175 m_EvalErrorPrototype = 0; 176 m_RangeErrorPrototype = 0; 177 m_ReferenceErrorPrototype = 0; 178 m_SyntaxErrorPrototype = 0; 179 m_TypeErrorPrototype = 0; 180 m_UriErrorPrototype = 0; 181 182 // Constructors 183 m_Object = 0; 184 m_Function = 0; 185 m_Array = 0; 186 m_String = 0; 187 m_Boolean = 0; 188 m_Number = 0; 189 m_Date = 0; 190 m_RegExp = 0; 191 m_Error = 0; 192 193 m_EvalError = 0; 194 m_RangeError = 0; 195 m_ReferenceError = 0; 196 m_SyntaxError = 0; 197 m_TypeError = 0; 198 m_UriError = 0; 199 200 // Prototypes 201 m_FunctionPrototype = new FunctionPrototype(&m_globalExec); 202 m_ObjectPrototype = new ObjectPrototype(&m_globalExec, m_FunctionPrototype); 203 m_FunctionPrototype->setPrototype(m_ObjectPrototype); 204 205 m_ArrayPrototype = new ArrayPrototype(&m_globalExec, m_ObjectPrototype); 206 m_StringPrototype = new StringPrototype(&m_globalExec, m_ObjectPrototype); 207 m_BooleanPrototype = new BooleanPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype); 208 m_NumberPrototype = new NumberPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype); 209 m_DatePrototype = new DatePrototype(&m_globalExec, m_ObjectPrototype); 210 m_RegExpPrototype = new RegExpPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype);; 211 m_ErrorPrototype = new ErrorPrototype(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype); 212 213 m_EvalErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, EvalError, "EvalError", "EvalError"); 214 m_RangeErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, RangeError, "RangeError", "RangeError"); 215 m_ReferenceErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, ReferenceError, "ReferenceError", "ReferenceError"); 216 m_SyntaxErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, SyntaxError, "SyntaxError", "SyntaxError"); 217 m_TypeErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, TypeError, "TypeError", "TypeError"); 218 m_UriErrorPrototype = new NativeErrorPrototype(&m_globalExec, m_ErrorPrototype, URIError, "URIError", "URIError"); 219 220 // Constructors 221 m_Object = new ObjectObjectImp(&m_globalExec, m_ObjectPrototype, m_FunctionPrototype); 222 m_Function = new FunctionObjectImp(&m_globalExec, m_FunctionPrototype); 223 m_Array = new ArrayObjectImp(&m_globalExec, m_FunctionPrototype, m_ArrayPrototype); 224 m_String = new StringObjectImp(&m_globalExec, m_FunctionPrototype, m_StringPrototype); 225 m_Boolean = new BooleanObjectImp(&m_globalExec, m_FunctionPrototype, m_BooleanPrototype); 226 m_Number = new NumberObjectImp(&m_globalExec, m_FunctionPrototype, m_NumberPrototype); 227 m_Date = new DateObjectImp(&m_globalExec, m_FunctionPrototype, m_DatePrototype); 228 m_RegExp = new RegExpObjectImp(&m_globalExec, m_FunctionPrototype, m_RegExpPrototype); 229 m_Error = new ErrorObjectImp(&m_globalExec, m_FunctionPrototype, m_ErrorPrototype); 230 231 m_EvalError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_EvalErrorPrototype); 232 m_RangeError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_RangeErrorPrototype); 233 m_ReferenceError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_ReferenceErrorPrototype); 234 m_SyntaxError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_SyntaxErrorPrototype); 235 m_TypeError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_TypeErrorPrototype); 236 m_UriError = new NativeErrorImp(&m_globalExec, m_FunctionPrototype, m_UriErrorPrototype); 237 238 m_FunctionPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum); 239 m_ObjectPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Object, DontEnum | DontDelete | ReadOnly); 240 m_FunctionPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum | DontDelete | ReadOnly); 241 m_ArrayPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Array, DontEnum | DontDelete | ReadOnly); 242 m_BooleanPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Boolean, DontEnum | DontDelete | ReadOnly); 243 m_StringPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_String, DontEnum | DontDelete | ReadOnly); 244 m_NumberPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Number, DontEnum | DontDelete | ReadOnly); 245 m_DatePrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Date, DontEnum | DontDelete | ReadOnly); 246 m_RegExpPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RegExp, DontEnum | DontDelete | ReadOnly); 247 m_ErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Error, DontEnum | DontDelete | ReadOnly); 248 m_EvalErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_EvalError, DontEnum | DontDelete | ReadOnly); 249 m_RangeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RangeError, DontEnum | DontDelete | ReadOnly); 250 m_ReferenceErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_ReferenceError, DontEnum | DontDelete | ReadOnly); 251 m_SyntaxErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_SyntaxError, DontEnum | DontDelete | ReadOnly); 252 m_TypeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_TypeError, DontEnum | DontDelete | ReadOnly); 253 m_UriErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_UriError, DontEnum | DontDelete | ReadOnly); 254 } 255 256 void Interpreter::setGlobalObjectProperties() 257 { 258 ASSERT(m_globalObject); 259 m_globalObject->setInterpreter(std::auto_ptr<Interpreter>(this)); 260 261 // Set global object prototype 262 JSObject* o = m_globalObject; 263 while (o->prototype()->isObject()) 264 o = static_cast<JSObject*>(o->prototype()); 265 o->setPrototype(m_ObjectPrototype); 266 267 // Set global constructors 268 // FIXME: kjs_window.cpp checks Internal/DontEnum as a performance hack, to 269 // see that these values can be put directly without a check for override 270 // properties. 271 // FIXME: These properties should be handled by JSGlobalObject 272 m_globalObject->putDirect("Object", m_Object, DontEnum); 273 m_globalObject->putDirect("Function", m_Function, DontEnum); 274 m_globalObject->putDirect("Array", m_Array, DontEnum); 275 m_globalObject->putDirect("Boolean", m_Boolean, DontEnum); 276 m_globalObject->putDirect("String", m_String, DontEnum); 277 m_globalObject->putDirect("Number", m_Number, DontEnum); 278 m_globalObject->putDirect("Date", m_Date, DontEnum); 279 m_globalObject->putDirect("RegExp", m_RegExp, DontEnum); 280 m_globalObject->putDirect("Error", m_Error, DontEnum); 281 m_globalObject->putDirect("EvalError",m_EvalError, Internal); 282 m_globalObject->putDirect("RangeError",m_RangeError, Internal); 283 m_globalObject->putDirect("ReferenceError",m_ReferenceError, Internal); 284 m_globalObject->putDirect("SyntaxError",m_SyntaxError, Internal); 285 m_globalObject->putDirect("TypeError",m_TypeError, Internal); 286 m_globalObject->putDirect("URIError",m_UriError, Internal); 287 288 // Set global values 289 m_globalObject->putDirect("Math", new MathObjectImp(&m_globalExec, m_ObjectPrototype), DontEnum); 290 m_globalObject->putDirect("NaN", jsNaN(), DontEnum|DontDelete); 291 m_globalObject->putDirect("Infinity", jsNumber(Inf), DontEnum|DontDelete); 292 m_globalObject->putDirect("undefined", jsUndefined(), DontEnum|DontDelete); 293 294 // Set global functions 295 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::Eval, 1, "eval"), DontEnum); 296 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum); 297 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum); 298 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum); 299 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum); 300 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::Escape, 1, "escape"), DontEnum); 301 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum); 302 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum); 303 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum); 304 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum); 305 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum); 306 #ifndef NDEBUG 307 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, m_FunctionPrototype, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum); 308 #endif 309 } 310 311 Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UString& code) 312 { 313 return checkSyntax(sourceURL, startingLineNumber, code.data(), code.size()); 314 } 315 316 Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength) 74 Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength) 317 75 { 318 76 JSLock lock; … … 322 80 RefPtr<ProgramNode> progNode = parser().parseProgram(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg); 323 81 if (!progNode) 324 return Completion(Throw, Error::create( &m_globalExec, SyntaxError, errMsg, errLine, 0, sourceURL));82 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, 0, sourceURL)); 325 83 return Completion(Normal); 326 84 } 327 85 328 Completion Interpreter::evaluate( const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)86 Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV) 329 87 { 330 return evaluate( sourceURL, startingLineNumber, code.data(), code.size(), thisV);88 return evaluate(exec, sourceURL, startingLineNumber, code.data(), code.size(), thisV); 331 89 } 332 90 333 Completion Interpreter::evaluate( const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)91 Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV) 334 92 { 335 93 JSLock lock; 336 94 337 // prevent against infinite recursion 338 if (m_recursion >= 20) 339 return Completion(Throw, Error::create(&m_globalExec, GeneralError, "Recursion too deep")); 95 JSGlobalObject* globalObject = exec->dynamicGlobalObject(); 96 97 if (globalObject->recursion() >= 20) 98 return Completion(Throw, Error::create(exec, GeneralError, "Recursion too deep")); 340 99 341 100 // parse the source code … … 346 105 347 106 // notify debugger that source has been parsed 348 if ( m_debugger) {349 bool cont = m_debugger->sourceParsed(&m_globalExec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);107 if (globalObject->debugger()) { 108 bool cont = globalObject->debugger()->sourceParsed(exec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg); 350 109 if (!cont) 351 110 return Completion(Break); … … 354 113 // no program node means a syntax error occurred 355 114 if (!progNode) 356 return Completion(Throw, Error::create( &m_globalExec, SyntaxError, errMsg, errLine, sourceId, sourceURL));115 return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL)); 357 116 358 m_globalExec.clearException();117 exec->clearException(); 359 118 360 m_recursion++;119 globalObject->incRecursion(); 361 120 362 JSGlobalObject* globalObj = m_globalObject; 363 JSObject* thisObj = globalObj; 121 JSObject* thisObj = globalObject; 364 122 365 123 // "this" must be an object... use same rules as Function.prototype.apply() 366 124 if (thisV && !thisV->isUndefinedOrNull()) 367 thisObj = thisV->toObject( &m_globalExec);125 thisObj = thisV->toObject(exec); 368 126 369 127 Completion res; 370 if ( m_globalExec.hadException())128 if (exec->hadException()) 371 129 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it 372 res = Completion(Throw, m_globalExec.exception());130 res = Completion(Throw, exec->exception()); 373 131 else { 374 132 // execute the code 375 ExecState newExec( this, globalObj, thisObj, progNode.get());133 ExecState newExec(globalObject, thisObj, progNode.get()); 376 134 res = progNode->execute(&newExec); 377 135 } 378 136 379 m_recursion--;137 globalObject->decRecursion(); 380 138 381 139 if (shouldPrintExceptions() && res.complType() == Throw) { 382 140 JSLock lock; 383 ExecState* exec = m_globalObject->globalExec();141 ExecState* exec = globalObject->globalExec(); 384 142 CString f = sourceURL.UTF8String(); 385 143 CString message = res.value()->toObject(exec)->toString(exec).UTF8String(); … … 393 151 394 152 return res; 395 }396 397 JSObject *Interpreter::builtinObject() const398 {399 return m_Object;400 }401 402 JSObject *Interpreter::builtinFunction() const403 {404 return m_Function;405 }406 407 JSObject *Interpreter::builtinArray() const408 {409 return m_Array;410 }411 412 JSObject *Interpreter::builtinBoolean() const413 {414 return m_Boolean;415 }416 417 JSObject *Interpreter::builtinString() const418 {419 return m_String;420 }421 422 JSObject *Interpreter::builtinNumber() const423 {424 return m_Number;425 }426 427 JSObject *Interpreter::builtinDate() const428 {429 return m_Date;430 }431 432 JSObject *Interpreter::builtinError() const433 {434 return m_Error;435 }436 437 JSObject *Interpreter::builtinObjectPrototype() const438 {439 return m_ObjectPrototype;440 }441 442 JSObject *Interpreter::builtinFunctionPrototype() const443 {444 return m_FunctionPrototype;445 }446 447 JSObject *Interpreter::builtinArrayPrototype() const448 {449 return m_ArrayPrototype;450 }451 452 JSObject *Interpreter::builtinBooleanPrototype() const453 {454 return m_BooleanPrototype;455 }456 457 JSObject *Interpreter::builtinStringPrototype() const458 {459 return m_StringPrototype;460 }461 462 JSObject *Interpreter::builtinNumberPrototype() const463 {464 return m_NumberPrototype;465 }466 467 JSObject *Interpreter::builtinDatePrototype() const468 {469 return m_DatePrototype;470 }471 472 JSObject *Interpreter::builtinRegExpPrototype() const473 {474 return m_RegExpPrototype;475 }476 477 JSObject *Interpreter::builtinErrorPrototype() const478 {479 return m_ErrorPrototype;480 }481 482 JSObject *Interpreter::builtinEvalError() const483 {484 return m_EvalError;485 }486 487 JSObject *Interpreter::builtinRangeError() const488 {489 return m_RangeError;490 }491 492 JSObject *Interpreter::builtinReferenceError() const493 {494 return m_ReferenceError;495 }496 497 JSObject *Interpreter::builtinSyntaxError() const498 {499 return m_SyntaxError;500 }501 502 JSObject *Interpreter::builtinTypeError() const503 {504 return m_TypeError;505 }506 507 JSObject *Interpreter::builtinURIError() const508 {509 return m_UriError;510 }511 512 JSObject *Interpreter::builtinEvalErrorPrototype() const513 {514 return m_EvalErrorPrototype;515 }516 517 JSObject *Interpreter::builtinRangeErrorPrototype() const518 {519 return m_RangeErrorPrototype;520 }521 522 JSObject *Interpreter::builtinReferenceErrorPrototype() const523 {524 return m_ReferenceErrorPrototype;525 }526 527 JSObject *Interpreter::builtinSyntaxErrorPrototype() const528 {529 return m_SyntaxErrorPrototype;530 }531 532 JSObject *Interpreter::builtinTypeErrorPrototype() const533 {534 return m_TypeErrorPrototype;535 }536 537 JSObject *Interpreter::builtinURIErrorPrototype() const538 {539 return m_UriErrorPrototype;540 153 } 541 154 … … 552 165 } 553 166 554 void Interpreter::saveBuiltins (SavedBuiltins& builtins) const 555 { 556 if (!builtins._internal) 557 builtins._internal = new SavedBuiltinsInternal; 558 559 builtins._internal->m_Object = m_Object; 560 builtins._internal->m_Function = m_Function; 561 builtins._internal->m_Array = m_Array; 562 builtins._internal->m_Boolean = m_Boolean; 563 builtins._internal->m_String = m_String; 564 builtins._internal->m_Number = m_Number; 565 builtins._internal->m_Date = m_Date; 566 builtins._internal->m_RegExp = m_RegExp; 567 builtins._internal->m_Error = m_Error; 568 569 builtins._internal->m_ObjectPrototype = m_ObjectPrototype; 570 builtins._internal->m_FunctionPrototype = m_FunctionPrototype; 571 builtins._internal->m_ArrayPrototype = m_ArrayPrototype; 572 builtins._internal->m_BooleanPrototype = m_BooleanPrototype; 573 builtins._internal->m_StringPrototype = m_StringPrototype; 574 builtins._internal->m_NumberPrototype = m_NumberPrototype; 575 builtins._internal->m_DatePrototype = m_DatePrototype; 576 builtins._internal->m_RegExpPrototype = m_RegExpPrototype; 577 builtins._internal->m_ErrorPrototype = m_ErrorPrototype; 578 579 builtins._internal->m_EvalError = m_EvalError; 580 builtins._internal->m_RangeError = m_RangeError; 581 builtins._internal->m_ReferenceError = m_ReferenceError; 582 builtins._internal->m_SyntaxError = m_SyntaxError; 583 builtins._internal->m_TypeError = m_TypeError; 584 builtins._internal->m_UriError = m_UriError; 585 586 builtins._internal->m_EvalErrorPrototype = m_EvalErrorPrototype; 587 builtins._internal->m_RangeErrorPrototype = m_RangeErrorPrototype; 588 builtins._internal->m_ReferenceErrorPrototype = m_ReferenceErrorPrototype; 589 builtins._internal->m_SyntaxErrorPrototype = m_SyntaxErrorPrototype; 590 builtins._internal->m_TypeErrorPrototype = m_TypeErrorPrototype; 591 builtins._internal->m_UriErrorPrototype = m_UriErrorPrototype; 592 } 593 594 void Interpreter::restoreBuiltins (const SavedBuiltins& builtins) 595 { 596 if (!builtins._internal) 597 return; 598 599 m_Object = builtins._internal->m_Object; 600 m_Function = builtins._internal->m_Function; 601 m_Array = builtins._internal->m_Array; 602 m_Boolean = builtins._internal->m_Boolean; 603 m_String = builtins._internal->m_String; 604 m_Number = builtins._internal->m_Number; 605 m_Date = builtins._internal->m_Date; 606 m_RegExp = builtins._internal->m_RegExp; 607 m_Error = builtins._internal->m_Error; 608 609 m_ObjectPrototype = builtins._internal->m_ObjectPrototype; 610 m_FunctionPrototype = builtins._internal->m_FunctionPrototype; 611 m_ArrayPrototype = builtins._internal->m_ArrayPrototype; 612 m_BooleanPrototype = builtins._internal->m_BooleanPrototype; 613 m_StringPrototype = builtins._internal->m_StringPrototype; 614 m_NumberPrototype = builtins._internal->m_NumberPrototype; 615 m_DatePrototype = builtins._internal->m_DatePrototype; 616 m_RegExpPrototype = builtins._internal->m_RegExpPrototype; 617 m_ErrorPrototype = builtins._internal->m_ErrorPrototype; 618 619 m_EvalError = builtins._internal->m_EvalError; 620 m_RangeError = builtins._internal->m_RangeError; 621 m_ReferenceError = builtins._internal->m_ReferenceError; 622 m_SyntaxError = builtins._internal->m_SyntaxError; 623 m_TypeError = builtins._internal->m_TypeError; 624 m_UriError = builtins._internal->m_UriError; 625 626 m_EvalErrorPrototype = builtins._internal->m_EvalErrorPrototype; 627 m_RangeErrorPrototype = builtins._internal->m_RangeErrorPrototype; 628 m_ReferenceErrorPrototype = builtins._internal->m_ReferenceErrorPrototype; 629 m_SyntaxErrorPrototype = builtins._internal->m_SyntaxErrorPrototype; 630 m_TypeErrorPrototype = builtins._internal->m_TypeErrorPrototype; 631 m_UriErrorPrototype = builtins._internal->m_UriErrorPrototype; 632 } 633 634 void Interpreter::startTimeoutCheck() 635 { 636 if (m_timeoutCheckCount == 0) 637 resetTimeoutCheck(); 638 639 m_timeoutCheckCount++; 640 } 641 642 void Interpreter::stopTimeoutCheck() 643 { 644 m_timeoutCheckCount--; 645 } 646 647 void Interpreter::resetTimeoutCheck() 648 { 649 m_tickCount = 0; 650 m_ticksUntilNextTimeoutCheck = initialTickCountThreshold; 651 m_timeAtLastCheckTimeout = 0; 652 m_timeExecuting = 0; 653 } 654 655 // Returns the current time in milliseconds 656 // It doesn't matter what "current time" is here, just as long as 657 // it's possible to measure the time difference correctly. 658 static inline unsigned getCurrentTime() { 659 #if HAVE(SYS_TIME_H) 660 struct timeval tv; 661 gettimeofday(&tv, 0); 662 return tv.tv_sec * 1000 + tv.tv_usec / 1000; 663 #elif PLATFORM(QT) 664 QDateTime t = QDateTime::currentDateTime(); 665 return t.toTime_t() * 1000 + t.time().msec(); 666 #elif PLATFORM(WIN_OS) 667 return timeGetTime(); 668 #else 669 #error Platform does not have getCurrentTime function 670 #endif 671 } 672 673 bool Interpreter::checkTimeout() 674 { 675 m_tickCount = 0; 676 677 unsigned currentTime = getCurrentTime(); 678 679 if (!m_timeAtLastCheckTimeout) { 680 // Suspicious amount of looping in a script -- start timing it 681 m_timeAtLastCheckTimeout = currentTime; 682 return false; 683 } 684 685 unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout; 686 687 if (timeDiff == 0) 688 timeDiff = 1; 689 690 m_timeExecuting += timeDiff; 691 m_timeAtLastCheckTimeout = currentTime; 692 693 // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in 694 // preferredScriptCheckTimeInterval 695 m_ticksUntilNextTimeoutCheck = (unsigned)((float)preferredScriptCheckTimeInterval / timeDiff) * m_ticksUntilNextTimeoutCheck; 696 697 // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the 698 // preferred script check time interval. 699 if (m_ticksUntilNextTimeoutCheck == 0) 700 m_ticksUntilNextTimeoutCheck = initialTickCountThreshold; 701 702 if (m_timeoutTime && m_timeExecuting > m_timeoutTime) { 703 if (m_globalObject->shouldInterruptScript()) 704 return true; 705 706 resetTimeoutCheck(); 707 } 708 709 return false; 710 } 711 712 713 SavedBuiltins::SavedBuiltins() : 714 _internal(0) 715 { 716 } 717 718 SavedBuiltins::~SavedBuiltins() 719 { 720 delete _internal; 721 } 722 723 } 167 } // namespace KJS
Note:
See TracChangeset
for help on using the changeset viewer.