nodes.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 3,000 行 · 第 1/5 页
CPP
3,000 行
return s;}// ----------------------------- AccessorNode1 --------------------------------void AccessorNode1::ref(){ Node::ref(); if ( expr1 ) expr1->ref(); if ( expr2 ) expr2->ref();}bool AccessorNode1::deref(){ if ( expr1 && expr1->deref() ) delete expr1; if ( expr2 && expr2->deref() ) delete expr2; return Node::deref();}// ECMA 11.2.1aReference AccessorNode1::evaluateReference(ExecState *exec) const{ Value v1 = expr1->evaluate(exec); KJS_CHECKEXCEPTIONREFERENCE Value v2 = expr2->evaluate(exec); KJS_CHECKEXCEPTIONREFERENCE#ifndef NDEBUG // catch errors before being caught in toObject(). better error message. if (v1.isA(UndefinedType) || v1.isA(NullType)) { UString s = "Attempted to access property on %s object " "(result of expression %s)"; (void)throwError(exec, TypeError, s.cstring().c_str(), v1, this); return Reference::makeValueReference(Undefined()); }#endif Object o = v1.toObject(exec); unsigned i; if (v2.toUInt32(i)) return Reference(o, i); UString s = v2.toString(exec); return Reference(o, Identifier(s));}// ----------------------------- AccessorNode2 --------------------------------void AccessorNode2::ref(){ Node::ref(); if ( expr ) expr->ref();}bool AccessorNode2::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.2.1bReference AccessorNode2::evaluateReference(ExecState *exec) const{ Value v = expr->evaluate(exec); KJS_CHECKEXCEPTIONREFERENCE assert(v.isValid());#ifndef NDEBUG // catch errors before being caught in toObject(). better error message. if (v.isA(UndefinedType) || v.isA(NullType)) { UString s = "Attempted to access '" + ident.ustring() + "' property on %s object (result of expression %s)"; (void)throwError(exec, TypeError, s.cstring().c_str(), v, this); return Reference::makeValueReference(Undefined()); }#endif Object o = v.toObject(exec); return Reference(o, ident);}// ----------------------------- ArgumentListNode -----------------------------void ArgumentListNode::ref(){ for (ArgumentListNode *n = this; n; n = n->list) { n->Node::ref(); if (n->expr) n->expr->ref(); }}bool ArgumentListNode::deref(){ ArgumentListNode *next; for (ArgumentListNode *n = this; n; n = next) { next = n->list; if (n->expr && n->expr->deref()) delete n->expr; if (n != this && n->Node::deref()) delete n; } return Node::deref();}Value ArgumentListNode::evaluate(ExecState * /*exec*/) const{ assert(0); return Value(); // dummy, see evaluateList()}// ECMA 11.2.4List ArgumentListNode::evaluateList(ExecState *exec) const{ List l; for (const ArgumentListNode *n = this; n; n = n->list) { Value v = n->expr->evaluate(exec); KJS_CHECKEXCEPTIONLIST l.append(v); } return l;}// ----------------------------- ArgumentsNode --------------------------------void ArgumentsNode::ref(){ Node::ref(); if ( list ) list->ref();}bool ArgumentsNode::deref(){ if ( list && list->deref() ) delete list; return Node::deref();}Value ArgumentsNode::evaluate(ExecState * /*exec*/) const{ assert(0); return Value(); // dummy, see evaluateList()}// ECMA 11.2.4List ArgumentsNode::evaluateList(ExecState *exec) const{ if (!list) return List(); return list->evaluateList(exec);}// ----------------------------- NewExprNode ----------------------------------// ECMA 11.2.2void NewExprNode::ref(){ Node::ref(); if ( expr ) expr->ref(); if ( args ) args->ref();}bool NewExprNode::deref(){ if ( expr && expr->deref() ) delete expr; if ( args && args->deref() ) delete args; return Node::deref();}Value NewExprNode::evaluate(ExecState *exec) const{ Value v = expr->evaluate(exec); KJS_CHECKEXCEPTIONVALUE List argList; if (args) { argList = args->evaluateList(exec); KJS_CHECKEXCEPTIONVALUE } if (v.type() != ObjectType) { return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr); } Object constr = Object(static_cast<ObjectImp*>(v.imp())); if (!constr.implementsConstruct()) { return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr); } Value res = constr.construct(exec,argList); return res;}// ----------------------------- FunctionCallNode -----------------------------void FunctionCallNode::ref(){ Node::ref(); if ( expr ) expr->ref(); if ( args ) args->ref();}bool FunctionCallNode::deref(){ if ( expr && expr->deref() ) delete expr; if ( args && args->deref() ) delete args; return Node::deref();}// ECMA 11.2.3Value FunctionCallNode::evaluate(ExecState *exec) const{ Reference ref = expr->evaluateReference(exec); KJS_CHECKEXCEPTIONVALUE List argList = args->evaluateList(exec); KJS_CHECKEXCEPTIONVALUE Value v = ref.getValue(exec); KJS_CHECKEXCEPTIONVALUE if (v.type() != ObjectType) { return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be called.", v, expr); } Object func = Object(static_cast<ObjectImp*>(v.imp())); if (!func.implementsCall()) { return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr); } Value thisVal; if (ref.isMutable()) thisVal = ref.getBase(exec); else thisVal = Null(); if (thisVal.type() == ObjectType && Object::dynamicCast(thisVal).inherits(&ActivationImp::info)) thisVal = Null(); if (thisVal.type() != ObjectType) { // ECMA 11.2.3 says that in this situation the this value should be null. // However, section 10.2.3 says that in the case where the value provided // by the caller is null, the global object should be used. It also says // that the section does not apply to interal functions, but for simplicity // of implementation we use the global object anyway here. This guarantees // that in host objects you always get a valid object for this. // thisVal = Null(); thisVal = exec->dynamicInterpreter()->globalObject(); } Object thisObj = Object::dynamicCast(thisVal); Value result = func.call(exec,thisObj, argList); return result;}// ----------------------------- PostfixNode ----------------------------------void PostfixNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool PostfixNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.3Value PostfixNode::evaluate(ExecState *exec) const{ Reference ref = expr->evaluateReference(exec); KJS_CHECKEXCEPTIONVALUE Value v = ref.getValue(exec); double n = v.toNumber(exec); double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1; ref.putValue(exec, Number(newValue)); return Number(n);}// ----------------------------- DeleteNode -----------------------------------void DeleteNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool DeleteNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.1Value DeleteNode::evaluate(ExecState *exec) const{ Reference ref = expr->evaluateReference(exec); KJS_CHECKEXCEPTIONVALUE return Boolean(ref.deleteValue(exec));}// ----------------------------- VoidNode -------------------------------------void VoidNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool VoidNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.2Value VoidNode::evaluate(ExecState *exec) const{ Value dummy1 = expr->evaluate(exec); KJS_CHECKEXCEPTIONVALUE return Undefined();}// ----------------------------- TypeOfNode -----------------------------------void TypeOfNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool TypeOfNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.3Value TypeOfNode::evaluate(ExecState *exec) const{ const char *s = 0L; Reference ref = expr->evaluateReference(exec); KJS_CHECKEXCEPTIONVALUE if (ref.isMutable()) { Value b = ref.getBase(exec); if (b.type() == NullType) return String("undefined"); } Value v = ref.getValue(exec); switch (v.type()) { case UndefinedType: s = "undefined"; break; case NullType: s = "object"; break; case BooleanType: s = "boolean"; break; case NumberType: s = "number"; break; case StringType: s = "string"; break; default: if (v.type() == ObjectType && static_cast<ObjectImp*>(v.imp())->implementsCall()) s = "function"; else s = "object"; break; } return String(s);}// ----------------------------- PrefixNode -----------------------------------void PrefixNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool PrefixNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.4 and 11.4.5Value PrefixNode::evaluate(ExecState *exec) const{ Reference ref = expr->evaluateReference(exec); KJS_CHECKEXCEPTION Value v = ref.getValue(exec); double n = v.toNumber(exec); double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1; Value n2 = Number(newValue); ref.putValue(exec,n2); return n2;}// ----------------------------- UnaryPlusNode --------------------------------void UnaryPlusNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool UnaryPlusNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.6double UnaryPlusNode::toNumber(ExecState *exec) const{ return expr->toNumber(exec);}// could goValue UnaryPlusNode::evaluate(ExecState *exec) const{ Value v = expr->evaluate(exec); KJS_CHECKEXCEPTIONVALUE return Number(v.toNumber(exec)); /* TODO: optimize */}// ----------------------------- NegateNode -----------------------------------void NegateNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool NegateNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.7double NegateNode::toNumber(ExecState *exec) const{ return -expr->toNumber(exec);}Value NegateNode::evaluate(ExecState *exec) const{ Value v = expr->evaluate(exec); KJS_CHECKEXCEPTIONVALUE double d = -v.toNumber(exec); return Number(d);}// ----------------------------- BitwiseNotNode -------------------------------void BitwiseNotNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool BitwiseNotNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.8Value BitwiseNotNode::evaluate(ExecState *exec) const{ Value v = expr->evaluate(exec); KJS_CHECKEXCEPTIONVALUE int i32 = v.toInt32(exec); return Number(~i32);}// ----------------------------- LogicalNotNode -------------------------------void LogicalNotNode::ref(){ Node::ref(); if ( expr ) expr->ref();}bool LogicalNotNode::deref(){ if ( expr && expr->deref() ) delete expr; return Node::deref();}// ECMA 11.4.9bool LogicalNotNode::toBoolean(ExecState *exec) const{ return !expr->toBoolean(exec);}// could remove thisValue LogicalNotNode::evaluate(ExecState *exec) const{ bool b = expr->toBoolean(exec); KJS_CHECKEXCEPTIONVALUE return Boolean(!b);}// ----------------------------- MultNode -------------------------------------void MultNode::ref(){ Node::ref(); if ( term1 ) term1->ref(); if ( term2 ) term2->ref();}bool MultNode::deref(){ if ( term1 && term1->deref() ) delete term1; if ( term2 && term2->deref() ) delete term2; return Node::deref();}// ECMA 11.5Value MultNode::evaluate(ExecState *exec) const{ Value v1 = term1->evaluate(exec); KJS_CHECKEXCEPTIONVALUE Value v2 = term2->evaluate(exec); KJS_CHECKEXCEPTIONVALUE return mult(exec,v1, v2, oper);}// ----------------------------- AddNode --------------------------------------// factory for an appropriate addition or substraction nodeNode* AddNode::create(Node *t1, Node *t2, char op){ // ### many more combinations to check for // fold constants
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?