kjs Library: object_object.cpp Source File (kjs Library)

| # kjs Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# object_object.cpp

    00001 // -*- c-basic-offset: 2 -*-
    00002 /*
    00003  *  This file is part of the KDE libraries
    00004  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    00005  *
    00006  *  This library is free software; you can redistribute it and/or
    00007  *  modify it under the terms of the GNU Lesser General Public
    00008  *  License as published by the Free Software Foundation; either
    00009  *  version 2 of the License, or (at your option) any later version.
    00010  *
    00011  *  This library is distributed in the hope that it will be useful,
    00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00014  *  Lesser General Public License for more details.
    00015  *
    00016  *  You should have received a copy of the GNU Lesser General Public
    00017  *  License along with this library; if not, write to the Free Software
    00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00019  *
    00020  */
    00021
    00022 #include "value.h"
    00023 #include "object.h"
    00024 #include "types.h"
    00025 #include "interpreter.h"
    00026 #include "operations.h"
    00027 #include "object_object.h"
    00028 #include "function_object.h"
    00029 #include "lookup.h"
    00030 #include <stdio.h>
    00031 #include <assert.h>
    00032
    00033 using namespace KJS;
    00034
    00035 // ------------------------------ ObjectPrototypeImp --------------------------------
    00036
    00037 ObjectPrototypeImp::ObjectPrototypeImp(ExecState *exec,
    00038                                        FunctionPrototypeImp *funcProto)
    00039   : ObjectImp() // [[Prototype]] is Null()
    00040 {
    00041   Value protect(this);
    00042   putDirect(toStringPropertyName, new ObjectProtoFuncImp(exec,funcProto,ObjectProtoFuncImp::ToString,
    00043                              0, toStringPropertyName), DontEnum);
    00044   putDirect(toLocaleStringPropertyName, new ObjectProtoFuncImp(exec,funcProto,ObjectProtoFuncImp::ToLocaleString,
    00045                                    0, toLocaleStringPropertyName), DontEnum);
    00046   putDirect(valueOfPropertyName, new ObjectProtoFuncImp(exec,funcProto,ObjectProtoFuncImp::ValueOf,
    00047                             0, valueOfPropertyName), DontEnum);
    00048   putDirect("hasOwnProperty", new ObjectProtoFuncImp(exec,funcProto,ObjectProtoFuncImp::HasOwnProperty,
    00049                              1,"hasOwnProperty"),DontEnum);
    00050   putDirect("isPrototypeOf", new ObjectProtoFuncImp(exec,funcProto,ObjectProtoFuncImp::IsPrototypeOf,
    00051                             1,"isPrototypeOf"),DontEnum);
    00052   putDirect("propertyIsEnumerable", new ObjectProtoFuncImp(exec,funcProto,ObjectProtoFuncImp::PropertyIsEnumerable,
    00053                                1,"propertyIsEnumerable"),DontEnum);
    00054
    00055 #ifndef KJS_PURE_ECMA // standard compliance location is the Global object
    00056   // see http://www.devguru.com/Technologies/ecmascript/quickref/object.html
    00057   put(exec, "eval",
    00058       Object(new GlobalFuncImp(exec, funcProto,GlobalFuncImp::Eval, 1, "eval")),
    00059       DontEnum);
    00060 #endif
    00061 }
    00062
    00063 // ------------------------------ ObjectProtoFuncImp --------------------------------
    00064
    00065 ObjectProtoFuncImp::ObjectProtoFuncImp(ExecState * /*exec*/,
    00066                                        FunctionPrototypeImp *funcProto,
    00067                                        int i, int len, const Identifier &_ident)
    00068   : InternalFunctionImp(funcProto), id(i)
    00069 {
    00070   Value protect(this);
    00071   putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
    00072   ident = _ident;
    00073 }
    00074
    00075
    00076 bool ObjectProtoFuncImp::implementsCall() const
    00077 {
    00078   return true;
    00079 }
    00080
    00081 // ECMA 15.2.4.2 + 15.2.4.3
    00082
    00083 Value ObjectProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
    00084 {
    00085   switch (id) {
    00086   case ToString:
    00087     // fall through
    00088   case ToLocaleString:
    00089     return String("[object "+thisObj.className()+"]");
    00090   case ValueOf:
    00091     return thisObj;
    00092   case HasOwnProperty: {
    00093     // Same as hasProperty() but without checking the prototype
    00094     Identifier propertyName(args[0].toString(exec));
    00095     Value tempProto(thisObj.imp()->prototype());
    00096     thisObj.imp()->setPrototype(Value());
    00097     bool exists = thisObj.hasProperty(exec,propertyName);
    00098     thisObj.imp()->setPrototype(tempProto);
    00099     return Value(exists ? BooleanImp::staticTrue : BooleanImp::staticFalse);
    00100   }
    00101   case IsPrototypeOf: {
    00102     Value v = args[0];
    00103     for (; v.isValid() && v.isA(ObjectType); v = Object::dynamicCast(v).prototype()) {
    00104       if (v.imp() == thisObj.imp())
    00105     return Value(BooleanImp::staticTrue);
    00106     }
    00107     return Value(BooleanImp::staticFalse);
    00108   }
    00109   case PropertyIsEnumerable: {
    00110     Identifier propertyName(args[0].toString(exec));
    00111     ObjectImp *obj = static_cast<ObjectImp*>(thisObj.imp());
    00112
    00113     int attributes;
    00114     ValueImp *v = obj->_prop.get(propertyName,attributes);
    00115     if (v)
    00116       return Value((attributes & DontEnum) ?
    00117            BooleanImp::staticFalse : BooleanImp::staticTrue);
    00118
    00119     if (propertyName == specialPrototypePropertyName)
    00120       return Value(BooleanImp::staticFalse);
    00121
    00122     const HashEntry *entry = obj->findPropertyHashEntry(propertyName);
    00123     return Value((entry && !(entry->attr & DontEnum)) ?
    00124          BooleanImp::staticTrue : BooleanImp::staticFalse);
    00125   }
    00126   }
    00127
    00128   return Undefined();
    00129 }
    00130
    00131 // ------------------------------ ObjectObjectImp --------------------------------
    00132
    00133 ObjectObjectImp::ObjectObjectImp(ExecState * /*exec*/,
    00134                                  ObjectPrototypeImp *objProto,
    00135                                  FunctionPrototypeImp *funcProto)
    00136   : InternalFunctionImp(funcProto)
    00137 {
    00138   Value protect(this);
    00139   // ECMA 15.2.3.1
    00140   putDirect(prototypePropertyName, objProto, DontEnum|DontDelete|ReadOnly);
    00141
    00142   // no. of arguments for constructor
    00143   putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
    00144 }
    00145
    00146
    00147 bool ObjectObjectImp::implementsConstruct() const
    00148 {
    00149   return true;
    00150 }
    00151
    00152 // ECMA 15.2.2
    00153 Object ObjectObjectImp::construct(ExecState *exec, const List &args)
    00154 {
    00155   // if no arguments have been passed ...
    00156   if (args.isEmpty()) {
    00157     Object proto = exec->interpreter()->builtinObjectPrototype();
    00158     Object result(new ObjectImp(proto));
    00159     return result;
    00160   }
    00161
    00162   Value arg = *(args.begin());
    00163   Object obj = Object::dynamicCast(arg);
    00164   if (obj.isValid())
    00165     return obj;
    00166
    00167   switch (arg.type()) {
    00168   case StringType:
    00169   case BooleanType:
    00170   case NumberType:
    00171     return arg.toObject(exec);
    00172   default:
    00173     assert(!"unhandled switch case in ObjectConstructor");
    00174   case NullType:
    00175   case UndefinedType:
    00176     Object proto = exec->interpreter()->builtinObjectPrototype();
    00177     return Object(new ObjectImp(proto));
    00178   }
    00179 }
    00180
    00181 bool ObjectObjectImp::implementsCall() const
    00182 {
    00183   return true;
    00184 }
    00185
    00186 Value ObjectObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
    00187 {
    00188   Value result;
    00189
    00190   List argList;
    00191   // Construct a new Object
    00192   if (args.isEmpty()) {
    00193     result = construct(exec,argList);
    00194   } else {
    00195     Value arg = args[0];
    00196     if (arg.type() == NullType || arg.type() == UndefinedType) {
    00197       argList.append(arg);
    00198       result = construct(exec,argList);
    00199     } else
    00200       result = arg.toObject(exec);
    00201   }
    00202   return result;
    00203 }
    00204

This file is part of the documentation for kjs Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:07 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003