Reviewed by Maciej.
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Apr 2005 10:14:35 +0000 (10:14 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Apr 2005 10:14:35 +0000 (10:14 +0000)
        - speedups, total 12% on JavaScript iBench

        I ran the benchmark under Shark and followed its advice a lot, mainly.

        * kjs/collector.cpp:
        (KJS::Collector::allocate): Take out special case for 0; costing speed but unexercised.
        Use numLiveObjectsAtLastCollect instead of numAllocationsSinceLastCollect so we don't
        have to bump it each time we call allocate. Put numLiveObjects into a local variable to
        cut down on global variable accesses. Make "next" cell pointer be a byte offset rather
        than a pointer so we don't need a special case for NULL. Allow freeList to point to some
        bogus item when the entire block is full rather than going out of our way to make it
        point to NULL.
        (KJS::Collector::markProtectedObjects): Get table size and pointer into locals outside
        the loop to avoid re-loading them over and over again.
        (KJS::Collector::collect): Put numLiveObjects into a local variable to cut down on global
        variable accesses. Make "next" cell pointer be a byte offset as above. Put numLiveObjects
        into a local variable to cut down on global variable accesses. Set numLiveObjectsAtLastCollect
        rather than numAllocationsSinceLastCollect.
        (KJS::Collector::numReferencedObjects): Get table size and pointer into locals outside
        the loop to avoid re-loading them over and over again.
        (KJS::Collector::rootObjectClasses): Ditto.

        * kjs/internal.h: Make Value be a friend of NumberImp so it can construct number objects
        directly, avoiding the conversion from Number to Value.

        * kjs/internal.cpp: (StringImp::toObject): Don't use Object::dynamicCast, because we know
        the thing is an object and we don't want to do all the extra work; just cast directly.

        * kjs/list.cpp: (KJS::List::List): Construct valueRefCount in a way that avoids the need for
        a branch -- in the hot case this just meant avoiding checking a variable we just set to false.

        * kjs/lookup.cpp: (keysMatch): Marked this inline.

        * kjs/nodes.cpp: Disabled KJS_BREAKPOINT, to avoid calling hitStatement all the time.
        (BooleanNode::evaluate): Make a Value directly, rather than making a Boolean which is converted
        into a Value.
        (NumberNode::evaluate): Ditto.
        (StringNode::evaluate): Ditto.
        (ArrayNode::evaluate): Ditto.
        (FunctionCallNode::evaluate): Use new inline baseIfMutable to avoid unnecessary getBase function.
        Also just use a pointer for func, rather than an Object.
        (PostfixNode::evaluate): Change code so that it doesn't make an excess Number, and so that it
        passes a "known to be integer" boolean in, often avoiding a conversion from floating point to
        integer and back.
        (DeleteNode::evaluate): Make a Value directly.
        (TypeOfNode::evaluate): Use new inline baseIfMutable and make Value directly.
        (PrefixNode::evaluate): Change code so that it doesn't make an excess Number, and so that it
        passes a "known to be integer" boolean in, often avoiding a conversion from floating point to
        integer and back.
        (UnaryPlusNode::evaluate): Make a Value directly.
        (NegateNode::evaluate): Change code so that it doesn't make an excess Number, and so that it
        passes a "known to be integer" boolean in, often avoiding a conversion from floating point to
        integer and back.
        (BitwiseNotNode::evaluate): Make a Value directly.
        (LogicalNotNode::evaluate): Ditto.
        (ShiftNode::evaluate): Don't convert to a double before making a Value.
        (RelationalNode::evaluate): Make a Value directly.
        (EqualNode::evaluate): Ditto.
        (BitOperNode::evaluate): Ditto.
        (AssignNode::evaluate): Make a Value directly. Change code so that it passes a "known to be integer"
        boolean in, often avoiding a conversion from floating point to integer and back.
        (VarDeclNode::evaluate): Make a Value directly.
        (ForNode::execute): Remove unused local variable.

        * kjs/operations.h:
        (KJS::isNaN): Inlined.
        (KJS::isInf): Ditto.
        (KJS::isPosInf): Ditto.
        (KJS::isNegInf): Ditto.

        * kjs/operations.cpp: Change isNaN, isInf, isPosInf, and isNegInf to be inlines.
        (KJS::equal): Rewrite to avoid creating values and recursing back into the function.
        (KJS::relation): Rearranged code so that we don't need explicit isNaN checks.
        (KJS::add): Changed code to make Value directly, and so that it passes a "known to be integer"
        boolean in, often avoiding a conversion from floating point to integer and back.
        (KJS::mult): Ditto.

        * kjs/property_map.cpp:
        (KJS::PropertyMap::~PropertyMap): Get size and entries pointer outside loop to avoid
        re-getting them inside the loop.
        (KJS::PropertyMap::clear): Ditto. Clear value pointer in addition to key, so we can just
        look at the value pointer in the mark function.
        (KJS::PropertyMap::get): Get sizeMask and entries pointer outside loop to avoid
        re-getting them inside the loop.
        (KJS::PropertyMap::put): Ditto.
        (KJS::PropertyMap::insert): Ditto.
        (KJS::PropertyMap::remove): Ditto.
        (KJS::PropertyMap::mark): Get size and entries pointer outside loop to avoid
        re-getting them inside the loop. Don't bother checking key for 0, since we already have
        to check value for 0. (Also had to change clear() to set value to 0.)
        (KJS::PropertyMap::addEnumerablesToReferenceList): Get size and entries pointer outside
        loop to avoid re-getting them inside the loop.
        (KJS::PropertyMap::addSparseArrayPropertiesToReferenceList): Ditto.
        (KJS::PropertyMap::save): Ditto.

        - other changes

        * kjs/protected_values.h: Remove unneeded class name qualifiers.

        * kjs/reference.h:
        (KJS::Reference::baseIfMutable): New inline function: replaces isMutable().
        (KJS::Reference::Reference): Inlined.
        * kjs/reference.cpp:
        (KJS::Reference::getValue): Rewrite to not use getBase.
        (KJS::Reference::putValue): Ditto.
        (KJS::Reference::deleteValue): Dittol

        * kjs/simple_number.h:
        (KJS::SimpleNumber::integerFits): Added. For use when the parameter is known to be integral.

        * kjs/string_object.cpp: (StringProtoFuncImp::call): Create the number without first converting
        to double in various cases that involve integers.

        * kjs/ustring.h:
        (KJS::UString::attach): Inlined.
        (KJS::UString::release): Inlined.
        * kjs/ustring.cpp:
        (KJS::UString::find): Get first character outside the loop instead of re-fetching it each time.

        * kjs/value.cpp:
        (Value::Value): Added overloads for all the various specific types of values, so you don't have
        to convert from, say, Number to Value, just to create one.
        (Number::Number): Added an overload that takes a boolean to indicate the number is already
        known to be an integer.

        * kjs/value.h: Added more Value constructors, added a version of toNumber that returns
        a boolean to indicate if the number is known to be an integer (because it was a "simple number").
        (KJS::ValueImp::marked): Inlined.
        (KJS::ValueImp::dispatchType): Inlined.
        (KJS::ValueImp::dispatchToPrimitive): Inlined.
        (KJS::ValueImp::dispatchToBoolean): Inlined.
        (KJS::ValueImp::dispatchToNumber): Inlined.
        (KJS::ValueImp::dispatchToString): Inlined.
        (KJS::ValueImp::dispatchToUInt32): Inlined.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9033 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/internal.cpp
JavaScriptCore/kjs/internal.h
JavaScriptCore/kjs/list.cpp
JavaScriptCore/kjs/lookup.cpp
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/operations.cpp
JavaScriptCore/kjs/operations.h
JavaScriptCore/kjs/property_map.cpp
JavaScriptCore/kjs/protected_values.h
JavaScriptCore/kjs/reference.cpp
JavaScriptCore/kjs/reference.h
JavaScriptCore/kjs/simple_number.h
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/ustring.cpp
JavaScriptCore/kjs/ustring.h
JavaScriptCore/kjs/value.cpp
JavaScriptCore/kjs/value.h
JavaScriptCore/tests/mozilla/expected.html

index 4aa4f2065d9b6f04b3d229331fcaa941f38de61a..007d6c545f9f3cd4e8d2cff4ee7485d1fb4afb88 100644 (file)
@@ -1,3 +1,142 @@
+2005-04-20  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - speedups, total 12% on JavaScript iBench
+
+        I ran the benchmark under Shark and followed its advice a lot, mainly.
+
+        * kjs/collector.cpp:
+        (KJS::Collector::allocate): Take out special case for 0; costing speed but unexercised.
+        Use numLiveObjectsAtLastCollect instead of numAllocationsSinceLastCollect so we don't
+        have to bump it each time we call allocate. Put numLiveObjects into a local variable to
+        cut down on global variable accesses. Make "next" cell pointer be a byte offset rather
+        than a pointer so we don't need a special case for NULL. Allow freeList to point to some
+        bogus item when the entire block is full rather than going out of our way to make it
+        point to NULL.
+        (KJS::Collector::markProtectedObjects): Get table size and pointer into locals outside
+        the loop to avoid re-loading them over and over again.
+        (KJS::Collector::collect): Put numLiveObjects into a local variable to cut down on global
+        variable accesses. Make "next" cell pointer be a byte offset as above. Put numLiveObjects
+        into a local variable to cut down on global variable accesses. Set numLiveObjectsAtLastCollect
+        rather than numAllocationsSinceLastCollect.
+        (KJS::Collector::numReferencedObjects): Get table size and pointer into locals outside
+        the loop to avoid re-loading them over and over again.
+        (KJS::Collector::rootObjectClasses): Ditto.
+
+        * kjs/internal.h: Make Value be a friend of NumberImp so it can construct number objects
+        directly, avoiding the conversion from Number to Value.
+
+        * kjs/internal.cpp: (StringImp::toObject): Don't use Object::dynamicCast, because we know
+        the thing is an object and we don't want to do all the extra work; just cast directly.
+
+        * kjs/list.cpp: (KJS::List::List): Construct valueRefCount in a way that avoids the need for
+        a branch -- in the hot case this just meant avoiding checking a variable we just set to false.
+
+        * kjs/lookup.cpp: (keysMatch): Marked this inline.
+
+        * kjs/nodes.cpp: Disabled KJS_BREAKPOINT, to avoid calling hitStatement all the time.
+        (BooleanNode::evaluate): Make a Value directly, rather than making a Boolean which is converted
+        into a Value.
+        (NumberNode::evaluate): Ditto.
+        (StringNode::evaluate): Ditto.
+        (ArrayNode::evaluate): Ditto.
+        (FunctionCallNode::evaluate): Use new inline baseIfMutable to avoid unnecessary getBase function.
+        Also just use a pointer for func, rather than an Object.
+        (PostfixNode::evaluate): Change code so that it doesn't make an excess Number, and so that it
+        passes a "known to be integer" boolean in, often avoiding a conversion from floating point to
+        integer and back.
+        (DeleteNode::evaluate): Make a Value directly.
+        (TypeOfNode::evaluate): Use new inline baseIfMutable and make Value directly.
+        (PrefixNode::evaluate): Change code so that it doesn't make an excess Number, and so that it
+        passes a "known to be integer" boolean in, often avoiding a conversion from floating point to
+        integer and back.
+        (UnaryPlusNode::evaluate): Make a Value directly.
+        (NegateNode::evaluate): Change code so that it doesn't make an excess Number, and so that it
+        passes a "known to be integer" boolean in, often avoiding a conversion from floating point to
+        integer and back.
+        (BitwiseNotNode::evaluate): Make a Value directly.
+        (LogicalNotNode::evaluate): Ditto.
+        (ShiftNode::evaluate): Don't convert to a double before making a Value.
+        (RelationalNode::evaluate): Make a Value directly.
+        (EqualNode::evaluate): Ditto.
+        (BitOperNode::evaluate): Ditto.
+        (AssignNode::evaluate): Make a Value directly. Change code so that it passes a "known to be integer"
+        boolean in, often avoiding a conversion from floating point to integer and back.
+        (VarDeclNode::evaluate): Make a Value directly.
+        (ForNode::execute): Remove unused local variable.
+
+        * kjs/operations.h:
+        (KJS::isNaN): Inlined.
+        (KJS::isInf): Ditto.
+        (KJS::isPosInf): Ditto.
+        (KJS::isNegInf): Ditto.
+
+        * kjs/operations.cpp: Change isNaN, isInf, isPosInf, and isNegInf to be inlines.
+        (KJS::equal): Rewrite to avoid creating values and recursing back into the function.
+        (KJS::relation): Rearranged code so that we don't need explicit isNaN checks.
+        (KJS::add): Changed code to make Value directly, and so that it passes a "known to be integer"
+        boolean in, often avoiding a conversion from floating point to integer and back.
+        (KJS::mult): Ditto.
+
+        * kjs/property_map.cpp:
+        (KJS::PropertyMap::~PropertyMap): Get size and entries pointer outside loop to avoid
+        re-getting them inside the loop.
+        (KJS::PropertyMap::clear): Ditto. Clear value pointer in addition to key, so we can just
+        look at the value pointer in the mark function.
+        (KJS::PropertyMap::get): Get sizeMask and entries pointer outside loop to avoid
+        re-getting them inside the loop.
+        (KJS::PropertyMap::put): Ditto.
+        (KJS::PropertyMap::insert): Ditto.
+        (KJS::PropertyMap::remove): Ditto.
+        (KJS::PropertyMap::mark): Get size and entries pointer outside loop to avoid
+        re-getting them inside the loop. Don't bother checking key for 0, since we already have
+        to check value for 0. (Also had to change clear() to set value to 0.)
+        (KJS::PropertyMap::addEnumerablesToReferenceList): Get size and entries pointer outside
+        loop to avoid re-getting them inside the loop.
+        (KJS::PropertyMap::addSparseArrayPropertiesToReferenceList): Ditto.
+        (KJS::PropertyMap::save): Ditto.
+
+        - other changes
+
+        * kjs/protected_values.h: Remove unneeded class name qualifiers.
+
+        * kjs/reference.h:
+        (KJS::Reference::baseIfMutable): New inline function: replaces isMutable().
+        (KJS::Reference::Reference): Inlined.
+        * kjs/reference.cpp:
+        (KJS::Reference::getValue): Rewrite to not use getBase.
+        (KJS::Reference::putValue): Ditto.
+        (KJS::Reference::deleteValue): Dittol
+
+        * kjs/simple_number.h:
+        (KJS::SimpleNumber::integerFits): Added. For use when the parameter is known to be integral.
+
+        * kjs/string_object.cpp: (StringProtoFuncImp::call): Create the number without first converting
+        to double in various cases that involve integers.
+
+        * kjs/ustring.h:
+        (KJS::UString::attach): Inlined.
+        (KJS::UString::release): Inlined.
+        * kjs/ustring.cpp:
+        (KJS::UString::find): Get first character outside the loop instead of re-fetching it each time.
+
+        * kjs/value.cpp:
+        (Value::Value): Added overloads for all the various specific types of values, so you don't have
+        to convert from, say, Number to Value, just to create one.
+        (Number::Number): Added an overload that takes a boolean to indicate the number is already
+        known to be an integer.
+
+        * kjs/value.h: Added more Value constructors, added a version of toNumber that returns
+        a boolean to indicate if the number is known to be an integer (because it was a "simple number").
+        (KJS::ValueImp::marked): Inlined.
+        (KJS::ValueImp::dispatchType): Inlined.
+        (KJS::ValueImp::dispatchToPrimitive): Inlined.
+        (KJS::ValueImp::dispatchToBoolean): Inlined.
+        (KJS::ValueImp::dispatchToNumber): Inlined.
+        (KJS::ValueImp::dispatchToString): Inlined.
+        (KJS::ValueImp::dispatchToUInt32): Inlined.
+
 2005-04-14  Maciej Stachowiak  <mjs@apple.com>
 
         - make fast_malloc.h a private header, not project
index 080db2383b0b8fe6ba605a8ed3f3ea5659fb4eae..01da57fd28f7ca188caa1603931f6f36f4d3e4f8 100644 (file)
@@ -58,7 +58,7 @@ struct CollectorCell {
     double memory[CELL_ARRAY_LENGTH];
     struct {
       void *zeroIfFree;
-      CollectorCell *next;
+      ptrdiff_t next;
     } freeCell;
   } u;
 };
@@ -81,7 +81,7 @@ struct CollectorHeap {
   int usedOversizeCells;
 
   int numLiveObjects;
-  int numAllocationsSinceLastCollect;
+  int numLiveObjectsAtLastCollect;
 };
 
 static CollectorHeap heap = {NULL, 0, 0, 0, NULL, 0, 0, 0, 0};
