📄 internal.cpp
字号:
dbg->detach(m_interpreter); delete globExec; globExec = 0L; clear();}void InterpreterImp::clear(){ //fprintf(stderr,"InterpreterImp::clear\n"); // remove from global chain (see init())#if APPLE_CHANGES lockInterpreter();#endif next->prev = prev; prev->next = next; s_hook = next; if (s_hook == this) { // This was the last interpreter s_hook = 0L; globalClear(); } InterpreterMap::removeInterpreterForGlobalObject(global.imp());#if APPLE_CHANGES unlockInterpreter();#endif}void InterpreterImp::mark(){ //if (exVal && !exVal->marked()) // exVal->mark(); //if (retVal && !retVal->marked()) // retVal->mark(); if (UndefinedImp::staticUndefined && !UndefinedImp::staticUndefined->marked()) UndefinedImp::staticUndefined->mark(); if (NullImp::staticNull && !NullImp::staticNull->marked()) NullImp::staticNull->mark(); if (BooleanImp::staticTrue && !BooleanImp::staticTrue->marked()) BooleanImp::staticTrue->mark(); if (BooleanImp::staticFalse && !BooleanImp::staticFalse->marked()) BooleanImp::staticFalse->mark(); //fprintf( stderr, "InterpreterImp::mark this=%p global.imp()=%p\n", this, global.imp() ); if (m_interpreter) m_interpreter->mark(); if (_context) _context->mark();}bool InterpreterImp::checkSyntax(const UString &code){ // Parser::parse() returns 0 in a syntax error occurs, so we just check for that ProgramNode *progNode = Parser::parse(UString(), 0, code.data(),code.size(),0,0,0); bool ok = (progNode != 0); if (progNode) { // must ref and deref to clean up properly progNode->ref(); progNode->deref(); delete progNode; } return ok;}Completion InterpreterImp::evaluate(const UString &code, const Value &thisV, const UString &sourceURL, int startingLineNumber){#if APPLE_CHANGES lockInterpreter();#endif // prevent against infinite recursion if (recursion >= 20) {#if APPLE_CHANGES Completion result = Completion(Throw,Error::create(globExec,GeneralError,"Recursion too deep")); unlockInterpreter(); return result;#else return Completion(Throw,Error::create(globExec,GeneralError,"Recursion too deep"));#endif } // parse the source code int sid; int errLine; UString errMsg; ProgramNode *progNode = Parser::parse(sourceURL, startingLineNumber, code.data(),code.size(),&sid,&errLine,&errMsg); // notify debugger that source has been parsed if (dbg) { bool cont = dbg->sourceParsed(globExec,sid,code,errLine); if (!cont)#if APPLE_CHANGES { unlockInterpreter(); return Completion(Break); }#else return Completion(Break);#endif } // no program node means a syntax error occurred if (!progNode) { Object err = Error::create(globExec,SyntaxError,errMsg.ascii(),errLine, -1, &sourceURL); err.put(globExec,"sid",Number(sid));#if APPLE_CHANGES unlockInterpreter();#endif return Completion(Throw,err); } globExec->clearException(); recursion++; progNode->ref(); Object &globalObj = globalObject(); Object thisObj = globalObject(); if (!thisV.isNull()) { // "this" must be an object... use same rules as Function.prototype.apply() if (thisV.isA(NullType) || thisV.isA(UndefinedType)) thisObj = globalObject(); else { thisObj = thisV.toObject(globExec); } } Completion res; if (globExec->hadException()) { // the thisArg.toObject() conversion above might have thrown an exception - if so, // propagate it back res = Completion(Throw,globExec->exception()); } else { // execute the code ContextImp ctx(globalObj, this, thisObj); ExecState newExec(m_interpreter,&ctx); res = progNode->execute(&newExec); } if (progNode->deref()) delete progNode; recursion--;#if APPLE_CHANGES unlockInterpreter();#endif return res;}void InterpreterImp::setDebugger(Debugger *d){ if (d) d->detach(m_interpreter); dbg = d;}void InterpreterImp::saveBuiltins (SavedBuiltins &builtins) const{ if (!builtins._internal) { builtins._internal = new SavedBuiltinsInternal; } builtins._internal->b_Object = b_Object; builtins._internal->b_Function = b_Function; builtins._internal->b_Array = b_Array; builtins._internal->b_Boolean = b_Boolean; builtins._internal->b_String = b_String; builtins._internal->b_Number = b_Number; builtins._internal->b_Date = b_Date; builtins._internal->b_RegExp = b_RegExp; builtins._internal->b_Error = b_Error; builtins._internal->b_ObjectPrototype = b_ObjectPrototype; builtins._internal->b_FunctionPrototype = b_FunctionPrototype; builtins._internal->b_ArrayPrototype = b_ArrayPrototype; builtins._internal->b_BooleanPrototype = b_BooleanPrototype; builtins._internal->b_StringPrototype = b_StringPrototype; builtins._internal->b_NumberPrototype = b_NumberPrototype; builtins._internal->b_DatePrototype = b_DatePrototype; builtins._internal->b_RegExpPrototype = b_RegExpPrototype; builtins._internal->b_ErrorPrototype = b_ErrorPrototype; builtins._internal->b_evalError = b_evalError; builtins._internal->b_rangeError = b_rangeError; builtins._internal->b_referenceError = b_referenceError; builtins._internal->b_syntaxError = b_syntaxError; builtins._internal->b_typeError = b_typeError; builtins._internal->b_uriError = b_uriError; builtins._internal->b_evalErrorPrototype = b_evalErrorPrototype; builtins._internal->b_rangeErrorPrototype = b_rangeErrorPrototype; builtins._internal->b_referenceErrorPrototype = b_referenceErrorPrototype; builtins._internal->b_syntaxErrorPrototype = b_syntaxErrorPrototype; builtins._internal->b_typeErrorPrototype = b_typeErrorPrototype; builtins._internal->b_uriErrorPrototype = b_uriErrorPrototype;}void InterpreterImp::restoreBuiltins (const SavedBuiltins &builtins){ if (!builtins._internal) { return; } b_Object = builtins._internal->b_Object; b_Function = builtins._internal->b_Function; b_Array = builtins._internal->b_Array; b_Boolean = builtins._internal->b_Boolean; b_String = builtins._internal->b_String; b_Number = builtins._internal->b_Number; b_Date = builtins._internal->b_Date; b_RegExp = builtins._internal->b_RegExp; b_Error = builtins._internal->b_Error; b_ObjectPrototype = builtins._internal->b_ObjectPrototype; b_FunctionPrototype = builtins._internal->b_FunctionPrototype; b_ArrayPrototype = builtins._internal->b_ArrayPrototype; b_BooleanPrototype = builtins._internal->b_BooleanPrototype; b_StringPrototype = builtins._internal->b_StringPrototype; b_NumberPrototype = builtins._internal->b_NumberPrototype; b_DatePrototype = builtins._internal->b_DatePrototype; b_RegExpPrototype = builtins._internal->b_RegExpPrototype; b_ErrorPrototype = builtins._internal->b_ErrorPrototype; b_evalError = builtins._internal->b_evalError; b_rangeError = builtins._internal->b_rangeError; b_referenceError = builtins._internal->b_referenceError; b_syntaxError = builtins._internal->b_syntaxError; b_typeError = builtins._internal->b_typeError; b_uriError = builtins._internal->b_uriError; b_evalErrorPrototype = builtins._internal->b_evalErrorPrototype; b_rangeErrorPrototype = builtins._internal->b_rangeErrorPrototype; b_referenceErrorPrototype = builtins._internal->b_referenceErrorPrototype; b_syntaxErrorPrototype = builtins._internal->b_syntaxErrorPrototype; b_typeErrorPrototype = builtins._internal->b_typeErrorPrototype; b_uriErrorPrototype = builtins._internal->b_uriErrorPrototype;}InterpreterImp *InterpreterImp::interpreterWithGlobalObject(ObjectImp *global){ return InterpreterMap::getInterpreterForGlobalObject(global);}// ------------------------------ InternalFunctionImp --------------------------const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};InternalFunctionImp::InternalFunctionImp(FunctionPrototypeImp *funcProto) : ObjectImp(funcProto){}bool InternalFunctionImp::implementsHasInstance() const{ return true;}Boolean InternalFunctionImp::hasInstance(ExecState *exec, const Value &value){ if (value.type() != ObjectType) return Boolean(false); Value prot = get(exec,prototypePropertyName); if (prot.type() != ObjectType && prot.type() != NullType) { Object err = Error::create(exec, TypeError, "Invalid prototype encountered " "in instanceof operation."); exec->setException(err); return Boolean(false); } Object v = Object(static_cast<ObjectImp*>(value.imp())); while ((v = Object::dynamicCast(v.prototype())).imp()) { if (v.imp() == prot.imp()) return Boolean(true); } return Boolean(false);}// ------------------------------ global functions -----------------------------double KJS::roundValue(ExecState *exec, const Value &v){ Number n = v.toNumber(exec); double d = n.value(); double ad = fabs(d); if (ad == 0 || isNaN(d) || isInf(d)) return d; return copysign(floor(ad), d);}#ifndef NDEBUG#include <stdio.h>void KJS::printInfo(ExecState *exec, const char *s, const Value &o, int lineno){ if (o.isNull()) fprintf(stderr, "KJS: %s: (null)", s); else { Value v = o; UString name; switch ( v.type() ) { case UnspecifiedType: name = "Unspecified"; break; case UndefinedType: name = "Undefined"; break; case NullType: name = "Null"; break; case BooleanType: name = "Boolean"; break; case StringType: name = "String"; break; case NumberType: name = "Number"; break; case ObjectType: name = Object::dynamicCast(v).className(); if (name.isNull()) name = "(unknown class)"; break; } UString vString = v.toString(exec); if ( vString.size() > 50 ) vString = vString.substr( 0, 50 ) + "..."; // Can't use two UString::ascii() in the same fprintf call CString tempString( vString.cstring() ); fprintf(stderr, "KJS: %s: %s : %s (%p)", s, tempString.c_str(), name.ascii(), (void*)v.imp()); if (lineno >= 0) fprintf(stderr, ", line %d\n",lineno); else fprintf(stderr, "\n"); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -