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