@@ -92,15 +92,14 @@ void* Collector::allocate(size_t s)
 {
   assert(Interpreter::lockCount() > 0);
 
-  if (s == 0)
-    return 0L;
-  
   // collect if needed
-  if (++heap.numAllocationsSinceLastCollect >= ALLOCATIONS_PER_COLLECTION) {
+  int numLiveObjects = heap.numLiveObjects;
+  if (numLiveObjects - heap.numLiveObjectsAtLastCollect >= ALLOCATIONS_PER_COLLECTION) {
     collect();
+    numLiveObjects = heap.numLiveObjects;
   }
   
-  if (s > (unsigned)CELL_SIZE) {
+  if (s > static_cast<size_t>(CELL_SIZE)) {
     // oversize allocator
     if (heap.usedOversizeCells == heap.numOversizeCells) {
       heap.numOversizeCells = MAX(MIN_ARRAY_SIZE, heap.numOversizeCells * GROWTH_FACTOR);
@@ -110,11 +109,12 @@ void* Collector::allocate(size_t s)
     void *newCell = kjs_fast_malloc(s);
     heap.oversizeCells[heap.usedOversizeCells] = (CollectorCell *)newCell;
     heap.usedOversizeCells++;
-    heap.numLiveObjects++;
+    heap.numLiveObjects = numLiveObjects + 1;
 
 #if !USE_CONSERVATIVE_GC
     ((ValueImp *)(newCell))->_flags = 0;
 #endif
+
     return newCell;
   }
   
@@ -148,24 +148,19 @@ void* Collector::allocate(size_t s)
   
   // find a free spot in the block and detach it from the free list
   CollectorCell *newCell = targetBlock->freeList;
-
-  if (newCell->u.freeCell.next != NULL) {
-    targetBlock->freeList = newCell->u.freeCell.next;
-  } else if (targetBlock->usedCells == (CELLS_PER_BLOCK - 1)) {
-    // last cell in this block
-    targetBlock->freeList = NULL;
-  } else {
-    // all next pointers are initially 0, meaning "next cell"
-    targetBlock->freeList = newCell + 1;
-  }
+  
+  // "next" field is a byte offset -- 0 means next cell, so a zeroed block is already initialized
+  // could avoid the casts by using a cell offset, but this avoids a relatively-slow multiply
+  targetBlock->freeList = reinterpret_cast<CollectorCell *>(reinterpret_cast<char *>(newCell + 1) + newCell->u.freeCell.next);
 
   targetBlock->usedCells++;
-  heap.numLiveObjects++;
+  heap.numLiveObjects = numLiveObjects + 1;
 
 #if !USE_CONSERVATIVE_GC
   ((ValueImp *)(newCell))->_flags = 0;
 #endif
-  return (void *)(newCell);
+
+  return newCell;
 }
 
 #if TEST_CONSERVATIVE_GC || USE_CONSERVATIVE_GC
@@ -334,8 +329,10 @@ void Collector::markStackObjectsConservatively()
 
 void Collector::markProtectedObjects()
 {
-  for (int i = 0; i < ProtectedValues::_tableSize; i++) {
-    ValueImp *val = ProtectedValues::_table[i].key;
+  int size = ProtectedValues::_tableSize;
+  ProtectedValues::KeyValue *table = ProtectedValues::_table;
+  for (int i = 0; i < size; i++) {
+    ValueImp *val = table[i].key;
     if (val && !val->marked()) {
       val->mark();
     }
@@ -424,20 +421,22 @@ bool Collector::collect()
   // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
   
   int emptyBlocks = 0;
+  int numLiveObjects = heap.numLiveObjects;
 
   for (int block = 0; block < heap.usedBlocks; block++) {
     CollectorBlock *curBlock = heap.blocks[block];
 
     int minimumCellsToProcess = curBlock->usedCells;
 
-    for (int cell = 0; cell < CELLS_PER_BLOCK; cell++) {
-      if (minimumCellsToProcess < cell) {
+    for (int i = 0; i < CELLS_PER_BLOCK; i++) {
+      if (minimumCellsToProcess < i) {
        goto skip_block_sweep;
       }
 
-      ValueImp *imp = (ValueImp *)(curBlock->cells + cell);
+      CollectorCell *cell = curBlock->cells + i;
+      ValueImp *imp = reinterpret_cast<ValueImp *>(cell);
 
-      if (((CollectorCell *)imp)->u.freeCell.zeroIfFree != 0) {
+      if (cell->u.freeCell.zeroIfFree != 0) {
 #if USE_CONSERVATIVE_GC
        if (!imp->_marked)
 #else
@@ -448,13 +447,13 @@ bool Collector::collect()
          // emulate destructing part of 'operator delete()'
          imp->~ValueImp();
          curBlock->usedCells--;
-         heap.numLiveObjects--;
+         numLiveObjects--;
          deleted = true;
 
          // put it on the free list
-         ((CollectorCell *)imp)->u.freeCell.zeroIfFree = 0;
-         ((CollectorCell *)imp)->u.freeCell.next = curBlock->freeList;
-         curBlock->freeList = (CollectorCell *)imp;
+         cell->u.freeCell.zeroIfFree = 0;
+         cell->u.freeCell.next = reinterpret_cast<char *>(curBlock->freeList) - reinterpret_cast<char *>(cell + 1);
+         curBlock->freeList = cell;
 
        } else {
 #if USE_CONSERVATIVE_GC
@@ -518,7 +517,7 @@ bool Collector::collect()
 
       heap.usedOversizeCells--;
       deleted = true;
-      heap.numLiveObjects--;
+      numLiveObjects--;
 
       if (heap.numOversizeCells > MIN_ARRAY_SIZE && heap.usedOversizeCells < heap.numOversizeCells / LOW_WATER_FACTOR) {
        heap.numOversizeCells = heap.numOversizeCells / GROWTH_FACTOR; 
@@ -537,9 +536,10 @@ bool Collector::collect()
     }
   }
   
-  heap.numAllocationsSinceLastCollect = 0;
+  heap.numLiveObjects = numLiveObjects;
+  heap.numLiveObjectsAtLastCollect = numLiveObjects;
   
-  memoryFull = (heap.numLiveObjects >= KJS_MEM_LIMIT);
+  memoryFull = (numLiveObjects >= KJS_MEM_LIMIT);
 
   return deleted;
 }
@@ -603,8 +603,10 @@ int Collector::numReferencedObjects()
   int count = 0;
 
 #if USE_CONSERVATIVE_GC
-  for (int i = 0; i < ProtectedValues::_tableSize; i++) {
-    ValueImp *val = ProtectedValues::_table[i].key;
+  int size = ProtectedValues::_tableSize;
+  ProtectedValues::KeyValue *table = ProtectedValues::_table;
+  for (int i = 0; i < size; i++) {
+    ValueImp *val = table[i].key;
     if (val) {
       ++count;
     }
@@ -641,8 +643,10 @@ const void *Collector::rootObjectClasses()
   CFMutableSetRef classes = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 
 #if USE_CONSERVATIVE_GC
-  for (int i = 0; i < ProtectedValues::_tableSize; i++) {
-    ValueImp *val = ProtectedValues::_table[i].key;
+  int size = ProtectedValues::_tableSize;
+  ProtectedValues::KeyValue *table = ProtectedValues::_table;
+  for (int i = 0; i < size; i++) {
+    ValueImp *val = table[i].key;
     if (val) {
       const char *mangled_name = typeid(*val).name();
       int status;
index b4c8dd780a601ce85392315b8e6f979ba457ed0e..40477f751a04f63edbb533ef11b197b816f9e35a 100644 (file)
@@ -225,7 +225,7 @@ Object StringImp::toObject(ExecState *exec) const
 {
   List args;
   args.append(const_cast<StringImp*>(this));
-  return Object::dynamicCast(exec->lexicalInterpreter()->builtinString().construct(exec,args));
+  return Object(static_cast<ObjectImp *>(exec->lexicalInterpreter()->builtinString().construct(exec, args).imp()));
 }
 
 // ------------------------------ NumberImp ------------------------------------
index fd14ef7812b88707ed8ef724a9e5d18f0e01230a..fff73c818526eb3bb2ee6990dba19456b646a764 100644 (file)
@@ -120,6 +120,7 @@ namespace KJS {
   inline String::String(StringImp *imp) : Value(imp) { }
 
   class NumberImp : public ValueImp {
+    friend class Value;
     friend class Number;
     friend class InterpreterImp;
   public:
index d77844328275f11ad89cb4f75ce47aec7b8b5794..3a959e1cf8393818b39a7ff588457a3c83c7e4a2 100644 (file)
@@ -188,12 +188,9 @@ List::List() : _impBase(allocateListImp()), _needsMarking(false)
     ListImp *imp = static_cast<ListImp *>(_impBase);
     imp->size = 0;
     imp->refCount = 1;
+    imp->valueRefCount = 1;
     imp->capacity = 0;
     imp->overflow = 0;
-
-    if (!_needsMarking) {
-       imp->valueRefCount = 1;
-    }
 #if DUMP_STATISTICS
     if (++numLists > numListsHighWaterMark)
         numListsHighWaterMark = numLists;
@@ -206,13 +203,10 @@ List::List(bool needsMarking) : _impBase(allocateListImp()), _needsMarking(needs
     ListImp *imp = static_cast<ListImp *>(_impBase);
     imp->size = 0;
     imp->refCount = 1;
+    imp->valueRefCount = !needsMarking;
     imp->capacity = 0;
     imp->overflow = 0;
 
-    if (!_needsMarking) {
-       imp->valueRefCount = 1;
-    }
-
 #if DUMP_STATISTICS
     if (++numLists > numListsHighWaterMark)
         numListsHighWaterMark = numLists;
index 5713b614bb42a417ff6975dff8c4cd5193468abc..1b7ab85c96f0d1a030cc855e9b95145ba3e54236 100644 (file)
@@ -31,7 +31,7 @@
 
 using namespace KJS;
 
-static bool keysMatch(const UChar *c, unsigned len, const char *s)
+static inline bool keysMatch(const UChar *c, unsigned len, const char *s)
 {
   for (unsigned i = 0; i != len; i++, c++, s++)
     if (c->uc != (unsigned char)*s)
index 7cb51d7c14c60cccd336bd87d1085989e106eaf6..8dd48d4950a9b4bc4e32c90c2421a0e658fe0326 100644 (file)
@@ -47,6 +47,9 @@
 
 using namespace KJS;
 
+// Disabled for now because it shows up on benchmark (0.5%).
+#if DEBUGGER_SUPPORT
+
 #define KJS_BREAKPOINT \
   if (!hitStatement(exec)) \
     return Completion(Normal);
@@ -56,6 +59,13 @@ using namespace KJS;
       exec->dynamicInterpreter()->imp()->debugger()->imp()->aborted()) \
     return Completion(Normal);
 
+#else
+
+#define KJS_BREAKPOINT
+#define KJS_ABORTPOINT
+
+#endif
+
 #define KJS_CHECKEXCEPTION \
   if (exec->hadException()) \
     return Completion(Throw, exec->exception()); \
@@ -209,21 +219,21 @@ Value NullNode::evaluate(ExecState */*exec*/)
 
 Value BooleanNode::evaluate(ExecState */*exec*/)
 {
-  return Boolean(value);
+  return Value(value);
 }
 
 // ------------------------------ NumberNode -----------------------------------
 
 Value NumberNode::evaluate(ExecState */*exec*/)
 {
-  return Number(value);
+  return Value(value);
 }
 
 // ------------------------------ StringNode -----------------------------------
 
 Value StringNode::evaluate(ExecState */*exec*/)
 {
-  return String(value);
+  return value;
 }
 
 // ------------------------------ RegExpNode -----------------------------------
@@ -378,7 +388,7 @@ Value ArrayNode::evaluate(ExecState *exec)
   }
 
   if (opt)
-    array.put(exec,lengthPropertyName, Number(elision + length), DontEnum | DontDelete);
+    array.put(exec,lengthPropertyName, Value(elision + length), DontEnum | DontDelete);
 
   return array;
 }
@@ -698,37 +708,29 @@ Value FunctionCallNode::evaluate(ExecState *exec)
     return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, expr);
   }
 
-  Object func = Object(static_cast<ObjectImp*>(v.imp()));
+  ObjectImp *func = static_cast<ObjectImp*>(v.imp());
 
-  if (!func.implementsCall()) {
+  if (!func->implementsCall()) {
     return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr);
   }
 
-  Value thisVal;
-  if (ref.isMutable())
-    thisVal = ref.getBase(exec);
-  else
-    thisVal = Null();
-
-  if (thisVal.type() == ObjectType &&
-      Object::dynamicCast(thisVal).inherits(&ActivationImp::info))
-    thisVal = Null();
+  ObjectImp *thisObjImp = 0;
+  ValueImp *thisValImp = ref.baseIfMutable();
+  if (thisValImp && thisValImp->type() == ObjectType && !static_cast<ObjectImp *>(thisValImp)->inherits(&ActivationImp::info))
+    thisObjImp = static_cast<ObjectImp *>(thisValImp);
 
-  if (thisVal.type() != ObjectType) {
+  if (!thisObjImp) {
     // ECMA 11.2.3 says that in this situation the this value should be null.
     // However, section 10.2.3 says that in the case where the value provided
     // by the caller is null, the global object should be used. It also says
     // that the section does not apply to interal functions, but for simplicity
     // of implementation we use the global object anyway here. This guarantees
     // that in host objects you always get a valid object for this.
-    // thisVal = Null();
-    thisVal = exec->dynamicInterpreter()->globalObject();
+    thisObjImp = exec->dynamicInterpreter()->globalObject().imp();
   }
 
-  Object thisObj = Object::dynamicCast(thisVal);
-  Value result = func.call(exec,thisObj, argList);
-
-  return result;
+  Object thisObj(thisObjImp);
+  return func->call(exec, thisObj, argList);
 }
 
 // ------------------------------ PostfixNode ----------------------------------
@@ -753,14 +755,14 @@ Value PostfixNode::evaluate(ExecState *exec)
   Reference ref = expr->evaluateReference(exec);
   KJS_CHECKEXCEPTIONVALUE
   Value v = ref.getValue(exec);
-  Number n = v.toNumber(exec);
 
-  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;
-  Value n2 = Number(newValue);
+  bool knownToBeInteger;
+  double n = v.toNumber(exec, knownToBeInteger);
 
-  ref.putValue(exec,n2);
+  double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
+  ref.putValue(exec, Value(newValue, knownToBeInteger));
 
-  return n;
+  return Value(n, knownToBeInteger);
 }
 
 // ------------------------------ DeleteNode -----------------------------------
@@ -784,7 +786,7 @@ Value DeleteNode::evaluate(ExecState *exec)
 {
   Reference ref = expr->evaluateReference(exec);
   KJS_CHECKEXCEPTIONVALUE
-  return Boolean(ref.deleteValue(exec));
+  return Value(ref.deleteValue(exec));
 }
 
 // ------------------------------ VoidNode -------------------------------------
@@ -834,11 +836,9 @@ Value TypeOfNode::evaluate(ExecState *exec)
   const char *s = 0L;
   Reference ref = expr->evaluateReference(exec);
   KJS_CHECKEXCEPTIONVALUE
-  if (ref.isMutable()) {
-    Value b = ref.getBase(exec);
-    if (b.type() == NullType)
-      return String("undefined");
-  }
+  ValueImp *b = ref.baseIfMutable();
+  if (b && b->dispatchType() == NullType)
+    return Value("undefined");
   Value v = ref.getValue(exec);
   switch (v.type())
     {
@@ -865,7 +865,7 @@ Value TypeOfNode::evaluate(ExecState *exec)
       break;
     }
 
-  return String(s);
+  return Value(s);
 }
 
 // ------------------------------ PrefixNode -----------------------------------
@@ -890,12 +890,14 @@ Value PrefixNode::evaluate(ExecState *exec)
   Reference ref = expr->evaluateReference(exec);
   KJS_CHECKEXCEPTIONVALUE
   Value v = ref.getValue(exec);
-  Number n = v.toNumber(exec);
 
-  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;
-  Value n2 = Number(newValue);
+  bool knownToBeInteger;
+  double n = v.toNumber(exec, knownToBeInteger);
+
+  double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
+  Value n2(newValue, knownToBeInteger);
 
-  ref.putValue(exec,n2);
+  ref.putValue(exec, n2);
 
   return n2;
 }
@@ -922,7 +924,7 @@ Value UnaryPlusNode::evaluate(ExecState *exec)
   Value v = expr->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
 
-  return Number(v.toNumber(exec)); /* TODO: optimize */
+  return Value(v.toNumber(exec)); /* TODO: optimize */
 }
 
 // ------------------------------ NegateNode -----------------------------------
@@ -946,11 +948,10 @@ Value NegateNode::evaluate(ExecState *exec)
 {
   Value v = expr->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
-  Number n = v.toNumber(exec);
-
-  double d = -n.value();
 
-  return Number(d);
+  bool knownToBeInteger;
+  double n = v.toNumber(exec, knownToBeInteger);
+  return Value(-n, knownToBeInteger && n != 0);
 }
 
 // ------------------------------ BitwiseNotNode -------------------------------
@@ -974,9 +975,7 @@ Value BitwiseNotNode::evaluate(ExecState *exec)
 {
   Value v = expr->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
-  int i32 = v.toInt32(exec);
-
-  return Number(~i32);
+  return Value(~v.toInt32(exec));
 }
 
 // ------------------------------ LogicalNotNode -------------------------------
@@ -1000,9 +999,7 @@ Value LogicalNotNode::evaluate(ExecState *exec)
 {
   Value v = expr->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
-  bool b = v.toBoolean(exec);
-
-  return Boolean(!b);
+  return Value(!v.toBoolean(exec));
 }
 
 // ------------------------------ MultNode -------------------------------------
@@ -1034,7 +1031,7 @@ Value MultNode::evaluate(ExecState *exec)
   Value v2 = term2->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
 
-  return mult(exec,v1, v2, oper);
+  return mult(exec, v1, v2, oper);
 }
 
 // ------------------------------ AddNode --------------------------------------
@@ -1066,7 +1063,7 @@ Value AddNode::evaluate(ExecState *exec)
   Value v2 = term2->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
 
-  return add(exec,v1, v2, oper);
+  return add(exec, v1, v2, oper);
 }
 
 // ------------------------------ ShiftNode ------------------------------------
@@ -1099,23 +1096,17 @@ Value ShiftNode::evaluate(ExecState *exec)
   unsigned int i2 = v2.toUInt32(exec);
   i2 &= 0x1f;
 
-  double result;
   switch (oper) {
   case OpLShift:
-    result = v1.toInt32(exec) << i2;
-    break;
+    return Value(v1.toInt32(exec) << i2);
   case OpRShift:
-    result = v1.toInt32(exec) >> i2;
-    break;
+    return Value(v1.toInt32(exec) >> i2);
   case OpURShift:
-    result = v1.toUInt32(exec) >> i2;
-    break;
+    return Value(v1.toUInt32(exec) >> i2);
   default:
     assert(!"ShiftNode: unhandled switch case");
-    result = 0;
+    return Undefined();
   }
-
-  return Number(result);
 }
 
 // ------------------------------ RelationalNode -------------------------------
@@ -1177,14 +1168,14 @@ Value RelationalNode::evaluate(ExecState *exec)
       // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
       // property. It seems that all object have the property, but not all implement it, so in this
       // case we return false (consistent with mozilla)
-      return Boolean(false);
+      return Value(false);
       //      return throwError(exec, TypeError,
       //                       "Object does not implement the [[HasInstance]] method." );
     }
     return o2.hasInstance(exec, v1);
   }
 
-  return Boolean(b);
+  return Value(b);
 }
 
 // ------------------------------ EqualNode ------------------------------------
@@ -1225,7 +1216,7 @@ Value EqualNode::evaluate(ExecState *exec)
     bool eq = strictEqual(exec,v1, v2);
     result = oper == OpStrEq ? eq : !eq;
   }
-  return Boolean(result);
+  return Value(result);
 }
 
 // ------------------------------ BitOperNode ----------------------------------
@@ -1265,7 +1256,7 @@ Value BitOperNode::evaluate(ExecState *exec)
   else
     result = i1 | i2;
 
-  return Number(result);
+  return Value(result);
 }
 
 // ------------------------------ BinaryLogicalNode ----------------------------
@@ -1395,37 +1386,39 @@ Value AssignNode::evaluate(ExecState *exec)
     case OpLShift:
       i1 = v1.toInt32(exec);
       i2 = v2.toInt32(exec);
-      v = Number(i1 <<= i2);
+      v = Value(i1 << i2);
       break;
     case OpRShift:
       i1 = v1.toInt32(exec);
       i2 = v2.toInt32(exec);
-      v = Number(i1 >>= i2);
+      v = Value(i1 >> i2);
       break;
     case OpURShift:
       ui = v1.toUInt32(exec);
       i2 = v2.toInt32(exec);
-      v = Number(ui >>= i2);
+      v = Value(ui >> i2);
       break;
     case OpAndEq:
       i1 = v1.toInt32(exec);
       i2 = v2.toInt32(exec);
-      v = Number(i1 &= i2);
+      v = Value(i1 & i2);
       break;
     case OpXOrEq:
       i1 = v1.toInt32(exec);
       i2 = v2.toInt32(exec);
-      v = Number(i1 ^= i2);
+      v = Value(i1 ^ i2);
       break;
     case OpOrEq:
       i1 = v1.toInt32(exec);
       i2 = v2.toInt32(exec);
-      v = Number(i1 |= i2);
+      v = Value(i1 | i2);
       break;
     case OpModEq: {
-      double d1 = v1.toNumber(exec);
-      double d2 = v2.toNumber(exec);
-      v = Number(fmod(d1,d2));
+      bool d1KnownToBeInteger;
+      double d1 = v1.toNumber(exec, d1KnownToBeInteger);
+      bool d2KnownToBeInteger;
+      double d2 = v2.toNumber(exec, d2KnownToBeInteger);
+      v = Value(fmod(d1, d2), d1KnownToBeInteger && d2KnownToBeInteger && d2 != 0);
     }
       break;
     default:
@@ -1595,7 +1588,7 @@ bool VarDeclNode::deref()
 // ECMA 12.2
 Value VarDeclNode::evaluate(ExecState *exec)
 {
-  Object variable = Object::dynamicCast(exec->context().imp()->variableObject());
+  Object variable = exec->context().imp()->variableObject();
 
   Value val;
   if (init) {
@@ -1616,7 +1609,7 @@ Value VarDeclNode::evaluate(ExecState *exec)
   // "var location" creates a dynamic property instead of activating window.location.
   variable.put(exec, ident, val, DontDelete | Internal);
 
-  return String(ident.ustring());
+  return ident.ustring();
 }
 
 void VarDeclNode::processVarDecls(ExecState *exec)
@@ -1977,8 +1970,7 @@ bool ForNode::deref()
 // ECMA 12.6.3
 Completion ForNode::execute(ExecState *exec)
 {
-  Value e, v, cval;
-  bool b;
+  Value v, cval;
 
   if (expr1) {
     v = expr1->evaluate(exec);
@@ -1988,8 +1980,7 @@ Completion ForNode::execute(ExecState *exec)
     if (expr2) {
       v = expr2->evaluate(exec);
       KJS_CHECKEXCEPTION
-      b = v.toBoolean(exec);
-      if (b == false)
+      if (!v.toBoolean(exec))
        return Completion(Normal, cval);
     }
     // bail out on error
index cbfecf61bfe6f9028a2de2e92034d3bacf364aec..84deba02c29f384ac5828cc003d0335079a29d36 100644 (file)
@@ -48,6 +48,8 @@
 
 using namespace KJS;
 
+#if !APPLE_CHANGES
+
 bool KJS::isNaN(double d)
 {
 #ifdef HAVE_FUNC_ISNAN
@@ -106,57 +108,61 @@ bool KJS::isNegInf(double d)
 #endif
 }
 
+#endif
+
 // ECMA 11.9.3
 bool KJS::equal(ExecState *exec, const Value& v1, const Value& v2)
 {
-  Type t1 = v1.type();
-  Type t2 = v2.type();
+    Type t1 = v1.type();
+    Type t2 = v2.type();
+
+    if (t1 != t2) {
+        if (t1 == UndefinedType)
+            t1 = NullType;
+        if (t2 == UndefinedType)
+            t2 = NullType;
+
+        if (t1 == BooleanType)
+            t1 = NumberType;
+        if (t2 == BooleanType)
+            t2 = NumberType;
+
+        if (t1 == NumberType && t2 == StringType) {
+            // use toNumber
+        } else if (t1 == StringType && t2 == NumberType) {
+            t1 = NumberType;
+            // use toNumber
+        } else {
+            if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType)
+                return equal(exec, v1, v2.toPrimitive(exec));
+            if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType))
+                return equal(exec, v1.toPrimitive(exec), v2);
+            if (t1 != t2)
+                return false;
+        }
+    }
 
-  if (t1 == t2) {
     if (t1 == UndefinedType || t1 == NullType)
-      return true;
-    if (t1 == NumberType)
-    {
-      double d1 = v1.toNumber(exec);
-      double d2 = v2.toNumber(exec);
-      if ( isNaN( d1 ) || isNaN( d2 ) )
-        return false;
-      return ( d1 == d2 ); /* TODO: +0, -0 ? */
+        return true;
+
+    if (t1 == NumberType) {
+        double d1 = v1.toNumber(exec);
+        double d2 = v2.toNumber(exec);
+        // FIXME: Isn't this already how NaN behaves?
+        // Why the extra line of code?
+        if (isNaN(d1) || isNaN(d2))
+            return false;
+        return d1 == d2; /* TODO: +0, -0 ? */
     }
+
     if (t1 == StringType)
-      return (v1.toString(exec) == v2.toString(exec));
+        return v1.toString(exec) == v2.toString(exec);
+
     if (t1 == BooleanType)
-      return (v1.toBoolean(exec) == v2.toBoolean(exec));
+        return v1.toBoolean(exec) == v2.toBoolean(exec);
 
     // types are Object
-    return (v1.imp() == v2.imp());
-  }
-
-  // different types
-  if ((t1 == NullType && t2 == UndefinedType) || (t1 == UndefinedType && t2 == NullType))
-    return true;
-  if (t1 == NumberType && t2 == StringType) {
-    Number n2 = v2.toNumber(exec);
-    return equal(exec,v1, n2);
-  }
-  if ((t1 == StringType && t2 == NumberType) || t1 == BooleanType) {
-    Number n1 = v1.toNumber(exec);
-    return equal(exec,n1, v2);
-  }
-  if (t2 == BooleanType) {
-    Number n2 = v2.toNumber(exec);
-    return equal(exec,v1, n2);
-  }
-  if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType) {
-    Value p2 = v2.toPrimitive(exec);
-    return equal(exec,v1, p2);
-  }
-  if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType)) {
-    Value p1 = v1.toPrimitive(exec);
-    return equal(exec,p1, v2);
-  }
-
-  return false;
+    return v1.imp() == v2.imp();
 }
 
 bool KJS::strictEqual(ExecState *exec, const Value &v1, const Value &v2)
