Changeset 200272 in webkit
- Timestamp:
- Apr 29, 2016 5:34:01 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r200269 r200272 1 2016-04-29 Mark Lam <mark.lam@apple.com> 2 3 Make RegExp.prototype.test spec compliant. 4 https://bugs.webkit.org/show_bug.cgi?id=155862 5 6 Reviewed by Saam Barati. 7 8 * js/regress/regexp-prototype-test-observable-side-effects-expected.txt: Added. 9 * js/regress/regexp-prototype-test-observable-side-effects.html: Added. 10 * js/regress/regexp-prototype-test-observable-side-effects2-expected.txt: Added. 11 * js/regress/regexp-prototype-test-observable-side-effects2.html: Added. 12 * js/regress/script-tests/regexp-prototype-test-observable-side-effects.js: Added. 13 * js/regress/script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js: Added. 14 * js/regress/script-tests/simple-regexp-test-folding-with-hoisted-regexp.js: Added. 15 * js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp-expected.txt: Added. 16 * js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp.html: Added. 17 * js/regress/simple-regexp-test-folding-with-hoisted-regexp-expected.txt: Added. 18 * js/regress/simple-regexp-test-folding-with-hoisted-regexp.html: Added. 19 1 20 2016-04-29 Commit Queue <commit-queue@webkit.org> 2 21 -
trunk/Source/JavaScriptCore/ChangeLog
r200263 r200272 1 2016-04-29 Mark Lam <mark.lam@apple.com> 2 3 Make RegExp.prototype.test spec compliant. 4 https://bugs.webkit.org/show_bug.cgi?id=155862 5 6 Reviewed by Saam Barati. 7 8 * builtins/RegExpPrototype.js: 9 (intrinsic.RegExpTestIntrinsic.test): 10 11 * create_hash_table: 12 - Delete obsoleted code. 13 14 * dfg/DFGByteCodeParser.cpp: 15 (JSC::DFG::ByteCodeParser::addToGraph): 16 (JSC::DFG::ByteCodeParser::handleIntrinsicCall): 17 - We now have 2 intrinsics for RegExp.prototype.test: 18 RegExpTestIntrinsic and RegExpTestFastIntrinsic. 19 20 RegExpTestIntrinsic maps to the entry at the top of the builtin ES6 21 RegExp.prototype.test. 22 RegExpTestFastIntrinsic maps to the fast path in the builtin ES6 23 RegExp.prototype.test. 24 25 Both will end up using the RegExpTest DFG node to implement the fast path 26 of RegExp.prototype.test. RegExpTestIntrinsic will have some additional checks 27 before the RegExpTest node. Those checks are for speculating that it is ok for 28 us to take the fast path. 29 30 * runtime/CommonIdentifiers.h: 31 * runtime/Intrinsic.h: 32 33 * runtime/JSGlobalObject.cpp: 34 (JSC::JSGlobalObject::init): 35 - Added the regExpTestFast function. 36 - Also fixed the parameter length on 2 other functions that were erroneous. 37 38 * runtime/RegExpPrototype.cpp: 39 (JSC::RegExpPrototype::finishCreation): 40 (JSC::regExpProtoFuncTestFast): 41 (JSC::regExpProtoFuncTest): Deleted. 42 * runtime/RegExpPrototype.h: 43 * tests/es6.yaml: 44 1 45 2016-04-29 Benjamin Poulain <benjamin@webkit.org> 2 46 -
trunk/Source/JavaScriptCore/builtins/RegExpPrototype.js
r200239 r200272 488 488 return result; 489 489 } 490 491 // ES 21.2.5.13 RegExp.prototype.test(string) 492 [intrinsic=RegExpTestIntrinsic] function test(strArg) 493 { 494 "use strict"; 495 496 let regexp = this; 497 498 // Check for observable side effects and call the fast path if there aren't any. 499 if (@isRegExpObject(regexp) && @tryGetById(regexp, "exec") === @regExpBuiltinExec) 500 return @regExpTestFast.@call(regexp, strArg); 501 502 // 1. Let R be the this value. 503 // 2. If Type(R) is not Object, throw a TypeError exception. 504 if (!@isObject(regexp)) 505 throw new @TypeError("RegExp.prototype.test requires that |this| be an Object"); 506 507 // 3. Let string be ? ToString(S). 508 let str = @toString(strArg); 509 510 // 4. Let match be ? RegExpExec(R, string). 511 let match = @regExpExec(regexp, str); 512 513 // 5. If match is not null, return true; else return false. 514 if (match !== null) 515 return true; 516 return false; 517 } -
trunk/Source/JavaScriptCore/create_hash_table
r193900 r200272 307 307 $intrinsic = "ArrayPopIntrinsic" if ($key eq "pop"); 308 308 } 309 if ($name eq "regExpPrototypeTable") {310 $intrinsic = "RegExpExecIntrinsic" if ($key eq "exec");311 $intrinsic = "RegExpTestIntrinsic" if ($key eq "test");312 }313 309 314 310 if ($values[$i]{"type"} eq "Function" && $firstValue eq "JSBuiltin") { -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r200149 r200272 49 49 #include "PutByIdFlags.h" 50 50 #include "PutByIdStatus.h" 51 #include <RegExpPrototype.h>51 #include "RegExpPrototype.h" 52 52 #include "StackAlignment.h" 53 53 #include "StringConstructor.h" … … 722 722 return addToGraph(result); 723 723 } 724 Node* addToGraph(NodeType op, OpInfo info, Edge child1, Edge child2 = Edge(), Edge child3 = Edge()) 725 { 726 Node* result = m_graph.addNode(SpecNone, op, currentNodeOrigin(), info, child1, child2, child3); 727 return addToGraph(result); 728 } 724 729 Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0) 725 730 { … … 727 732 SpecNone, op, currentNodeOrigin(), info1, info2, 728 733 Edge(child1), Edge(child2), Edge(child3)); 734 return addToGraph(result); 735 } 736 Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Edge child1, Edge child2 = Edge(), Edge child3 = Edge()) 737 { 738 Node* result = m_graph.addNode( 739 SpecNone, op, currentNodeOrigin(), info1, info2, child1, child2, child3); 729 740 return addToGraph(result); 730 741 } … … 2206 2217 } 2207 2218 2208 case RegExpTestIntrinsic: { 2219 case RegExpTestIntrinsic: 2220 case RegExpTestFastIntrinsic: { 2209 2221 if (argumentCountIncludingThis != 2) 2210 2222 return false; 2211 2223 2224 if (intrinsic == RegExpTestIntrinsic) { 2225 // Don't inline intrinsic if we exited due to one of the primordial RegExp checks failing. 2226 if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) 2227 return false; 2228 2229 JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject(); 2230 Structure* regExpStructure = globalObject->regExpStructure(); 2231 m_graph.registerStructure(regExpStructure); 2232 ASSERT(regExpStructure->storedPrototype().isObject()); 2233 ASSERT(regExpStructure->storedPrototype().asCell()->classInfo() == RegExpPrototype::info()); 2234 2235 FrozenValue* regExpPrototypeObjectValue = m_graph.freeze(regExpStructure->storedPrototype()); 2236 Structure* regExpPrototypeStructure = regExpPrototypeObjectValue->structure(); 2237 2238 auto isRegExpPropertySame = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) { 2239 JSValue currentProperty; 2240 if (!m_graph.getRegExpPrototypeProperty(regExpStructure->storedPrototypeObject(), regExpPrototypeStructure, propertyUID, currentProperty)) 2241 return false; 2242 2243 return currentProperty == primordialProperty; 2244 }; 2245 2246 // Check that RegExp.exec is still the primordial RegExp.prototype.exec 2247 if (!isRegExpPropertySame(globalObject->regExpProtoExecFunction(), m_vm->propertyNames->exec.impl())) 2248 return false; 2249 2250 // Check that regExpObject is actually a RegExp object. 2251 Node* regExpObject = get(virtualRegisterForArgument(0, registerOffset)); 2252 addToGraph(Check, Edge(regExpObject, RegExpObjectUse)); 2253 2254 // Check that regExpObject's exec is actually the primodial RegExp.prototype.exec. 2255 UniquedStringImpl* execPropertyID = m_vm->propertyNames->exec.impl(); 2256 unsigned execIndex = m_graph.identifiers().ensure(execPropertyID); 2257 Node* actualProperty = addToGraph(TryGetById, OpInfo(execIndex), OpInfo(SpecFunction), Edge(regExpObject, CellUse)); 2258 FrozenValue* regExpPrototypeExec = m_graph.freeze(globalObject->regExpProtoExecFunction()); 2259 addToGraph(CheckCell, OpInfo(regExpPrototypeExec), Edge(actualProperty, CellUse)); 2260 } 2261 2212 2262 insertChecks(); 2213 Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset))); 2263 Node* regExpObject = get(virtualRegisterForArgument(0, registerOffset)); 2264 Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), regExpObject, get(virtualRegisterForArgument(1, registerOffset))); 2214 2265 set(VirtualRegister(resultOperand), regExpExec); 2215 2266 -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r200252 r200272 437 437 macro(regExpProtoStickyGetter) \ 438 438 macro(regExpProtoUnicodeGetter) \ 439 macro(regExpPrototypeSymbolReplace) \ 439 440 macro(regExpReplaceFast) \ 440 441 macro(regExpSearchFast) \ 441 442 macro(regExpSplitFast) \ 442 macro(regExp PrototypeSymbolReplace) \443 macro(regExpTestFast) \ 443 444 macro(stringIncludesInternal) \ 444 445 macro(stringSplitFast) \ -
trunk/Source/JavaScriptCore/runtime/Intrinsic.h
r200149 r200272 52 52 RegExpExecIntrinsic, 53 53 RegExpTestIntrinsic, 54 RegExpTestFastIntrinsic, 54 55 StringPrototypeValueOfIntrinsic, 55 56 StringPrototypeReplaceIntrinsic, -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r200218 r200272 653 653 GlobalPropertyInfo(vm.propertyNames->builtinNames().advanceStringIndexPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeAdvanceStringIndexCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly), 654 654 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpExecPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeRegExpExecCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly), 655 GlobalPropertyInfo(vm.propertyNames->regExpMatchFastPrivateName, JSFunction::create(vm, this, 2, String(), regExpProtoFuncMatchFast), DontEnum | DontDelete | ReadOnly),656 GlobalPropertyInfo(vm.propertyNames->regExpSearchFastPrivateName, JSFunction::create(vm, this, 2, String(), regExpProtoFuncSearchFast), DontEnum | DontDelete | ReadOnly),655 GlobalPropertyInfo(vm.propertyNames->regExpMatchFastPrivateName, JSFunction::create(vm, this, 1, String(), regExpProtoFuncMatchFast), DontEnum | DontDelete | ReadOnly), 656 GlobalPropertyInfo(vm.propertyNames->regExpSearchFastPrivateName, JSFunction::create(vm, this, 1, String(), regExpProtoFuncSearchFast), DontEnum | DontDelete | ReadOnly), 657 657 GlobalPropertyInfo(vm.propertyNames->regExpSplitFastPrivateName, JSFunction::create(vm, this, 2, String(), regExpProtoFuncSplitFast), DontEnum | DontDelete | ReadOnly), 658 658 GlobalPropertyInfo(vm.propertyNames->regExpPrototypeSymbolReplacePrivateName, m_regExpPrototype->getDirect(vm, vm.propertyNames->replaceSymbol), DontEnum | DontDelete | ReadOnly), 659 GlobalPropertyInfo(vm.propertyNames->regExpTestFastPrivateName, JSFunction::create(vm, this, 1, String(), regExpProtoFuncTestFast, RegExpTestFastIntrinsic), DontEnum | DontDelete | ReadOnly), 659 660 660 661 // String.prototype helpers. -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
r200117 r200272 45 45 namespace JSC { 46 46 47 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*);48 47 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*); 49 48 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*); … … 70 69 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->compile, regExpProtoFuncCompile, DontEnum, 2); 71 70 JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->exec, regExpProtoFuncExec, DontEnum, 1, RegExpExecIntrinsic); 72 JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->test, regExpProtoFuncTest, DontEnum, 1, RegExpTestIntrinsic);73 71 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, regExpProtoFuncToString, DontEnum, 0); 74 72 JSC_NATIVE_GETTER(vm.propertyNames->global, regExpProtoGetterGlobal, DontEnum | Accessor); … … 83 81 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->searchSymbol, regExpPrototypeSearchCodeGenerator, DontEnum); 84 82 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->splitSymbol, regExpPrototypeSplitCodeGenerator, DontEnum); 83 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->test, regExpPrototypeTestCodeGenerator, DontEnum); 85 84 86 85 m_emptyRegExp.set(vm, this, RegExp::create(vm, "", NoFlags)); … … 98 97 // ------------------------------ Functions --------------------------- 99 98 100 EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest (ExecState* exec)99 EncodedJSValue JSC_HOST_CALL regExpProtoFuncTestFast(ExecState* exec) 101 100 { 102 101 JSValue thisValue = exec->thisValue(); -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h
r199812 r200272 62 62 EncodedJSValue JSC_HOST_CALL regExpProtoFuncSearchFast(ExecState*); 63 63 EncodedJSValue JSC_HOST_CALL regExpProtoFuncSplitFast(ExecState*); 64 EncodedJSValue JSC_HOST_CALL regExpProtoFuncTestFast(ExecState*); 64 65 65 66 } // namespace JSC -
trunk/Source/JavaScriptCore/tests/es6.yaml
r200149 r200272 998 998 cmd: runES6 :normal 999 999 - path: es6/Proxy_internal_get_calls_RegExp.prototype.test.js 1000 cmd: runES6 : fail1000 cmd: runES6 :normal 1001 1001 - path: es6/Proxy_internal_get_calls_RegExp.prototype.toString.js 1002 1002 cmd: runES6 :normal
Note: See TracChangeset
for help on using the changeset viewer.