internal.cpp

来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 915 行 · 第 1/2 页

CPP
915
字号
/* *  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 "internal.h"#include <assert.h>#include <stdio.h>#include "kjs.h"#include "object.h"#include "types.h"#include "operations.h"#include "regexp.h"#include "nodes.h"#include "lexer.h"#include "collector.h"#include "debugger.h"#define I18N_NOOP(s) sextern int kjsyyparse();using namespace KJS;const TypeInfo UndefinedImp::info = { "Undefined", UndefinedType, 0, 0, 0 };const TypeInfo NullImp::info = { "Null", NullType, 0, 0, 0 };const TypeInfo NumberImp::info = { "Number", NumberType, 0, 0,0  };const TypeInfo StringImp::info = { "String", StringType, 0, 0, 0 };const TypeInfo BooleanImp::info = { "Boolean", BooleanType, 0, 0, 0 };const TypeInfo CompletionImp::info = { "Completion", CompletionType, 0, 0, 0 };const TypeInfo ReferenceImp::info = { "Reference", ReferenceType, 0, 0, 0 };UndefinedImp *UndefinedImp::staticUndefined = 0;UndefinedImp::UndefinedImp(){}KJSO UndefinedImp::toPrimitive(Type) const{  return (Imp*)this;}Boolean UndefinedImp::toBoolean() const{  return Boolean(false);}Number UndefinedImp::toNumber() const{  return Number(NaN);}String UndefinedImp::toString() const{  return String("undefined");}Object UndefinedImp::toObject() const{  return Error::createObject(TypeError, I18N_NOOP("Undefined value"));}NullImp *NullImp::staticNull = 0;NullImp::NullImp(){}KJSO NullImp::toPrimitive(Type) const{  return (Imp*)this;}Boolean NullImp::toBoolean() const{  return Boolean(false);}Number NullImp::toNumber() const{  return Number(0);}String NullImp::toString() const{  return String("null");}Object NullImp::toObject() const{  return Error::createObject(TypeError, I18N_NOOP("Null value"));}BooleanImp* BooleanImp::staticTrue = 0;BooleanImp* BooleanImp::staticFalse = 0;KJSO BooleanImp::toPrimitive(Type) const{  return (Imp*)this;}Boolean BooleanImp::toBoolean() const{  return Boolean((BooleanImp*)this);}Number BooleanImp::toNumber() const{  return Number(val ? 1 : 0);}String BooleanImp::toString() const{  return String(val ? "true" : "false");}Object BooleanImp::toObject() const{  return Object::create(BooleanClass, Boolean((BooleanImp*)this));}NumberImp::NumberImp(double v)  : val(v){}KJSO NumberImp::toPrimitive(Type) const{  return (Imp*)this;}Boolean NumberImp::toBoolean() const{  bool b = !((val == 0) /* || (iVal() == N0) */ || isNaN(val));  return Boolean(b);}Number NumberImp::toNumber() const{  return Number((NumberImp*)this);}String NumberImp::toString() const{  return String(UString::from(val));}Object NumberImp::toObject() const{  return Object::create(NumberClass, Number((NumberImp*)this));}StringImp::StringImp(const UString& v)  : val(v){}KJSO StringImp::toPrimitive(Type) const{  return (Imp*)this;}Boolean StringImp::toBoolean() const{  return Boolean(val.size() > 0);}Number StringImp::toNumber() const{  return Number(val.toDouble());}String StringImp::toString() const{  return String((StringImp*)this);}Object StringImp::toObject() const{  return Object::create(StringClass, String((StringImp*)this));}ReferenceImp::ReferenceImp(const KJSO& b, const UString& p)  : base(b), prop(p){}void ReferenceImp::mark(Imp*){  Imp::mark();  Imp *im = base.imp();  if (im && !im->marked())    im->mark();}CompletionImp::CompletionImp(Compl c, const KJSO& v, const UString& t)  : comp(c), val(v), tar(t){}void CompletionImp::mark(Imp*){  Imp::mark();  Imp *im = val.imp();  if (im && !im->marked())    im->mark();}RegExpImp::RegExpImp()  : ObjectImp(RegExpClass), reg(0L){}RegExpImp::~RegExpImp(){  delete reg;}// ECMA 10.2Context::Context(CodeType type, Context *callingContext,		 FunctionImp *func, const List *args, Imp *thisV){  Global glob(Global::current());  // create and initialize activation object (ECMA 10.1.6)  if (type == FunctionCode || type == AnonymousCode || type == HostCode) {    activation = new ActivationImp(func, args);    variable = activation;  } else {    activation = KJSO();    variable = glob;  }  // ECMA 10.2  switch(type) {    case EvalCode:      if (callingContext) {	scopeChain = callingContext->copyOfChain();	variable = callingContext->variableObject();	thisVal = callingContext->thisValue();	break;      } // else same as GlobalCode    case GlobalCode:      scopeChain = new List();      scopeChain->append(glob);      thisVal = glob.imp();      break;    case FunctionCode:    case AnonymousCode:      if (type == FunctionCode) {	scopeChain = ((DeclaredFunctionImp*)func)->scopeChain()->copy();	scopeChain->prepend(activation);      } else {	scopeChain = new List();	scopeChain->append(activation);	scopeChain->append(glob);      }      variable = activation; /* TODO: DontDelete ? (ECMA 10.2.3) */      if (thisV->type() >= ObjectType) {	thisVal = thisV;      }      else	thisVal = glob.imp();      break;    case HostCode:      if (thisV->type() >= ObjectType)	thisVal = thisV;      else	thisVal = glob;      variable = activation; /* TODO: DontDelete (ECMA 10.2.4) */      scopeChain = new List();      scopeChain->append(activation);      if (func->hasAttribute(ImplicitThis))	scopeChain->append(KJSO(thisVal));      if (func->hasAttribute(ImplicitParents)) {	/* TODO ??? */      }      scopeChain->append(glob);      break;    }}Context::~Context(){  delete scopeChain;}Context *Context::current(){  return KJScriptImp::curr ? KJScriptImp::curr->con : 0L;}void Context::setCurrent(Context *c){  KJScriptImp::current()->con = c;}void Context::pushScope(const KJSO &s){  scopeChain->prepend(s);}void Context::popScope(){  scopeChain->removeFirst();}List* Context::copyOfChain(){  return scopeChain->copy();}AnonymousFunction::AnonymousFunction()  : Function(0L){  /* TODO */}DeclaredFunctionImp::DeclaredFunctionImp(const UString &n,					 FunctionBodyNode *b, const List *sc)  : ConstructorImp(n), body(b), scopes(sc->copy()){}DeclaredFunctionImp::~DeclaredFunctionImp(){  delete scopes;}// step 2 of ECMA 13.2.1. rest in FunctionImp::executeCall()Completion DeclaredFunctionImp::execute(const List &){ /* TODO */#ifdef KJS_DEBUGGER  Debugger *dbg = KJScriptImp::current()->debugger();  int oldSourceId = -1;  if (dbg) {    oldSourceId = dbg->sourceId();    dbg->setSourceId(body->sourceId());  }#endif  Completion result = body->execute();#ifdef KJS_DEBUGGER  if (dbg) {    dbg->setSourceId(oldSourceId);  }#endif  if (result.complType() == Throw || result.complType() == ReturnValue)      return result;  return Completion(Normal, Undefined()); /* TODO: or ReturnValue ? */}// ECMA 13.2.2 [[Construct]]Object DeclaredFunctionImp::construct(const List &args){  Object obj(ObjectClass);  KJSO p = get("prototype");  if (p.isObject())    obj.setPrototype(p);  else    obj.setPrototype(Global::current().objectPrototype());  KJSO res = executeCall(obj.imp(), &args);  Object v = Object::dynamicCast(res);  if (v.isNull())    return obj;  else    return v;}Completion AnonymousFunction::execute(const List &){ /* TODO */  return Completion(Normal, Null());}// ECMA 10.1.8class ArgumentsObject : public ObjectImp {public:  ArgumentsObject(FunctionImp *func, const List *args);};ArgumentsObject::ArgumentsObject(FunctionImp *func, const List *args)  : ObjectImp(UndefClass){  put("callee", Function(func), DontEnum);  if (args) {    put("length", Number(args->size()), DontEnum);    ListIterator arg = args->begin();    for (int i = 0; arg != args->end(); arg++, i++) {      put(UString::from(i), *arg, DontEnum);    }  }}const TypeInfo ActivationImp::info = { "Activation", ActivationType, 0, 0, 0 };// ECMA 10.1.6ActivationImp::ActivationImp(FunctionImp *f, const List *args){  KJSO aobj(new ArgumentsObject(f, args));  put("arguments", aobj, DontDelete);  /* TODO: this is here to get myFunc.arguments and myFunc.a1 going.     I can't see this described in the spec but it's possible in browsers. */  if (!f->name().isNull())    f->put("arguments", aobj);}ExecutionStack::ExecutionStack()  : progNode(0L), firstNode(0L), prev(0){}ExecutionStack* ExecutionStack::push(){  ExecutionStack *s = new ExecutionStack();  s->prev = this;  return s;}ExecutionStack* ExecutionStack::pop(){  ExecutionStack *s = prev;  delete this;  return s;}KJScriptImp* KJScriptImp::curr = 0L;KJScriptImp* KJScriptImp::hook = 0L;int          KJScriptImp::instances = 0;int          KJScriptImp::running = 0;

⌨️ 快捷键说明

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