internal.cpp
来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 915 行 · 第 1/2 页
CPP
915 行
KJScriptImp::KJScriptImp(KJScript *s) : scr(s), initialized(false), glob(0L),#ifdef KJS_DEBUGGER dbg(0L),#endif retVal(0L){ instances++; KJScriptImp::curr = this; // are we the first interpreter instance ? Initialize some stuff if (instances == 1) globalInit(); stack = new ExecutionStack(); clearException(); lex = new Lexer();}KJScriptImp::~KJScriptImp(){ KJScriptImp::curr = this;#ifdef KJS_DEBUGGER attachDebugger(0L);#endif clear(); delete lex; lex = 0L; delete stack; stack = 0L; KJScriptImp::curr = 0L; // are we the last of our kind ? Free global stuff. if (instances == 1) globalClear(); instances--;}void KJScriptImp::globalInit(){ UndefinedImp::staticUndefined = new UndefinedImp(); UndefinedImp::staticUndefined->ref(); NullImp::staticNull = new NullImp(); NullImp::staticNull->ref(); BooleanImp::staticTrue = new BooleanImp(true); BooleanImp::staticTrue->ref(); BooleanImp::staticFalse = new BooleanImp(false); BooleanImp::staticFalse->ref();}void KJScriptImp::globalClear(){ UndefinedImp::staticUndefined->deref(); UndefinedImp::staticUndefined = 0L; NullImp::staticNull->deref(); NullImp::staticNull = 0L; BooleanImp::staticTrue->deref(); BooleanImp::staticTrue = 0L; BooleanImp::staticFalse->deref(); BooleanImp::staticFalse = 0L;}void KJScriptImp::mark(){ if (exVal && !exVal->marked()) exVal->mark(); if (retVal && !retVal->marked()) retVal->mark(); if (glob.imp()) glob.imp()->mark(); UndefinedImp::staticUndefined->mark(); NullImp::staticNull->mark(); BooleanImp::staticTrue->mark(); BooleanImp::staticFalse->mark();}void KJScriptImp::init(){ KJScriptImp::curr = this; clearException(); retVal = 0L; if (!initialized) { // add this interpreter to the global chain // as a root set for garbage collection if (hook) { prev = hook; next = hook->next; hook->next->prev = this; hook->next = this; } else { hook = next = prev = this; } glob.init(); con = new Context(); firstN = 0L; progN = 0L; recursion = 0; errMsg = ""; initialized = true;#ifdef KJS_DEBUGGER sid = -1;#endif }}void KJScriptImp::clear(){ if ( recursion ) {#ifndef NDEBUG fprintf(stderr, "KJS: ignoring clear() while running\n");#endif return; } KJScriptImp *old = curr; if (initialized) { KJScriptImp::curr = this; Node::setFirstNode(firstNode()); Node::deleteAllNodes(); setFirstNode(0L); setProgNode(0L); clearException(); retVal = 0L; delete con; con = 0L; glob.clear(); Collector::collect(); // remove from global chain (see init()) next->prev = prev; prev->next = next; hook = next; if (hook == this) hook = 0L;#ifdef KJS_DEBUGGER sid = -1;#endif initialized = false; } if (old != this) KJScriptImp::curr = old;}bool KJScriptImp::evaluate(const UChar *code, unsigned int length, const KJSO &thisV, bool onlyCheckSyntax){ init();#ifdef KJS_DEBUGGER sid++; if (debugger()) debugger()->setSourceId(sid);#endif if (recursion > 7) { fprintf(stderr, "KJS: breaking out of recursion\n"); return true; } else if (recursion > 0) {#ifndef NDEBUG fprintf(stderr, "KJS: entering recursion level %d\n", recursion);#endif pushStack(); } assert(Lexer::curr()); Lexer::curr()->setCode(code, length); Node::setFirstNode(firstNode()); int parseError = kjsyyparse(); setFirstNode(Node::firstNode()); if (parseError) { errType = 99; /* TODO */ errLine = Lexer::curr()->lineNo(); errMsg = "Parse error at line " + UString::from(errLine);#ifndef NDEBUG fprintf(stderr, "JavaScript parse error at line %d.\n", errLine);#endif /* TODO: either clear everything or keep previously parsed function definitions */ // Node::deleteAllNodes(); return false; } if (onlyCheckSyntax) return true; clearException(); KJSO oldVar; if (!thisV.isNull()) { context()->setThisValue(thisV); context()->pushScope(thisV); oldVar = context()->variableObject(); context()->setVariableObject(thisV); } running++; recursion++; assert(progNode()); Completion res = progNode()->execute(); recursion--; running--; if (hadException()) { KJSO err = exception(); errType = 99; /* TODO */ errLine = err.get("line").toInt32(); errMsg = err.get("name").toString().value() + ". "; errMsg += err.get("message").toString().value();#ifdef KJS_DEBUGGER if (dbg) dbg->setSourceId(err.get("sid").toInt32());#endif clearException(); } else { errType = 0; errLine = -1; errMsg = ""; // catch return value retVal = 0L; if (res.complType() == ReturnValue || !thisV.isNull()) retVal = res.value().imp(); } if (!thisV.isNull()) { context()->popScope(); context()->setVariableObject(oldVar); } if (progNode()) progNode()->deleteGlobalStatements(); if (recursion > 0) { popStack(); } return !errType;}void KJScriptImp::pushStack(){ stack = stack->push();}void KJScriptImp::popStack(){ stack = stack->pop(); assert(stack);}bool KJScriptImp::call(const KJSO &scope, const UString &func, const List &args){ init(); KJSO callScope(scope); if (callScope.isNull()) callScope = Global::current().imp(); if (!callScope.hasProperty(func)) {#ifndef NDEBUG fprintf(stderr, "couldn't resolve function name %s. call() failed\n", func.ascii());#endif return false; } KJSO v = callScope.get(func); if (!v.isA(ConstructorType)) {#ifndef NDEBUG fprintf(stderr, "%s is not a function. call() failed.\n", func.ascii());#endif return false; } running++; recursion++; static_cast<ConstructorImp*>(v.imp())->executeCall(scope.imp(), &args); recursion--; running--; return !hadException();}bool KJScriptImp::call(const KJSO &func, const KJSO &thisV, const List &args, const List &extraScope){ init(); if(!func.implementsCall()) return false; running++; recursion++; retVal = func.executeCall(thisV, &args, &extraScope).imp(); recursion--; running--; return !hadException();}void KJScriptImp::setException(Imp *e){ assert(curr); curr->exVal = e; curr->exMsg = "Exception"; // not very meaningful but we use !0L to test}void KJScriptImp::setException(const char *msg){ assert(curr); curr->exVal = 0L; // will be created later on exception() curr->exMsg = msg;}KJSO KJScriptImp::exception(){ assert(curr); if (!curr->exMsg) return Undefined(); if (curr->exVal) return curr->exVal; return Error::create(GeneralError, curr->exMsg);}void KJScriptImp::clearException(){ assert(curr); curr->exMsg = 0L; curr->exVal = 0L;}#ifdef KJS_DEBUGGERvoid KJScriptImp::attachDebugger(Debugger *d){ static bool detaching = false; if (detaching) // break circular detaching return; if (dbg) { detaching = true; dbg->detach(); detaching = false; } dbg = d;}bool KJScriptImp::setBreakpoint(int id, int line, bool set){ init(); return Node::setBreakpoint(firstNode(), id, line, set);}#endifbool PropList::contains(const UString &name){ PropList *p = this; while (p) { if (name == p->name) return true; p = p->next; } return false;}bool LabelStack::push(const UString &id){ if (id.isEmpty() || contains(id)) return false; StackElm *newtos = new StackElm; newtos->id = id; newtos->prev = tos; tos = newtos; return true;}bool LabelStack::contains(const UString &id) const{ if (id.isEmpty()) return true; for (StackElm *curr = tos; curr; curr = curr->prev) if (curr->id == id) return true; return false;}void LabelStack::pop(){ if (tos) { StackElm *prev = tos->prev; delete tos; tos = prev; }}LabelStack::~LabelStack(){ StackElm *prev; while (tos) { prev = tos->prev; delete tos; tos = prev; }}// ECMA 15.3.5.3 [[HasInstance]]// see comment in header fileKJSO KJS::hasInstance(const KJSO &F, const KJSO &V){ if (V.isObject()) { KJSO prot = F.get("prototype"); if (!prot.isObject()) return Error::create(TypeError, "Invalid prototype encountered " "in instanceof operation."); Imp *v = V.imp(); while ((v = v->prototype())) { if (v == prot.imp()) return Boolean(true); } } return Boolean(false);}#ifndef NDEBUG#include <stdio.h>void KJS::printInfo( const char *s, const KJSO &o ){ if (o.isNull()) fprintf(stderr, "%s: (null)\n", s); else { KJSO v = o; if (o.isA(ReferenceType)) v = o.getValue(); fprintf(stderr, "JS: %s: %s : %s (%p)\n", s, v.toString().value().ascii(), v.imp()->typeInfo()->name, (void*)v.imp()); if (o.isA(ReferenceType)) { fprintf(stderr, "JS: Was property '%s'\n", o.getPropertyName().ascii()); printInfo("of", o.getBase()); } }}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?