reference.cpp
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #include "reference.h"
00024 #include "internal.h"
00025 #include "context.h"
00026 
00027 #include <assert.h>
00028 
00029 using namespace KJS;
00030 
00031 
00032 
00033 Reference::Reference(const Object& b, const Identifier& p)
00034   : base(b),
00035     baseIsValue(false),
00036     propertyNameIsNumber(false),
00037     prop(p)
00038 {
00039 }
00040 
00041 Reference::Reference(const Object& b, unsigned p)
00042   : base(b),
00043     propertyNameAsNumber(p),
00044     baseIsValue(false),
00045     propertyNameIsNumber(true)
00046 {
00047 }
00048 
00049 Reference::Reference(ObjectImp *b, const Identifier& p)
00050   : base(b),
00051     baseIsValue(false),
00052     propertyNameIsNumber(false),
00053     prop(p)
00054 {
00055 }
00056 
00057 Reference::Reference(ObjectImp *b, unsigned p)
00058   : base(b),
00059     propertyNameAsNumber(p),
00060     baseIsValue(false),
00061     propertyNameIsNumber(true)
00062 {
00063 }
00064 
00065 Reference::Reference(const Null& b, const Identifier& p)
00066   : base(b),
00067     baseIsValue(false),
00068     propertyNameIsNumber(false),
00069     prop(p)
00070 {
00071 }
00072 
00073 Reference::Reference(const Null& b, unsigned p)
00074   : base(b),
00075     propertyNameAsNumber(p),
00076     baseIsValue(false),
00077     propertyNameIsNumber(true)
00078 {
00079 }
00080 
00081 Reference Reference::makeValueReference(const Value& v)
00082 {
00083   Reference valueRef;
00084   valueRef.base = v;
00085   valueRef.baseIsValue = true;
00086   return valueRef;
00087 }
00088 
00089 Reference::Reference()
00090 {
00091 }
00092 
00093 Value Reference::getBase(ExecState *exec) const
00094 {
00095   if (baseIsValue) {
00096     Object err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base"));
00097     exec->setException(err);
00098     return err;
00099   }
00100 
00101   return base;
00102 }
00103 
00104 Identifier Reference::getPropertyName(ExecState *) const
00105 {
00106   if (baseIsValue) {
00107     
00108     
00109     
00110     return Identifier();
00111   }
00112 
00113   if (propertyNameIsNumber && prop.isNull())
00114     prop = Identifier::from(propertyNameAsNumber);
00115   return prop;
00116 }
00117 
00118 Value Reference::getValue(ExecState *exec) const
00119 {
00120   if (baseIsValue) {
00121     return base;
00122   }
00123 
00124   Value o = getBase(exec);
00125 
00126   if (o.isNull() || o.type() == NullType) {
00127     UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec).ustring();
00128     Object err = Error::create(exec, ReferenceError, m.ascii());
00129     exec->setException(err);
00130     return err;
00131   }
00132 
00133   if (o.type() != ObjectType) {
00134     UString m = I18N_NOOP("Base is not an object");
00135     Object err = Error::create(exec, ReferenceError, m.ascii());
00136     exec->setException(err);
00137     return err;
00138   }
00139 
00140   ObjectImp *oimp = static_cast<ObjectImp*>(o.imp());
00141   if (propertyNameIsNumber)
00142     return oimp->getPropertyByIndex(exec, propertyNameAsNumber);
00143   return oimp->get(exec, prop);
00144 }
00145 
00146 void Reference::putValue(ExecState *exec, const Value &w)
00147 {
00148   if (baseIsValue) {
00149     Object err = Error::create(exec,ReferenceError);
00150     exec->setException(err);
00151     return;
00152   }
00153 
00154 #ifdef KJS_VERBOSE
00155   printInfo(exec,(UString("setting property ")+getPropertyName(exec).ustring()).cstring().c_str(),w);
00156 #endif
00157   Value o = getBase(exec);
00158   if (o.type() == NullType)
00159     o = Value(exec->context().imp()->scopeChain().bottom());
00160 
00161   ObjectImp *oimp = static_cast<ObjectImp*>(o.imp());
00162   if (propertyNameIsNumber)
00163     oimp->putPropertyByIndex(exec, propertyNameAsNumber, w);
00164   else
00165     oimp->put(exec, prop, w);
00166 }
00167 
00168 bool Reference::deleteValue(ExecState *exec)
00169 {
00170   if (baseIsValue) {
00171     Object err = Error::create(exec,ReferenceError);
00172     exec->setException(err);
00173     return false;
00174   }
00175 
00176   Value b = getBase(exec);
00177 
00178   
00179   if (b.type() != ObjectType) {
00180     assert(b.type() == NullType);
00181     return true;
00182   }
00183 
00184   ObjectImp *bimp = static_cast<ObjectImp*>(b.imp());
00185   if (propertyNameIsNumber)
00186     return bimp->deletePropertyByIndex(exec, propertyNameAsNumber);
00187   return bimp->deleteProperty(exec, prop);
00188 }
00189 
00190 bool Reference::isMutable()
00191 {
00192   return !baseIsValue;
00193 }
 
This file is part of the documentation for kjs Library Version 3.2.0.