Changeset 1850 in webkit for trunk/JavaScriptCore/kjs


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.
Location:
trunk/JavaScriptCore/kjs
Files:
7 edited

Legend:

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

    r1840 r1850  
    253253  uint32 = (unsigned)val;
    254254  return (double)uint32 == val;
    255 }
    256 
    257 // ------------------------------ ReferenceImp ---------------------------------
    258 
    259 ReferenceImp::ReferenceImp(const Value& v, unsigned p)
    260   : base(v.imp()), propertyNameIsNumber(true), propertyNameAsNumber(p)
    261 {
    262 }
    263 
    264 ReferenceImp::ReferenceImp(const Value& v, const UString& p)
    265   : base(v.imp()), propertyNameIsNumber(false), prop(p)
    266 {
    267 }
    268 
    269 void ReferenceImp::mark()
    270 {
    271   ValueImp::mark();
    272   if (base && !base->marked())
    273     base->mark();
    274 }
    275 
    276 Value ReferenceImp::toPrimitive(ExecState */*exec*/, Type /*preferredType*/) const
    277 {
    278   // invalid for Reference
    279   assert(false);
    280   return Value();
    281 }
    282 
    283 bool ReferenceImp::toBoolean(ExecState */*exec*/) const
    284 {
    285   // invalid for Reference
    286   assert(false);
    287   return false;
    288 }
    289 
    290 double ReferenceImp::toNumber(ExecState */*exec*/) const
    291 {
    292   // invalid for Reference
    293   assert(false);
    294   return 0;
    295 }
    296 
    297 UString ReferenceImp::toString(ExecState */*exec*/) const
    298 {
    299   // invalid for Reference
    300   assert(false);
    301   return UString::null;
    302 }
    303 
    304 Object ReferenceImp::toObject(ExecState */*exec*/) const
    305 {
    306   // invalid for Reference
    307   assert(false);
    308   return Object();
    309 }
    310 
    311 UString ReferenceImp::getPropertyName(ExecState *) const
    312 {
    313   if (propertyNameIsNumber && prop.isNull())
    314     prop = UString::from(propertyNameAsNumber);
    315   return prop;
    316 }
    317 
    318 Value ReferenceImp::getValue(ExecState *exec) const
    319 {
    320   Value o = getBase(exec);
    321 
    322   if (o.isNull() || o.type() == NullType) {
    323     UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec);
    324     Object err = Error::create(exec, ReferenceError, m.ascii());
    325     exec->setException(err);
    326     return err;
    327   }
    328 
    329   if (o.type() != ObjectType) {
    330     UString m = I18N_NOOP("Base is not an object");
    331     Object err = Error::create(exec, ReferenceError, m.ascii());
    332     exec->setException(err);
    333     return err;
    334   }
    335 
    336   if (propertyNameIsNumber)
    337     return static_cast<ObjectImp*>(o.imp())->get(exec,propertyNameAsNumber);
    338   return static_cast<ObjectImp*>(o.imp())->get(exec,prop);
    339 }
    340 
    341 void ReferenceImp::putValue(ExecState *exec, const Value& w)
    342 {
    343 #ifdef KJS_VERBOSE
    344   printInfo(exec,(UString("setting property ")+getPropertyName(exec)).cstring().c_str(),w);
    345 #endif
    346   Value o = getBase(exec);
    347   if (o.type() == NullType)
    348     o = exec->interpreter()->globalObject();
    349 
    350   if (propertyNameIsNumber)
    351     return static_cast<ObjectImp*>(o.imp())->put(exec,propertyNameAsNumber, w);
    352   return static_cast<ObjectImp*>(o.imp())->put(exec,prop, w);
    353 }
    354 
    355 bool ReferenceImp::deleteValue(ExecState *exec)
    356 {
    357   Value b = getBase(exec);
    358 
    359   // The spec doesn't mention what to do if the base is null... just return true
    360   if (b.type() != ObjectType) {
    361     assert(b.type() == NullType);
    362     return true;
    363   }
    364 
    365   if (propertyNameIsNumber)
    366     return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,propertyNameAsNumber);
    367   return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,prop);
    368255}
    369256
  • trunk/JavaScriptCore/kjs/internal.h

    r1824 r1850  
    143143  // ---------------------------------------------------------------------------
    144144
    145   class ReferenceImp : public ValueImp {
    146   public:
    147     ReferenceImp(const Value& v, const UString& p);
    148     ReferenceImp(const Value& v, unsigned p);
    149     virtual void mark();
    150 
    151     Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
    152     bool toBoolean(ExecState *exec) const;
    153     double toNumber(ExecState *exec) const;
    154     UString toString(ExecState *exec) const;
    155     Object toObject(ExecState *exec) const;
    156 
    157     Value getBase(ExecState *) const { return Value(base); }
    158     UString getPropertyName(ExecState *) const;
    159     Value getValue(ExecState *exec) const;
    160     void putValue(ExecState *exec, const Value& w);
    161     bool deleteValue(ExecState *exec);
    162 
    163     Type type() const { return ReferenceType; }
    164 
    165   private:
    166     ValueImp *base;
    167     bool propertyNameIsNumber;
    168     unsigned propertyNameAsNumber;
    169     mutable UString prop;
    170   };
    171  
    172   inline Reference::Reference(ReferenceImp *imp) : Value(imp) { }
    173 
    174145  class CompletionImp : public ValueImp {
    175146  public:
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r1841 r1850  
    6969#define KJS_CHECKEXCEPTIONREFERENCE \
    7070  if (exec->hadException()) \
    71     return ConstReference(UndefinedImp::staticUndefined);; \
     71    return Reference::makeValueReference(Undefined());; \
    7272  if (Collector::outOfMemory()) \
    73     return ConstReference(UndefinedImp::staticUndefined); // will be picked up by KJS_CHECKEXCEPTION
     73    return Reference::makeValueReference(Undefined()); // will be picked up by KJS_CHECKEXCEPTION
    7474
    7575#define KJS_CHECKEXCEPTIONLIST \
     
    106106  Value v = evaluate(exec);
    107107  KJS_CHECKEXCEPTIONREFERENCE
    108   return ConstReference(v.imp());
     108  return Reference::makeValueReference(v);
    109109}
    110110
  • 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}
  • trunk/JavaScriptCore/kjs/reference.h

    r1841 r1850  
    3636    Reference(const Null& b, const UString& p);
    3737    Reference(const Null& b, unsigned p);
    38     Reference(ReferenceImp *v);
     38    static Reference makeValueReference(const Value& v);
    3939   
    40     /**
    41      * Converts a Value into an Reference. If the value's type is not
    42      * ReferenceType, a null object will be returned (i.e. one with it's
    43      * internal pointer set to 0). If you do not know for sure whether the
    44      * value is of type ReferenceType, you should check the @ref isNull()
    45      * methods afterwards before calling any methods on the returned value.
    46      *
    47      * @return The value converted to an Reference
    48      */
    49     static Reference dynamicCast(const Value &v);
    50 
    5140    /**
    5241     * Performs the GetBase type conversion operation on this value (ECMA 8.7)
     
    5544     * this method is guaranteed to return either Null() or an Object value.
    5645     */
    57     Value getBase(ExecState *exec) const { return rep->dispatchGetBase(exec); }
     46    Value getBase(ExecState *exec) const;
    5847
    5948    /**
     
    6150     * (ECMA 8.7)
    6251     */
    63     UString getPropertyName(ExecState *exec) const { return rep->dispatchGetPropertyName(exec); }
     52    UString getPropertyName(ExecState *exec) const;
    6453
    6554    /**
     
    6756     * (ECMA 8.7.1)
    6857     */
    69     Value getValue(ExecState *exec) const { return rep->dispatchGetValue(exec); }
     58    Value getValue(ExecState *exec) const;
    7059
    7160    /**
     
    7362     * (ECMA 8.7.1)
    7463     */
    75     void putValue(ExecState *exec, const Value &w) { rep->dispatchPutValue(exec, w); }
    76     bool deleteValue(ExecState *exec) { return rep->dispatchDeleteValue(exec); }
    77     bool isMutable() { return type() == ReferenceType; }
    78   };
     64    void putValue(ExecState *exec, const Value &w);
     65    bool deleteValue(ExecState *exec);
    7966
    80   class ConstReference : public Reference {
    81   public:
    82     ConstReference(ValueImp *v);
     67    bool isMutable();
     68
     69  private:
     70    Reference();
     71
     72    Value base;
     73    unsigned propertyNameAsNumber;
     74    bool baseIsValue;
     75    bool propertyNameIsNumber;
     76    mutable UString prop;
    8377  };
    8478}
  • trunk/JavaScriptCore/kjs/value.cpp

    r1832 r1850  
    141141}
    142142
    143 // ECMA 8.7.1
    144 Value ValueImp::getBase(ExecState *exec) const
    145 {
    146   Object err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base"));
    147   exec->setException(err);
    148   return err;
    149 }
    150 
    151 // ECMA 8.7.2
    152 UString ValueImp::getPropertyName(ExecState * /*exec*/) const
    153 {
    154   // the spec wants a runtime error here. But getValue() and putValue()
    155   // will catch this case on their own earlier. When returning a Null
    156   // string we should be on the safe side.
    157   return UString();
    158 }
    159 
    160 // ECMA 8.7.1
    161 Value ValueImp::getValue(ExecState *exec) const
    162 {
    163   return Value(const_cast<ValueImp*>(this));
    164 }
    165 
    166 void ValueImp::putValue(ExecState *exec, const Value& w)
    167 {
    168   Object err = Error::create(exec,ReferenceError);
    169   exec->setException(err);
    170 }
    171 
    172 bool ValueImp::deleteValue(ExecState *exec)
    173 {
    174   Object err = Error::create(exec,ReferenceError);
    175   exec->setException(err);
    176   return false;
    177 }
    178 
    179143// Dispatchers for virtual functions, to special-case simple numbers which
    180144// won't be real pointers.
     
    234198}
    235199
    236 Value ValueImp::dispatchGetBase(ExecState *exec) const
    237 {
    238   if (SimpleNumber::is(this))
    239     return ValueImp::getBase(exec);
    240   return getBase(exec);
    241 }
    242 
    243 UString ValueImp::dispatchGetPropertyName(ExecState *exec) const
    244 {
    245   if (SimpleNumber::is(this))
    246     return ValueImp::getPropertyName(exec);
    247   return getPropertyName(exec);
    248 }
    249 
    250 void ValueImp::dispatchPutValue(ExecState *exec, const Value& w)
    251 {
    252   if (SimpleNumber::is(this))
    253     ValueImp::putValue(exec, w);
    254   putValue(exec, w);
    255 }
    256 
    257 bool ValueImp::dispatchDeleteValue(ExecState *exec)
    258 {
    259   if (SimpleNumber::is(this))
    260     return ValueImp::deleteValue(exec);
    261   return deleteValue(exec);
    262 }
    263 
    264 
    265200// ------------------------------ Value ----------------------------------------
    266201
  • trunk/JavaScriptCore/kjs/value.h

    r1837 r1850  
    7878    NumberType      = 5,
    7979    ObjectType      = 6,
    80     ReferenceType   = 7,
    8180    ListType        = 8,
    8281    CompletionType  = 9
     
    126125    UString dispatchToString(ExecState *exec) const;
    127126    bool dispatchToUInt32(unsigned&) const;
    128     Value dispatchGetBase(ExecState *exec) const;
    129     UString dispatchGetPropertyName(ExecState *exec) const;
    130     void dispatchPutValue(ExecState *exec, const Value& w);
    131     bool dispatchDeleteValue(ExecState *exec);
    132     Value dispatchGetValue(ExecState *exec) const;
    133127    Object dispatchToObject(ExecState *exec) const;
    134128
     
    145139    virtual bool toUInt32(unsigned&) const;
    146140
    147     // Reference operations
    148 
    149     virtual Value getBase(ExecState *exec) const;
    150     virtual UString getPropertyName(ExecState *exec) const;
    151     virtual Value getValue(ExecState *exec) const;
    152     virtual void putValue(ExecState *exec, const Value& w);
    153     virtual bool deleteValue(ExecState *exec);
    154    
    155141    enum {
    156142      VI_MARKED = 1,
     
    403389  };
    404390
    405   inline Value ValueImp::dispatchGetValue(ExecState *exec) const
    406   {
    407     if (SimpleNumber::is(this))
    408         return Value(const_cast<ValueImp*>(this));
    409     return getValue(exec);
    410   }
    411 
    412391}; // namespace
    413392
Note: See TracChangeset for help on using the changeset viewer.