Changeset 199400 in webkit


Ignore:
Timestamp:
Apr 12, 2016 6:31:52 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

Rollout: ES6: Implement String.prototype.split and RegExp.prototype[@@split].
https://bugs.webkit.org/show_bug.cgi?id=156013

Speculative rollout to fix 32-bit shadow-chicken.yaml/tests/v8-v6/v8-regexp.js.shadow-chicken test failure.

Not reviewed.

Source/JavaScriptCore:

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • builtins/GlobalObject.js:

(speciesGetter):
(speciesConstructor): Deleted.

  • builtins/PromisePrototype.js:
  • builtins/RegExpPrototype.js:

(advanceStringIndexUnicode):
(match):
(advanceStringIndex): Deleted.
(regExpExec): Deleted.
(hasObservableSideEffectsForRegExpSplit): Deleted.
(split): Deleted.

  • builtins/StringPrototype.js:

(repeat):
(split): Deleted.

  • bytecode/BytecodeIntrinsicRegistry.cpp:

(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
(JSC::BytecodeIntrinsicRegistry::lookup):

  • bytecode/BytecodeIntrinsicRegistry.h:
  • runtime/CommonIdentifiers.h:
  • runtime/ECMAScriptSpecInternalFunctions.cpp: Removed.
  • runtime/ECMAScriptSpecInternalFunctions.h: Removed.
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::setGlobalThis):
(JSC::JSGlobalObject::init):
(JSC::getGetterById): Deleted.

  • runtime/PropertyDescriptor.cpp:

(JSC::PropertyDescriptor::setDescriptor):

  • runtime/RegExpObject.h:

(JSC::RegExpObject::offsetOfLastIndexIsWritable):

  • runtime/RegExpPrototype.cpp:

(JSC::RegExpPrototype::finishCreation):
(JSC::regExpProtoFuncExec):
(JSC::regExpProtoFuncSearch):
(JSC::advanceStringIndex): Deleted.
(JSC::regExpProtoFuncSplitFast): Deleted.

  • runtime/RegExpPrototype.h:
  • runtime/StringObject.h:

(JSC::jsStringWithReuse): Deleted.
(JSC::jsSubstring): Deleted.

  • runtime/StringPrototype.cpp:

(JSC::StringPrototype::finishCreation):
(JSC::jsStringWithReuse):
(JSC::jsSubstring):
(JSC::substituteBackreferencesSlow):
(JSC::splitStringByOneCharacterImpl):
(JSC::stringProtoFuncSplit):
(JSC::stringProtoFuncSubstr):
(JSC::stringProtoFuncSubstring):
(JSC::stringProtoFuncEndsWith):
(JSC::stringProtoFuncIncludes):
(JSC::stringProtoFuncIterator):
(JSC::stringProtoFuncSplitFast): Deleted.
(JSC::builtinStringSubstrInternal): Deleted.
(JSC::stringIncludesImpl): Deleted.
(JSC::builtinStringIncludesInternal): Deleted.

  • runtime/StringPrototype.h:
  • tests/es6.yaml:

LayoutTests:

  • js/Object-getOwnPropertyNames-expected.txt:
  • js/dom/string-prototype-properties-expected.txt:
  • js/regress/regexp-prototype-split-observable-side-effects-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects2-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects2.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-flags-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-flags.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-global-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-global.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-ignoreCase-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-ignoreCase.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-multiline-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-multiline.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-sticky-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-sticky.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-unicode-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects3-unicode.html: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects4-expected.txt: Removed.
  • js/regress/regexp-prototype-split-observable-side-effects4.html: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects2.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects3-flags.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects3-global.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects3-ignoreCase.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects3-multiline.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects3-sticky.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects3-unicode.js: Removed.
  • js/regress/script-tests/regexp-prototype-split-observable-side-effects4.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects2.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects3-flags.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects3-global.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects3-ignoreCase.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects3-multiline.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects3-sticky.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects3-unicode.js: Removed.
  • js/regress/script-tests/string-prototype-split-observable-side-effects4.js: Removed.
  • js/regress/string-prototype-split-observable-side-effects-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects2-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects2.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-flags-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-flags.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-global-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-global.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-ignoreCase-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-ignoreCase.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-multiline-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-multiline.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-sticky-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-sticky.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-unicode-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects3-unicode.html: Removed.
  • js/regress/string-prototype-split-observable-side-effects4-expected.txt: Removed.
  • js/regress/string-prototype-split-observable-side-effects4.html: Removed.
  • js/script-tests/Object-getOwnPropertyNames.js:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt:
