📄 nodes.cpp
字号:
Node::ref(); if ( expr1 ) expr1->ref(); if ( expr2 ) expr2->ref();}bool CommaNode::deref(){ if ( expr1 && expr1->deref() ) delete expr1; if ( expr2 && expr2->deref() ) delete expr2; return Node::deref();}// ECMA 11.14Value CommaNode::evaluate(ExecState *exec){ Value dummy = expr1->evaluate(exec); KJS_CHECKEXCEPTIONVALUE Value v = expr2->evaluate(exec); KJS_CHECKEXCEPTIONVALUE return v;}// ------------------------------ StatListNode ---------------------------------StatListNode::StatListNode(StatementNode *s) : statement(s), list(this){ setLoc(s->firstLine(), s->lastLine(), s->sourceId());} StatListNode::StatListNode(StatListNode *l, StatementNode *s) : statement(s), list(l->list){ l->list = this; setLoc(l->firstLine(), s->lastLine(), l->sourceId());}void StatListNode::ref(){ for (StatListNode *n = this; n; n = n->list) { n->Node::ref(); if (n->statement) n->statement->ref(); }}bool StatListNode::deref(){ StatListNode *next; for (StatListNode *n = this; n; n = next) { next = n->list; if (n->statement && n->statement->deref()) delete n->statement; if (n != this && n->Node::deref()) delete n; } return Node::deref();}// ECMA 12.1Completion StatListNode::execute(ExecState *exec){ Completion c = statement->execute(exec); KJS_ABORTPOINT if (exec->hadException()) { Value ex = exec->exception(); exec->clearException(); return Completion(Throw, ex); } if (c.complType() != Normal) return c; Value v = c.value(); for (StatListNode *n = list; n; n = n->list) { Completion c2 = n->statement->execute(exec); KJS_ABORTPOINT if (c2.complType() != Normal) return c2; if (exec->hadException()) { Value ex = exec->exception(); exec->clearException(); return Completion(Throw, ex); } if (c2.isValueCompletion()) v = c2.value(); c = c2; } return Completion(c.complType(), v, c.target());}void StatListNode::processVarDecls(ExecState *exec){ for (StatListNode *n = this; n; n = n->list) n->statement->processVarDecls(exec);}// ------------------------------ AssignExprNode -------------------------------void AssignExprNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool AssignExprNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 12.2Value AssignExprNode::evaluate(ExecState *exec){ return expr->evaluate(exec);}// ------------------------------ VarDeclNode ----------------------------------VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in) : ident(id), init(in){}void VarDeclNode::ref(){ Node::ref(); if ( init ) init->ref();}bool VarDeclNode::deref(){ if ( init && init->deref() ) delete init; return Node::deref();}// ECMA 12.2Value VarDeclNode::evaluate(ExecState *exec){ Object variable = Object::dynamicCast(exec->context().imp()->variableObject()); Value val; if (init) { val = init->evaluate(exec); KJS_CHECKEXCEPTIONVALUE } else { // already declared? - check with getDirect so you can override // built-in properties of the global object with var declarations. if ( variable.imp()->getDirect(ident) ) return Value(); val = Undefined(); }#ifdef KJS_VERBOSE printInfo(exec,(UString("new variable ")+ident).cstring().c_str(),val);#endif // We use Internal to bypass all checks in derived objects, e.g. so that // "var location" creates a dynamic property instead of activating window.location. variable.put(exec, ident, val, DontDelete | Internal); return String(ident.ustring());}void VarDeclNode::processVarDecls(ExecState *exec){ Object variable = exec->context().imp()->variableObject(); // If a variable by this name already exists, don't clobber it - // it might be a function parameter if (!variable.hasProperty(exec, ident)) { variable.put(exec,ident, Undefined(), DontDelete); }}// ------------------------------ VarDeclListNode ------------------------------void VarDeclListNode::ref(){ for (VarDeclListNode *n = this; n; n = n->list) { n->Node::ref(); if (n->var) n->var->ref(); }}bool VarDeclListNode::deref(){ VarDeclListNode *next; for (VarDeclListNode *n = this; n; n = next) { next = n->list; if (n->var && n->var->deref()) delete n->var; if (n != this && n->Node::deref()) delete n; } return Node::deref();}// ECMA 12.2Value VarDeclListNode::evaluate(ExecState *exec){ for (VarDeclListNode *n = this; n; n = n->list) { n->var->evaluate(exec); KJS_CHECKEXCEPTIONVALUE } return Undefined();}void VarDeclListNode::processVarDecls(ExecState *exec){ for (VarDeclListNode *n = this; n; n = n->list) n->var->processVarDecls(exec);}// ------------------------------ VarStatementNode -----------------------------void VarStatementNode::ref(){ Node::ref(); if ( list ) list->ref();}bool VarStatementNode::deref(){ if ( list && list->deref() ) delete list; return Node::deref();}// ECMA 12.2Completion VarStatementNode::execute(ExecState *exec){ KJS_BREAKPOINT; (void) list->evaluate(exec); // returns 0L KJS_CHECKEXCEPTION return Completion(Normal);}void VarStatementNode::processVarDecls(ExecState *exec){ list->processVarDecls(exec);}// ------------------------------ BlockNode ------------------------------------BlockNode::BlockNode(SourceElementsNode *s){ if (s) { source = s->elements; s->elements = 0; setLoc(s->firstLine(), s->lastLine(), s->sourceId()); } else { source = 0; }}void BlockNode::ref(){ Node::ref(); if ( source ) source->ref();}bool BlockNode::deref(){ if ( source && source->deref() ) delete source; return Node::deref();}// ECMA 12.1Completion BlockNode::execute(ExecState *exec){ if (!source) return Completion(Normal); source->processFuncDecl(exec); return source->execute(exec);}void BlockNode::processVarDecls(ExecState *exec){ if (source) source->processVarDecls(exec);}// ------------------------------ EmptyStatementNode ---------------------------// ECMA 12.3Completion EmptyStatementNode::execute(ExecState */*exec*/){ return Completion(Normal);}// ------------------------------ ExprStatementNode ----------------------------void ExprStatementNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool ExprStatementNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 12.4Completion ExprStatementNode::execute(ExecState *exec){ KJS_BREAKPOINT; Value v = expr->evaluate(exec); KJS_CHECKEXCEPTION return Completion(Normal, v);}// ------------------------------ IfNode ---------------------------------------void IfNode::ref(){ Node::ref(); if ( statement1 ) statement1->ref(); if ( statement2 ) statement2->ref(); if ( expr ) expr->ref();}bool IfNode::deref(){ if ( statement1 && statement1->deref() ) delete statement1; if ( statement2 && statement2->deref() ) delete statement2; if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 12.5Completion IfNode::execute(ExecState *exec){ KJS_BREAKPOINT; Value v = expr->evaluate(exec); KJS_CHECKEXCEPTION bool b = v.toBoolean(exec); // if ... then if (b) return statement1->execute(exec); // no else if (!statement2) return Completion(Normal); // else return statement2->execute(exec);}void IfNode::processVarDecls(ExecState *exec){ statement1->processVarDecls(exec); if (statement2) statement2->processVarDecls(exec);}// ------------------------------ DoWhileNode ----------------------------------void DoWhileNode::ref(){ Node::ref(); if ( statement ) statement->ref(); if ( expr ) expr->ref();}bool DoWhileNode::deref(){ if ( statement && statement->deref() ) delete statement; if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 12.6.1Completion DoWhileNode::execute(ExecState *exec){ KJS_BREAKPOINT; Value be, bv; Completion c; Value value; do { // bail out on error KJS_CHECKEXCEPTION c = statement->execute(exec); 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; } bv = expr->evaluate(exec); KJS_CHECKEXCEPTION } while (bv.toBoolean(exec)); return Completion(Normal, value);}void DoWhileNode::processVarDecls(ExecState *exec){ statement->processVarDecls(exec);}// ------------------------------ WhileNode ------------------------------------void WhileNode::ref(){ Node::ref(); if ( statement ) statement->ref(); if ( expr ) expr->ref();}bool WhileNode::deref(){ if ( statement && statement->deref() ) delete statement; if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 12.6.2Completion WhileNode::execute(ExecState *exec){ KJS_BREAKPOINT; Value be, bv; Completion c; bool b(false); Value value; while (1) { bv = expr->evaluate(exec); KJS_CHECKEXCEPTION b = bv.toBoolean(exec); // bail out on error KJS_CHECKEXCEPTION if (!b) return Completion(Normal, value); c = statement->execute(exec); 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; }}void WhileNode::processVarDecls(ExecState *exec){ statement->processVarDecls(exec);}// ------------------------------ ForNode --------------------------------------void ForNode::ref(){ Node::ref(); if ( statement ) statement->ref(); if ( expr1 ) expr1->ref(); if ( expr2 ) expr2->ref(); if ( expr3 ) expr3->ref();}bool ForNode::deref(){ if ( statement && statement->deref() ) delete statement; if ( expr1 && expr1->deref() ) delete expr1; if ( expr2 && expr2->deref() ) delete expr2; if ( expr3 && expr3->deref() ) delete expr3; return Node::deref();}// ECMA 12.6.3Completion ForNode::execute(ExecState *exec){ Value e, v, cval; bool b; if (expr1) { v = expr1->evaluate(exec); KJS_CHECKEXCEPTION } while (1) { if (expr2) { v = expr2->evaluate(exec); KJS_CHECKEXCEPTION b = v.toBoolean(exec); if (b == false) return Completion(Normal, cval); } // bail out on error KJS_CHECKEXCEPTION Completion c = statement->execute(exec); 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) { v = expr3->evaluate(exec); KJS_CHECKEXCEPTION } }}void ForNode::processVarDecls(ExecState *exec){ if (expr1) expr1->processVarDecls(exec); statement->processVarDecls(exec);}// ------------------------------ ForInNode ------------------------------------ForInNode::ForInNode(Node *l, Node *e, StatementNode *s) : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s){}ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s) : ident(i), init(in), expr(e), statement(s){ // for( var foo = bar in baz ) varDecl = new VarDeclNode(ident, init); lexpr = new ResolveNode(ident);}void ForInNode::ref(){ Node::ref(); if ( statement ) statement->ref(); if ( expr ) expr->ref(); if ( lexpr ) lexpr->ref(); if ( init ) init->ref(); if ( varDecl ) varDecl->ref();}bool ForInNode::deref(){ if ( statement && statement->deref() ) delete statement; if ( expr && expr->deref() ) delete expr; if ( lexpr && lexpr->deref() ) delete lexpr; if ( init && init->deref() ) delete init; if ( varDecl && varDecl->deref() ) delete varDecl; return Node::deref();}// ECMA 12.6.4Completion ForInNode::execute(ExecState *exec){ Value e, retval; Object v; Completion c; ReferenceList propList; if ( varDecl ) { varDecl->evaluate(exec); KJS_CHECKEXCEPTION } e = expr->evaluate(exec); // for Null and Undefined, we want to make sure not to go through // the loop at all, because their object wrappers will have a // property list but will throw an exception if you attempt to // access any property. if (e.type() == UndefinedType || e.type() == NullType) { return Completion(Normal, retval); } KJS_CHECKEXCEPTION v = e.toObject(exec); propList = v.propList(exec); ReferenceListIterator propIt = propList.begin(); while (propIt != propList.end()) { Identifier name = propIt->getPropertyName(exec); if (!v.hasProperty(exec,name)) { propIt++; continue; } Reference ref = lexpr->evaluateReference(exec); KJS_CHECKEXCEPTION ref.putValue(exec, String(name.ustring())); c = statement->execute(exec); 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) { return c; } } propIt++; } // bail out on error KJS_CHECKEXCEPTION return Completion(Normal, retval);}void ForInNode::processVarDecls(ExecState *exec){ statement->processVarDecls(exec);}// ------------------------------ ContinueNode ---------------------------------// ECMA 12.7Completion ContinueNode::execute(ExecState *exec){ KJS_BREAKPOINT; Value dummy; return exec->context().imp()->seenLabels()->contains(ident) ? Completion(Continue, dummy, ident) : Completion(Throw, throwError(exec, SyntaxError, "Label %s not found in containing block. Can't continue.", ident));}// ------------------------------ BreakNode ------------------------------------// ECMA 12.8Completion BreakNode::execute(ExecState *exec){ KJS_BREAKPOINT; Value dummy; return exec->context().imp()->seenLabels()->contains(ident) ? Completion(Break, dummy, ident) : Completion(Throw, throwError(exec, SyntaxError, "Label %s not found in containing block. Can't break.", ident));}// ------------------------------ ReturnNode -----------------------------------void ReturnNode::ref(){ Node::ref();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -