⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nodes.cpp

📁 将konqueror浏览器移植到ARM9 2410中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* *  This file is part of the KDE libraries *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Library General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Library General Public License for more details. * *  You should have received a copy of the GNU Library General Public License *  along with this library; see the file COPYING.LIB.  If not, write to *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330, *  Boston, MA 02111-1307, USA. */#include "nodes.h"#include <assert.h>#include <stdio.h>#include <math.h>#include "kjs.h"#include "ustring.h"#include "lexer.h"#include "types.h"#include "internal.h"#include "operations.h"#include "regexp_object.h"#include "debugger.h"using namespace KJS;#ifdef KJS_DEBUGGER#define KJS_BREAKPOINT if (!hitStatement()) return Completion(Normal);#define KJS_ABORTPOINT if (abortStatement()) return Completion(Normal);#else#define KJS_BREAKPOINT#define KJS_ABORTPOINT#endifint   Node::nodeCount = 0;Node* Node::first = 0;Node::Node(){  assert(Lexer::curr());  line = Lexer::curr()->lineNo();  nodeCount++;  //  cout << "Node()" << endl;  // create a list of allocated objects. Makes  // deleting (even after a parse error) quite easy  next = first;  prev = 0L;  if (first)    first->prev = this;  first = this;}Node::~Node(){  //  cout << "~Node()" << endl;  if (next)    next->prev = prev;  if (prev)    prev->next = next;  nodeCount--;}void Node::deleteAllNodes(){  Node *tmp, *n = first;  while ((tmp = n)) {    n = n->next;    delete tmp;  }  first = 0L;  //  assert(nodeCount == 0);}KJSO Node::throwError(ErrorType e, const char *msg){  return Error::create(e, msg, lineNo());}#ifdef KJS_DEBUGGERvoid StatementNode::setLoc(int line0, int line1){    l0 = line0;    l1 = line1;    sid = KJScriptImp::current()->sourceId();}bool StatementNode::hitStatement(){  if (KJScriptImp::current()->debugger())    return KJScriptImp::current()->debugger()->hit(firstLine(), breakPoint);  else    return true;}// return true if the debugger wants us to stop at this pointbool StatementNode::abortStatement(){  if (KJScriptImp::current()->debugger() &&      KJScriptImp::current()->debugger()->mode() == Debugger::Stop)      return true;  return false;}bool Node::setBreakpoint(Node *firstNode, int id, int line, bool set){  while (firstNode) {    if (firstNode->setBreakpoint(id, line, set) && line >= 0) // line<0 for all      return true;    firstNode = firstNode->next;  }  return false;}/** * Try to set or delete a breakpoint depending on the value of set. * The call will return true if successful, i.e. if line is inside * of the statement's range. Additionally, a breakpoint had to * be set already if you tried to delete with set=false. */bool StatementNode::setBreakpoint(int id, int line, bool set){  // in our source unit and line range ?  if (id != sid || ((line < l0 || line > l1) && line >= 0))    return false;  if (!set && !breakPoint)    return false;  breakPoint = set;  return true;}#endifKJSO NullNode::evaluate(){  return Null();}KJSO BooleanNode::evaluate(){  return Boolean(value);}KJSO NumberNode::evaluate(){  return Number(value);}KJSO StringNode::evaluate(){  return String(value);}KJSO RegExpNode::evaluate(){  List list;  String p(pattern);  String f(flags);  list.append(p);  list.append(f);  // very ugly  KJSO r = Global::current().get("RegExp");  RegExpObject *r2 = (RegExpObject*)r.imp();  return r2->construct(list);}// ECMA 11.1.1KJSO ThisNode::evaluate(){  return Context::current()->thisValue();}// ECMA 11.1.2 & 10.1.4KJSO ResolveNode::evaluate(){  assert(Context::current());  const List *chain = Context::current()->pScopeChain();  assert(chain);  ListIterator scope = chain->begin();  while (scope != chain->end()) {    if (scope->hasProperty(ident)) {//        cout << "Resolve: found '" << ident.ascii() << "'"// 	    << " type " << scope->get(ident).imp()->typeInfo()->name << endl;      return Reference(*scope, ident);    }    scope++;  }  // identifier not found//  cout << "Resolve: didn't find '" << ident.ascii() << "'" << endl;  return Reference(Null(), ident);}// ECMA 11.1.4KJSO ArrayNode::evaluate(){  KJSO array;  int length;  int elisionLen = elision ? elision->evaluate().toInt32() : 0;  if (element) {    array = element->evaluate();    length = opt ? array.get("length").toInt32() : 0;  } else {    array = Object::create(ArrayClass);    length = 0;  }  if (opt)    array.put("length", Number(elisionLen + length), DontEnum | DontDelete);  return array;}// ECMA 11.1.4KJSO ElementNode::evaluate(){  KJSO array, val;  int length = 0;  int elisionLen = elision ? elision->evaluate().toInt32() : 0;  if (list) {    array = list->evaluate();    val = node->evaluate().getValue();    length = array.get("length").toInt32();  } else {    array = Object::create(ArrayClass);    val = node->evaluate().getValue();  }  array.putArrayElement(UString::from(elisionLen + length), val);  return array;}// ECMA 11.1.4KJSO ElisionNode::evaluate(){  if (elision)    return Number(elision->evaluate().toNumber().value() + 1);  else    return Number(1);}// ECMA 11.1.5KJSO ObjectLiteralNode::evaluate(){  if (list)    return list->evaluate();  return Object::create(ObjectClass);}// ECMA 11.1.5KJSO PropertyValueNode::evaluate(){  KJSO obj;  if (list)    obj = list->evaluate();  else    obj = Object::create(ObjectClass);  KJSO n = name->evaluate();  KJSO a = assign->evaluate();  KJSO v = a.getValue();  obj.put(n.toString().value(), v);  return obj;}// ECMA 11.1.5KJSO PropertyNode::evaluate(){  KJSO s;  if (str.isNull()) {    s = String(UString::from(numeric));  } else    s = String(str);  return s;}// ECMA 11.1.6KJSO GroupNode::evaluate(){  return group->evaluate();}// ECMA 11.2.1aKJSO AccessorNode1::evaluate(){  KJSO e1 = expr1->evaluate();  KJSO v1 = e1.getValue();  KJSO e2 = expr2->evaluate();  KJSO v2 = e2.getValue();  Object o = v1.toObject();  String s = v2.toString();  return Reference(o, s.value());}// ECMA 11.2.1bKJSO AccessorNode2::evaluate(){  KJSO e = expr->evaluate();  KJSO v = e.getValue();  KJSO o = v.toObject();  return Reference(o, ident);}// ECMA 11.2.2KJSO NewExprNode::evaluate(){  KJSO e = expr->evaluate();  KJSO v = e.getValue();  List *argList = args ? args->evaluateList() : 0;  if (!v.isObject()) {    delete argList;    return throwError(TypeError, "Expression is no object. Cannot be new'ed");  }  Constructor constr = Constructor::dynamicCast(v);  if (constr.isNull()) {    delete argList;    return throwError(TypeError, "Expression is no constructor.");  }  if (!argList)    argList = new List;  KJSO res = constr.construct(*argList);  delete argList;  return res;}// ECMA 11.2.3KJSO FunctionCallNode::evaluate(){  KJSO e = expr->evaluate();  List *argList = args->evaluateList();  KJSO v = e.getValue();  if (!v.isObject()) {#ifndef NDEBUG    printInfo("Failed function call attempt on", e);#endif    delete argList;    return throwError(TypeError, "Expression is no object. Cannot be called.");  }  if (!v.implementsCall()) {#ifndef NDEBUG    printInfo("Failed function call attempt on", e);#endif    delete argList;    return throwError(TypeError, "Expression does not allow calls.");  }  KJSO o;  if (e.isA(ReferenceType))    o = e.getBase();  else    o = Null();  if (o.isA(ActivationType))    o = Null();#ifdef KJS_DEBUGGER  steppingInto(true);#endif  KJSO result = v.executeCall(o, argList);#ifdef KJS_DEBUGGER  steppingInto(false);#endif  delete argList;  return result;}#ifdef KJS_DEBUGGERvoid FunctionCallNode::steppingInto(bool in){  Debugger *dbg = KJScriptImp::current()->debugger();  if (!dbg)    return;  if (in) {    // before entering function. Don't step inside if 'Next' is chosen.    previousMode = dbg->mode();    if (previousMode == Debugger::Next)      dbg->setMode(Debugger::Continue);  } else {    // restore mode after leaving function    dbg->setMode(previousMode);  }}#endifKJSO ArgumentsNode::evaluate(){  assert(0);  return KJSO(); // dummy, see evaluateList()}// ECMA 11.2.4List* ArgumentsNode::evaluateList(){  if (!list)    return new List();  return list->evaluateList();}KJSO ArgumentListNode::evaluate(){  assert(0);  return KJSO(); // dummy, see evaluateList()}// ECMA 11.2.4List* ArgumentListNode::evaluateList(){  KJSO e = expr->evaluate();  KJSO v = e.getValue();  if (!list) {    List *l = new List();    l->append(v);    return l;  }  List *l = list->evaluateList();  l->append(v);  return l;}// ECMA 11.8KJSO RelationalNode::evaluate(){  KJSO e1 = expr1->evaluate();  KJSO v1 = e1.getValue();  KJSO e2 = expr2->evaluate();  KJSO v2 = e2.getValue();  bool b;  if (oper == OpLess || oper == OpGreaterEq) {    int r = relation(v1, v2);    if (r < 0)      b = false;    else      b = (oper == OpLess) ? (r == 1) : (r == 0);  } else if (oper == OpGreater || oper == OpLessEq) {    int r = relation(v2, v1);    if (r < 0)      b = false;    else      b = (oper == OpGreater) ? (r == 1) : (r == 0);  } else if (oper == OpIn) {      /* Is all of this OK for host objects? */      if (!v2.isObject())          return throwError( TypeError,                             "Shift expression not an object into IN expression." );      b = v2.hasProperty(v1.toString().value());  } else {    /* TODO: should apply to Function _objects_ only */    if (!v2.derivedFrom("Function"))      return throwError(TypeError,			"Called instanceof operator on non-function object." );    return hasInstance(v2, v1);	/* TODO: make object member function */  }  return Boolean(b);}// ECMA 11.9KJSO EqualNode::evaluate(){  KJSO e1 = expr1->evaluate();  KJSO e2 = expr2->evaluate();  KJSO v1 = e1.getValue();  KJSO v2 = e2.getValue();  bool result;  if (oper == OpEqEq || oper == OpNotEq) {    // == and !=    bool eq = equal(v1, v2);    result = oper == OpEqEq ? eq : !eq;  } else {    // === and !==    bool eq = strictEqual(v1, v2);    result = oper == OpStrEq ? eq : !eq;  }  return Boolean(result);}// ECMA 11.10KJSO BitOperNode::evaluate(){  KJSO e1 = expr1->evaluate();  KJSO v1 = e1.getValue();  KJSO e2 = expr2->evaluate();  KJSO v2 = e2.getValue();  int i1 = v1.toInt32();  int i2 = v2.toInt32();  int result;  if (oper == OpBitAnd)    result = i1 & i2;  else if (oper == OpBitXOr)    result = i1 ^ i2;  else    result = i1 | i2;  return Number(result);}// ECMA 11.11KJSO BinaryLogicalNode::evaluate(){  KJSO e1 = expr1->evaluate();  KJSO v1 = e1.getValue();  Boolean b1 = v1.toBoolean();  if ((!b1.value() && oper == OpAnd) || (b1.value() && oper == OpOr))    return v1;  KJSO e2 = expr2->evaluate();  KJSO v2 = e2.getValue();  return v2;}// ECMA 11.12KJSO ConditionalNode::evaluate(){  KJSO e = logical->evaluate();  KJSO v = e.getValue();  Boolean b = v.toBoolean();  if (b.value())    e = expr1->evaluate();  else    e = expr2->evaluate();  return e.getValue();}// ECMA 11.13KJSO AssignNode::evaluate(){  KJSO l, e, v;  ErrorType err;  if (oper == OpEqual) {    l = left->evaluate();    e = expr->evaluate();    v = e.getValue();  } else {    l = left->evaluate();    KJSO v1 = l.getValue();    e = expr->evaluate();    KJSO v2 = e.getValue();    int i1 = v1.toInt32();    int i2 = v2.toInt32();    switch (oper) {    case OpMultEq:      v = mult(v1, v2, '*');      break;    case OpDivEq:      v = mult(v1, v2, '/');      break;    case OpPlusEq:      v = add(v1, v2, '+');      break;    case OpMinusEq:      v = add(v1, v2, '-');      break;    case OpLShift:      v = Number(i1 <<= i2);      break;    case OpRShift:      v = Number(i1 >>= i2);      break;    case OpURShift:      i1 = v1.toUInt32();      v = Number(i1 >>= i2);      break;    case OpAndEq:      v = Number(i1 &= i2);      break;    case OpXOrEq:      v = Number(i1 ^= i2);      break;    case OpOrEq:      v = Number(i1 |= i2);      break;    case OpModEq:      v = Number(i1 %= i2);      break;    default:      v = Undefined();    }    err = l.putValue(v);  };  err = l.putValue(v);  if (err == NoError)    return v;  else    return throwError(err, "Invalid reference.");}// ECMA 11.3KJSO PostfixNode::evaluate(){  KJSO e = expr->evaluate();  KJSO v = e.getValue();  Number n = v.toNumber();  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;  KJSO n2 = Number(newValue);  e.putValue(n2);  return n;}// ECMA 11.4.1KJSO DeleteNode::evaluate(){  KJSO e = expr->evaluate();  if (!e.isA(ReferenceType))    return Boolean(true);  KJSO b = e.getBase();  UString n = e.getPropertyName();  bool ret = b.deleteProperty(n);  return Boolean(ret);}// ECMA 11.4.2KJSO VoidNode::evaluate(){  KJSO dummy1 = expr->evaluate();  KJSO dummy2 = dummy1.getValue();  return Undefined();}// ECMA 11.4.3KJSO TypeOfNode::evaluate(){  const char *s = 0L;  KJSO e = expr->evaluate();  if (e.isA(ReferenceType)) {    KJSO b = e.getBase();    if (b.isA(NullType))      return String("undefined");  }  KJSO v = e.getValue();  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.implementsCall())	s = "function";      else	s = "object";      break;    }  return String(s);}// ECMA 11.4.4 and 11.4.5KJSO PrefixNode::evaluate(){  KJSO e = expr->evaluate();  KJSO v = e.getValue();  Number n = v.toNumber();  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;  KJSO n2 = Number(newValue);  e.putValue(n2);  return n2;}// ECMA 11.4.6KJSO UnaryPlusNode::evaluate(){  KJSO e = expr->evaluate();  KJSO v = e.getValue();  return v.toNumber();}// ECMA 11.4.7KJSO NegateNode::evaluate(){  KJSO e = expr->evaluate();  KJSO v = e.getValue();  Number n = v.toNumber();  double d = -n.value();  return Number(d);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -