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