@@ -171,6 +177,8 @@ bool KJS::strictEqual(ExecState *exec, const Value &v1, const Value &v2)
   if (t1 == NumberType) {
     double n1 = v1.toNumber(exec);
     double n2 = v2.toNumber(exec);
+    // FIXME: Isn't this already how NaN behaves?
+    // Why the extra line of code?
     if (isNaN(n1) || isNaN(n2))
       return false;
     if (n1 == n2)
@@ -199,24 +207,11 @@ int KJS::relation(ExecState *exec, const Value& v1, const Value& v2)
 
   double n1 = p1.toNumber(exec);
   double n2 = p2.toNumber(exec);
-  if ( isNaN( n1 ) || isNaN( n2 ) )
-    return -1; // means undefined
-#if APPLE_CHANGES
-  return n1 < n2;
-#else
-  if (n1 == n2)
-    return 0;
-  /* TODO: +0, -0 */
-  if ( isPosInf( n1 ) )
-    return 0;
-  if ( isPosInf( n2 ) )
+  if (n1 < n2)
     return 1;
-  if ( isNegInf( n2 ) )
+  if (n1 >= n2)
     return 0;
-  if ( isNegInf( n1 ) )
-    return 1;
-  return (n1 < n2) ? 1 : 0;
-#endif
+  return -1; // must be NaN, so undefined
 }
 
 int KJS::maxInt(int d1, int d2)
@@ -238,35 +233,43 @@ Value KJS::add(ExecState *exec, const Value &v1, const Value &v2, char oper)
   Value p2 = v2.toPrimitive(exec, preferred);
 
   if ((p1.type() == StringType || p2.type() == StringType) && oper == '+') {
-    UString s1 = p1.toString(exec);
-    UString s2 = p2.toString(exec);
-
-    return String(s1 + s2);
+    return p1.toString(exec) + p2.toString(exec);
   }
 
-  double n1 = p1.toNumber(exec);
-  double n2 = p2.toNumber(exec);
+  bool n1KnownToBeInteger;
+  double n1 = p1.toNumber(exec, n1KnownToBeInteger);
+  bool n2KnownToBeInteger;
+  double n2 = p2.toNumber(exec, n2KnownToBeInteger);
+
+  bool resultKnownToBeInteger = n1KnownToBeInteger && n2KnownToBeInteger;
 
   if (oper == '+')
-    return Number(n1 + n2);
+    return Value(n1 + n2, resultKnownToBeInteger);
   else
-    return Number(n1 - n2);
+    return Value(n1 - n2, resultKnownToBeInteger);
 }
 
 // ECMA 11.5
 Value KJS::mult(ExecState *exec, const Value &v1, const Value &v2, char oper)
 {
-  double n1 = v1.toNumber(exec);
-  double n2 = v2.toNumber(exec);
+  bool n1KnownToBeInteger;
+  double n1 = v1.toNumber(exec, n1KnownToBeInteger);
+  bool n2KnownToBeInteger;
+  double n2 = v2.toNumber(exec, n2KnownToBeInteger);
 
   double result;
+  bool resultKnownToBeInteger;
 
-  if (oper == '*')
+  if (oper == '*') {
     result = n1 * n2;
-  else if (oper == '/')
+    resultKnownToBeInteger = n1KnownToBeInteger && n2KnownToBeInteger;
+  } else if (oper == '/') {
     result = n1 / n2;
-  else
+    resultKnownToBeInteger = false;
+  } else {
     result = fmod(n1, n2);
+    resultKnownToBeInteger = n1KnownToBeInteger && n2KnownToBeInteger && n2 != 0;
+  }
 
-  return Number(result);
+  return Value(result, resultKnownToBeInteger);
 }
