Ignore:
Timestamp:
Mar 10, 2011, 12:31:21 PM (14 years ago)
Author:
[email protected]
Message:

Bug 56077 - ES5 conformance issues with RegExp.prototype

Reviewed by Oliver Hunt.

There are three issues causing test failures in sputnik.

(1) lastIndex should be converted at the point it is used, not the point it is set (this is visible if valueOf is overridden).
(2) The 'length' property of the test/exec functions should be 1.
(3) If no input is specified, the input to test()/exec() is "undefined" (i.e. ToString(undefined)) - not RegExp.input.

Source/JavaScriptCore:

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::markChildren):

  • Added to mark lastIndex

(JSC::regExpObjectLastIndex):
(JSC::setRegExpObjectLastIndex):

  • lastIndex is now stored as a JSValue.

(JSC::RegExpObject::match):

  • Use accessor methods to get/set lastIndex, add fast case for isUInt32 (don't convert to double).
  • runtime/RegExpObject.h:

(JSC::RegExpObject::setLastIndex):
(JSC::RegExpObject::setLastIndex):

  • Set lastIndex, either from a size_t or a JSValue.

(JSC::RegExpObject::getLastIndex):

  • Get lastIndex.

(JSC::RegExpObject::RegExpObjectData::RegExpObjectData):

  • Initialize as a JSValue.
  • runtime/RegExpPrototype.cpp:

(JSC::RegExpPrototype::RegExpPrototype):

  • Add test/exec properties with length 1.
  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncMatch):
(JSC::stringProtoFuncSearch):

  • Do not read RegExp.input if none is provided.
  • tests/mozilla/js1_2/regexp/RegExp_input.js:
  • tests/mozilla/js1_2/regexp/RegExp_input_as_array.js:
    • Update these tests (they relied on non-ES5 behaviour).

LayoutTests:

  • fast/js/kde/function_length-expected.txt:
  • fast/js/kde/script-tests/function_length.js:
    • 'length' of RexExp.test/RexExp.exec is 1
  • fast/js/regexp-caching-expected.txt:
  • fast/js/regexp-test-null-string-expected.txt:
  • fast/js/regexp-test-null-string.html:
    • test() is equivalent to test("undefined")
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.2_RegExp.prototype.exec/S15.10.6.2_A11-expected.txt:
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.2_RegExp.prototype.exec/S15.10.6.2_A1_T16-expected.txt:
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.2_RegExp.prototype.exec/S15.10.6.2_A4_T11-expected.txt:
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.3_RegExp.prototype.test/S15.10.6.3_A11-expected.txt:
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.3_RegExp.prototype.test/S15.10.6.3_A1_T16-expected.txt:
    • These tests now pass!
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.h

    r79211 r80743  
    2929    class RegExpObject : public JSObjectWithGlobalObject {
    3030    public:
     31        typedef JSObjectWithGlobalObject Base;
     32
    3133        RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure>, NonNullPassRefPtr<RegExp>);
    3234        virtual ~RegExpObject();
     
    3537        RegExp* regExp() const { return d->regExp.get(); }
    3638
    37         void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; }
    38         double lastIndex() const { return d->lastIndex; }
     39        void setLastIndex(size_t lastIndex)
     40        {
     41            d->lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
     42        }
     43        void setLastIndex(JSGlobalData& globalData, JSValue lastIndex)
     44        {
     45            d->lastIndex.set(globalData, this, lastIndex);
     46        }
     47        JSValue getLastIndex() const
     48        {
     49            return d->lastIndex.get();
     50        }
    3951
    4052        JSValue test(ExecState*);
     
    5365
    5466    protected:
    55         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObjectWithGlobalObject::StructureFlags;
    56        
     67        static const unsigned StructureFlags = OverridesMarkChildren | OverridesGetOwnPropertySlot | JSObjectWithGlobalObject::StructureFlags;
     68
    5769    private:
     70        virtual void markChildren(MarkStack&);
     71
    5872        bool match(ExecState*);
    5973
     
    6175            WTF_MAKE_FAST_ALLOCATED;
    6276        public:
    63             RegExpObjectData(NonNullPassRefPtr<RegExp> regExp, double lastIndex)
     77            RegExpObjectData(NonNullPassRefPtr<RegExp> regExp)
    6478                : regExp(regExp)
    65                 , lastIndex(lastIndex)
    6679            {
     80                lastIndex.setWithoutWriteBarrier(jsNumber(0));
    6781            }
    6882
    6983            RefPtr<RegExp> regExp;
    70             double lastIndex;
     84            WriteBarrier<Unknown> lastIndex;
    7185        };
    7286#if COMPILER(MSVC)
Note: See TracChangeset for help on using the changeset viewer.