📄 nodes.cpp
字号:
}// ECMA 11.4.8KJSO BitwiseNotNode::evaluate(){ KJSO e = expr->evaluate(); KJSO v = e.getValue(); int i32 = v.toInt32(); return Number(~i32);}// ECMA 11.4.9KJSO LogicalNotNode::evaluate(){ KJSO e = expr->evaluate(); KJSO v = e.getValue(); Boolean b = v.toBoolean(); return Boolean(!b.value());}// ECMA 11.5KJSO MultNode::evaluate(){ KJSO t1 = term1->evaluate(); KJSO v1 = t1.getValue(); KJSO t2 = term2->evaluate(); KJSO v2 = t2.getValue(); return mult(v1, v2, oper);}// ECMA 11.7KJSO ShiftNode::evaluate(){ KJSO t1 = term1->evaluate(); KJSO v1 = t1.getValue(); KJSO t2 = term2->evaluate(); KJSO v2 = t2.getValue(); unsigned int i2 = v2.toUInt32(); i2 &= 0x1f; long result; switch (oper) { case OpLShift: result = v1.toInt32() << i2; break; case OpRShift: result = v1.toInt32() >> i2; break; case OpURShift: result = v1.toUInt32() >> i2; break; default: assert(!"ShiftNode: unhandled switch case"); result = 0L; } return Number(static_cast<double>(result));}// ECMA 11.6KJSO AddNode::evaluate(){ KJSO t1 = term1->evaluate(); KJSO v1 = t1.getValue(); KJSO t2 = term2->evaluate(); KJSO v2 = t2.getValue(); return add(v1, v2, oper);}// ECMA 11.14KJSO CommaNode::evaluate(){ KJSO e = expr1->evaluate(); KJSO dummy = e.getValue(); // ignore return value e = expr2->evaluate(); return e.getValue();}// ECMA 12.1Completion BlockNode::execute(){ if (!statlist) return Completion(Normal); return statlist->execute();}// ECMA 12.1Completion StatListNode::execute(){ if (!list) { Completion c = statement->execute(); KJS_ABORTPOINT if (KJScriptImp::hadException()) { KJSO ex = KJScriptImp::exception(); KJScriptImp::clearException(); return Completion(Throw, ex); } else return c; } Completion l = list->execute(); KJS_ABORTPOINT if (l.complType() != Normal) return l; Completion e = statement->execute(); KJS_ABORTPOINT; if (KJScriptImp::hadException()) { KJSO ex = KJScriptImp::exception(); KJScriptImp::clearException(); return Completion(Throw, ex); } KJSO v = e.isValueCompletion() ? e.value() : l.value(); return Completion(e.complType(), v, e.target() );}// ECMA 12.2Completion VarStatementNode::execute(){ KJS_BREAKPOINT; (void) list->evaluate(); // returns 0L return Completion(Normal);}// ECMA 12.2KJSO VarDeclNode::evaluate(){ KJSO variable = Context::current()->variableObject(); KJSO val, tmp; if (init) { tmp = init->evaluate(); val = tmp.getValue(); } else { if ( variable.hasProperty( ident ) ) // already declared ? return KJSO(); val = Undefined(); } variable.put(ident, val, DontDelete); // spec wants to return ident. But what for ? Will be ignored above. return KJSO();}// ECMA 12.2KJSO VarDeclListNode::evaluate(){ if (list) (void) list->evaluate(); (void) var->evaluate(); return KJSO();}// ECMA 12.2KJSO AssignExprNode::evaluate(){ return expr->evaluate();}// ECMA 12.3Completion EmptyStatementNode::execute(){ return Completion(Normal);}// ECMA 12.6.3Completion ForNode::execute(){ KJSO e, v, cval; Boolean b; if (expr1) { e = expr1->evaluate(); v = e.getValue(); } while (1) { if (expr2) { e = expr2->evaluate(); v = e.getValue(); b = v.toBoolean(); if (b.value() == false) return Completion(Normal, cval); } // bail out on error if (KJScriptImp::hadException()) return Completion(Throw, KJScriptImp::exception()); Completion c = stat->execute(); if (c.isValueCompletion()) cval = c.value(); if (!((c.complType() == Continue) && ls.contains(c.target()))) { if ((c.complType() == Break) && ls.contains(c.target())) return Completion(Normal, cval); if (c.complType() != Normal) return c; } if (expr3) { e = expr3->evaluate(); v = e.getValue(); } }}// ECMA 12.6.4Completion ForInNode::execute(){ KJSO e, v, retval; Completion c; VarDeclNode *vd = 0; const PropList *lst, *curr; // This should be done in the constructor if (!lexpr) { // for( var foo = bar in baz ) vd = new VarDeclNode(&ident, init); vd->evaluate(); lexpr = new ResolveNode(&ident); } e = expr->evaluate(); v = e.getValue().toObject(); curr = lst = v.imp()->propList(); while (curr) { if (!v.hasProperty(curr->name)) { curr = curr->next; continue; } e = lexpr->evaluate(); e.putValue(String(curr->name)); c = stat->execute(); if (c.isValueCompletion()) retval = c.value(); if (!((c.complType() == Continue) && ls.contains(c.target()))) { if ((c.complType() == Break) && ls.contains(c.target())) break; if (c.complType() != Normal) { delete lst; return c; } } curr = curr->next; } delete lst; return Completion(Normal, retval);}// ECMA 12.4Completion ExprStatementNode::execute(){ KJS_BREAKPOINT; KJSO e = expr->evaluate(); KJSO v = e.getValue(); return Completion(Normal, v);}// ECMA 12.5Completion IfNode::execute(){ KJS_BREAKPOINT; KJSO e = expr->evaluate(); KJSO v = e.getValue(); Boolean b = v.toBoolean(); // if ... then if (b.value()) return statement1->execute(); // no else if (!statement2) return Completion(Normal); // else return statement2->execute();}// ECMA 12.6.1Completion DoWhileNode::execute(){ KJS_BREAKPOINT; KJSO be, bv; Completion c; KJSO value; do { // bail out on error if (KJScriptImp::hadException()) return Completion(Throw, KJScriptImp::exception()); c = statement->execute(); if (!((c.complType() == Continue) && ls.contains(c.target()))) { if ((c.complType() == Break) && ls.contains(c.target())) return Completion(Normal, value); if (c.complType() != Normal) return c; } be = expr->evaluate(); bv = be.getValue(); } while (bv.toBoolean().value()); return Completion(Normal, value);}// ECMA 12.6.2Completion WhileNode::execute(){ KJS_BREAKPOINT; KJSO be, bv; Completion c; Boolean b(false); KJSO value; while (1) { be = expr->evaluate(); bv = be.getValue(); b = bv.toBoolean(); // bail out on error if (KJScriptImp::hadException()) return Completion(Throw, KJScriptImp::exception()); if (!b.value()) return Completion(Normal, value); c = statement->execute(); if (c.isValueCompletion()) value = c.value(); if ((c.complType() == Continue) && ls.contains(c.target())) continue; if ((c.complType() == Break) && ls.contains(c.target())) return Completion(Normal, value); if (c.complType() != Normal) return c; }}// ECMA 12.7Completion ContinueNode::execute(){ KJS_BREAKPOINT; KJSO dummy; return Context::current()->seenLabels()->contains(ident) ? Completion(Continue, dummy, ident) : Completion(Throw, throwError(SyntaxError, "Label not found in containing block"));}// ECMA 12.8Completion BreakNode::execute(){ KJS_BREAKPOINT; KJSO dummy; return Context::current()->seenLabels()->contains(ident) ? Completion(Break, dummy, ident) : Completion(Throw, throwError(SyntaxError, "Label not found in containing block"));}// ECMA 12.9Completion ReturnNode::execute(){ KJS_BREAKPOINT; if (!value) return Completion(ReturnValue, Undefined()); KJSO e = value->evaluate(); KJSO v = e.getValue(); return Completion(ReturnValue, v);}// ECMA 12.10Completion WithNode::execute(){ KJS_BREAKPOINT; KJSO e = expr->evaluate(); KJSO v = e.getValue(); Object o = v.toObject(); Context::current()->pushScope(o); Completion res = stat->execute(); Context::current()->popScope(); return res;}// ECMA 12.11ClauseListNode* ClauseListNode::append(CaseClauseNode *c){ ClauseListNode *l = this; while (l->nx) l = l->nx; l->nx = new ClauseListNode(c); return this;}// ECMA 12.11Completion SwitchNode::execute(){ KJS_BREAKPOINT; KJSO e = expr->evaluate(); KJSO v = e.getValue(); Completion res = block->evalBlock(v); if ((res.complType() == Break) && ls.contains(res.target())) return Completion(Normal, res.value()); else return res;}// ECMA 12.11Completion CaseBlockNode::evalBlock(const KJSO& input){ KJSO v; Completion res; ClauseListNode *a = list1, *b = list2; CaseClauseNode *clause; if (a) { while (a) { clause = a->clause(); a = a->next(); v = clause->evaluate(); if (strictEqual(input, v)) { res = clause->evalStatements(); if (res.complType() != Normal) return res; while (a) { res = a->clause()->evalStatements(); if (res.complType() != Normal) return res; a = a->next(); } break; } } } while (b) { clause = b->clause(); b = b->next(); v = clause->evaluate(); if (strictEqual(input, v)) { res = clause->evalStatements(); if (res.complType() != Normal) return res; goto step18; } } // default clause if (def) { res = def->evalStatements(); if (res.complType() != Normal) return res; } b = list2; step18: while (b) { clause = b->clause(); res = clause->evalStatements(); if (res.complType() != Normal) return res; b = b->next(); } return Completion(Normal);}// ECMA 12.11KJSO CaseClauseNode::evaluate(){ KJSO e = expr->evaluate(); KJSO v = e.getValue(); return v;}// ECMA 12.11Completion CaseClauseNode::evalStatements(){ if (list) return list->execute(); else return Completion(Normal, Undefined());}// ECMA 12.12Completion LabelNode::execute(){ Completion e; if (!Context::current()->seenLabels()->push(label)) { return Completion( Throw, throwError(SyntaxError, "Duplicated label found" )); }; e = stat->execute(); Context::current()->seenLabels()->pop(); if ((e.complType() == Break) && (e.target() == label)) return Completion(Normal, e.value()); else return e;}// ECMA 12.13Completion ThrowNode::execute(){ KJS_BREAKPOINT; KJSO v = expr->evaluate().getValue(); return Completion(Throw, v);}// ECMA 12.14Completion TryNode::execute(){ KJS_BREAKPOINT; Completion c, c2; c = block->execute(); if (!_final) { if (c.complType() != Throw) return c; return _catch->execute(c.value()); } if (!_catch) { c2 = _final->execute(); return (c2.complType() == Normal) ? c : c2; } if (c.complType() == Throw) c = _catch->execute(c.value()); c2 = _final->execute(); return (c2.complType() == Normal) ? c : c2;}Completion CatchNode::execute(){ // should never be reached. execute(const KJS &arg) is used instead assert(0L); return Completion();}// ECMA 12.14Completion CatchNode::execute(const KJSO &arg){ /* TODO: correct ? Not part of the spec */ KJScriptImp::clearException(); Object obj; obj.put(ident, arg, DontDelete); Context::current()->pushScope(obj); Completion c = block->execute(); Context::current()->popScope(); return c;}// ECMA 12.14Completion FinallyNode::execute(){ return block->execute();}FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s) : source(s){#ifdef KJS_DEBUGGER setLoc(-1, -1);#endif}// ECMA 13 + 14 for ProgramNodeCompletion FunctionBodyNode::execute(){ /* TODO: workaround for empty body which I don't see covered by the spec */ if (!source) return Completion(ReturnValue, Undefined()); source->processFuncDecl(); return source->execute();}// ECMA 13void FuncDeclNode::processFuncDecl(){ const List *sc = Context::current()->pScopeChain(); /* TODO: let this be an object with [[Class]] property "Function" */ FunctionImp *fimp = new DeclaredFunctionImp(ident, body, sc); Function func(fimp); // protect from GC fimp->put("prototype", Object::create(ObjectClass), DontDelete); int plen = 0; for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++) fimp->addParameter(p->ident()); fimp->setLength(plen); Context::current()->variableObject().put(ident, func);}// ECMA 13KJSO FuncExprNode::evaluate(){ const List *sc = Context::current()->pScopeChain(); FunctionImp *fimp = new DeclaredFunctionImp(UString::null, body, sc->copy()); Function ret(fimp); int plen = 0; for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++) fimp->addParameter(p->ident()); fimp->setLength(plen); return ret;}ParameterNode* ParameterNode::append(const UString *i){ ParameterNode *p = this; while (p->next) p = p->next; p->next = new ParameterNode(i); return this;}// ECMA 13KJSO ParameterNode::evaluate(){ return Undefined();}void ProgramNode::deleteGlobalStatements(){ source->deleteStatements();}// ECMA 14Completion SourceElementsNode::execute(){ if (KJScriptImp::hadException()) return Completion(Throw, KJScriptImp::exception()); if (!elements) return element->execute(); Completion c1 = elements->execute(); if (KJScriptImp::hadException()) return Completion(Throw, KJScriptImp::exception()); if (c1.complType() != Normal) return c1; Completion c2 = element->execute(); if (KJScriptImp::hadException()) return Completion(Throw, KJScriptImp::exception()); return c2;}// ECMA 14void SourceElementsNode::processFuncDecl(){ if (elements) elements->processFuncDecl(); element->processFuncDecl();}void SourceElementsNode::deleteStatements(){ element->deleteStatements(); if (elements) elements->deleteStatements();}// ECMA 14Completion SourceElementNode::execute(){ if (statement) return statement->execute(); return Completion(Normal);}// ECMA 14void SourceElementNode::processFuncDecl(){ if (function) function->processFuncDecl();}void SourceElementNode::deleteStatements(){ delete statement;}ArgumentListNode::ArgumentListNode(Node *e) : list(0L), expr(e) {}VarDeclNode::VarDeclNode(const UString *id, AssignExprNode *in) : ident(*id), init(in) { }ArgumentListNode::ArgumentListNode(ArgumentListNode *l, Node *e) : list(l), expr(e) {}ArgumentsNode::ArgumentsNode(ArgumentListNode *l) : list(l) {}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -