Ignore:
Timestamp:
Aug 16, 2002, 12:07:48 PM (23 years ago)
Author:
mjs
Message:

Final step of the Reference change. Completely separate Reference
from Value, and eliminate ReferenceImp.

18% speedup on cvs-js-performance test.

  • kjs/internal.cpp, kjs/internal.h: Remove ReferenceImp.
  • kjs/nodes.cpp: (Node::evaluateReference): Use Reference::makeValueReference(), not ConstReference.
  • kjs/reference.cpp: (Reference::Reference): New implementation, handles both regular and value references. (Reference::makeValueReference): Incorporate functionality of ConstReference into this class. (Reference::getBase): New implementation (incorporates error vase for value references). (Reference::getPropertyName): New implementation (incorporates error case for value references). (Reference::putValue): New implementation (incorporates error case for value references). (Reference::deleteValue): New implementation (incorporates error case for value references). (Reference::getValue): New implementation (incorporates special case for value references). (Reference::isMutable): New implementation.
  • kjs/reference.h: New implementation that merges ReferenceImp into the stack object.
  • kjs/value.h, kjs/value.cpp: Removed all reference-related method.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/reference.cpp

    r1841 r1850  
    2929
    3030Reference::Reference(const Object& b, const UString& p)
    31   : Value(new ReferenceImp(b,p))
     31  : base(b),
     32    baseIsValue(false),
     33    propertyNameIsNumber(false),
     34    prop(p)
    3235{
    3336}
    3437
    3538Reference::Reference(const Object& b, unsigned p)
    36   : Value(new ReferenceImp(b,p))
     39  : base(b),
     40    propertyNameAsNumber(p),
     41    baseIsValue(false),
     42    propertyNameIsNumber(true)
    3743{
    3844}
    3945
    4046Reference::Reference(const Null& b, const UString& p)
    41   : Value(new ReferenceImp(b,p))
     47  : base(b),
     48    baseIsValue(false),
     49    propertyNameIsNumber(false),
     50    prop(p)
    4251{
    4352}
    4453
    4554Reference::Reference(const Null& b, unsigned p)
    46   : Value(new ReferenceImp(b,p))
     55  : base(b),
     56    propertyNameAsNumber(p),
     57    baseIsValue(false),
     58    propertyNameIsNumber(true)
    4759{
    4860}
    4961
    50 Reference Reference::dynamicCast(const Value &v)
     62Reference Reference::makeValueReference(const Value& v)
    5163{
    52   if (v.isNull() || v.type() != ReferenceType)
    53     return 0;
    54 
    55   return static_cast<ReferenceImp*>(v.imp());
     64  Reference valueRef;
     65  valueRef.base = v;
     66  valueRef.baseIsValue = true;
     67  return valueRef;
    5668}
    5769
    58 ConstReference::ConstReference(ValueImp *v) :
    59   Reference((ReferenceImp *)v)
     70Reference::Reference()
    6071{
    6172}
     73
     74Value Reference::getBase(ExecState *exec) const
     75{
     76  if (baseIsValue) {
     77    Object err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base"));
     78    exec->setException(err);
     79    return err;
     80  }
     81
     82  return base;
     83}
     84
     85UString Reference::getPropertyName(ExecState *exec) const
     86{
     87  if (baseIsValue) {
     88    // the spec wants a runtime error here. But getValue() and putValue()
     89    // will catch this case on their own earlier. When returning a Null
     90    // string we should be on the safe side.
     91    return UString();
     92  }
     93
     94  if (propertyNameIsNumber && prop.isNull())
     95    prop = UString::from(propertyNameAsNumber);
     96  return prop;
     97}
     98
     99Value Reference::getValue(ExecState *exec) const
     100{
     101  if (baseIsValue) {
     102    return base;
     103  }
     104
     105  Value o = getBase(exec);
     106
     107  if (o.isNull() || o.type() == NullType) {
     108    UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec);
     109    Object err = Error::create(exec, ReferenceError, m.ascii());
     110    exec->setException(err);
     111    return err;
     112  }
     113
     114  if (o.type() != ObjectType) {
     115    UString m = I18N_NOOP("Base is not an object");
     116    Object err = Error::create(exec, ReferenceError, m.ascii());
     117    exec->setException(err);
     118    return err;
     119  }
     120
     121  if (propertyNameIsNumber)
     122    return static_cast<ObjectImp*>(o.imp())->get(exec,propertyNameAsNumber);
     123  return static_cast<ObjectImp*>(o.imp())->get(exec,prop);
     124}
     125
     126void Reference::putValue(ExecState *exec, const Value &w)
     127{
     128  if (baseIsValue) {
     129    Object err = Error::create(exec,ReferenceError);
     130    exec->setException(err);
     131    return;
     132  }
     133
     134#ifdef KJS_VERBOSE
     135  printInfo(exec,(UString("setting property ")+getPropertyName(exec)).cstring().c_str(),w);
     136#endif
     137  Value o = getBase(exec);
     138  if (o.type() == NullType)
     139    o = exec->interpreter()->globalObject();
     140
     141  if (propertyNameIsNumber)
     142    return static_cast<ObjectImp*>(o.imp())->put(exec,propertyNameAsNumber, w);
     143  return static_cast<ObjectImp*>(o.imp())->put(exec,prop, w);
     144}
     145
     146bool Reference::deleteValue(ExecState *exec)
     147{
     148  if (baseIsValue) {
     149    Object err = Error::create(exec,ReferenceError);
     150    exec->setException(err);
     151    return false;
     152  }
     153
     154  Value b = getBase(exec);
     155
     156  // The spec doesn't mention what to do if the base is null... just return true
     157  if (b.type() != ObjectType) {
     158    assert(b.type() == NullType);
     159    return true;
     160  }
     161
     162  if (propertyNameIsNumber)
     163    return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,propertyNameAsNumber);
     164  return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,prop);
     165}
     166
     167bool Reference::isMutable()
     168{
     169  return !baseIsValue;
     170}
Note: See TracChangeset for help on using the changeset viewer.