kjs Library API Documentation

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
KDE Logo
This file is part of the documentation for kjs Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:48:58 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003