Location:
trunk
Files:
56 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r199397 r199400  
     12016-04-12  Mark Lam  <mark.lam@apple.com>
     2
     3        Rollout: ES6: Implement String.prototype.split and RegExp.prototype[@@split].
     4        https://bugs.webkit.org/show_bug.cgi?id=156013
     5
     6        Speculative rollout to fix 32-bit shadow-chicken.yaml/tests/v8-v6/v8-regexp.js.shadow-chicken test failure.
     7
     8        Not reviewed.
     9
     10        * js/Object-getOwnPropertyNames-expected.txt:
     11        * js/dom/string-prototype-properties-expected.txt:
     12        * js/regress/regexp-prototype-split-observable-side-effects-expected.txt: Removed.
     13        * js/regress/regexp-prototype-split-observable-side-effects.html: Removed.
     14        * js/regress/regexp-prototype-split-observable-side-effects2-expected.txt: Removed.
     15        * js/regress/regexp-prototype-split-observable-side-effects2.html: Removed.
     16        * js/regress/regexp-prototype-split-observable-side-effects3-flags-expected.txt: Removed.
     17        * js/regress/regexp-prototype-split-observable-side-effects3-flags.html: Removed.
     18        * js/regress/regexp-prototype-split-observable-side-effects3-global-expected.txt: Removed.
     19        * js/regress/regexp-prototype-split-observable-side-effects3-global.html: Removed.
     20        * js/regress/regexp-prototype-split-observable-side-effects3-ignoreCase-expected.txt: Removed.
     21        * js/regress/regexp-prototype-split-observable-side-effects3-ignoreCase.html: Removed.
     22        * js/regress/regexp-prototype-split-observable-side-effects3-multiline-expected.txt: Removed.
     23        * js/regress/regexp-prototype-split-observable-side-effects3-multiline.html: Removed.
     24        * js/regress/regexp-prototype-split-observable-side-effects3-sticky-expected.txt: Removed.
     25        * js/regress/regexp-prototype-split-observable-side-effects3-sticky.html: Removed.
     26        * js/regress/regexp-prototype-split-observable-side-effects3-unicode-expected.txt: Removed.
     27        * js/regress/regexp-prototype-split-observable-side-effects3-unicode.html: Removed.
     28        * js/regress/regexp-prototype-split-observable-side-effects4-expected.txt: Removed.
     29        * js/regress/regexp-prototype-split-observable-side-effects4.html: Removed.
     30        * js/regress/script-tests/regexp-prototype-split-observable-side-effects.js: Removed.
     31        * js/regress/script-tests/regexp-prototype-split-observable-side-effects2.js: Removed.
     32        * js/regress/script-tests/regexp-prototype-split-observable-side-effects3-flags.js: Removed.
     33        * js/regress/script-tests/regexp-prototype-split-observable-side-effects3-global.js: Removed.
     34        * js/regress/script-tests/regexp-prototype-split-observable-side-effects3-ignoreCase.js: Removed.
     35        * js/regress/script-tests/regexp-prototype-split-observable-side-effects3-multiline.js: Removed.
     36        * js/regress/script-tests/regexp-prototype-split-observable-side-effects3-sticky.js: Removed.
     37        * js/regress/script-tests/regexp-prototype-split-observable-side-effects3-unicode.js: Removed.
     38        * js/regress/script-tests/regexp-prototype-split-observable-side-effects4.js: Removed.
     39        * js/regress/script-tests/string-prototype-split-observable-side-effects.js: Removed.
     40        * js/regress/script-tests/string-prototype-split-observable-side-effects2.js: Removed.
     41        * js/regress/script-tests/string-prototype-split-observable-side-effects3-flags.js: Removed.
     42        * js/regress/script-tests/string-prototype-split-observable-side-effects3-global.js: Removed.
     43        * js/regress/script-tests/string-prototype-split-observable-side-effects3-ignoreCase.js: Removed.
     44        * js/regress/script-tests/string-prototype-split-observable-side-effects3-multiline.js: Removed.
     45        * js/regress/script-tests/string-prototype-split-observable-side-effects3-sticky.js: Removed.
     46        * js/regress/script-tests/string-prototype-split-observable-side-effects3-unicode.js: Removed.
     47        * js/regress/script-tests/string-prototype-split-observable-side-effects4.js: Removed.
     48        * js/regress/string-prototype-split-observable-side-effects-expected.txt: Removed.
     49        * js/regress/string-prototype-split-observable-side-effects.html: Removed.
     50        * js/regress/string-prototype-split-observable-side-effects2-expected.txt: Removed.
     51        * js/regress/string-prototype-split-observable-side-effects2.html: Removed.
     52        * js/regress/string-prototype-split-observable-side-effects3-flags-expected.txt: Removed.
     53        * js/regress/string-prototype-split-observable-side-effects3-flags.html: Removed.
     54        * js/regress/string-prototype-split-observable-side-effects3-global-expected.txt: Removed.
     55        * js/regress/string-prototype-split-observable-side-effects3-global.html: Removed.
     56        * js/regress/string-prototype-split-observable-side-effects3-ignoreCase-expected.txt: Removed.
     57        * js/regress/string-prototype-split-observable-side-effects3-ignoreCase.html: Removed.
     58        * js/regress/string-prototype-split-observable-side-effects3-multiline-expected.txt: Removed.
     59        * js/regress/string-prototype-split-observable-side-effects3-multiline.html: Removed.
     60        * js/regress/string-prototype-split-observable-side-effects3-sticky-expected.txt: Removed.
     61        * js/regress/string-prototype-split-observable-side-effects3-sticky.html: Removed.
     62        * js/regress/string-prototype-split-observable-side-effects3-unicode-expected.txt: Removed.
     63        * js/regress/string-prototype-split-observable-side-effects3-unicode.html: Removed.
     64        * js/regress/string-prototype-split-observable-side-effects4-expected.txt: Removed.
     65        * js/regress/string-prototype-split-observable-side-effects4.html: Removed.
     66        * js/script-tests/Object-getOwnPropertyNames.js:
     67        * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt:
     68
    1692016-04-12  Keith Miller  <keith_miller@apple.com>
    270
  • trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt

    r199397 r199400  
    6262PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
    6363PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
    64 PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']
     64PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']
    6565PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf']
    6666PASS getSortedOwnPropertyNames(Map) is ['length', 'name', 'prototype']
  • trunk/LayoutTests/js/dom/string-prototype-properties-expected.txt

    r199393 r199400  
    1515PASS String.prototype.search.call(undefined, '4') threw exception TypeError: String.prototype.search requires that |this| not be undefined.
    1616PASS String.prototype.slice.call(undefined, 1, 3) threw exception TypeError: Type error.
    17 PASS String.prototype.split.call(undefined, '2') threw exception TypeError: String.prototype.split requires that |this| not be undefined.
     17PASS String.prototype.split.call(undefined, '2') threw exception TypeError: Type error.
    1818PASS String.prototype.slice.call(undefined, 1, 3) threw exception TypeError: Type error.
    1919PASS String.prototype.substr.call(undefined, 1, 3) threw exception TypeError: Type error.
  • trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js

    r199397 r199400  
    7171    "Math": "['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']",
    7272    "JSON": "['parse', 'stringify']",
    73     "Symbol": "['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']",
     73    "Symbol": "['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']",
    7474    "Symbol.prototype": "['constructor', 'toString', 'valueOf']",
    7575    "Map": "['length', 'name', 'prototype']",
  • trunk/LayoutTests/sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt

    r199393 r199400  
    11S15.5.4.14_A1_T3
    22
    3 FAIL TypeError: String.prototype.split requires that |this| not be undefined
     3FAIL TypeError: Type error
    44
    55TEST COMPLETE
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r199393 r199400  
    639639    runtime/DirectArgumentsOffset.cpp
    640640    runtime/DumpContext.cpp
    641     runtime/ECMAScriptSpecInternalFunctions.cpp
    642641    runtime/Error.cpp
    643642    runtime/ErrorConstructor.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r199398 r199400  
     12016-04-12  Mark Lam  <mark.lam@apple.com>
     2
     3        Rollout: ES6: Implement String.prototype.split and RegExp.prototype[@@split].
     4        https://bugs.webkit.org/show_bug.cgi?id=156013
     5
     6        Speculative rollout to fix 32-bit shadow-chicken.yaml/tests/v8-v6/v8-regexp.js.shadow-chicken test failure.
     7
     8        Not reviewed.
     9
     10        * CMakeLists.txt:
     11        * JavaScriptCore.xcodeproj/project.pbxproj:
     12        * builtins/GlobalObject.js:
     13        (speciesGetter):
     14        (speciesConstructor): Deleted.
     15        * builtins/PromisePrototype.js:
     16        * builtins/RegExpPrototype.js:
     17        (advanceStringIndexUnicode):
     18        (match):
     19        (advanceStringIndex): Deleted.
     20        (regExpExec): Deleted.
     21        (hasObservableSideEffectsForRegExpSplit): Deleted.
     22        (split): Deleted.
     23        * builtins/StringPrototype.js:
     24        (repeat):
     25        (split): Deleted.
     26        * bytecode/BytecodeIntrinsicRegistry.cpp:
     27        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
     28        (JSC::BytecodeIntrinsicRegistry::lookup):
     29        * bytecode/BytecodeIntrinsicRegistry.h:
     30        * runtime/CommonIdentifiers.h:
     31        * runtime/ECMAScriptSpecInternalFunctions.cpp: Removed.
     32        * runtime/ECMAScriptSpecInternalFunctions.h: Removed.
     33        * runtime/JSGlobalObject.cpp:
     34        (JSC::JSGlobalObject::setGlobalThis):
     35        (JSC::JSGlobalObject::init):
     36        (JSC::getGetterById): Deleted.
     37        * runtime/PropertyDescriptor.cpp:
     38        (JSC::PropertyDescriptor::setDescriptor):
     39        * runtime/RegExpObject.h:
     40        (JSC::RegExpObject::offsetOfLastIndexIsWritable):
     41        * runtime/RegExpPrototype.cpp:
     42        (JSC::RegExpPrototype::finishCreation):
     43        (JSC::regExpProtoFuncExec):
     44        (JSC::regExpProtoFuncSearch):
     45        (JSC::advanceStringIndex): Deleted.
     46        (JSC::regExpProtoFuncSplitFast): Deleted.
     47        * runtime/RegExpPrototype.h:
     48        * runtime/StringObject.h:
     49        (JSC::jsStringWithReuse): Deleted.
     50        (JSC::jsSubstring): Deleted.
     51        * runtime/StringPrototype.cpp:
     52        (JSC::StringPrototype::finishCreation):
     53        (JSC::jsStringWithReuse):
     54        (JSC::jsSubstring):
     55        (JSC::substituteBackreferencesSlow):
     56        (JSC::splitStringByOneCharacterImpl):
     57        (JSC::stringProtoFuncSplit):
     58        (JSC::stringProtoFuncSubstr):
     59        (JSC::stringProtoFuncSubstring):
     60        (JSC::stringProtoFuncEndsWith):
     61        (JSC::stringProtoFuncIncludes):
     62        (JSC::stringProtoFuncIterator):
     63        (JSC::stringProtoFuncSplitFast): Deleted.
     64        (JSC::builtinStringSubstrInternal): Deleted.
     65        (JSC::stringIncludesImpl): Deleted.
     66        (JSC::builtinStringIncludesInternal): Deleted.
     67        * runtime/StringPrototype.h:
     68        * tests/es6.yaml:
     69
    1702016-04-12  Mark Lam  <mark.lam@apple.com>
    271
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r199397 r199400  
    20552055                FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */; };
    20562056                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2057                 FE318FDF1CAC982700DFCC54 /* ECMAScriptSpecInternalFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE318FDD1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.cpp */; };
    2058                 FE318FE01CAC982F00DFCC54 /* ECMAScriptSpecInternalFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE318FDE1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.h */; };
    20592057                FE384EE51ADDB7AD0055DE2C /* JSDollarVM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */; };
    20602058                FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */ = {isa = PBXBuildFile; fileRef = FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    43044302                FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
    43054303                FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
    4306                 FE318FDD1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ECMAScriptSpecInternalFunctions.cpp; sourceTree = "<group>"; };
    4307                 FE318FDE1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECMAScriptSpecInternalFunctions.h; sourceTree = "<group>"; };
    43084304                FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDollarVM.cpp; sourceTree = "<group>"; };
    43094305                FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDollarVM.h; sourceTree = "<group>"; };
     
    55865582                                A70447EB17A0BD7000F5898E /* DumpContext.cpp */,
    55875583                                A70447EC17A0BD7000F5898E /* DumpContext.h */,
    5588                                 FE318FDD1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.cpp */,
    5589                                 FE318FDE1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.h */,
    55905584                                2AD2EDFA19799E38004D6478 /* EnumerationMode.h */,
    55915585                                BC337BEA0E1B00CB0076918A /* Error.cpp */,
     
    79507944                                C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */,
    79517945                                0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
    7952                                 FE318FE01CAC982F00DFCC54 /* ECMAScriptSpecInternalFunctions.h in Headers */,
    79537946                                0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */,
    79547947                                0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */,
     
    87688761                                A77A423D17A0BBFD00A8DB81 /* DFGAbstractHeap.cpp in Sources */,
    87698762                                0F55C19417276E4600CEABFD /* DFGAbstractValue.cpp in Sources */,
    8770                                 FE318FDF1CAC982700DFCC54 /* ECMAScriptSpecInternalFunctions.cpp in Sources */,
    87718763                                0FD3E4011B618AAF00C80E1E /* DFGAdaptiveInferredPropertyValueWatchpoint.cpp in Sources */,
    87728764                                0F18D3CF1B55A6E0002C5C9F /* DFGAdaptiveStructureWatchpoint.cpp in Sources */,
  • trunk/Source/JavaScriptCore/builtins/GlobalObject.js

    r199393 r199400  
    11/*
    22 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
    3  * Copyright (C) 2016 Apple Inc. All rights reserved.
    43 *
    54 * Redistribution and use in source and binary forms, with or without
     
    6261    return this;
    6362}
    64 
    65 function speciesConstructor(obj, defaultConstructor)
    66 {
    67     var constructor = obj.constructor;
    68     if (constructor === @undefined)
    69         return defaultConstructor;
    70     if (!@isObject(constructor))
    71         throw new @TypeError("|this|.constructor is not an Object or undefined");
    72     constructor = constructor[@symbolSpecies];
    73     if (constructor == null)
    74         return defaultConstructor;
    75     if (@isConstructor(constructor))
    76         return constructor;
    77     throw new @TypeError("|this|.constructor[Symbol.species] is not a constructor");
    78 }
  • trunk/Source/JavaScriptCore/builtins/PromisePrototype.js

    r199393 r199400  
    11/*
    2  * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3838        throw new @TypeError("|this| is not a object");
    3939
    40     var constructor = @speciesConstructor(this, @Promise);
     40    var constructor = this.constructor;
     41    if (constructor === @undefined)
     42        constructor = @Promise;
     43    else if (!@isObject(constructor))
     44        throw new @TypeError("|this|.constructor is not an Object or undefined");
     45    else {
     46        constructor = constructor[@symbolSpecies];
     47        if (constructor == null)
     48            constructor = @Promise;
     49    }
    4150
    4251    var resultCapability = @newPromiseCapability(constructor);
  • trunk/Source/JavaScriptCore/builtins/RegExpPrototype.js

    r199393 r199400  
    2424 */
    2525
    26 function advanceStringIndex(string, index, unicode)
     26function advanceStringIndexUnicode(string, stringLength, index)
    2727{
    28     // This function implements AdvanceStringIndex described in ES6 21.2.5.2.3.
     28    // This function implements AdvanceStringIndex described in ES6 21.2.5.2.3, steps 6-11.
     29    // It assumes that "unicode" is true for its callers.
    2930    "use strict";
    3031
    31     if (!unicode)
    32         return index + 1;
    33 
    34     if (index + 1 >= string.length)
     32    if (index + 1 >= stringLength)
    3533        return index + 1;
    3634
     
    5048    "use strict";
    5149
    52     if (!@isObject(this))
     50    if (!(this instanceof @Object))
    5351        throw new @TypeError("RegExp.prototype.@@match requires that |this| be an Object");
    5452
    55     let regexp = this;
     53    let regexp = @Object(this);
    5654    let stringArg = @toString(str);
    5755
     
    8280            let resultString = @toString(result[0]);
    8381
    84             if (!resultString.length)
    85                 regexp.lastIndex = @advanceStringIndex(stringArg, regexp.lastIndex, unicode);
     82            if (!resultString.length) {
     83                if (unicode)
     84                    regexp.lastIndex = @advanceStringIndexUnicode(stringArg, stringLength, regexp.lastIndex);
     85                else
     86                    regexp.lastIndex++;
     87            }
    8688
    8789            resultList.@push(resultString);
     
    9496}
    9597
    96 function regExpExec(regexp, str)
    97 {
    98     "use strict";
    99 
    100     let exec = regexp.exec;
    101     let builtinExec = @RegExp.prototype.@exec;
    102     if (exec !== builtinExec && typeof exec === "function") {
    103         let result = exec.@call(regexp, str);
    104         if (result !== null && !@isObject(result))
    105             throw new @TypeError("The result of a RegExp exec must be null or an object");
    106         return result;
    107     }
    108     return builtinExec.@call(regexp, str);
    109 }
    110 
    111 function hasObservableSideEffectsForRegExpSplit(regexp) {
    112     // This is accessed by the RegExpExec internal function.
    113     let regexpExec = @tryGetById(regexp, "exec");
    114     if (regexpExec !== @RegExp.prototype.@exec)
    115         return true;
    116    
    117     // This is accessed by step 5 below.
    118     let regexpFlags = @tryGetById(regexp, "flags");
    119     if (regexpFlags !== @regExpProtoFlagsGetter)
    120         return true;
    121    
    122     // These are accessed by the builtin flags getter.
    123     let regexpGlobal = @tryGetById(regexp, "global");
    124     if (regexpGlobal !== @regExpProtoGlobalGetter)
    125         return true;
    126     let regexpIgnoreCase = @tryGetById(regexp, "ignoreCase");
    127     if (regexpIgnoreCase !== @regExpProtoIgnoreCaseGetter)
    128         return true;
    129     let regexpMultiline = @tryGetById(regexp, "multiline");
    130     if (regexpMultiline !== @regExpProtoMultilineGetter)
    131         return true;
    132     let regexpSticky = @tryGetById(regexp, "sticky");
    133     if (regexpSticky !== @regExpProtoStickyGetter)
    134         return true;
    135     let regexpUnicode = @tryGetById(regexp, "unicode");
    136     if (regexpUnicode !== @regExpProtoUnicodeGetter)
    137         return true;
    138    
    139     // This is accessed by the RegExp species constructor.
    140     let regexpSource = @tryGetById(regexp, "source");
    141     if (regexpSource !== @regExpProtoSourceGetter)
    142         return true;
    143    
    144     return !@isRegExp(regexp);
    145 }
    146 
    147 // ES 21.2.5.11 RegExp.prototype[@@split](string, limit)
    148 function split(string, limit)
    149 {
    150     "use strict";
    151 
    152     // 1. Let rx be the this value.
    153     // 2. If Type(rx) is not Object, throw a TypeError exception.
    154     if (!@isObject(this))
    155         throw new @TypeError("RegExp.prototype.@@split requires that |this| be an Object");
    156     let regexp = this;
    157 
    158     // 3. Let S be ? ToString(string).
    159     let str = @toString(string);
    160 
    161     // 4. Let C be ? SpeciesConstructor(rx, %RegExp%).
    162     let speciesConstructor = @speciesConstructor(regexp, @RegExp);
    163 
    164     if (speciesConstructor === @RegExp && !@hasObservableSideEffectsForRegExpSplit(regexp))
    165         return @regExpSplitFast.@call(regexp, str, limit);
    166 
    167     // 5. Let flags be ? ToString(? Get(rx, "flags")).
    168     let flags = @toString(regexp.flags);
    169 
    170     // 6. If flags contains "u", let unicodeMatching be true.
    171     // 7. Else, let unicodeMatching be false.
    172     let unicodeMatching = @stringIncludesInternal.@call(flags, "u");
    173     // 8. If flags contains "y", let newFlags be flags.
    174     // 9. Else, let newFlags be the string that is the concatenation of flags and "y".
    175     let newFlags = @stringIncludesInternal.@call(flags, "y") ? flags : flags + "y";
    176 
    177     // 10. Let splitter be ? Construct(C, « rx, newFlags »).
    178     let splitter = new speciesConstructor(regexp, newFlags);
    179 
    180     // We need to check again for RegExp subclasses that will fail the speciesConstructor test
    181     // but can still use the fast path after we invoke the constructor above.
    182     if (!@hasObservableSideEffectsForRegExpSplit(splitter))
    183         return @regExpSplitFast.@call(splitter, str, limit);
    184 
    185     // 11. Let A be ArrayCreate(0).
    186     // 12. Let lengthA be 0.
    187     let result = [];
    188 
    189     // 13. If limit is undefined, let lim be 2^32-1; else let lim be ? ToUint32(limit).
    190     limit = (limit === @undefined) ? 0xffffffff : limit >>> 0;
    191 
    192     // 16. If lim = 0, return A.
    193     if (!limit)
    194         return result;
    195 
    196     // 14. [Defered from above] Let size be the number of elements in S.
    197     let size = str.length;
    198 
    199     // 17. If size = 0, then
    200     if (!size) {
    201         // a. Let z be ? RegExpExec(splitter, S).
    202         let z = @regExpExec(splitter, str);
    203         // b. If z is not null, return A.
    204         if (z != null)
    205             return result;
    206         // c. Perform ! CreateDataProperty(A, "0", S).
    207         @putByValDirect(result, 0, str);
    208         // d. Return A.
    209         return result;
    210     }
    211 
    212     // 15. [Defered from above] Let p be 0.
    213     let position = 0;
    214     // 18. Let q be p.
    215     let matchPosition = 0;
    216 
    217     // 19. Repeat, while q < size
    218     while (matchPosition < size) {
    219         // a. Perform ? Set(splitter, "lastIndex", q, true).
    220         splitter.lastIndex = matchPosition;
    221         // b. Let z be ? RegExpExec(splitter, S).
    222         let matches = @regExpExec(splitter, str);
    223         // c. If z is null, let q be AdvanceStringIndex(S, q, unicodeMatching).
    224         if (matches === null)
    225             matchPosition = @advanceStringIndex(str, matchPosition, unicodeMatching);
    226         // d. Else z is not null,
    227         else {
    228             // i. Let e be ? ToLength(? Get(splitter, "lastIndex")).
    229             let endPosition = @toLength(splitter.lastIndex);
    230             // ii. Let e be min(e, size).
    231             endPosition = (endPosition <= size) ? endPosition : size;
    232             // iii. If e = p, let q be AdvanceStringIndex(S, q, unicodeMatching).
    233             if (endPosition === position)
    234                 matchPosition = @advanceStringIndex(str, matchPosition, unicodeMatching);
    235             // iv. Else e != p,
    236             else {
    237                 // 1. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through q (exclusive).
    238                 let subStr = @stringSubstrInternal.@call(str, position, matchPosition - position);
    239                 // 2. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
    240                 // 3. Let lengthA be lengthA + 1.
    241                 @putByValDirect(result, result.length, subStr);
    242                 // 4. If lengthA = lim, return A.
    243                 if (result.length == limit)
    244                     return result;
    245 
    246                 // 5. Let p be e.
    247                 position = endPosition;
    248                 // 6. Let numberOfCaptures be ? ToLength(? Get(z, "length")).
    249                 // 7. Let numberOfCaptures be max(numberOfCaptures-1, 0).
    250                 let numberOfCaptures = matches.length > 1 ? matches.length - 1 : 0;
    251 
    252                 // 8. Let i be 1.
    253                 let i = 1;
    254                 // 9. Repeat, while i <= numberOfCaptures,
    255                 while (i <= numberOfCaptures) {
    256                     // a. Let nextCapture be ? Get(z, ! ToString(i)).
    257                     let nextCapture = matches[i];
    258                     // b. Perform ! CreateDataProperty(A, ! ToString(lengthA), nextCapture).
    259                     // d. Let lengthA be lengthA + 1.
    260                     @putByValDirect(result, result.length, nextCapture);
    261                     // e. If lengthA = lim, return A.
    262                     if (result.length == limit)
    263                         return result;
    264                     // c. Let i be i + 1.
    265                     i++;
    266                 }
    267                 // 10. Let q be p.
    268                 matchPosition = position;
    269             }
    270         }
    271     }
    272     // 20. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through size (exclusive).
    273     let remainingStr = @stringSubstrInternal.@call(str, position, size);
    274     // 21. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
    275     @putByValDirect(result, result.length, remainingStr);
    276     // 22. Return A.
    277     return result;
    278 }
    279 
  • trunk/Source/JavaScriptCore/builtins/StringPrototype.js

    r199393 r199400  
    126126    return @repeatSlowPath(string, count);
    127127}
    128 
    129 function split(separator, limit)
    130 {
    131     "use strict";
    132    
    133     if (this == null) {
    134         if (this === null)
    135             throw new @TypeError("String.prototype.split requires that |this| not be null");
    136         throw new @TypeError("String.prototype.split requires that |this| not be undefined");
    137     }
    138    
    139     if (separator != null) {
    140         var splitter = separator[@symbolSplit];
    141         if (splitter != @undefined)
    142             return splitter.@call(separator, this, limit);
    143     }
    144    
    145     return @stringSplitFast.@call(this, separator, limit);
    146 }
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp

    r199397 r199400  
    11/*
    22 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
    3  * Copyright (C) 2016 Apple Inc. All rights reserved.
    43 *
    54 * Redistribution and use in source and binary forms, with or without
     
    6059    m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->searchSymbol.impl())));
    6160    m_symbolSpecies.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->speciesSymbol.impl())));
    62     m_symbolSplit.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->splitSymbol.impl())));
    6361}
    6462
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h

    r199397 r199400  
    11/*
    22 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
    3  * Copyright (C) 2016 Apple Inc. All rights reserved.
    43 *
    54 * Redistribution and use in source and binary forms, with or without
     
    6362    macro(symbolSearch) \
    6463    macro(symbolSpecies) \
    65     macro(symbolSplit) \
    6664
    6765class BytecodeIntrinsicRegistry {
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r199397 r199400  
    310310#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\
    311311    macro(replace) \
     312    macro(split)
    312313
    313314#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \
     
    318319    macro(search) \
    319320    macro(species) \
    320     macro(split) \
    321321    macro(toPrimitive) \
    322322    macro(toStringTag) \
     
    414414    macro(isJSArray) \
    415415    macro(isArrayConstructor) \
    416     macro(isConstructor) \
    417     macro(isRegExp) \
    418416    macro(concatMemcpy) \
    419417    macro(appendMemcpy) \
     
    427425    macro(MapIterator) \
    428426    macro(mapIteratorNext) \
    429     macro(regExpProtoFlagsGetter) \
    430     macro(regExpProtoGlobalGetter) \
    431     macro(regExpProtoIgnoreCaseGetter) \
    432     macro(regExpProtoMultilineGetter) \
    433     macro(regExpProtoSourceGetter) \
    434     macro(regExpProtoStickyGetter) \
    435     macro(regExpProtoUnicodeGetter) \
    436     macro(regExpSplitFast) \
    437     macro(stringIncludesInternal) \
    438     macro(stringSplitFast) \
    439     macro(stringSubstrInternal) \
     427
    440428
    441429namespace JSC {
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r199397 r199400  
    4646#include "DebuggerScope.h"
    4747#include "DirectArguments.h"
    48 #include "ECMAScriptSpecInternalFunctions.h"
    4948#include "Error.h"
    5049#include "ErrorConstructor.h"
     
    258257}
    259258
    260 
    261 static JSObject* getGetterById(ExecState* exec, JSObject* base, const Identifier& ident)
    262 {
    263     JSValue baseValue = JSValue(base);
    264     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
    265     baseValue.getPropertySlot(exec, ident, slot);
    266     return slot.getPureResult().toObject(exec);
    267 }
    268 
    269259void JSGlobalObject::init(VM& vm)
    270260{
     
    557547    JSFunction* privateFuncConcatSlowPath = JSFunction::createBuiltinFunction(vm, arrayPrototypeConcatSlowPathCodeGenerator(vm), this);
    558548
    559     JSObject* regExpProtoFlagsGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->flags);
    560     JSObject* regExpProtoGlobalGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->global);
    561     JSObject* regExpProtoIgnoreCaseGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->ignoreCase);
    562     JSObject* regExpProtoMultilineGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->multiline);
    563     JSObject* regExpProtoSourceGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->source);
    564     JSObject* regExpProtoStickyGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->sticky);
    565     JSObject* regExpProtoUnicodeGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->unicode);
    566    
    567549    GlobalPropertyInfo staticGlobals[] = {
    568550        GlobalPropertyInfo(vm.propertyNames->NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
     
    623605        GlobalPropertyInfo(vm.propertyNames->builtinNames().promiseResolveThenableJobPrivateName(), JSFunction::createBuiltinFunction(vm, promiseOperationsPromiseResolveThenableJobCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
    624606        GlobalPropertyInfo(vm.propertyNames->builtinNames().InspectorInstrumentationPrivateName(), InspectorInstrumentationObject::create(vm, this, InspectorInstrumentationObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum | DontDelete | ReadOnly),
     607        GlobalPropertyInfo(vm.propertyNames->builtinNames().advanceStringIndexUnicodePrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeAdvanceStringIndexUnicodeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
    625608        GlobalPropertyInfo(vm.propertyNames->MapPrivateName, mapConstructor, DontEnum | DontDelete | ReadOnly),
    626609        GlobalPropertyInfo(vm.propertyNames->builtinNames().generatorResumePrivateName(), JSFunction::createBuiltinFunction(vm, generatorPrototypeGeneratorResumeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
     
    632615#endif // ENABLE(INTL)
    633616
    634         GlobalPropertyInfo(vm.propertyNames->isConstructorPrivateName, JSFunction::create(vm, this, 1, String(), esSpecIsConstructor, NoIntrinsic), DontEnum | DontDelete | ReadOnly),
    635         GlobalPropertyInfo(vm.propertyNames->isRegExpPrivateName, JSFunction::create(vm, this, 1, String(), esSpecIsRegExp, NoIntrinsic), DontEnum | DontDelete | ReadOnly),
    636         GlobalPropertyInfo(vm.propertyNames->builtinNames().speciesConstructorPrivateName(), JSFunction::createBuiltinFunction(vm, globalObjectSpeciesConstructorCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
    637 
    638         GlobalPropertyInfo(vm.propertyNames->regExpProtoFlagsGetterPrivateName, regExpProtoFlagsGetterObject, DontEnum | DontDelete | ReadOnly),
    639         GlobalPropertyInfo(vm.propertyNames->regExpProtoGlobalGetterPrivateName, regExpProtoGlobalGetterObject, DontEnum | DontDelete | ReadOnly),
    640         GlobalPropertyInfo(vm.propertyNames->regExpProtoIgnoreCaseGetterPrivateName, regExpProtoIgnoreCaseGetterObject, DontEnum | DontDelete | ReadOnly),
    641         GlobalPropertyInfo(vm.propertyNames->regExpProtoMultilineGetterPrivateName, regExpProtoMultilineGetterObject, DontEnum | DontDelete | ReadOnly),
    642         GlobalPropertyInfo(vm.propertyNames->regExpProtoSourceGetterPrivateName, regExpProtoSourceGetterObject, DontEnum | DontDelete | ReadOnly),
    643         GlobalPropertyInfo(vm.propertyNames->regExpProtoStickyGetterPrivateName, regExpProtoStickyGetterObject, DontEnum | DontDelete | ReadOnly),
    644         GlobalPropertyInfo(vm.propertyNames->regExpProtoUnicodeGetterPrivateName, regExpProtoUnicodeGetterObject, DontEnum | DontDelete | ReadOnly),
    645 
    646         // RegExp.prototype helpers.
    647617        GlobalPropertyInfo(vm.propertyNames->regExpCreatePrivateName, JSFunction::create(vm, this, 2, String(), esSpecRegExpCreate, NoIntrinsic), DontEnum | DontDelete | ReadOnly),
    648         GlobalPropertyInfo(vm.propertyNames->builtinNames().hasObservableSideEffectsForRegExpSplitPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeHasObservableSideEffectsForRegExpSplitCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
    649         GlobalPropertyInfo(vm.propertyNames->builtinNames().advanceStringIndexPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeAdvanceStringIndexCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
    650         GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpExecPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeRegExpExecCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
    651         GlobalPropertyInfo(vm.propertyNames->regExpSplitFastPrivateName, JSFunction::create(vm, this, 2, String(), regExpProtoFuncSplitFast), DontEnum | DontDelete | ReadOnly),
    652 
    653         // String.prototype helpers.
    654         GlobalPropertyInfo(vm.propertyNames->stringIncludesInternalPrivateName, JSFunction::create(vm, this, 1, String(), builtinStringIncludesInternal), DontEnum | DontDelete | ReadOnly),
    655         GlobalPropertyInfo(vm.propertyNames->stringSplitFastPrivateName, JSFunction::create(vm, this, 2, String(), stringProtoFuncSplitFast), DontEnum | DontDelete | ReadOnly),
    656         GlobalPropertyInfo(vm.propertyNames->stringSubstrInternalPrivateName, JSFunction::create(vm, this, 2, String(), builtinStringSubstrInternal), DontEnum | DontDelete | ReadOnly),
    657618    };
    658619    addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
  • trunk/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp

    r199393 r199400  
    11/*
    2  * Copyright (C) 2009, 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    115115{
    116116    ASSERT(value);
     117    ASSERT(value.isGetterSetter() == !!(attributes & Accessor));
    117118
    118119    m_attributes = attributes;
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.h

    r199393 r199400  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007-2008, 2012, 2016 Apple Inc. All Rights Reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2012, 2016 Apple Inc. All Rights Reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    9494    }
    9595
    96     static unsigned advanceStringUnicode(String, unsigned length, unsigned currentIndex);
    97 
    9896protected:
    9997    JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
     
    107105    JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    108106    JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
     107    unsigned advanceStringUnicode(String, unsigned, unsigned);
    109108
    110109private:
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp

    r199393 r199400  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007-2008, 2016 Apple Inc. All Rights Reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2016 Apple Inc. All Rights Reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    4040#include "RegExpConstructor.h"
    4141#include "RegExpMatchesArray.h"
    42 #include "StringObject.h"
    4342#include "StringRecursionChecker.h"
    4443
     
    8382    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->matchSymbol, regExpPrototypeMatchCodeGenerator, DontEnum);
    8483    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->searchSymbol, regExpProtoFuncSearch, DontEnum, 1);
    85     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->splitSymbol, regExpPrototypeSplitCodeGenerator, DontEnum);
    8684
    8785    JSFunction* execFunction = JSFunction::create(vm, globalObject, 1, vm.propertyNames->exec.string(), regExpProtoFuncExec, RegExpExecIntrinsic);
     
    118116    JSValue thisValue = exec->thisValue();
    119117    if (!thisValue.inherits(RegExpObject::info()))
    120         return throwVMTypeError(exec, "Builtin RegExp exec can only be called on a RegExp object");
     118        return throwVMTypeError(exec);
    121119    JSString* string = exec->argument(0).toStringOrNull(exec);
    122120    if (!string)
     
    437435}
    438436
    439 static inline unsigned advanceStringIndex(String str, unsigned strSize, unsigned index, bool isUnicode)
    440 {
    441     if (!isUnicode)
    442         return ++index;
    443     return RegExpObject::advanceStringUnicode(str, strSize, index);
    444 }
    445 
    446 // ES 21.2.5.11 RegExp.prototype[@@split](string, limit)
    447 EncodedJSValue JSC_HOST_CALL regExpProtoFuncSplitFast(ExecState* exec)
    448 {
    449     VM& vm = exec->vm();
    450 
    451     // 1. [handled by JS builtin] Let rx be the this value.
    452     // 2. [handled by JS builtin] If Type(rx) is not Object, throw a TypeError exception.
    453     JSValue thisValue = exec->thisValue();
    454     RegExp* regexp = asRegExpObject(thisValue)->regExp();
    455 
    456     // 3. [handled by JS builtin] Let S be ? ToString(string).
    457     String input = exec->argument(0).toString(exec)->value(exec);
    458     if (vm.exception())
    459         return JSValue::encode(jsUndefined());
    460     ASSERT(!input.isNull());
    461 
    462     // 4. [handled by JS builtin] Let C be ? SpeciesConstructor(rx, %RegExp%).
    463     // 5. [handled by JS builtin] Let flags be ? ToString(? Get(rx, "flags")).
    464     // 6. [handled by JS builtin] If flags contains "u", let unicodeMatching be true.
    465     // 7. [handled by JS builtin] Else, let unicodeMatching be false.
    466     // 8. [handled by JS builtin] If flags contains "y", let newFlags be flags.
    467     // 9. [handled by JS builtin] Else, let newFlags be the string that is the concatenation of flags and "y".
    468     // 10. [handled by JS builtin] Let splitter be ? Construct(C, « rx, newFlags »).
    469 
    470     // 11. Let A be ArrayCreate(0).
    471     // 12. Let lengthA be 0.
    472     JSArray* result = constructEmptyArray(exec, 0);
    473     unsigned resultLength = 0;
    474 
    475     // 13. If limit is undefined, let lim be 2^32-1; else let lim be ? ToUint32(limit).
    476     JSValue limitValue = exec->argument(1);
    477     unsigned limit = limitValue.isUndefined() ? 0xFFFFFFFFu : limitValue.toUInt32(exec);
    478 
    479     // 14. Let size be the number of elements in S.
    480     unsigned inputSize = input.length();
    481 
    482     // 15. Let p = 0.
    483     unsigned position = 0;
    484 
    485     // 16. If lim == 0, return A.
    486     if (!limit)
    487         return JSValue::encode(result);
    488 
    489     // 17. If size == 0, then
    490     if (input.isEmpty()) {
    491         // a. Let z be ? RegExpExec(splitter, S).
    492         // b. If z is not null, return A.
    493         // c. Perform ! CreateDataProperty(A, "0", S).
    494         // d. Return A.
    495         if (!regexp->match(vm, input, 0))
    496             result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input));
    497         return JSValue::encode(result);
    498     }
    499 
    500     // 18. Let q = p.
    501     unsigned matchPosition = position;
    502     // 19. Repeat, while q < size
    503     bool regExpIsSticky = regexp->sticky();
    504     bool regExpIsUnicode = regexp->unicode();
    505     while (matchPosition < inputSize) {
    506         Vector<int, 32> ovector;
    507 
    508         // a. Perform ? Set(splitter, "lastIndex", q, true).
    509         // b. Let z be ? RegExpExec(splitter, S).
    510         int mpos = regexp->match(vm, input, matchPosition, ovector);
    511 
    512         // c. If z is null, let q be AdvanceStringIndex(S, q, unicodeMatching).
    513         if (mpos < 0) {
    514             if (!regExpIsSticky)
    515                 break;
    516             matchPosition = advanceStringIndex(input, inputSize, matchPosition, regExpIsUnicode);
    517             continue;
    518         }
    519         if (static_cast<unsigned>(mpos) >= inputSize) {
    520             // The spec redoes the RegExpExec starting at the next character of the input.
    521             // But in our case, mpos < 0 means that the native regexp already searched all permutations
    522             // and know that we won't be able to find a match for the separator even if we redo the
    523             // RegExpExec starting at the next character of the input. So, just bail.
    524             break;
    525         }
    526 
    527         // d. Else, z is not null
    528         //    i. Let e be ? ToLength(? Get(splitter, "lastIndex")).
    529         //   ii. Let e be min(e, size).
    530         matchPosition = mpos;
    531         unsigned matchEnd = ovector[1];
    532 
    533         //  iii. If e = p, let q be AdvanceStringIndex(S, q, unicodeMatching).
    534         if (matchEnd == position) {
    535             matchPosition = advanceStringIndex(input, inputSize, matchPosition, regExpIsUnicode);
    536             continue;
    537         }
    538         // if matchEnd == 0 then position should also be zero and thus matchEnd should equal position.
    539         ASSERT(matchEnd);
    540 
    541         //   iv. Else e != p,
    542         {
    543             unsigned numberOfCaptures = regexp->numSubpatterns();
    544             unsigned newResultLength = resultLength + numberOfCaptures + 1;
    545             if (newResultLength < numberOfCaptures || newResultLength >= MAX_STORAGE_VECTOR_INDEX) {
    546                 // Let's consider what's best for users here. We're about to increase the length of
    547                 // the split array beyond the maximum length that we can support efficiently. This
    548                 // will cause us to use a HashMap for the new entries after this point. That's going
    549                 // to result in a very long running time of this function and very large memory
    550                 // usage. In my experiments, JSC will sit spinning for minutes after getting here and
    551                 // it was using >4GB of memory and eventually grew to 8GB. It kept running without
    552                 // finishing until I killed it. That's probably not what the user wanted. The user,
    553                 // or the program that the user is running, probably made a mistake by calling this
    554                 // method in such a way that it resulted in such an obnoxious array. Therefore, to
    555                 // protect ourselves, we bail at this point.
    556                 throwOutOfMemoryError(exec);
    557                 return JSValue::encode(jsUndefined());
    558             }
    559 
    560             // 1. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through q (exclusive).
    561             // 2. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
    562             result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position));
    563 
    564             // 3. Let lengthA be lengthA + 1.
    565             // 4. If lengthA = lim, return A.
    566             if (++resultLength == limit)
    567                 return JSValue::encode(result);
    568 
    569             // 5. Let p be e.
    570             position = matchEnd;
    571 
    572             // 6. Let numberOfCaptures be ? ToLength(? Get(z, "length")).
    573             // 7. Let numberOfCaptures be max(numberOfCaptures-1, 0).
    574             // 8. Let i be 1.
    575             // 9. Repeat, while i <= numberOfCaptures,
    576             for (unsigned i = 1; i <= numberOfCaptures; ++i) {
    577                 // a. Let nextCapture be ? Get(z, ! ToString(i)).
    578                 // b. Perform ! CreateDataProperty(A, ! ToString(lengthA), nextCapture).
    579                 int sub = ovector[i * 2];
    580                 result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, thisValue, input, sub, ovector[i * 2 + 1] - sub));
    581 
    582                 // c. Let i be i + 1.
    583                 // d. Let lengthA be lengthA + 1.
    584                 // e. If lengthA = lim, return A.
    585                 if (++resultLength == limit)
    586                     return JSValue::encode(result);
    587             }
    588 
    589             // 10. Let q be p.
    590             matchPosition = position;
    591         }
    592     }
    593 
    594     // 20. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through size (exclusive).
    595     // 21. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
    596     result->putDirectIndex(exec, resultLength++, jsSubstring(exec, thisValue, input, position, inputSize - position));
    597 
    598     // 22. Return A.
    599     return JSValue::encode(result);
    600 }
    601 
    602437} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h

    r199393 r199400  
    5959};
    6060
    61 EncodedJSValue JSC_HOST_CALL regExpProtoFuncSplitFast(ExecState*);
    62 
    6361} // namespace JSC
    6462
  • trunk/Source/JavaScriptCore/runtime/StringObject.h

    r199393 r199400  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2007-2008, 2016 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    8282JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue);
    8383
    84 // Helper for producing a JSString for 'string', where 'string' was been produced by
    85 // calling ToString on 'originalValue'. In cases where 'originalValue' already was a
    86 // string primitive we can just use this, otherwise we need to allocate a new JSString.
    87 static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue, const String& string)
    88 {
    89     if (originalValue.isString()) {
    90         ASSERT(asString(originalValue)->value(exec) == string);
    91         return asString(originalValue);
    92     }
    93     return jsString(exec, string);
    94 }
    95 
    96 // Helper that tries to use the JSString substring sharing mechanism if 'originalValue' is a JSString.
    97 static inline JSString* jsSubstring(ExecState* exec, JSValue originalValue, const String& string, unsigned offset, unsigned length)
    98 {
    99     if (originalValue.isString()) {
    100         ASSERT(asString(originalValue)->value(exec) == string);
    101         return jsSubstring(exec, asString(originalValue), offset, length);
    102     }
    103     return jsSubstring(exec, string, offset, length);
    104 }
    105 
    106 
    10784} // namespace JSC
    10885
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r199393 r199400  
    11/*
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2004-2008, 2013, 2016 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013, 2016 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2009 Torch Mobile, Inc.
    55 *  Copyright (C) 2015 Jordan Harband (ljharb@gmail.com)
     
    7171EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*);
    7272EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*);
     73EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*);
    7374EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState*);
    7475EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState*);
     
    113114    repeat    JSBuiltin    DontEnum|Function 1
    114115    search    JSBuiltin    DontEnum|Function 1
    115     split     JSBuiltin    DontEnum|Function 1
    116116@end
    117117*/
     
    140140    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("replace", stringProtoFuncReplace, DontEnum, 2, StringPrototypeReplaceIntrinsic);
    141141    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("slice", stringProtoFuncSlice, DontEnum, 2);
     142    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("split", stringProtoFuncSplit, DontEnum, 2);
    142143    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("substr", stringProtoFuncSubstr, DontEnum, 2);
    143144    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("substring", stringProtoFuncSubstring, DontEnum, 2);
     
    195196// ------------------------------ Functions --------------------------
    196197
     198// Helper for producing a JSString for 'string', where 'string' was been produced by
     199// calling ToString on 'originalValue'. In cases where 'originalValue' already was a
     200// string primitive we can just use this, otherwise we need to allocate a new JSString.
     201static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue, const String& string)
     202{
     203    if (originalValue.isString()) {
     204        ASSERT(asString(originalValue)->value(exec) == string);
     205        return asString(originalValue);
     206    }
     207    return jsString(exec, string);
     208}
     209
     210// Helper that tries to use the JSString substring sharing mechanism if 'originalValue' is a JSString.
     211static inline JSString* jsSubstring(ExecState* exec, JSValue originalValue, const String& string, unsigned offset, unsigned length)
     212{
     213    if (originalValue.isString()) {
     214        ASSERT(asString(originalValue)->value(exec) == string);
     215        return jsSubstring(exec, asString(originalValue), offset, length);
     216    }
     217    return jsSubstring(exec, string, offset, length);
     218}
     219
    197220static NEVER_INLINE String substituteBackreferencesSlow(StringView replacement, StringView source, const int* ovector, RegExp* reg, size_t i)
    198221{
     
    11591182}
    11601183
    1161 // ES 21.1.3.17 String.prototype.split(separator, limit)
    1162 EncodedJSValue JSC_HOST_CALL stringProtoFuncSplitFast(ExecState* exec)
    1163 {
    1164     JSValue thisValue = exec->thisValue();
    1165     ASSERT(checkObjectCoercible(thisValue));
    1166 
    1167     // 3. Let S be the result of calling ToString, giving it the this value as its argument.
    1168     // 7. Let s be the number of characters in S.
     1184// ES 5.1 - 15.5.4.14 String.prototype.split (separator, limit)
     1185EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
     1186{
     1187    // 1. Call CheckObjectCoercible passing the this value as its argument.
     1188    JSValue thisValue = exec->thisValue();
     1189    if (!checkObjectCoercible(thisValue))
     1190        return throwVMTypeError(exec);
     1191
     1192    // 2. Let S be the result of calling ToString, giving it the this value as its argument.
     1193    // 6. Let s be the number of characters in S.
    11691194    String input = thisValue.toString(exec)->value(exec);
    11701195    if (exec->hadException())
     
    11721197    ASSERT(!input.isNull());
    11731198
    1174     // 4. Let A be a new array created as if by the expression new Array()
     1199    // 3. Let A be a new array created as if by the expression new Array()
    11751200    //    where Array is the standard built-in constructor with that name.
    11761201    JSArray* result = constructEmptyArray(exec, 0);
    11771202
    1178     // 5. Let lengthA be 0.
     1203    // 4. Let lengthA be 0.
    11791204    unsigned resultLength = 0;
    11801205
    1181     // 6. If limit is undefined, let lim = 2^32-1; else let lim = ToUint32(limit).
    1182     JSValue limitValue = exec->uncheckedArgument(1);
     1206    // 5. If limit is undefined, let lim = 2^32-1; else let lim = ToUint32(limit).
     1207    JSValue limitValue = exec->argument(1);
    11831208    unsigned limit = limitValue.isUndefined() ? 0xFFFFFFFFu : limitValue.toUInt32(exec);
    11841209
    1185     // 8. Let p = 0.
     1210    // 7. Let p = 0.
    11861211    size_t position = 0;
    11871212
    1188     // 9. If separator is a RegExp object (its [[Class]] is "RegExp"), let R = separator;
     1213    // 8. If separator is a RegExp object (its [[Class]] is "RegExp"), let R = separator;
    11891214    //    otherwise let R = ToString(separator).
    1190     JSValue separatorValue = exec->uncheckedArgument(0);
    1191     { // FIXME: Keeping this indentation here to minimize the diff. Will unindent and remove this later.
     1215    JSValue separatorValue = exec->argument(0);
     1216    if (separatorValue.inherits(RegExpObject::info())) {
     1217        VM* vm = &exec->vm();
     1218        RegExp* reg = asRegExpObject(separatorValue)->regExp();
     1219
     1220        // 9. If lim == 0, return A.
     1221        if (!limit)
     1222            return JSValue::encode(result);
     1223
     1224        // 10. If separator is undefined, then
     1225        if (separatorValue.isUndefined()) {
     1226            // a. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
     1227            //    Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
     1228            result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input));
     1229            // b. Return A.
     1230            return JSValue::encode(result);
     1231        }
     1232
     1233        // 11. If s == 0, then
     1234        if (input.isEmpty()) {
     1235            // a. Call SplitMatch(S, 0, R) and let z be its MatchResult result.
     1236            // b. If z is not failure, return A.
     1237            // c. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
     1238            //    Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
     1239            // d. Return A.
     1240            if (!reg->match(*vm, input, 0))
     1241                result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input));
     1242            return JSValue::encode(result);
     1243        }
     1244
     1245        // 12. Let q = p.
     1246        size_t matchPosition = 0;
     1247        // 13. Repeat, while q != s
     1248        while (matchPosition < input.length()) {
     1249            // a. Call SplitMatch(S, q, R) and let z be its MatchResult result.
     1250            Vector<int, 32> ovector;
     1251            int mpos = reg->match(*vm, input, matchPosition, ovector);
     1252
     1253            // b. If z is a failure then we can break because there are no matches
     1254            if (mpos < 0)
     1255                break;
     1256            matchPosition = mpos;
     1257
     1258            // if the match is the empty match at the end, break.
     1259            if (matchPosition >= input.length())
     1260                break;
     1261
     1262            // c. Else, z is not failure
     1263            // i. z must be a State. Let e be z's endIndex and let cap be z's captures array.
     1264            size_t matchEnd = ovector[1];
     1265
     1266            // ii. If e == p, then let q = q + 1.
     1267            if (matchEnd == position) {
     1268                ++matchPosition;
     1269                continue;
     1270            }
     1271            // iii. if matchEnd == 0 then position should also be zero and thus matchEnd should equal position.
     1272            ASSERT(matchEnd);
     1273
     1274            // iii. Else, e != p
     1275
     1276            // 1. Let T be a String value equal to the substring of S consisting of the characters at positions p (inclusive)
     1277            //    through q (exclusive).
     1278            // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA),
     1279            //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
     1280            result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position));
     1281
     1282            // 3. Increment lengthA by 1.
     1283            // 4. If lengthA == lim, return A.
     1284            ++resultLength;
     1285            if (resultLength == limit)
     1286                return JSValue::encode(result);
     1287            if (resultLength >= MAX_STORAGE_VECTOR_INDEX) {
     1288                // Let's consider what's best for users here. We're about to increase the length of
     1289                // the split array beyond the maximum length that we can support efficiently. This
     1290                // will cause us to use a HashMap for the new entries after this point. That's going
     1291                // to result in a very long running time of this function and very large memory
     1292                // usage. In my experiments, JSC will sit spinning for minutes after getting here and
     1293                // it was using >4GB of memory and eventually grew to 8GB. It kept running without
     1294                // finishing until I killed it. That's probably not what the user wanted. The user,
     1295                // or the program that the user is running, probably made a mistake by calling this
     1296                // method in such a way that it resulted in such an obnoxious array. Therefore, to
     1297                // protect ourselves, we bail at this point.
     1298                throwOutOfMemoryError(exec);
     1299                return JSValue::encode(jsUndefined());
     1300            }
     1301
     1302            // 5. Let p = e.
     1303            // 8. Let q = p.
     1304            position = matchEnd;
     1305            matchPosition = matchEnd;
     1306
     1307            // 6. Let i = 0.
     1308            // 7. Repeat, while i is not equal to the number of elements in cap.
     1309            //  a Let i = i + 1.
     1310            for (unsigned i = 1; i <= reg->numSubpatterns(); ++i) {
     1311                // b Call the [[DefineOwnProperty]] internal method of A with arguments
     1312                //   ToString(lengthA), Property Descriptor {[[Value]]: cap[i], [[Writable]]:
     1313                //   true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
     1314                int sub = ovector[i * 2];
     1315                result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, thisValue, input, sub, ovector[i * 2 + 1] - sub));
     1316                // c Increment lengthA by 1.
     1317                // d If lengthA == lim, return A.
     1318                if (++resultLength == limit)
     1319                    return JSValue::encode(result);
     1320            }
     1321        }
     1322    } else {
    11921323        String separator = separatorValue.toString(exec)->value(exec);
    11931324        if (exec->hadException())
    11941325            return JSValue::encode(jsUndefined());
    11951326
    1196         // 10. If lim == 0, return A.
     1327        // 9. If lim == 0, return A.
    11971328        if (!limit)
    11981329            return JSValue::encode(result);
    11991330
    1200         // 11. If separator is undefined, then
     1331        // 10. If separator is undefined, then
     1332        JSValue separatorValue = exec->argument(0);
    12011333        if (separatorValue.isUndefined()) {
    12021334            // a.  Call the [[DefineOwnProperty]] internal method of A with arguments "0",
     1335            //     Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    12031336            result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input));
    12041337            // b.  Return A.
     
    12061339        }
    12071340
    1208         // 12. If s == 0, then
     1341        // 11. If s == 0, then
    12091342        if (input.isEmpty()) {
    1210             // a. Let z be SplitMatch(S, 0, R) where S is input, R is separator.
    1211             // b. If z is not false, return A.
    1212             // c. Call CreateDataProperty(A, "0", S).
     1343            // a. Call SplitMatch(S, 0, R) and let z be its MatchResult result.
     1344            // b. If z is not failure, return A.
     1345            // c. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
     1346            //    Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    12131347            // d. Return A.
    12141348            if (!separator.isEmpty())
     
    12531387            }
    12541388        } else {
    1255             // 13. Let q = p.
     1389            // 12. Let q = p.
    12561390            size_t matchPosition;
    1257             // 14. Repeat, while q != s
    1258             //   a. let e be SplitMatch(S, q, R).
    1259             //   b. If e is failure, then let q = q+1.
    1260             //   c. Else, e is an integer index <= s.
     1391            // 13. Repeat, while q != s
     1392            //   a. Call SplitMatch(S, q, R) and let z be its MatchResult result.
     1393            //   b. If z is failure, then let q = q+1.
     1394            //   c. Else, z is not failure
    12611395            while ((matchPosition = stringImpl->find(separatorImpl, position)) != notFound) {
    12621396                // 1. Let T be a String value equal to the substring of S consisting of the characters at positions p (inclusive)
    12631397                //    through q (exclusive).
    1264                 // 2. Call CreateDataProperty(A, ToString(lengthA), T).
     1398                // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA),
     1399                //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    12651400                result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position));
    12661401                // 3. Increment lengthA by 1.
     
    12701405
    12711406                // 5. Let p = e.
    1272                 // 6. Let q = p.
     1407                // 8. Let q = p.
    12731408                position = matchPosition + separator.length();
    12741409            }
    12751410        }
    1276     } // FIXME: Keeping this indentation here to minimize the diff. Will unindent and remove this later.
    1277 
    1278     // 15. Let T be a String value equal to the substring of S consisting of the characters at positions p (inclusive)
     1411    }
     1412
     1413    // 14. Let T be a String value equal to the substring of S consisting of the characters at positions p (inclusive)
    12791414    //     through s (exclusive).
    1280     // 16. Call CreateDataProperty(A, ToString(lengthA), T).
     1415    // 15. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), Property Descriptor
     1416    //     {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    12811417    result->putDirectIndex(exec, resultLength++, jsSubstring(exec, thisValue, input, position, input.length() - position));
    12821418
    1283     // 17. Return A.
     1419    // 16. Return A.
    12841420    return JSValue::encode(result);
    12851421}
     
    13221458        return JSValue::encode(jsSubstring(exec, jsString, substringStart, substringLength));
    13231459    return JSValue::encode(jsSubstring(exec, uString, substringStart, substringLength));
    1324 }
    1325 
    1326 EncodedJSValue JSC_HOST_CALL builtinStringSubstrInternal(ExecState* exec)
    1327 {
    1328     // @substrInternal should not have any observable side effects (e.g. it should not call
    1329     // GetMethod(..., @@toPrimitive) on the thisValue).
    1330 
    1331     // It is ok to use the default stringProtoFuncSubstr as the implementation of
    1332     // @substrInternal because @substrInternal will only be called by builtins, which will
    1333     // guarantee that we only pass it a string thisValue. As a result, stringProtoFuncSubstr
    1334     // will not need to call toString() on the thisValue, and there will be no observable
    1335     // side-effects.
    1336 #if !ASSERT_DISABLED
    1337     JSValue thisValue = exec->thisValue();
    1338     ASSERT(thisValue.isString());
    1339 #endif
    1340     return stringProtoFuncSubstr(exec);
    13411460}
    13421461
     
    18771996}
    18781997
    1879 static EncodedJSValue JSC_HOST_CALL stringIncludesImpl(VM& vm, ExecState* exec, String stringToSearchIn, String searchString, JSValue positionArg)
    1880 {
    1881     unsigned start = 0;
    1882     if (positionArg.isInt32())
    1883         start = std::max(0, positionArg.asInt32());
    1884     else {
    1885         unsigned length = stringToSearchIn.length();
    1886         start = clampAndTruncateToUnsigned(positionArg.toInteger(exec), 0, length);
    1887         if (vm.exception())
    1888             return JSValue::encode(jsUndefined());
    1889     }
    1890 
    1891     return JSValue::encode(jsBoolean(stringToSearchIn.contains(searchString, true, start)));
    1892 }
    1893 
    18941998EncodedJSValue JSC_HOST_CALL stringProtoFuncIncludes(ExecState* exec)
    18951999{
     
    19152019
    19162020    JSValue positionArg = exec->argument(1);
    1917 
    1918     return stringIncludesImpl(vm, exec, stringToSearchIn, searchString, positionArg);
    1919 }
    1920 
    1921 EncodedJSValue JSC_HOST_CALL builtinStringIncludesInternal(ExecState* exec)
    1922 {
    1923     JSValue thisValue = exec->thisValue();
    1924     ASSERT(checkObjectCoercible(thisValue));
    1925 
    1926     String stringToSearchIn = thisValue.toString(exec)->value(exec);
    1927     if (exec->hadException())
    1928         return JSValue::encode(jsUndefined());
    1929 
    1930     JSValue a0 = exec->uncheckedArgument(0);
    1931     VM& vm = exec->vm();
    1932     String searchString = a0.toString(exec)->value(exec);
    1933     if (exec->hadException())
    1934         return JSValue::encode(jsUndefined());
    1935 
    1936     JSValue positionArg = exec->argument(1);
    1937 
    1938     return stringIncludesImpl(vm, exec, stringToSearchIn, searchString, positionArg);
     2021    unsigned start = 0;
     2022    if (positionArg.isInt32())
     2023        start = std::max(0, positionArg.asInt32());
     2024    else {
     2025        unsigned length = stringToSearchIn.length();
     2026        start = clampAndTruncateToUnsigned(positionArg.toInteger(exec), 0, length);
     2027        if (exec->hadException())
     2028            return JSValue::encode(jsUndefined());
     2029    }
     2030
     2031    return JSValue::encode(jsBoolean(stringToSearchIn.contains(searchString, true, start)));
    19392032}
    19402033
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.h

    r199393 r199400  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2007-2008, 2013, 2016 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2007, 2008, 2013, 2016 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    6767
    6868EncodedJSValue JSC_HOST_CALL stringProtoFuncRepeatCharacter(ExecState*);
    69 EncodedJSValue JSC_HOST_CALL stringProtoFuncSplitFast(ExecState*);
    70 
    71 EncodedJSValue JSC_HOST_CALL builtinStringSubstrInternal(ExecState*);
    72 EncodedJSValue JSC_HOST_CALL builtinStringIncludesInternal(ExecState*);
    7369
    7470} // namespace JSC
  • trunk/Source/JavaScriptCore/tests/es6.yaml

    r199397 r199400  
    10081008  cmd: runES6 :fail
    10091009- path: es6/Proxy_internal_get_calls_RegExp.prototype[Symbol.split].js
    1010   cmd: runES6 :normal
     1010  cmd: runES6 :fail
    10111011- path: es6/Proxy_internal_get_calls_RegExp_constructor.js
    10121012  cmd: runES6 :normal
     
    10181018  cmd: runES6 :normal
    10191019- path: es6/Proxy_internal_get_calls_String.prototype.split.js
    1020   cmd: runES6 :normal
     1020  cmd: runES6 :fail
    10211021- path: es6/Proxy_internal_get_calls_String.raw.js
    10221022  cmd: runES6 :normal
     
    10941094  cmd: runES6 :normal
    10951095- path: es6/RegExp.prototype_properties_RegExp.prototype[Symbol.split].js
    1096   cmd: runES6 :normal
     1096  cmd: runES6 :fail
    10971097- path: es6/RegExp.prototype_properties_RegExp[Symbol.species].js
    10981098  cmd: runES6 :normal
     
    12161216  cmd: runES6 :normal
    12171217- path: es6/well-known_symbols_Symbol.species_RegExp.prototype[Symbol.split].js
    1218   cmd: runES6 :normal
     1218  cmd: runES6 :fail
    12191219- path: es6/well-known_symbols_Symbol.split.js
    1220   cmd: runES6 :normal
     1220  cmd: runES6 :fail
    12211221- path: es6/well-known_symbols_Symbol.toPrimitive.js
    12221222  cmd: runES6 :normal
Note: See TracChangeset for help on using the changeset viewer.