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 + -
显示快捷键?