index 3b5a56ccf8487e4d2a6706e8eeaa0f0db8fec1db..5df904f560ec35e17963a5cc53ed936179de4d34 100644 (file)
@@ -29,6 +29,12 @@ namespace KJS {
 
   class ExecState;
 
+#if APPLE_CHANGES
+  inline bool isNaN(double d) { return isnan(d); }
+  inline bool isInf(double d) { return isinf(d); }
+  inline bool isPosInf(double d) { return isinf(d) && d > 0; }
+  inline bool isNegInf(double d) { return isinf(d) && d < 0; }
+#else
   /**
    * @return True if d is not a number (platform support required).
    */
@@ -39,6 +45,8 @@ namespace KJS {
   bool isInf(double d);
   bool isPosInf(double d);
   bool isNegInf(double d);
+#endif
+
   bool equal(ExecState *exec, const Value& v1, const Value& v2);
   bool strictEqual(ExecState *exec, const Value &v1, const Value &v2);
   /**
index dbbce655bdf89d7c16fbdb1a6de4d0670e8a98bd..c153be892e25b55a5cef7e66ecf7ba5000034495 100644 (file)
@@ -113,8 +113,10 @@ PropertyMap::~PropertyMap()
         return;
     }
     
-    for (int i = 0; i < _table->size; i++) {
-        UString::Rep *key = _table->entries[i].key;
+    int size = _table->size;
+    Entry *entries = _table->entries;
+    for (int i = 0; i < size; i++) {
+        UString::Rep *key = entries[i].key;
         if (key)
             key->deref();
     }
@@ -134,11 +136,14 @@ void PropertyMap::clear()
         return;
     }
 
-    for (int i = 0; i < _table->size; i++) {
-        UString::Rep *key = _table->entries[i].key;
+    int size = _table->size;
+    Entry *entries = _table->entries;
+    for (int i = 0; i < size; i++) {
+        UString::Rep *key = entries[i].key;
         if (key) {
             key->deref();
-            _table->entries[i].key = 0;
+            entries[i].key = 0;
+            entries[i].value = 0;
         }
     }
     _table->keyCount = 0;
@@ -163,20 +168,22 @@ ValueImp *PropertyMap::get(const Identifier &name, int &attributes) const
     }
     
     unsigned h = rep->hash();
-    int i = h & _table->sizeMask;
+    int sizeMask = _table->sizeMask;
+    Entry *entries = _table->entries;
+    int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
     ++numProbes;
-    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;
+    numCollisions += entries[i].key && entries[i].key != rep;
 #endif
-    while (UString::Rep *key = _table->entries[i].key) {
+    while (UString::Rep *key = entries[i].key) {
         if (rep == key) {
-            attributes = _table->entries[i].attributes;
-            return _table->entries[i].value;
+            attributes = entries[i].attributes;
+            return entries[i].value;
         }
         if (k == 0)
-            k = 1 | (h % _table->sizeMask);
-        i = (i + k) & _table->sizeMask;
+            k = 1 | (h % sizeMask);
+        i = (i + k) & sizeMask;
 #if DUMP_STATISTICS
         ++numRehashes;
 #endif
@@ -200,18 +207,20 @@ ValueImp *PropertyMap::get(const Identifier &name) const
     }
     
     unsigned h = rep->hash();
-    int i = h & _table->sizeMask;
+    int sizeMask = _table->sizeMask;
+    Entry *entries = _table->entries;
+    int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
     ++numProbes;
-    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;
+    numCollisions += entries[i].key && entries[i].key != rep;
 #endif
-    while (UString::Rep *key = _table->entries[i].key) {
+    while (UString::Rep *key = entries[i].key) {
         if (rep == key)
-            return _table->entries[i].value;
+            return entries[i].value;
         if (k == 0)
-            k = 1 | (h % _table->sizeMask);
-        i = (i + k) & _table->sizeMask;
+            k = 1 | (h % sizeMask);
+        i = (i + k) & sizeMask;
 #if DUMP_STATISTICS
         ++numRehashes;
 #endif
@@ -277,18 +286,20 @@ void PropertyMap::put(const Identifier &name, ValueImp *value, int attributes)
         expand();
     
     unsigned h = rep->hash();
-    int i = h & _table->sizeMask;
+    int sizeMask = _table->sizeMask;
+    Entry *entries = _table->entries;
+    int i = h & sizeMask;
     int k = 0;
     bool foundDeletedElement = false;
     int deletedElementIndex = 0;    /* initialize to make the compiler happy */
 #if DUMP_STATISTICS
     ++numProbes;
-    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;
+    numCollisions += entries[i].key && entries[i].key != rep;
 #endif
-    while (UString::Rep *key = _table->entries[i].key) {
+    while (UString::Rep *key = entries[i].key) {
         if (rep == key) {
             // Put a new value in an existing hash table entry.
-            _table->entries[i].value = value;
+            entries[i].value = value;
             // Attributes are intentionally not updated.
             return;
         }
@@ -298,8 +309,8 @@ void PropertyMap::put(const Identifier &name, ValueImp *value, int attributes)
             deletedElementIndex = i;
         }
         if (k == 0)
-            k = 1 | (h % _table->sizeMask);
-        i = (i + k) & _table->sizeMask;
+            k = 1 | (h % sizeMask);
+        i = (i + k) & sizeMask;
 #if DUMP_STATISTICS
         ++numRehashes;
 #endif
@@ -308,16 +319,16 @@ void PropertyMap::put(const Identifier &name, ValueImp *value, int attributes)
     // Use either the deleted element or the 0 at the end of the chain.
     if (foundDeletedElement) {
         i = deletedElementIndex;
-        _table->entries[i].key->deref();
+        entries[i].key->deref();
         --_table->sentinelCount;
     }
 
     // Create a new hash table entry.
     rep->ref();
-    _table->entries[i].key = rep;
-    _table->entries[i].value = value;
-    _table->entries[i].attributes = attributes;
-    _table->entries[i].index = ++_table->lastIndexUsed;
+    entries[i].key = rep;
+    entries[i].value = value;
+    entries[i].attributes = attributes;
+    entries[i].index = ++_table->lastIndexUsed;
     ++_table->keyCount;
 
     checkConsistency();
@@ -328,26 +339,28 @@ void PropertyMap::insert(UString::Rep *key, ValueImp *value, int attributes, int
     assert(_table);
 
     unsigned h = key->hash();
-    int i = h & _table->sizeMask;
+    int sizeMask = _table->sizeMask;
+    Entry *entries = _table->entries;
+    int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
     ++numProbes;
-    numCollisions += _table->entries[i].key && _table->entries[i].key != key;
+    numCollisions += entries[i].key && entries[i].key != key;
 #endif
-    while (_table->entries[i].key) {
-        assert(_table->entries[i].key != &UString::Rep::null);
+    while (entries[i].key) {
+        assert(entries[i].key != &UString::Rep::null);
         if (k == 0)
-            k = 1 | (h % _table->sizeMask);
-        i = (i + k) & _table->sizeMask;
+            k = 1 | (h % sizeMask);
+        i = (i + k) & sizeMask;
 #if DUMP_STATISTICS
         ++numRehashes;
 #endif
     }
     
-    _table->entries[i].key = key;
-    _table->entries[i].value = value;
-    _table->entries[i].attributes = attributes;
-    _table->entries[i].index = index;
+    entries[i].key = key;
+    entries[i].value = value;
+    entries[i].attributes = attributes;
+    entries[i].index = index;
 }
 
 void PropertyMap::expand()
@@ -435,19 +448,21 @@ void PropertyMap::remove(const Identifier &name)
 
     // Find the thing to remove.
     unsigned h = rep->hash();
-    int i = h & _table->sizeMask;
+    int sizeMask = _table->sizeMask;
+    Entry *entries = _table->entries;
+    int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
     ++numProbes;
     ++numRemoves;
-    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;
+    numCollisions += entries[i].key && entries[i].key != rep;
 #endif
-    while ((key = _table->entries[i].key)) {
+    while ((key = entries[i].key)) {
         if (rep == key)
             break;
         if (k == 0)
-            k = 1 | (h % _table->sizeMask);
-        i = (i + k) & _table->sizeMask;
+            k = 1 | (h % sizeMask);
+        i = (i + k) & sizeMask;
 #if DUMP_STATISTICS
         ++numRehashes;
 #endif
@@ -461,9 +476,9 @@ void PropertyMap::remove(const Identifier &name)
     key->deref();
     key = &UString::Rep::null;
     key->ref();
-    _table->entries[i].key = key;
-    _table->entries[i].value = 0;
-    _table->entries[i].attributes = DontEnum;
+    entries[i].key = key;
+    entries[i].value = 0;
+    entries[i].attributes = DontEnum;
     assert(_table->keyCount >= 1);
     --_table->keyCount;
     ++_table->sentinelCount;
@@ -487,15 +502,12 @@ void PropertyMap::mark() const
         return;
     }
 
-    for (int i = 0; i != _table->size; ++i) {
-        UString::Rep *key = _table->entries[i].key;
-        if (key) {
-            ValueImp *v = _table->entries[i].value;
-            // Check v against 0 to handle deleted elements
-            // without comparing key to UString::Rep::null.
-            if (v && !v->marked())
-                v->mark();
-        }
+    int size = _table->size;
+    Entry *entries = _table->entries;
+    for (int i = 0; i != size; ++i) {
+        ValueImp *v = entries[i].value;
+        if (v && !v->marked())
+            v->mark();
     }
 }
 
@@ -531,8 +543,10 @@ void PropertyMap::addEnumerablesToReferenceList(ReferenceList &list, const Objec
 
     // Get pointers to the enumerable entries in the buffer.
     Entry **p = sortedEnumerables;
-    for (int i = 0; i != _table->size; ++i) {
-        Entry *e = &_table->entries[i];
+    int size = _table->size;
+    Entry *entries = _table->entries;
+    for (int i = 0; i != size; ++i) {
+        Entry *e = &entries[i];
         if (e->key && !(e->attributes & DontEnum))
             *p++ = e;
     }
@@ -566,8 +580,10 @@ void PropertyMap::addSparseArrayPropertiesToReferenceList(ReferenceList &list, c
         return;
     }
 
-    for (int i = 0; i != _table->size; ++i) {
-        UString::Rep *key = _table->entries[i].key;
+    int size = _table->size;
+    Entry *entries = _table->entries;
+    for (int i = 0; i != size; ++i) {
+        UString::Rep *key = entries[i].key;
         if (key && key != &UString::Rep::null)
         {
             UString k(key);
@@ -589,8 +605,10 @@ void PropertyMap::save(SavedProperties &p) const
             ++count;
 #endif
     } else {
-        for (int i = 0; i != _table->size; ++i)
-            if (_table->entries[i].key && !(_table->entries[i].attributes & (ReadOnly | Function)))
+        int size = _table->size;
+        Entry *entries = _table->entries;
+        for (int i = 0; i != size; ++i)
+            if (entries[i].key && !(entries[i].attributes & (ReadOnly | Function)))
                 ++count;
     }
 
@@ -630,8 +648,10 @@ void PropertyMap::save(SavedProperties &p) const
 
         // Get pointers to the entries in the buffer.
         Entry **p = sortedEntries;
-        for (int i = 0; i != _table->size; ++i) {
-            Entry *e = &_table->entries[i];
+        int size = _table->size;
+        Entry *entries = _table->entries;
+        for (int i = 0; i != size; ++i) {
+            Entry *e = &entries[i];
             if (e->key && !(e->attributes & (ReadOnly | Function)))
                 *p++ = e;
         }
index 40bb1523d66eb40bb40a5314cee478b9a58fb180..169eb9fa150814fa33ee215cfbe650d179e3bdde 100644 (file)
@@ -46,14 +46,13 @@ namespace KJS {
        static void rehash(int newTableSize);
        static unsigned computeHash(ValueImp *pointer);
 
-       // let the collector scan the table directly for protected
-       // values
+       // let the collector scan the table directly for protected values
        friend class Collector;
 
-       static KeyValue * ProtectedValues::_table;
-       static int ProtectedValues::_tableSize;
-       static int ProtectedValues::_tableSizeMask;
-       static int ProtectedValues::_keyCount;
+       static KeyValue *_table;
+       static int _tableSize;
+       static int _tableSizeMask;
+       static int _keyCount;
     };
 }
 
index 9eed1b65d84e7ae63a3facdd20d2f07b9c7d3d1c..86c6721132952668fbbe935502ba3d555cc1805c 100644 (file)
@@ -23,7 +23,7 @@
 #include "reference.h"
 #include "internal.h"
 
-using namespace KJS;
+namespace KJS {
 
 // ------------------------------ Reference ------------------------------------
 
@@ -83,10 +83,6 @@ Reference Reference::makeValueReference(const Value& v)
   return valueRef;
 }
 
-Reference::Reference()
-{
-}
-
 Value Reference::getBase(ExecState *exec) const
 {
   if (baseIsValue) {
@@ -118,16 +114,17 @@ Value Reference::getValue(ExecState *exec) const
     return base;
   }
 
-  Value o = getBase(exec);
+  ValueImp *o = base.imp();
+  Type t = o ? o->dispatchType() : NullType;
 
-  if (o.isNull() || o.type() == NullType) {
+  if (t == NullType) {
     UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec).ustring();
     Object err = Error::create(exec, ReferenceError, m.ascii());
     exec->setException(err);
     return err;
   }
 
-  if (o.type() != ObjectType) {
+  if (t != ObjectType) {
     UString m = I18N_NOOP("Base is not an object");
     Object err = Error::create(exec, ReferenceError, m.ascii());
     exec->setException(err);
@@ -135,14 +132,14 @@ Value Reference::getValue(ExecState *exec) const
   }
 
   if (propertyNameIsNumber)
-    return static_cast<ObjectImp*>(o.imp())->get(exec,propertyNameAsNumber);
-  return static_cast<ObjectImp*>(o.imp())->get(exec,prop);
+    return static_cast<ObjectImp*>(o)->get(exec, propertyNameAsNumber);
+  return static_cast<ObjectImp*>(o)->get(exec, prop);
 }
 
 void Reference::putValue(ExecState *exec, const Value &w)
 {
   if (baseIsValue) {
-    Object err = Error::create(exec,ReferenceError);
+    Object err = Error::create(exec, ReferenceError);
     exec->setException(err);
     return;
   }
@@ -150,13 +147,16 @@ void Reference::putValue(ExecState *exec, const Value &w)
 #ifdef KJS_VERBOSE
   printInfo(exec,(UString("setting property ")+getPropertyName(exec)).cstring().c_str(),w);
 #endif
-  Value o = getBase(exec);
-  if (o.type() == NullType)
-    o = exec->lexicalInterpreter()->globalObject();
+
+  ValueImp *o = base.imp();
+  Type t = o ? o->dispatchType() : NullType;
+
+  if (t == NullType)
+    o = exec->lexicalInterpreter()->globalObject().imp();
 
   if (propertyNameIsNumber)
-    return static_cast<ObjectImp*>(o.imp())->put(exec,propertyNameAsNumber, w);
-  return static_cast<ObjectImp*>(o.imp())->put(exec,prop, w);
+    return static_cast<ObjectImp*>(o)->put(exec, propertyNameAsNumber, w);
+  return static_cast<ObjectImp*>(o)->put(exec, prop, w);
 }
 
 bool Reference::deleteValue(ExecState *exec)
@@ -167,20 +167,18 @@ bool Reference::deleteValue(ExecState *exec)
     return false;
   }
 
-  Value b = getBase(exec);
+  ValueImp *o = base.imp();
+  Type t = o ? o->dispatchType() : NullType;
 
   // The spec doesn't mention what to do if the base is null... just return true
-  if (b.type() != ObjectType) {
-    assert(b.type() == NullType);
+  if (t != ObjectType) {
+    assert(t == NullType);
     return true;
   }
 
   if (propertyNameIsNumber)
-    return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,propertyNameAsNumber);
-  return static_cast<ObjectImp*>(b.imp())->deleteProperty(exec,prop);
+    return static_cast<ObjectImp*>(o)->deleteProperty(exec,propertyNameAsNumber);
+  return static_cast<ObjectImp*>(o)->deleteProperty(exec,prop);
 }
 
-bool Reference::isMutable()
-{ 
-  return !baseIsValue;
 }
index 706a15ca09a0ed6a3c6079a774828f67132e297f..941890cefdda5bc6d082e56b6a6d47d980c217c8 100644 (file)
@@ -68,10 +68,10 @@ namespace KJS {
     void putValue(ExecState *exec, const Value &w);
     bool deleteValue(ExecState *exec);
 
-    bool isMutable();
+    ValueImp *baseIfMutable() const { return baseIsValue ? 0 : base.imp(); }
 
   private:
-    Reference();
+    Reference() { }
 
     Value base;
     unsigned propertyNameAsNumber;
index b9ac9453d9c70e697d99b90179b1a3fd88cec56c..7d97f40fbad3c82a498ff91add0be4238c5ea44d 100644 (file)
 #ifndef _KJS_SIMPLE_NUMBER_H_
 #define _KJS_SIMPLE_NUMBER_H_
 
-#include <limits.h>
 #include <math.h>
 #include <string.h>
 
-#define IS_NEGATIVE_ZERO(num) (num == 0.0 && !memcmp(&num,&SimpleNumber::negZero,sizeof(double)))
+#define IS_NEGATIVE_ZERO(num) (num == 0.0 && !memcmp(&num, &SimpleNumber::negZero, sizeof(double)))
 
 namespace KJS {
     class ValueImp;
@@ -43,8 +42,8 @@ namespace KJS {
        static inline bool fits(unsigned i) { return i <= (unsigned)max; }
        static inline bool fits(long i) { return i <= max && i >= min; }
        static inline bool fits(unsigned long i) { return i <= (unsigned)max; }
-       static inline bool fits(double d) { return d <= max && d >= min && d == (double)(long)d &&
-                                           !IS_NEGATIVE_ZERO(d); }
+       static inline bool integerFits(double d) { return !(d < min || d > max); }
+       static inline bool fits(double d) { return d >= min && d <= max && d == (double)(long)d && !IS_NEGATIVE_ZERO(d); }
        static inline ValueImp *make(long i) { return (ValueImp *)((i << shift) | tag); }
 
        static double negZero;
index 056f2ad8dae29c9d2cf239dec0d5de626105a834..32a3fe7f6c2827f2be7bcfd6486c73a2f6a5cb2f 100644 (file)
@@ -378,10 +378,9 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
     // That doesn't match the ECMA standard, but is needed for site compatibility.
     dpos = a0.isA(UndefinedType) ? 0 : a0.toInteger(exec);
     if (dpos >= 0 && dpos < len) // false for NaN
-      d = s[static_cast<int>(dpos)].unicode();
+      result = Number(s[static_cast<int>(dpos)].unicode());
     else
-      d = NaN;
-    result = Number(d);
+      result = Number(NaN);
     break;
   case Concat: {
     ListIterator it = args.begin();
@@ -403,8 +402,7 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
       } else
         dpos = 0;
     }
-    d = s.find(u2, static_cast<int>(dpos));
-    result = Number(d);
+    result = Number(s.find(u2, static_cast<int>(dpos)));
     break;
   case LastIndexOf:
     u2 = a0.toString(exec);
@@ -419,8 +417,7 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
       } else
         dpos = 0;
     }
-    d = s.rfind(u2, static_cast<int>(dpos));
-    result = Number(d);
+    result = Number(s.rfind(u2, static_cast<int>(dpos)));
     break;
   case Match:
   case Search: {
index 4ad631b16cfe70792115bfbed84094a7e4f1e913..d7cd5e33e2158e43a8bad381b47ec799ae733175 100644 (file)
@@ -1047,8 +1047,10 @@ int UString::find(const UString &f, int pos) const
   const UChar *end = data() + sz - fsz;
   long fsizeminusone = (fsz - 1) * sizeof(UChar);
   const UChar *fdata = f.data();
+  unsigned short fchar = fdata->uc;
+  ++fdata;
   for (const UChar *c = data() + pos; c <= end; c++)
-    if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
+    if (c->uc == fchar && !memcmp(c + 1, fdata, fsizeminusone))
       return (c-data());
 
   return -1;
@@ -1125,12 +1127,6 @@ UString UString::substr(int pos, int len) const
   return result;
 }
 
-void UString::attach(Rep *r)
-{
-  rep = r;
-  rep->ref();
-}
-
 void UString::detach()
 {
   if (rep->rc > 1 || rep->baseString) {
@@ -1142,11 +1138,6 @@ void UString::detach()
   }
 }
 
-void UString::release()
-{
-  rep->deref();
-}
-
 bool KJS::operator==(const UString& s1, const UString& s2)
 {
   if (s1.rep->len != s2.rep->len)
index f32368e67d68f56e2c9532f62837eb7767e9f045..4ac40e0209749196beba64b551cc8b22ff7b5900 100644 (file)
@@ -470,9 +470,9 @@ namespace KJS {
 #endif
   private:
     UString(Rep *r) { attach(r); }
-    void attach(Rep *r);
+    void attach(Rep *r) { rep = r; r->ref(); }
     void detach();
-    void release();
+    void release() { rep->deref(); }
     int expandedSize(int size, int otherSize) const;
     int usedCapacity() const;
     int usedPreCapacity() const;
index e9a374d25dd3a4468da55d3f9e33ee50005fadc3..f7c1a139b8993aad7113a3ff1e5d5ce80fff97c7 100644 (file)
@@ -86,22 +86,6 @@ void ValueImp::mark()
 #endif
 }
 
-bool ValueImp::marked() const
-{
-  // Simple numbers are always considered marked.
-#if USE_CONSERVATIVE_GC
-  return SimpleNumber::is(this) || _marked;
-#elif TEST_CONSERVATIVE_GC
-  if (conservativeMark) {
-    return SimpleNumber::is(this) || (_flags & VI_CONSERVATIVE_MARKED);
-  } else {
-    return SimpleNumber::is(this) || (_flags & VI_MARKED);
-  }
-#else
-  return SimpleNumber::is(this) || (_flags & VI_MARKED);
-#endif
-}
-
 #if !USE_CONSERVATIVE_GC
 void ValueImp::setGcAllowed()
 {
@@ -190,44 +174,6 @@ uint16_t ValueImp::toUInt16(ExecState *exec) const
   return static_cast<uint16_t>(d16);
 }
 
-// Dispatchers for virtual functions, to special-case simple numbers which
-// won't be real pointers.
-
-Type ValueImp::dispatchType() const
-{
-  if (SimpleNumber::is(this))
-    return NumberType;
-  return type();
-}
-
-Value ValueImp::dispatchToPrimitive(ExecState *exec, Type preferredType) const
-{
-  if (SimpleNumber::is(this))
-    return Value(const_cast<ValueImp *>(this));
-  return toPrimitive(exec, preferredType);
-}
-
-bool ValueImp::dispatchToBoolean(ExecState *exec) const
-{
-  if (SimpleNumber::is(this))
-    return SimpleNumber::value(this);
-  return toBoolean(exec);
-}
-
-double ValueImp::dispatchToNumber(ExecState *exec) const
-{
-  if (SimpleNumber::is(this))
-    return SimpleNumber::value(this);
-  return toNumber(exec);
-}
-
-UString ValueImp::dispatchToString(ExecState *exec) const
-{
-  if (SimpleNumber::is(this))
-    return UString::from(SimpleNumber::value(this));
-  return toString(exec);
-}
-
 Object ValueImp::dispatchToObject(ExecState *exec) const
 {
   if (SimpleNumber::is(this))
@@ -235,18 +181,6 @@ Object ValueImp::dispatchToObject(ExecState *exec) const
   return toObject(exec);
 }
 
-bool ValueImp::dispatchToUInt32(uint32_t& result) const
-{
-  if (SimpleNumber::is(this)) {
-    long i = SimpleNumber::value(this);
-    if (i < 0)
-      return false;
-    result = i;
-    return true;
-  }
-  return toUInt32(result);
-}
-
 // ------------------------------ Value ----------------------------------------
 
 #if !USE_CONSERVATIVE_GC
@@ -305,6 +239,36 @@ Value& Value::operator=(const Value &v)
 }
 #endif
 
+Value::Value(bool b) : rep(b ? BooleanImp::staticTrue : BooleanImp::staticFalse) { }
+
+Value::Value(int i)
+    : rep(SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i))) { }
+
+Value::Value(unsigned u)
+    : rep(SimpleNumber::fits(u) ? SimpleNumber::make(u) : new NumberImp(static_cast<double>(u))) { }
+
+Value::Value(double d)
+    : rep(SimpleNumber::fits(d)
+        ? SimpleNumber::make(static_cast<long>(d))
+        : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d)))
+{ }
+
+Value::Value(double d, bool knownToBeInteger)
+    : rep((knownToBeInteger ? SimpleNumber::integerFits(d) : SimpleNumber::fits(d))
+        ? SimpleNumber::make(static_cast<long>(d))
+        : ((!knownToBeInteger && KJS::isNaN(d)) ? NumberImp::staticNaN : new NumberImp(d)))
+{ }
+
+Value::Value(long l)
+    : rep(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
+
+Value::Value(unsigned long l)
+    : rep(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
+
+Value::Value(const char *s) : rep(new StringImp(s)) { }
+
+Value::Value(const UString &s) : rep(new StringImp(s)) { }
+
 // ------------------------------ Undefined ------------------------------------
 
 Undefined::Undefined() : Value(UndefinedImp::staticUndefined)
@@ -383,7 +347,16 @@ Number::Number(unsigned int u)
   : Value(SimpleNumber::fits(u) ? SimpleNumber::make(u) : new NumberImp(static_cast<double>(u))) { }
 
 Number::Number(double d)
-  : Value(SimpleNumber::fits(d) ? SimpleNumber::make((long)d) : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d))) { }
+  : Value(SimpleNumber::fits(d)
+        ? SimpleNumber::make(static_cast<long>(d))
+        : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d)))
+{ }
+
+Number::Number(double d, bool knownToBeInteger)
+  : Value((knownToBeInteger ? SimpleNumber::integerFits(d) : SimpleNumber::fits(d))
+        ? SimpleNumber::make(static_cast<long>(d))
+        : ((!knownToBeInteger && KJS::isNaN(d)) ? NumberImp::staticNaN : new NumberImp(d)))
+{ }
 
 Number::Number(long int l)
   : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
index ac5186ff00ab8e82fb97f641c1ea983c5e715ce6..12c4e7574fc16507dc2418f16c76b8e588cb2c5e 100644 (file)
@@ -94,6 +94,7 @@ namespace KJS {
     friend class Collector;
     friend class Value;
     friend class ContextImp;
+    friend class FunctionCallNode;
   public:
 #if USE_CONSERVATIVE_GC
     ValueImp() : _marked(0) {}
@@ -136,6 +137,7 @@ namespace KJS {
     Value dispatchToPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const;
     bool dispatchToBoolean(ExecState *exec) const;
     double dispatchToNumber(ExecState *exec) const;
+    double dispatchToNumber(ExecState *exec, bool &knownToBeInteger) const;
     UString dispatchToString(ExecState *exec) const;
     bool dispatchToUInt32(uint32_t&) const;
     Object dispatchToObject(ExecState *exec) const;
@@ -210,6 +212,18 @@ namespace KJS {
     Value& operator=(const Value &v);
 #endif
 
+    explicit Value(bool);
+
+    explicit Value(int);
+    explicit Value(unsigned);
+    explicit Value(double);
+    explicit Value(long);
+    explicit Value(unsigned long);
+    Value(double, bool knownToBeInteger);
+
+    explicit Value(const char *);
+    Value(const UString &);
+
     bool isNull() const { return rep == 0; }
     ValueImp *imp() const { return rep; }
 
@@ -246,6 +260,7 @@ namespace KJS {
      * Performs the ToNumber type conversion operation on this value (ECMA 9.3)
      */
     double toNumber(ExecState *exec) const { return rep->dispatchToNumber(exec); }
+    double toNumber(ExecState *exec, bool &knownToBeInteger) const { return rep->dispatchToNumber(exec, knownToBeInteger); }
 
     /**
      * Performs the ToInteger type conversion operation on this value (ECMA 9.4)
@@ -399,6 +414,7 @@ namespace KJS {
     Number(double d = 0.0);
     Number(long int l);
     Number(long unsigned int l);
+    Number(double d, bool knownToBeInteger);
 
     double value() const;
     int intValue() const;
@@ -421,6 +437,82 @@ namespace KJS {
     explicit Number(NumberImp *v);
   };
 
-}; // namespace
+inline bool ValueImp::marked() const
+{
+  // Simple numbers are always considered marked.
+#if USE_CONSERVATIVE_GC
+  return SimpleNumber::is(this) || _marked;
+#elif TEST_CONSERVATIVE_GC
+  if (conservativeMark) {
+    return SimpleNumber::is(this) || (_flags & VI_CONSERVATIVE_MARKED);
+  } else {
+    return SimpleNumber::is(this) || (_flags & VI_MARKED);
+  }
+#else
+  return SimpleNumber::is(this) || (_flags & VI_MARKED);
+#endif
+}
+
+// Dispatchers for virtual functions, to special-case simple numbers which
+// won't be real pointers.
+
+inline Type ValueImp::dispatchType() const
+{
+  if (SimpleNumber::is(this))
+    return NumberType;
+  return type();
+}
+
+inline Value ValueImp::dispatchToPrimitive(ExecState *exec, Type preferredType) const
+{
+    if (SimpleNumber::is(this))
+        return Value(const_cast<ValueImp *>(this));
+    return toPrimitive(exec, preferredType);
+}
+
+inline bool ValueImp::dispatchToBoolean(ExecState *exec) const
+{
+    if (SimpleNumber::is(this))
+        return SimpleNumber::value(this);
+    return toBoolean(exec);
+}
+
+inline double ValueImp::dispatchToNumber(ExecState *exec) const
+{
+    if (SimpleNumber::is(this))
+        return SimpleNumber::value(this);
+    return toNumber(exec);
+}
+
+inline double ValueImp::dispatchToNumber(ExecState *exec, bool &knownToBeInteger) const
+{
+    if (SimpleNumber::is(this)) {
+        knownToBeInteger = true;
+        return SimpleNumber::value(this);
+    }
+    knownToBeInteger = false;
+    return toNumber(exec);
+}
+
+inline UString ValueImp::dispatchToString(ExecState *exec) const
+{
+    if (SimpleNumber::is(this))
+        return UString::from(SimpleNumber::value(this));
+    return toString(exec);
+}
+
+inline bool ValueImp::dispatchToUInt32(uint32_t& result) const
+{
+    if (SimpleNumber::is(this)) {
+        long i = SimpleNumber::value(this);
+        if (i < 0)
+            return false;
+        result = i;
+        return true;
+    }
+    return toUInt32(result);
+}
+
+} // namespace
 
 #endif // _KJS_VALUE_H_
index 95f18ef7864521c9e0e06f5317c21c16f4bb2857..47cf0c3c7b8210b8feb7efd313744a9ecce086db 100644 (file)
@@ -7,11 +7,11 @@
 <p class='results_summary'>
 Test List: All tests<br>
 Skip List: ecma/Date<br>
-967 test(s) selected, 962 test(s) completed, 132 failures reported (13.72% failed)<br>
+967 test(s) selected, 962 test(s) completed, 131 failures reported (13.61% failed)<br>
 Engine command line: /Users/darin/symroots/testkjs <br>
-OS type: Darwin hq-bentspoon-com.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug  5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC  Power Macintosh powerpc<br>
-Testcase execution time: 8 minutes, 42 seconds.<br>
-Tests completed on Sun Sep 26 17:58:04 2004.<br><br>
+OS type: Darwin darin-adlers-power-mac-g4.local 8.0.0 Darwin Kernel Version 8.0.0: Sat Mar 26 14:15:22 PST 2005; root:xnu-792.obj~1/RELEASE_PPC Power Macintosh powerpc<br>
+Testcase execution time: 1 minutes, 28 seconds.<br>
+Tests completed on Wed Apr 20 02:42:18 2005.<br><br>
 [ <a href='#fail_detail'>Failure Details</a> | <a href='#retest_list'>Retest List</a> | <a href='menu.html'>Test Selection Page</a> ]<br>
 <hr>
 <a name='fail_detail'></a>
@@ -77,10 +77,6 @@ Failure messages were:<br>
 --> parseFloat("1e2000") = NaN FAILED! expected: Infinity<br>
 --> -s2 == -Infinity || -s2 == -1.7976931348623157e+308  = false FAILED! expected: true<br>
 --> -s3 == -Infinity || -s3 == -1.7976931348623157e+308 = false FAILED! expected: true<br>
---> parseInt(s1,10) == 1.7976931348623157e+308 || parseInt(s1,10) == Infinity = false FAILED! expected: true<br>
---> parseInt(s2,10) == Infinity || parseInt(s2,10) == 1.7976931348623157e+308 = false FAILED! expected: true<br>
---> parseInt(s1) == 1.7976931348623157e+308 || parseInt(s1) == Infinity = false FAILED! expected: true<br>
---> parseInt(s2) == Infinity || parseInt(s2) == 1.7976931348623157e+308 = false FAILED! expected: true<br>
 --> 0x1000000000000081 = 1152921504606847000 FAILED! expected: 1152921504606847200<br>
 --> 0x1000000000000281 = 1152921504606847500 FAILED! expected: 1152921504606847700<br>
 --> parseInt("0000001000000001001000110100010101100111100010011010101111011",2) = 18054430506169720 FAILED! expected: 18054430506169724<br>
@@ -191,15 +187,15 @@ Failure messages were:<br>
 Failure messages were:<br>
 --> (Wed Dec 31 1969 16:00:00 GMT-0800).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
 --> (Wed Dec 31 1969 08:00:00 GMT-0800).toLocaleTimeString() = 8:00:00 AM PST FAILED! expected: 08:00:00<br>
---> (Fri Dec 13 1901 12:45:52 GMT-0800).toLocaleTimeString() = 12:45:52 PM PST FAILED! expected: 12:45:52<br>
---> (Fri Dec 13 1901 12:45:52 GMT-0800).toLocaleTimeString() = 12:45:52 PM PST FAILED! expected: 12:45:52<br>
+--> (Fri Dec 13 1901 12:45:52 GMT-0800).toLocaleTimeString() = 1:45:52 PM PDT FAILED! expected: 12:45:52<br>
+--> (Fri Dec 13 1901 12:45:52 GMT-0800).toLocaleTimeString() = 1:45:52 PM PDT FAILED! expected: 12:45:52<br>
 --> (Fri Dec 31 1999 16:00:00 GMT-0800).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
 --> (Sat Jan 01 2000 00:00:00 GMT-0800).toLocaleTimeString() = 12:00:00 AM PST FAILED! expected: 00:00:00<br>
 --> (Mon Feb 28 2000 16:00:00 GMT-0800).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
 --> (Mon Feb 28 2000 15:59:59 GMT-0800).toLocaleTimeString() = 3:59:59 PM PST FAILED! expected: 15:59:59<br>
 --> (Tue Feb 29 2000 00:00:00 GMT-0800).toLocaleTimeString() = 12:00:00 AM PST FAILED! expected: 00:00:00<br>
---> (Sun Sep 26 2004 17:55:40 GMT-0700).toLocaleTimeString() = 5:55:40 PM PDT FAILED! expected: 17:55:40<br>
---> (Mon Sep 27 2004 01:55:40 GMT-0700).toLocaleTimeString() = 1:55:40 AM PDT FAILED! expected: 01:55:40<br>
+--> (Wed Apr 20 2005 02:41:53 GMT-0700).toLocaleTimeString() = 2:41:53 AM PDT FAILED! expected: 02:41:53<br>
+--> (Wed Apr 20 2005 10:41:53 GMT-0700).toLocaleTimeString() = 10:41:53 AM PDT FAILED! expected: 10:41:53<br>
 --> (Fri Dec 31 2004 16:00:00 GMT-0800).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
 --> (Fri Dec 31 2004 15:59:59 GMT-0800).toLocaleTimeString() = 3:59:59 PM PST FAILED! expected: 15:59:59<br>
 --> (Sat Jan 01 2005 00:00:00 GMT-0800).toLocaleTimeString() = 12:00:00 AM PST FAILED! expected: 00:00:00<br>
@@ -554,20 +550,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Actual: ["Abc"]<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure45'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/octal-002.js'>ecma_3/RegExp/octal-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=141078' target='other_window'>Bug Number 141078</a><br>
+<a name='failure45'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/perlstress-001.js'>ecma_3/RegExp/perlstress-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
  [ <a href='#failure44'>Previous Failure</a> | <a href='#failure46'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
-<tt>--> STATUS: Testing regexps containing octal escape sequences<br>
-Failure messages were:<br>
---> FAILED!: [reported from test()] Section 8 of test -<br>
---> FAILED!: [reported from test()] regexp = /a<br>
---> FAILED!: [reported from test()] string = 'a<br>
---> FAILED!: [reported from test()] ERROR !!! regexp failed to give expected match array:<br>
---> FAILED!: [reported from test()] Expect: ["a<br>
---> FAILED!: [reported from test()] Actual: ["a"]<br>
---> FAILED!: [reported from test()] <br>
-</tt><br>
-<a name='failure46'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/perlstress-001.js'>ecma_3/RegExp/perlstress-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
- [ <a href='#failure45'>Previous Failure</a> | <a href='#failure47'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing regular expression edge cases<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 14 of test -<br>
@@ -655,8 +639,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Actual: ["aabbaa", "aa", "bb"]<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure47'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/perlstress-002.js'>ecma_3/RegExp/perlstress-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
- [ <a href='#failure46'>Previous Failure</a> | <a href='#failure48'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure46'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/perlstress-002.js'>ecma_3/RegExp/perlstress-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
+ [ <a href='#failure45'>Previous Failure</a> | <a href='#failure47'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing regular expression edge cases<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 40 of test -<br>
@@ -674,8 +658,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Actual: null<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure48'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-100199.js'>ecma_3/RegExp/regress-100199.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=100199' target='other_window'>Bug Number 100199</a><br>
- [ <a href='#failure47'>Previous Failure</a> | <a href='#failure49'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure47'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-100199.js'>ecma_3/RegExp/regress-100199.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=100199' target='other_window'>Bug Number 100199</a><br>
+ [ <a href='#failure46'>Previous Failure</a> | <a href='#failure48'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: [], [^] are valid RegExp conditions. Should not cause errors -<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 19 of test -<br>
@@ -777,8 +761,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Actual: null<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure49'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-188206.js'>ecma_3/RegExp/regress-188206.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=188206' target='other_window'>Bug Number 188206</a><br>
- [ <a href='#failure48'>Previous Failure</a> | <a href='#failure50'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure48'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-188206.js'>ecma_3/RegExp/regress-188206.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=188206' target='other_window'>Bug Number 188206</a><br>
+ [ <a href='#failure47'>Previous Failure</a> | <a href='#failure49'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Invalid use of regexp quantifiers should generate SyntaxErrors<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 1 of test -<br>
@@ -839,8 +823,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Expected value 'SyntaxError', Actual value 'Did not generate ANY error!!!'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure50'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-209067.js'>ecma_3/RegExp/regress-209067.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=209067' target='other_window'>Bug Number 209067</a><br>
- [ <a href='#failure49'>Previous Failure</a> | <a href='#failure51'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure49'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-209067.js'>ecma_3/RegExp/regress-209067.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=209067' target='other_window'>Bug Number 209067</a><br>
+ [ <a href='#failure48'>Previous Failure</a> | <a href='#failure50'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing complicated str.replace()<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 1 of test -<br>
@@ -851,8 +835,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] }</span>'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure51'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-209919.js'>ecma_3/RegExp/regress-209919.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=209919' target='other_window'>Bug Number 209919</a><br>
- [ <a href='#failure50'>Previous Failure</a> | <a href='#failure52'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure50'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-209919.js'>ecma_3/RegExp/regress-209919.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=209919' target='other_window'>Bug Number 209919</a><br>
+ [ <a href='#failure49'>Previous Failure</a> | <a href='#failure51'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing regexp submatches with quantifiers<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 1 of test -<br>
@@ -891,8 +875,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Actual: ["1.000,00", "", ",00"]<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure52'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-72964.js'>ecma_3/RegExp/regress-72964.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=72964' target='other_window'>Bug Number 72964</a><br>
- [ <a href='#failure51'>Previous Failure</a> | <a href='#failure53'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure51'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-72964.js'>ecma_3/RegExp/regress-72964.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=72964' target='other_window'>Bug Number 72964</a><br>
+ [ <a href='#failure50'>Previous Failure</a> | <a href='#failure52'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing regular expressions containing non-Latin1 characters<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 3 of test -<br>
@@ -910,8 +894,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Actual: null<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure53'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-78156.js'>ecma_3/RegExp/regress-78156.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=78156' target='other_window'>Bug Number 78156</a><br>
- [ <a href='#failure52'>Previous Failure</a> | <a href='#failure54'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure52'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-78156.js'>ecma_3/RegExp/regress-78156.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=78156' target='other_window'>Bug Number 78156</a><br>
+ [ <a href='#failure51'>Previous Failure</a> | <a href='#failure53'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing regular expressions with  ^, $, and the m flag -<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 2 of test -<br>
@@ -929,8 +913,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Actual: null<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure54'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-85721.js'>ecma_3/RegExp/regress-85721.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
- [ <a href='#failure53'>Previous Failure</a> | <a href='#failure55'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure53'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-85721.js'>ecma_3/RegExp/regress-85721.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
+ [ <a href='#failure52'>Previous Failure</a> | <a href='#failure54'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Performance: execution of regular expression<br>
 Failure messages were:<br>
 --> FAILED!: Section 4 of test -<br>
@@ -1159,47 +1143,47 @@ Failure messages were:<br>
 --> FAILED!: Actual: null<br>
 --> FAILED!: <br>
 </tt><br>
-<a name='failure55'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Statements/regress-194364.js'>ecma_3/Statements/regress-194364.js</a> failed</b> <br>
- [ <a href='#failure54'>Previous Failure</a> | <a href='#failure56'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure54'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Statements/regress-194364.js'>ecma_3/Statements/regress-194364.js</a> failed</b> <br>
+ [ <a href='#failure53'>Previous Failure</a> | <a href='#failure55'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 1: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure56'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-001.js'>ecma_3/Unicode/uc-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=23610' target='other_window'>Bug Number 23610</a><br>
- [ <a href='#failure55'>Previous Failure</a> | <a href='#failure57'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure55'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-001.js'>ecma_3/Unicode/uc-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=23610' target='other_window'>Bug Number 23610</a><br>
+ [ <a href='#failure54'>Previous Failure</a> | <a href='#failure56'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Unicode format-control character (Category Cf) test.<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Unicode format-control character test (Category Cf.)<br>
 --> FAILED!: [reported from test()] Expected value 'no error', Actual value 'no\ e error'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure57'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-002.js'>ecma_3/Unicode/uc-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=23613' target='other_window'>Bug Number 23613</a><br>
- [ <a href='#failure56'>Previous Failure</a> | <a href='#failure58'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure56'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-002.js'>ecma_3/Unicode/uc-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=23613' target='other_window'>Bug Number 23613</a><br>
+ [ <a href='#failure55'>Previous Failure</a> | <a href='#failure57'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Unicode non-breaking space character test.<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Unicode non-breaking space character regexp test.<br>
 --> FAILED!: [reported from test()] Expected value '0', Actual value '-1'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure58'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-003.js'>ecma_3/Unicode/uc-003.js</a> failed</b> <br>
- [ <a href='#failure57'>Previous Failure</a> | <a href='#failure59'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure57'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-003.js'>ecma_3/Unicode/uc-003.js</a> failed</b> <br>
+ [ <a href='#failure56'>Previous Failure</a> | <a href='#failure58'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 yylex: ERROR.<br>
 Exception, line 32: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure59'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-005.js'>ecma_3/Unicode/uc-005.js</a> failed</b> <br>
- [ <a href='#failure58'>Previous Failure</a> | <a href='#failure60'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure58'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-005.js'>ecma_3/Unicode/uc-005.js</a> failed</b> <br>
+ [ <a href='#failure57'>Previous Failure</a> | <a href='#failure59'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 yylex: ERROR.<br>
 Exception, line 118: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure60'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Array/tostring_1.js'>js1_2/Array/tostring_1.js</a> failed</b> <br>
- [ <a href='#failure59'>Previous Failure</a> | <a href='#failure61'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure59'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Array/tostring_1.js'>js1_2/Array/tostring_1.js</a> failed</b> <br>
+ [ <a href='#failure58'>Previous Failure</a> | <a href='#failure60'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> var a = new Array(); a.toString() =  FAILED! expected: []<br>
@@ -1210,16 +1194,16 @@ Failure messages were:<br>
 --> var b = new Array(1000); b.toString() = ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, FAILED! expected: [1000]<br>
 --> b.length = 1000 FAILED! expected: 1<br>
 </tt><br>
-<a name='failure61'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Array/tostring_2.js'>js1_2/Array/tostring_2.js</a> failed</b> <br>
- [ <a href='#failure60'>Previous Failure</a> | <a href='#failure62'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure60'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Array/tostring_2.js'>js1_2/Array/tostring_2.js</a> failed</b> <br>
+ [ <a href='#failure59'>Previous Failure</a> | <a href='#failure61'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> a.toString() =  FAILED! expected: []<br>
 --> String( a ) =  FAILED! expected: []<br>
 --> a +'' =  FAILED! expected: []<br>
 </tt><br>
-<a name='failure62'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/function-001-n.js'>js1_2/function/function-001-n.js</a> failed</b> <br>
- [ <a href='#failure61'>Previous Failure</a> | <a href='#failure63'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure61'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/function-001-n.js'>js1_2/function/function-001-n.js</a> failed</b> <br>
+ [ <a href='#failure60'>Previous Failure</a> | <a href='#failure62'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1227,8 +1211,8 @@ Complete testcase output was:<br>
 --> eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
 OK.<br>
 </tt><br>
-<a name='failure63'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/Function_object.js'>js1_2/function/Function_object.js</a> failed</b> <br>
- [ <a href='#failure62'>Previous Failure</a> | <a href='#failure64'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure62'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/Function_object.js'>js1_2/function/Function_object.js</a> failed</b> <br>
+ [ <a href='#failure61'>Previous Failure</a> | <a href='#failure63'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> f.name = undefined FAILED! expected: a_test_function<br>
@@ -1236,29 +1220,29 @@ Failure messages were:<br>
 --> (new Function()).name = undefined FAILED! expected: anonymous<br>
 } FAILED! expected: <br>
 </tt><br>
-<a name='failure64'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/Number.js'>js1_2/function/Number.js</a> failed</b> <br>
- [ <a href='#failure63'>Previous Failure</a> | <a href='#failure65'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure63'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/Number.js'>js1_2/function/Number.js</a> failed</b> <br>
+ [ <a href='#failure62'>Previous Failure</a> | <a href='#failure64'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> Number([1,2,3])          = NaN FAILED! expected: 3<br>
 </tt><br>
-<a name='failure65'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/regexparg-1.js'>js1_2/function/regexparg-1.js</a> failed</b> <br>
- [ <a href='#failure64'>Previous Failure</a> | <a href='#failure66'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure64'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/regexparg-1.js'>js1_2/function/regexparg-1.js</a> failed</b> <br>
+ [ <a href='#failure63'>Previous Failure</a> | <a href='#failure65'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 --> JS_1.2 The variable statment<br>
 Exception, line 81: TypeError - Object /abc/ (result of expression x) does not allow calls.<br>
 </tt><br>
-<a name='failure66'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/String.js'>js1_2/function/String.js</a> failed</b> <br>
- [ <a href='#failure65'>Previous Failure</a> | <a href='#failure67'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure65'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/String.js'>js1_2/function/String.js</a> failed</b> <br>
+ [ <a href='#failure64'>Previous Failure</a> | <a href='#failure66'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> String({p:1})            = [object Object] FAILED! expected: {p:1}<br>
 --> String([1,2,3])             = 1,2,3 FAILED! expected: [1, 2, 3]<br>
 </tt><br>
-<a name='failure67'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-1.js'>js1_2/function/tostring-1.js</a> failed</b> <br>
- [ <a href='#failure66'>Previous Failure</a> | <a href='#failure68'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure66'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-1.js'>js1_2/function/tostring-1.js</a> failed</b> <br>
+ [ <a href='#failure65'>Previous Failure</a> | <a href='#failure67'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 } FAILED! expected: <br>
@@ -1267,8 +1251,8 @@ Failure messages were:<br>
 } FAILED! expected: <br>
 } FAILED! expected: <br>
 </tt><br>
-<a name='failure68'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-2.js'>js1_2/function/tostring-2.js</a> failed</b> <br>
- [ <a href='#failure67'>Previous Failure</a> | <a href='#failure69'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure67'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-2.js'>js1_2/function/tostring-2.js</a> failed</b> <br>
+ [ <a href='#failure66'>Previous Failure</a> | <a href='#failure68'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 } FAILED! expected: <br>
@@ -1281,29 +1265,29 @@ Failure messages were:<br>
 } FAILED! expected: <br>
 } FAILED! expected: <br>
 </tt><br>
-<a name='failure69'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Objects/toString-001.js'>js1_2/Objects/toString-001.js</a> failed</b> <br>
- [ <a href='#failure68'>Previous Failure</a> | <a href='#failure70'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure68'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Objects/toString-001.js'>js1_2/Objects/toString-001.js</a> failed</b> <br>
+ [ <a href='#failure67'>Previous Failure</a> | <a href='#failure69'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 --> JS1_2 Object.toString()<br>
 Exception, line 104: TypeError - Object /^\{(.*)\}$/ (result of expression ^\{(.*)\}$) does not allow calls.<br>
 </tt><br>
-<a name='failure70'></a><dd><b>Testcase <a target='other_window' href='./js1_2/operator/equality.js'>js1_2/operator/equality.js</a> failed</b> <br>
- [ <a href='#failure69'>Previous Failure</a> | <a href='#failure71'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure69'></a><dd><b>Testcase <a target='other_window' href='./js1_2/operator/equality.js'>js1_2/operator/equality.js</a> failed</b> <br>
+ [ <a href='#failure68'>Previous Failure</a> | <a href='#failure70'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> (new String('x') == 'x')                  = true FAILED! expected: false<br>
 --> ('x' == new String('x'))                  = true FAILED! expected: false<br>
 </tt><br>
-<a name='failure71'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/beginLine.js'>js1_2/regexp/beginLine.js</a> failed</b> <br>
- [ <a href='#failure70'>Previous Failure</a> | <a href='#failure72'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure70'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/beginLine.js'>js1_2/regexp/beginLine.js</a> failed</b> <br>
+ [ <a href='#failure69'>Previous Failure</a> | <a href='#failure71'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 123xyz'.match(new RegExp('^\d+')) = null FAILED! expected: 123<br>
 </tt><br>
-<a name='failure72'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/compile.js'>js1_2/regexp/compile.js</a> failed</b> <br>
- [ <a href='#failure71'>Previous Failure</a> | <a href='#failure73'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure71'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/compile.js'>js1_2/regexp/compile.js</a> failed</b> <br>
+ [ <a href='#failure70'>Previous Failure</a> | <a href='#failure72'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1311,14 +1295,14 @@ Complete testcase output was:<br>
 --> As described in Netscape doc "Whats new in JavaScript 1.2" RegExp: compile<br>
 Exception, line 44: TypeError - Value undefined (result of expression regularExpression.compile) is not object.<br>
 </tt><br>
-<a name='failure73'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/endLine.js'>js1_2/regexp/endLine.js</a> failed</b> <br>
- [ <a href='#failure72'>Previous Failure</a> | <a href='#failure74'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure72'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/endLine.js'>js1_2/regexp/endLine.js</a> failed</b> <br>
+ [ <a href='#failure71'>Previous Failure</a> | <a href='#failure73'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 xyz'.match(new RegExp('\d+$')) = null FAILED! expected: 890<br>
 </tt><br>
-<a name='failure74'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_input.js'>js1_2/regexp/RegExp_input.js</a> failed</b> <br>
- [ <a href='#failure73'>Previous Failure</a> | <a href='#failure75'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure73'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_input.js'>js1_2/regexp/RegExp_input.js</a> failed</b> <br>
+ [ <a href='#failure72'>Previous Failure</a> | <a href='#failure74'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> RegExp.input = 'abcd12357efg'; /\d+/.exec() = null FAILED! expected: 12357<br>
@@ -1327,8 +1311,8 @@ Failure messages were:<br>
 --> RegExp.input = 'abcd12357efg'; /[h-z]+/.test() = true FAILED! expected: false<br>
 --> RegExp.input = 'abcd12357efg'; (new RegExp('[h-z]+')).test() = true FAILED! expected: false<br>
 </tt><br>
-<a name='failure75'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_input_as_array.js'>js1_2/regexp/RegExp_input_as_array.js</a> failed</b> <br>
- [ <a href='#failure74'>Previous Failure</a> | <a href='#failure76'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure74'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_input_as_array.js'>js1_2/regexp/RegExp_input_as_array.js</a> failed</b> <br>
+ [ <a href='#failure73'>Previous Failure</a> | <a href='#failure75'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> RegExp['$_'] = 'abcd12357efg'; /\d+/.exec() = null FAILED! expected: 12357<br>
@@ -1337,15 +1321,15 @@ Failure messages were:<br>
 --> RegExp['$_'] = 'abcd12357efg'; /[h-z]+/.test() = true FAILED! expected: false<br>
 --> RegExp['$_'] = 'abcd12357efg'; (new RegExp('[h-z]+')).test() = true FAILED! expected: false<br>
 </tt><br>
-<a name='failure76'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastIndex.js'>js1_2/regexp/RegExp_lastIndex.js</a> failed</b> <br>
- [ <a href='#failure75'>Previous Failure</a> | <a href='#failure77'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure75'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastIndex.js'>js1_2/regexp/RegExp_lastIndex.js</a> failed</b> <br>
+ [ <a href='#failure74'>Previous Failure</a> | <a href='#failure76'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> re=/x./g; re.lastIndex=4; re.exec('xyabcdxa') = xa FAILED! expected: ["xa"]<br>
 --> re.exec('xyabcdef') = xy FAILED! expected: ["xy"]<br>
 </tt><br>
-<a name='failure77'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastMatch.js'>js1_2/regexp/RegExp_lastMatch.js</a> failed</b> <br>
- [ <a href='#failure76'>Previous Failure</a> | <a href='#failure78'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure76'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastMatch.js'>js1_2/regexp/RegExp_lastMatch.js</a> failed</b> <br>
+ [ <a href='#failure75'>Previous Failure</a> | <a href='#failure77'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'foo'.match(/foo/); RegExp.lastMatch = undefined FAILED! expected: foo<br>
@@ -1355,8 +1339,8 @@ Failure messages were:<br>
 --> 'abcdefg'.match(/^..(cd)[a-z]+/); RegExp.lastMatch = undefined FAILED! expected: abcdefg<br>
 --> 'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\1/); RegExp.lastMatch = undefined FAILED! expected: abcdefgabcdefg<br>
 </tt><br>
-<a name='failure78'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastMatch_as_array.js'>js1_2/regexp/RegExp_lastMatch_as_array.js</a> failed</b> <br>
- [ <a href='#failure77'>Previous Failure</a> | <a href='#failure79'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure77'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastMatch_as_array.js'>js1_2/regexp/RegExp_lastMatch_as_array.js</a> failed</b> <br>
+ [ <a href='#failure76'>Previous Failure</a> | <a href='#failure78'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'foo'.match(/foo/); RegExp['$&'] = undefined FAILED! expected: foo<br>
@@ -1366,8 +1350,8 @@ Failure messages were:<br>
 --> 'abcdefg'.match(/^..(cd)[a-z]+/); RegExp['$&'] = undefined FAILED! expected: abcdefg<br>
 --> 'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\1/); RegExp['$&'] = undefined FAILED! expected: abcdefgabcdefg<br>
 </tt><br>
-<a name='failure79'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastParen.js'>js1_2/regexp/RegExp_lastParen.js</a> failed</b> <br>
- [ <a href='#failure78'>Previous Failure</a> | <a href='#failure80'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure78'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastParen.js'>js1_2/regexp/RegExp_lastParen.js</a> failed</b> <br>
+ [ <a href='#failure77'>Previous Failure</a> | <a href='#failure79'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'abcd'.match(/(abc)d/); RegExp.lastParen = undefined FAILED! expected: abc<br>
@@ -1380,8 +1364,8 @@ Failure messages were:<br>
 --> 'abcdefg'.match(new RegExp('(^a)bc')); RegExp.lastParen = undefined FAILED! expected: a<br>
 --> 'abcdefg'.match(/bc/); RegExp.lastParen = undefined FAILED! expected: <br>
 </tt><br>
-<a name='failure80'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastParen_as_array.js'>js1_2/regexp/RegExp_lastParen_as_array.js</a> failed</b> <br>
- [ <a href='#failure79'>Previous Failure</a> | <a href='#failure81'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure79'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastParen_as_array.js'>js1_2/regexp/RegExp_lastParen_as_array.js</a> failed</b> <br>
+ [ <a href='#failure78'>Previous Failure</a> | <a href='#failure80'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'abcd'.match(/(abc)d/); RegExp['$+'] = undefined FAILED! expected: abc<br>
@@ -1394,8 +1378,8 @@ Failure messages were:<br>
 --> 'abcdefg'.match(new RegExp('(^a)bc')); RegExp['$+'] = undefined FAILED! expected: a<br>
 --> 'abcdefg'.match(/bc/); RegExp['$+'] = undefined FAILED! expected: <br>
 </tt><br>
-<a name='failure81'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_leftContext.js'>js1_2/regexp/RegExp_leftContext.js</a> failed</b> <br>
- [ <a href='#failure80'>Previous Failure</a> | <a href='#failure82'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure80'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_leftContext.js'>js1_2/regexp/RegExp_leftContext.js</a> failed</b> <br>
+ [ <a href='#failure79'>Previous Failure</a> | <a href='#failure81'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'abc123xyz'.match(/123/); RegExp.leftContext = undefined FAILED! expected: abc<br>
@@ -1406,8 +1390,8 @@ Failure messages were:<br>
 --> 'xxxx'.match(new RegExp('$')); RegExp.leftContext = undefined FAILED! expected: xxxx<br>
 --> 'test'.match(new RegExp('^')); RegExp.leftContext = undefined FAILED! expected: <br>
 </tt><br>
-<a name='failure82'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_leftContext_as_array.js'>js1_2/regexp/RegExp_leftContext_as_array.js</a> failed</b> <br>
- [ <a href='#failure81'>Previous Failure</a> | <a href='#failure83'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure81'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_leftContext_as_array.js'>js1_2/regexp/RegExp_leftContext_as_array.js</a> failed</b> <br>
+ [ <a href='#failure80'>Previous Failure</a> | <a href='#failure82'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'abc123xyz'.match(/123/); RegExp['$`'] = undefined FAILED! expected: abc<br>
@@ -1418,8 +1402,8 @@ Failure messages were:<br>
 --> 'xxxx'.match(new RegExp('$')); RegExp['$`'] = undefined FAILED! expected: xxxx<br>
 --> 'test'.match(new RegExp('^')); RegExp['$`'] = undefined FAILED! expected: <br>
 </tt><br>
-<a name='failure83'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline.js'>js1_2/regexp/RegExp_multiline.js</a> failed</b> <br>
- [ <a href='#failure82'>Previous Failure</a> | <a href='#failure84'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure82'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline.js'>js1_2/regexp/RegExp_multiline.js</a> failed</b> <br>
+ [ <a href='#failure81'>Previous Failure</a> | <a href='#failure83'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> RegExp.multiline = undefined FAILED! expected: false<br>
@@ -1429,8 +1413,8 @@ Failure messages were:<br>
 --> (multiline == true) 'a11\na22\na23\na24'.match(/a..$/g) = a24 FAILED! expected: a11,a22,a23,a24<br>
 --> (multiline == true) 'a11\na22\na23\na24'.match(new RegExp('a..$','g')) = a24 FAILED! expected: a11,a22,a23,a24<br>
 </tt><br>
-<a name='failure84'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline_as_array.js'>js1_2/regexp/RegExp_multiline_as_array.js</a> failed</b> <br>
- [ <a href='#failure83'>Previous Failure</a> | <a href='#failure85'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure83'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline_as_array.js'>js1_2/regexp/RegExp_multiline_as_array.js</a> failed</b> <br>
+ [ <a href='#failure82'>Previous Failure</a> | <a href='#failure84'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> RegExp['$*'] = undefined FAILED! expected: false<br>
@@ -1440,8 +1424,8 @@ Failure messages were:<br>
 --> (['$*'] == true) 'a11\na22\na23\na24'.match(/a..$/g) = a24 FAILED! expected: a11,a22,a23,a24<br>
 --> (['$*'] == true) 'a11\na22\na23\na24'.match(new RegExp('a..$','g')) = a24 FAILED! expected: a11,a22,a23,a24<br>
 </tt><br>
-<a name='failure85'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_rightContext.js'>js1_2/regexp/RegExp_rightContext.js</a> failed</b> <br>
- [ <a href='#failure84'>Previous Failure</a> | <a href='#failure86'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure84'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_rightContext.js'>js1_2/regexp/RegExp_rightContext.js</a> failed</b> <br>
+ [ <a href='#failure83'>Previous Failure</a> | <a href='#failure85'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'abc123xyz'.match(/123/); RegExp.rightContext = undefined FAILED! expected: xyz<br>
@@ -1452,8 +1436,8 @@ Failure messages were:<br>
 --> 'xxxx'.match(new RegExp('$')); RegExp.rightContext = undefined FAILED! expected: <br>
 --> 'test'.match(new RegExp('^')); RegExp.rightContext = undefined FAILED! expected: test<br>
 </tt><br>
-<a name='failure86'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_rightContext_as_array.js'>js1_2/regexp/RegExp_rightContext_as_array.js</a> failed</b> <br>
- [ <a href='#failure85'>Previous Failure</a> | <a href='#failure87'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure85'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_rightContext_as_array.js'>js1_2/regexp/RegExp_rightContext_as_array.js</a> failed</b> <br>
+ [ <a href='#failure84'>Previous Failure</a> | <a href='#failure86'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'abc123xyz'.match(/123/); RegExp['$''] = undefined FAILED! expected: xyz<br>
@@ -1464,24 +1448,24 @@ Failure messages were:<br>
 --> 'xxxx'.match(new RegExp('$')); RegExp['$''] = undefined FAILED! expected: <br>
 --> 'test'.match(new RegExp('^')); RegExp['$''] = undefined FAILED! expected: test<br>
 </tt><br>
-<a name='failure87'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/regress-6359.js'>js1_2/regexp/regress-6359.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=http://bugzilla.mozilla.org/show_bug.cgi?id=6359' target='other_window'>Bug Number http://bugzilla.mozilla.org/show_bug.cgi?id=6359</a><br>
- [ <a href='#failure86'>Previous Failure</a> | <a href='#failure88'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure86'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/regress-6359.js'>js1_2/regexp/regress-6359.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=http://bugzilla.mozilla.org/show_bug.cgi?id=6359' target='other_window'>Bug Number http://bugzilla.mozilla.org/show_bug.cgi?id=6359</a><br>
+ [ <a href='#failure85'>Previous Failure</a> | <a href='#failure87'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 --> BUGNUMBER: http://bugzilla.mozilla.org/show_bug.cgi?id=6359<br>
 Exception, line 57: TypeError - Object /(a*)b\1+/ (result of expression (a*)b\1+) does not allow calls.<br>
 </tt><br>
-<a name='failure88'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/regress-9141.js'>js1_2/regexp/regress-9141.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=http://bugzilla.mozilla.org/show_bug.cgi?id=9141' target='other_window'>Bug Number http://bugzilla.mozilla.org/show_bug.cgi?id=9141</a><br>
- [ <a href='#failure87'>Previous Failure</a> | <a href='#failure89'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure87'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/regress-9141.js'>js1_2/regexp/regress-9141.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=http://bugzilla.mozilla.org/show_bug.cgi?id=9141' target='other_window'>Bug Number http://bugzilla.mozilla.org/show_bug.cgi?id=9141</a><br>
+ [ <a href='#failure86'>Previous Failure</a> | <a href='#failure88'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 --> BUGNUMBER: http://bugzilla.mozilla.org/show_bug.cgi?id=9141<br>
 Exception, line 74: TypeError - Object /(?:xx|x)*/ (result of expression (?:xx|x)*) does not allow calls.<br>
 </tt><br>
-<a name='failure89'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/simple_form.js'>js1_2/regexp/simple_form.js</a> failed</b> <br>
- [ <a href='#failure88'>Previous Failure</a> | <a href='#failure90'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure88'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/simple_form.js'>js1_2/regexp/simple_form.js</a> failed</b> <br>
+ [ <a href='#failure87'>Previous Failure</a> | <a href='#failure89'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1489,14 +1473,14 @@ Complete testcase output was:<br>
 --> As described in Netscape doc "Whats new in JavaScript 1.2" RegExp: simple form<br>
 Exception, line 44: TypeError - Object /[0-9]{3}/ (result of expression [0-9]{3}) does not allow calls.<br>
 </tt><br>
-<a name='failure90'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/special_characters.js'>js1_2/regexp/special_characters.js</a> failed</b> <br>
- [ <a href='#failure89'>Previous Failure</a> | <a href='#failure91'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure89'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/special_characters.js'>js1_2/regexp/special_characters.js</a> failed</b> <br>
+ [ <a href='#failure88'>Previous Failure</a> | <a href='#failure90'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'a\v\vb a  b'.match(/a\v{2}/) = null FAILED! expected: a\v\v<br>
 </tt><br>
-<a name='failure91'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/string_split.js'>js1_2/regexp/string_split.js</a> failed</b> <br>
- [ <a href='#failure90'>Previous Failure</a> | <a href='#failure92'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure90'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/string_split.js'>js1_2/regexp/string_split.js</a> failed</b> <br>
+ [ <a href='#failure89'>Previous Failure</a> | <a href='#failure91'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> 'abc'.split(/[a-z]/) = ,,, FAILED! expected: ,,<br>
@@ -1504,8 +1488,8 @@ Failure messages were:<br>
 --> 'abc'.split(new RegExp('[a-z]')) = ,,, FAILED! expected: ,,<br>
 --> 'abc'.split(new RegExp('[a-z]')) = ,,, FAILED! expected: ,,<br>
 </tt><br>
-<a name='failure92'></a><dd><b>Testcase <a target='other_window' href='./js1_2/String/concat.js'>js1_2/String/concat.js</a> failed</b> <br>
- [ <a href='#failure91'>Previous Failure</a> | <a href='#failure93'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure91'></a><dd><b>Testcase <a target='other_window' href='./js1_2/String/concat.js'>js1_2/String/concat.js</a> failed</b> <br>
+ [ <a href='#failure90'>Previous Failure</a> | <a href='#failure92'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> aString.concat([])      = test string FAILED! expected: test string[]<br>
@@ -1513,29 +1497,29 @@ Failure messages were:<br>
 --> 'abcde'.concat([])      = abcde FAILED! expected: abcde[]<br>
 --> 'abcde'.concat([1,2,3]) = abcde1,2,3 FAILED! expected: abcde[1, 2, 3]<br>
 </tt><br>
-<a name='failure93'></a><dd><b>Testcase <a target='other_window' href='./js1_2/String/slice.js'>js1_2/String/slice.js</a> failed</b> <br>
- [ <a href='#failure92'>Previous Failure</a> | <a href='#failure94'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure92'></a><dd><b>Testcase <a target='other_window' href='./js1_2/String/slice.js'>js1_2/String/slice.js</a> failed</b> <br>
+ [ <a href='#failure91'>Previous Failure</a> | <a href='#failure93'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> exhaustive String.slice test 1 = false FAILED! expected: true<br>
 --> exhaustive String.slice test 2 = false FAILED! expected: true<br>
 </tt><br>
-<a name='failure94'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/boolean-001.js'>js1_2/version120/boolean-001.js</a> failed</b> <br>
- [ <a href='#failure93'>Previous Failure</a> | <a href='#failure95'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure93'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/boolean-001.js'>js1_2/version120/boolean-001.js</a> failed</b> <br>
+ [ <a href='#failure92'>Previous Failure</a> | <a href='#failure94'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> new Boolean(false) = true FAILED! expected: false<br>
 </tt><br>
-<a name='failure95'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/regress-99663.js'>js1_2/version120/regress-99663.js</a> failed</b> <br>
- [ <a href='#failure94'>Previous Failure</a> | <a href='#failure96'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure94'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/regress-99663.js'>js1_2/version120/regress-99663.js</a> failed</b> <br>
+ [ <a href='#failure93'>Previous Failure</a> | <a href='#failure95'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Regression test for Bugzilla bug 99663<br>
 Failure messages were:<br>
 --> Section 1 of test - got Error: Can't find variable: it FAILED! expected: a "read-only" error<br>
 --> Section 2 of test - got Error: Can't find variable: it FAILED! expected: a "read-only" error<br>
 --> Section 3 of test - got Error: Can't find variable: it FAILED! expected: a "read-only" error<br>
 </tt><br>
-<a name='failure96'></a><dd><b>Testcase <a target='other_window' href='./js1_3/regress/function-001-n.js'>js1_3/regress/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
- [ <a href='#failure95'>Previous Failure</a> | <a href='#failure97'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure95'></a><dd><b>Testcase <a target='other_window' href='./js1_3/regress/function-001-n.js'>js1_3/regress/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
+ [ <a href='#failure94'>Previous Failure</a> | <a href='#failure96'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1544,8 +1528,8 @@ Complete testcase output was:<br>
 --> eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
 OK.<br>
 </tt><br>
-<a name='failure97'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/function-001-n.js'>js1_3/Script/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
- [ <a href='#failure96'>Previous Failure</a> | <a href='#failure98'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure96'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/function-001-n.js'>js1_3/Script/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
+ [ <a href='#failure95'>Previous Failure</a> | <a href='#failure97'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1554,35 +1538,35 @@ Complete testcase output was:<br>
 --> eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
 OK.<br>
 </tt><br>
-<a name='failure98'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/script-001.js'>js1_3/Script/script-001.js</a> failed</b> <br>
- [ <a href='#failure97'>Previous Failure</a> | <a href='#failure99'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure97'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/script-001.js'>js1_3/Script/script-001.js</a> failed</b> <br>
+ [ <a href='#failure96'>Previous Failure</a> | <a href='#failure98'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 --> script-001 NativeScript<br>
 Exception: ReferenceError - Can't find variable: Script<br>
 </tt><br>
-<a name='failure99'></a><dd><b>Testcase <a target='other_window' href='./js1_4/Functions/function-001.js'>js1_4/Functions/function-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=324455' target='other_window'>Bug Number 324455</a><br>
- [ <a href='#failure98'>Previous Failure</a> | <a href='#failure100'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure98'></a><dd><b>Testcase <a target='other_window' href='./js1_4/Functions/function-001.js'>js1_4/Functions/function-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=324455' target='other_window'>Bug Number 324455</a><br>
+ [ <a href='#failure97'>Previous Failure</a> | <a href='#failure99'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> return arguments when function contains an arguments property = [object Arguments] FAILED! expected: PASS<br>
 --> return function.arguments when function contains an arguments property = [object Arguments] FAILED! expected: PASS<br>
 </tt><br>
-<a name='failure100'></a><dd><b>Testcase <a target='other_window' href='./js1_4/Regress/function-002.js'>js1_4/Regress/function-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=330462' target='other_window'>Bug Number 330462</a><br>
- [ <a href='#failure99'>Previous Failure</a> | <a href='#failure101'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure99'></a><dd><b>Testcase <a target='other_window' href='./js1_4/Regress/function-002.js'>js1_4/Regress/function-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=330462' target='other_window'>Bug Number 330462</a><br>
+ [ <a href='#failure98'>Previous Failure</a> | <a href='#failure100'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 --> f1.toString() == dec1 = false FAILED! expected: true<br>
 </tt><br>
-<a name='failure101'></a><dd><b>Testcase <a target='other_window' href='./js1_4/Regress/function-003.js'>js1_4/Regress/function-003.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=310514' target='other_window'>Bug Number 310514</a><br>
- [ <a href='#failure100'>Previous Failure</a> | <a href='#failure102'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure100'></a><dd><b>Testcase <a target='other_window' href='./js1_4/Regress/function-003.js'>js1_4/Regress/function-003.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=310514' target='other_window'>Bug Number 310514</a><br>
+ [ <a href='#failure99'>Previous Failure</a> | <a href='#failure101'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
---> StripSpaces(Array.prototype.concat.toString()).substring(0,17) = (Internalfunction FAILED! expected: functionconcat(){<br>
+--> StripSpaces(Array.prototype.concat.toString()).substring(0,17) = (InternalFunction FAILED! expected: functionconcat(){<br>
 </tt><br>
-<a name='failure102'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Array/regress-157652.js'>js1_5/Array/regress-157652.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=157652' target='other_window'>Bug Number 157652</a><br>
- [ <a href='#failure101'>Previous Failure</a> | <a href='#failure103'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure101'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Array/regress-157652.js'>js1_5/Array/regress-157652.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=157652' target='other_window'>Bug Number 157652</a><br>
+ [ <a href='#failure100'>Previous Failure</a> | <a href='#failure102'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1591,36 +1575,36 @@ Complete testcase output was:<br>
 --> --- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE 3 ---<br>
 OK.<br>
 </tt><br>
-<a name='failure103'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-001.js'>js1_5/Exceptions/catchguard-001.js</a> failed</b> <br>
- [ <a href='#failure102'>Previous Failure</a> | <a href='#failure104'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure102'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-001.js'>js1_5/Exceptions/catchguard-001.js</a> failed</b> <br>
+ [ <a href='#failure101'>Previous Failure</a> | <a href='#failure103'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 42: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure104'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-002.js'>js1_5/Exceptions/catchguard-002.js</a> failed</b> <br>
- [ <a href='#failure103'>Previous Failure</a> | <a href='#failure105'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure103'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-002.js'>js1_5/Exceptions/catchguard-002.js</a> failed</b> <br>
+ [ <a href='#failure102'>Previous Failure</a> | <a href='#failure104'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 42: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure105'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-003.js'>js1_5/Exceptions/catchguard-003.js</a> failed</b> <br>
- [ <a href='#failure104'>Previous Failure</a> | <a href='#failure106'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure104'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-003.js'>js1_5/Exceptions/catchguard-003.js</a> failed</b> <br>
+ [ <a href='#failure103'>Previous Failure</a> | <a href='#failure105'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 42: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure106'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/errstack-001.js'>js1_5/Exceptions/errstack-001.js</a> failed</b> <br>
- [ <a href='#failure105'>Previous Failure</a> | <a href='#failure107'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure105'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/errstack-001.js'>js1_5/Exceptions/errstack-001.js</a> failed</b> <br>
+ [ <a href='#failure104'>Previous Failure</a> | <a href='#failure106'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception: TypeError - Undefined value<br>
 </tt><br>
-<a name='failure107'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/regress-123002.js'>js1_5/Exceptions/regress-123002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=123002' target='other_window'>Bug Number 123002</a><br>
- [ <a href='#failure106'>Previous Failure</a> | <a href='#failure108'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure106'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/regress-123002.js'>js1_5/Exceptions/regress-123002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=123002' target='other_window'>Bug Number 123002</a><br>
+ [ <a href='#failure105'>Previous Failure</a> | <a href='#failure107'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing Error.length<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section "Error" of test -<br>
@@ -1645,8 +1629,8 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Expected value '3', Actual value '0'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure108'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/regress-50447.js'>js1_5/Exceptions/regress-50447.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=50447' target='other_window'>Bug Number 50447</a><br>
- [ <a href='#failure107'>Previous Failure</a> | <a href='#failure109'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure107'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/regress-50447.js'>js1_5/Exceptions/regress-50447.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=50447' target='other_window'>Bug Number 50447</a><br>
+ [ <a href='#failure106'>Previous Failure</a> | <a href='#failure108'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1654,99 +1638,99 @@ Complete testcase output was:<br>
 --> STATUS: Test (non-ECMA) Error object properties fileName, lineNumber<br>
 Exception: TypeError - Undefined value<br>
 </tt><br>
-<a name='failure109'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-001.js'>js1_5/GetSet/getset-001.js</a> failed</b> <br>
- [ <a href='#failure108'>Previous Failure</a> | <a href='#failure110'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure108'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-001.js'>js1_5/GetSet/getset-001.js</a> failed</b> <br>
+ [ <a href='#failure107'>Previous Failure</a> | <a href='#failure109'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 33: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure110'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-002.js'>js1_5/GetSet/getset-002.js</a> failed</b> <br>
- [ <a href='#failure109'>Previous Failure</a> | <a href='#failure111'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure109'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-002.js'>js1_5/GetSet/getset-002.js</a> failed</b> <br>
+ [ <a href='#failure108'>Previous Failure</a> | <a href='#failure110'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 29: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure111'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-003.js'>js1_5/GetSet/getset-003.js</a> failed</b> <br>
- [ <a href='#failure110'>Previous Failure</a> | <a href='#failure112'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure110'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-003.js'>js1_5/GetSet/getset-003.js</a> failed</b> <br>
+ [ <a href='#failure109'>Previous Failure</a> | <a href='#failure111'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 48: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure112'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-004.js'>js1_5/GetSet/getset-004.js</a> failed</b> <br>
- [ <a href='#failure111'>Previous Failure</a> | <a href='#failure113'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure111'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-004.js'>js1_5/GetSet/getset-004.js</a> failed</b> <br>
+ [ <a href='#failure110'>Previous Failure</a> | <a href='#failure112'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 48: TypeError - Value undefined (result of expression obj.__defineSetter__) is not object.<br>
 </tt><br>
-<a name='failure113'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-005.js'>js1_5/GetSet/getset-005.js</a> failed</b> <br>
- [ <a href='#failure112'>Previous Failure</a> | <a href='#failure114'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure112'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-005.js'>js1_5/GetSet/getset-005.js</a> failed</b> <br>
+ [ <a href='#failure111'>Previous Failure</a> | <a href='#failure113'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 57: TypeError - Value undefined (result of expression obj.__defineSetter__) is not object.<br>
 </tt><br>
-<a name='failure114'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-006.js'>js1_5/GetSet/getset-006.js</a> failed</b> <br>
- [ <a href='#failure113'>Previous Failure</a> | <a href='#failure115'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure113'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-006.js'>js1_5/GetSet/getset-006.js</a> failed</b> <br>
+ [ <a href='#failure112'>Previous Failure</a> | <a href='#failure114'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 62: TypeError - Value undefined (result of expression obj.__defineSetter__) is not object.<br>
 </tt><br>
-<a name='failure115'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-001.js'>js1_5/Object/regress-90596-001.js</a> failed</b> <br>
- [ <a href='#failure114'>Previous Failure</a> | <a href='#failure116'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure114'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-001.js'>js1_5/Object/regress-90596-001.js</a> failed</b> <br>
+ [ <a href='#failure113'>Previous Failure</a> | <a href='#failure115'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 49: TypeError - Value undefined (result of expression obj.toSource) is not object.<br>
 </tt><br>
-<a name='failure116'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-002.js'>js1_5/Object/regress-90596-002.js</a> failed</b> <br>
- [ <a href='#failure115'>Previous Failure</a> | <a href='#failure117'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure115'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-002.js'>js1_5/Object/regress-90596-002.js</a> failed</b> <br>
+ [ <a href='#failure114'>Previous Failure</a> | <a href='#failure116'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 49: TypeError - Object  (result of expression uneval) does not allow calls.<br>
 </tt><br>
-<a name='failure117'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-001.js'>js1_5/Object/regress-96284-001.js</a> failed</b> <br>
- [ <a href='#failure116'>Previous Failure</a> | <a href='#failure118'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure116'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-001.js'>js1_5/Object/regress-96284-001.js</a> failed</b> <br>
+ [ <a href='#failure115'>Previous Failure</a> | <a href='#failure117'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 50: TypeError - Value undefined (result of expression obj1.toSource) is not object.<br>
 </tt><br>
-<a name='failure118'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-002.js'>js1_5/Object/regress-96284-002.js</a> failed</b> <br>
- [ <a href='#failure117'>Previous Failure</a> | <a href='#failure119'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure117'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-002.js'>js1_5/Object/regress-96284-002.js</a> failed</b> <br>
+ [ <a href='#failure116'>Previous Failure</a> | <a href='#failure118'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 50: TypeError - Object  (result of expression uneval) does not allow calls.<br>
 </tt><br>
-<a name='failure119'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-104077.js'>js1_5/Regress/regress-104077.js</a> failed</b> <br>
- [ <a href='#failure118'>Previous Failure</a> | <a href='#failure120'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure118'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-104077.js'>js1_5/Regress/regress-104077.js</a> failed</b> <br>
+ [ <a href='#failure117'>Previous Failure</a> | <a href='#failure119'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 351: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure120'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-127557.js'>js1_5/Regress/regress-127557.js</a> failed</b> <br>
- [ <a href='#failure119'>Previous Failure</a> | <a href='#failure121'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure119'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-127557.js'>js1_5/Regress/regress-127557.js</a> failed</b> <br>
+ [ <a href='#failure118'>Previous Failure</a> | <a href='#failure120'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 76: TypeError - Object  (result of expression clone) does not allow calls.<br>
 </tt><br>
-<a name='failure121'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-156354.js'>js1_5/Regress/regress-156354.js</a> failed</b> <br>
- [ <a href='#failure120'>Previous Failure</a> | <a href='#failure122'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure120'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-156354.js'>js1_5/Regress/regress-156354.js</a> failed</b> <br>
+ [ <a href='#failure119'>Previous Failure</a> | <a href='#failure121'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 56: TypeError - Value undefined (result of expression this.propertyIsEnumerable) is not object.<br>
 </tt><br>
-<a name='failure122'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-168347.js'>js1_5/Regress/regress-168347.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=168347' target='other_window'>Bug Number 168347</a><br>
- [ <a href='#failure121'>Previous Failure</a> | <a href='#failure123'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure121'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-168347.js'>js1_5/Regress/regress-168347.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=168347' target='other_window'>Bug Number 168347</a><br>
+ [ <a href='#failure120'>Previous Failure</a> | <a href='#failure122'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing F.toString()<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 2 of test -<br>
@@ -1756,15 +1740,15 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Expected value '{--f.i;print("--isucceededi="+f.i);}catch(e){print("--ifailedwith"+e+"i="+f.i);}try{f.i--;print("i--', Actual value '{f.i--;print("--isucceededi="+f.i);}catch(e){print("--ifailedwith"+e+"i="+f.i);}try{f.i--;print("i--'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure123'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-172699.js'>js1_5/Regress/regress-172699.js</a> failed</b> <br>
- [ <a href='#failure122'>Previous Failure</a> | <a href='#failure124'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure122'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-172699.js'>js1_5/Regress/regress-172699.js</a> failed</b> <br>
+ [ <a href='#failure121'>Previous Failure</a> | <a href='#failure123'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception: URIError - URI error<br>
 </tt><br>
-<a name='failure124'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-179524.js'>js1_5/Regress/regress-179524.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=179524' target='other_window'>Bug Number 179524</a><br>
- [ <a href='#failure123'>Previous Failure</a> | <a href='#failure125'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure123'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-179524.js'>js1_5/Regress/regress-179524.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=179524' target='other_window'>Bug Number 179524</a><br>
+ [ <a href='#failure122'>Previous Failure</a> | <a href='#failure124'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Don't crash on extraneous arguments to str.match(), etc.<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 14 of test -<br>
@@ -1814,16 +1798,16 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Expected value 'SHOULD HAVE FALLEN INTO CATCH-BLOCK!', Actual value 'ABC Zbc'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure125'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-185165.js'>js1_5/Regress/regress-185165.js</a> failed</b> <br>
- [ <a href='#failure124'>Previous Failure</a> | <a href='#failure126'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure124'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-185165.js'>js1_5/Regress/regress-185165.js</a> failed</b> <br>
+ [ <a href='#failure123'>Previous Failure</a> | <a href='#failure125'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 yylex: ERROR.<br>
 Exception, line 3: SyntaxError - Parse error<br>
 </tt><br>
-<a name='failure126'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-44009.js'>js1_5/Regress/regress-44009.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=44009' target='other_window'>Bug Number 44009</a><br>
- [ <a href='#failure125'>Previous Failure</a> | <a href='#failure127'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure125'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-44009.js'>js1_5/Regress/regress-44009.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=44009' target='other_window'>Bug Number 44009</a><br>
+ [ <a href='#failure124'>Previous Failure</a> | <a href='#failure126'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1831,16 +1815,16 @@ Complete testcase output was:<br>
 --> STATUS: Testing that we don't crash on obj.toSource()<br>
 Exception, line 61: TypeError - Value undefined (result of expression obj.toSource) is not object.<br>
 </tt><br>
-<a name='failure127'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-68498-002.js'>js1_5/Regress/regress-68498-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=68498' target='other_window'>Bug Number 68498</a><br>
- [ <a href='#failure126'>Previous Failure</a> | <a href='#failure128'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure126'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-68498-002.js'>js1_5/Regress/regress-68498-002.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=68498' target='other_window'>Bug Number 68498</a><br>
+ [ <a href='#failure125'>Previous Failure</a> | <a href='#failure127'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Creating a Deletable local variable using eval<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Creating a Deletable local variable using eval; currently at expect[1] within test -<br>
 --> FAILED!: [reported from test()] Expected value 'true', Actual value 'false'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure128'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-68498-003.js'>js1_5/Regress/regress-68498-003.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=68498' target='other_window'>Bug Number 68498</a><br>
- [ <a href='#failure127'>Previous Failure</a> | <a href='#failure129'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure127'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-68498-003.js'>js1_5/Regress/regress-68498-003.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=68498' target='other_window'>Bug Number 68498</a><br>
+ [ <a href='#failure126'>Previous Failure</a> | <a href='#failure128'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing calling obj.eval(str)<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Testing calling obj.eval(str); currently at expect[1] within test -<br>
@@ -1848,16 +1832,16 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] Expected value '43', Actual value 'false'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure129'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-96128-n.js'>js1_5/Regress/regress-96128-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=96128' target='other_window'>Bug Number 96128</a><br>
- [ <a href='#failure128'>Previous Failure</a> | <a href='#failure130'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure128'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-96128-n.js'>js1_5/Regress/regress-96128-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=96128' target='other_window'>Bug Number 96128</a><br>
+ [ <a href='#failure127'>Previous Failure</a> | <a href='#failure129'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 11<br>
 Complete testcase output was:<br>
 --> BUGNUMBER: 96128<br>
 --> STATUS: Testing that JS infinite recursion protection works<br>
 </tt><br>
-<a name='failure130'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/regress-185485.js'>js1_5/Scope/regress-185485.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=185485' target='other_window'>Bug Number 185485</a><br>
- [ <a href='#failure129'>Previous Failure</a> | <a href='#failure131'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure129'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/regress-185485.js'>js1_5/Scope/regress-185485.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=185485' target='other_window'>Bug Number 185485</a><br>
+ [ <a href='#failure128'>Previous Failure</a> | <a href='#failure130'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>--> STATUS: Testing |with (x) {function f() {}}| when |x.f| already exists<br>
 Failure messages were:<br>
 --> FAILED!: [reported from test()] Section 2 of test -<br>
@@ -1872,15 +1856,15 @@ Failure messages were:<br>
 --> FAILED!: [reported from test()] }', Actual value '0'<br>
 --> FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure131'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/regress-220584.js'>js1_5/Scope/regress-220584.js</a> failed</b> <br>
- [ <a href='#failure130'>Previous Failure</a> | <a href='#failure132'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure130'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/regress-220584.js'>js1_5/Scope/regress-220584.js</a> failed</b> <br>
+ [ <a href='#failure129'>Previous Failure</a> | <a href='#failure131'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Exception, line 57: TypeError - Object  (result of expression Script) does not allow calls.<br>
 </tt><br>
-<a name='failure132'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/scope-001.js'>js1_5/Scope/scope-001.js</a> failed</b> <br>
- [ <a href='#failure131'>Previous Failure</a> | <a href='#failure133'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure131'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/scope-001.js'>js1_5/Scope/scope-001.js</a> failed</b> <br>
+ [ <a href='#failure130'>Previous Failure</a> | <a href='#failure132'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -1892,9 +1876,9 @@ Exception, line 40: SyntaxError - Parse error<br>
 <pre>
 <a name='retest_list'></a>
 <h2>Retest List</h2><br>
-# Retest List, kjs, generated Sun Sep 26 17:58:04 2004.
+# Retest List, kjs, generated Wed Apr 20 02:42:18 2005.
 # Original test base was: All tests.
-# 962 of 967 test(s) were completed, 132 failures reported.
+# 962 of 967 test(s) were completed, 131 failures reported.
 ecma/ExecutionContexts/10.1.6.js
 ecma/GlobalObject/15.1.2.2-2.js
 ecma/LexicalConventions/7.7.3-1.js
@@ -1939,7 +1923,6 @@ ecma_3/Object/class-004.js
 ecma_3/Object/regress-72773.js
 ecma_3/RegExp/15.10.2-1.js
 ecma_3/RegExp/15.10.6.2-2.js
-ecma_3/RegExp/octal-002.js
 ecma_3/RegExp/perlstress-001.js
 ecma_3/RegExp/perlstress-002.js
 ecma_3/RegExp/regress-100199.js