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 }