From: barraclough@apple.com Date: Fri, 23 Sep 2011 07:18:48 +0000 (+0000) Subject: Source/JavaScriptCore: GetScopedVar should have value profiling X-Git-Tag: 070512121124~23827 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a6805302093822f1227a89ef4d71114074585ef4;p=profile%2Fivi%2Fwebkit-efl.git Source/JavaScriptCore: GetScopedVar should have value profiling https://bugs.webkit.org/show_bug.cgi?id=68676 Patch by Filip Pizlo on 2011-09-22 Reviewed by Oliver Hunt. Added GetScopedVar value profiling and predictin propagation. Added GetScopeChain to CSE. * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGGraph.h: (JSC::DFG::Graph::predict): * dfg/DFGNode.h: (JSC::DFG::Node::hasPrediction): * dfg/DFGPropagator.cpp: (JSC::DFG::Propagator::propagateNodePredictions): (JSC::DFG::Propagator::getScopeChainLoadElimination): (JSC::DFG::Propagator::performNodeCSE): * jit/JITPropertyAccess.cpp: (JSC::JIT::emit_op_get_scoped_var): LayoutTests: [Qt] Unreviewed gardening, update expected file after r95745. Patch by Csaba Osztrogonác on 2011-09-22 * platform/qt/editing/deleting/merge-whitespace-pre-expected.png: * platform/qt/editing/deleting/merge-whitespace-pre-expected.txt: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95787 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index eb4e9ee..d39fd6c 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -93,6 +93,31 @@ 2011-09-22 Gavin Barraclough + Incorrect this value passed to callbacks. + https://bugs.webkit.org/show_bug.cgi?id=68668 + + Reviewed by Oliver Hunt. + + From Array/String prototype function. Should be undefined, but + global object is passed instead (this is visible for strict callbacks). + + * fast/js/array-prototype-properties-expected.txt: + * fast/js/script-tests/strict-callback-this.js: Added. + (strictThrowThisString): + (nonstrictThrowThisString): + (testArrayPrototypeSort): + (testArrayPrototypeFilter): + (testArrayPrototypeMap): + (testArrayPrototypeEvery): + (testArrayPrototypeForEach): + (testArrayPrototypeSome): + (testStringPrototypeReplace): + * fast/js/strict-callback-this-expected.txt: Added. + * fast/js/strict-callback-this.html: Added. + * ietestcenter/Javascript/15.3.4.5-0-2-expected.txt: + +2011-09-22 Gavin Barraclough + Function.prototype.bind.length shoudl be 1. Rubber stamped by Olier Hunt. diff --git a/LayoutTests/fast/js/array-prototype-properties-expected.txt b/LayoutTests/fast/js/array-prototype-properties-expected.txt index 60e1448..8cc2c35 100644 --- a/LayoutTests/fast/js/array-prototype-properties-expected.txt +++ b/LayoutTests/fast/js/array-prototype-properties-expected.txt @@ -23,7 +23,7 @@ PASS Array.prototype.indlastIndexOfexOf.call(undefined, 0) threw exception TypeE FAIL Array.prototype.filter.call(undefined, toString) should throw an exception. Was [object Object]. FAIL Array.prototype.reduce.call(undefined, toString) should throw an exception. Was [object Object]. FAIL Array.prototype.reduceRight.call(undefined, toString) should throw an exception. Was [object Object]. -FAIL Array.prototype.map.call(undefined, toString) should throw an exception. Was [object DOMWindow]. +FAIL Array.prototype.map.call(undefined, toString) should throw an exception. Was [object Undefined]. PASS successfullyParsed is true TEST COMPLETE diff --git a/LayoutTests/fast/js/script-tests/strict-callback-this.js b/LayoutTests/fast/js/script-tests/strict-callback-this.js new file mode 100644 index 0000000..7dbd1b0 --- /dev/null +++ b/LayoutTests/fast/js/script-tests/strict-callback-this.js @@ -0,0 +1,105 @@ +description( +"This tests that a call to array/string prototype methods pass the correct this value (undefined) to strict callees." +); + +var undefinedString = String(undefined); +var globalObjectString = String(this); + +function strictThrowThisString() +{ + "use strict"; + throw String(this); +} + +function nonstrictThrowThisString() +{ + throw String(this); +} + +function testArrayPrototypeSort(callback) +{ + try { + [1,2].sort(callback); + } catch (e) { + return e; + } + return "FAILED"; +} + +function testArrayPrototypeFilter(callback) +{ + try { + [1,2].filter(callback); + } catch (e) { + return e; + } + return "FAILED"; +} + +function testArrayPrototypeMap(callback) +{ + try { + [1,2].map(callback); + } catch (e) { + return e; + } + return "FAILED"; +} + +function testArrayPrototypeEvery(callback) +{ + try { + [1,2].every(callback); + } catch (e) { + return e; + } + return "FAILED"; +} + +function testArrayPrototypeForEach(callback) +{ + try { + [1,2].forEach(callback); + } catch (e) { + return e; + } + return "FAILED"; +} + +function testArrayPrototypeSome(callback) +{ + try { + [1,2].some(callback); + } catch (e) { + return e; + } + return "FAILED"; +} + +function testStringPrototypeReplace(callback) +{ + try { + "1,2".replace('1', callback); + } catch (e) { + return e; + } + return "FAILED"; +} + +shouldBe('testArrayPrototypeSort(strictThrowThisString)', 'undefinedString'); +shouldBe('testArrayPrototypeFilter(strictThrowThisString)', 'undefinedString'); +shouldBe('testArrayPrototypeMap(strictThrowThisString)', 'undefinedString'); +shouldBe('testArrayPrototypeEvery(strictThrowThisString)', 'undefinedString'); +shouldBe('testArrayPrototypeForEach(strictThrowThisString)', 'undefinedString'); +shouldBe('testArrayPrototypeSome(strictThrowThisString)', 'undefinedString'); +shouldBe('testStringPrototypeReplace(strictThrowThisString)', 'undefinedString'); + +shouldBe('testArrayPrototypeSort(nonstrictThrowThisString)', 'globalObjectString'); +shouldBe('testArrayPrototypeFilter(nonstrictThrowThisString)', 'globalObjectString'); +shouldBe('testArrayPrototypeMap(nonstrictThrowThisString)', 'globalObjectString'); +shouldBe('testArrayPrototypeEvery(nonstrictThrowThisString)', 'globalObjectString'); +shouldBe('testArrayPrototypeForEach(nonstrictThrowThisString)', 'globalObjectString'); +shouldBe('testArrayPrototypeSome(nonstrictThrowThisString)', 'globalObjectString'); +shouldBe('testStringPrototypeReplace(nonstrictThrowThisString)', 'globalObjectString'); + +var successfullyParsed = true; diff --git a/LayoutTests/fast/js/strict-callback-this-expected.txt b/LayoutTests/fast/js/strict-callback-this-expected.txt new file mode 100644 index 0000000..d27990c --- /dev/null +++ b/LayoutTests/fast/js/strict-callback-this-expected.txt @@ -0,0 +1,23 @@ +This tests that a call to array/string prototype methods pass the correct this value (undefined) to strict callees. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS testArrayPrototypeSort(strictThrowThisString) is undefinedString +PASS testArrayPrototypeFilter(strictThrowThisString) is undefinedString +PASS testArrayPrototypeMap(strictThrowThisString) is undefinedString +PASS testArrayPrototypeEvery(strictThrowThisString) is undefinedString +PASS testArrayPrototypeForEach(strictThrowThisString) is undefinedString +PASS testArrayPrototypeSome(strictThrowThisString) is undefinedString +PASS testStringPrototypeReplace(strictThrowThisString) is undefinedString +PASS testArrayPrototypeSort(nonstrictThrowThisString) is globalObjectString +PASS testArrayPrototypeFilter(nonstrictThrowThisString) is globalObjectString +PASS testArrayPrototypeMap(nonstrictThrowThisString) is globalObjectString +PASS testArrayPrototypeEvery(nonstrictThrowThisString) is globalObjectString +PASS testArrayPrototypeForEach(nonstrictThrowThisString) is globalObjectString +PASS testArrayPrototypeSome(nonstrictThrowThisString) is globalObjectString +PASS testStringPrototypeReplace(nonstrictThrowThisString) is globalObjectString +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/js/strict-callback-this.html b/LayoutTests/fast/js/strict-callback-this.html new file mode 100644 index 0000000..2c22a3c --- /dev/null +++ b/LayoutTests/fast/js/strict-callback-this.html @@ -0,0 +1,13 @@ + + + + + + + +

+
+ + + + diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 3d5f6f9..f33f654 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -46,6 +46,29 @@ 2011-09-22 Gavin Barraclough + Incorrect this value passed to callbacks. + https://bugs.webkit.org/show_bug.cgi?id=68668 + + Reviewed by Oliver Hunt. + + From Array/String prototype function. Should be undefined, but + global object is passed instead (this is visible for strict callbacks). + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncSort): + (JSC::arrayProtoFuncFilter): + (JSC::arrayProtoFuncMap): + (JSC::arrayProtoFuncEvery): + (JSC::arrayProtoFuncForEach): + (JSC::arrayProtoFuncSome): + * runtime/JSArray.cpp: + (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key): + (JSC::JSArray::sort): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncReplace): + +2011-09-22 Gavin Barraclough + Function.prototype.bind.length shoudl be 1. Rubber stamped by Olier Hunt. diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp index c7655d3..3b4b446 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -543,7 +543,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec) MarkedArgumentBuffer l; l.append(jObj); l.append(minObj); - compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec); + compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec); } else compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1; @@ -671,7 +671,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec) if (callType == CallTypeNone) return throwVMTypeError(exec); - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec); + JSValue applyThis = exec->argument(1); JSArray* resultArray = constructEmptyArray(exec); unsigned filterIndex = 0; @@ -730,7 +730,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec) if (callType == CallTypeNone) return throwVMTypeError(exec); - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec); + JSValue applyThis = exec->argument(1); JSArray* resultArray = constructEmptyArray(exec, length); unsigned k = 0; @@ -792,7 +792,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec) if (callType == CallTypeNone) return throwVMTypeError(exec); - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec); + JSValue applyThis = exec->argument(1); JSValue result = jsBoolean(true); @@ -850,7 +850,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec) if (callType == CallTypeNone) return throwVMTypeError(exec); - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec); + JSValue applyThis = exec->argument(1); unsigned k = 0; if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) { @@ -900,7 +900,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec) if (callType == CallTypeNone) return throwVMTypeError(exec); - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec); + JSValue applyThis = exec->argument(1); JSValue result = jsBoolean(false); diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp index 4b0caa2..d7be946 100644 --- a/Source/JavaScriptCore/runtime/JSArray.cpp +++ b/Source/JavaScriptCore/runtime/JSArray.cpp @@ -1016,7 +1016,6 @@ struct AVLTreeAbstractorForArrayCompare { JSValue m_compareFunction; CallType m_compareCallType; const CallData* m_compareCallData; - JSValue m_globalThisValue; OwnPtr m_cachedCall; handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; } @@ -1055,7 +1054,7 @@ struct AVLTreeAbstractorForArrayCompare { double compareResult; if (m_cachedCall) { - m_cachedCall->setThis(m_globalThisValue); + m_cachedCall->setThis(jsUndefined()); m_cachedCall->setArgument(0, va); m_cachedCall->setArgument(1, vb); compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame(m_exec)); @@ -1063,7 +1062,7 @@ struct AVLTreeAbstractorForArrayCompare { MarkedArgumentBuffer arguments; arguments.append(va); arguments.append(vb); - compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec); + compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, jsUndefined(), arguments).toNumber(m_exec); } return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent. } @@ -1099,7 +1098,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, tree.abstractor().m_compareFunction = compareFunction; tree.abstractor().m_compareCallType = callType; tree.abstractor().m_compareCallData = &callData; - tree.abstractor().m_globalThisValue = exec->globalThisValue(); tree.abstractor().m_nodes.grow(nodeCount); if (callType == CallTypeJS) diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp index 76db0c8..2281efb 100644 --- a/Source/JavaScriptCore/runtime/StringPrototype.cpp +++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp @@ -448,7 +448,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) cachedCall.setArgument(i++, jsNumber(completeMatchStart)); cachedCall.setArgument(i++, sourceVal); - cachedCall.setThis(exec->globalThisValue()); + cachedCall.setThis(jsUndefined()); JSValue result = cachedCall.call(); if (LIKELY(result.isString())) replacements.append(asString(result)->value(exec)); @@ -495,7 +495,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) args.append(jsNumber(completeMatchStart)); args.append(sourceVal); - replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec)); + replacements.append(call(exec, replacement, callType, callData, jsUndefined(), args).toString(exec)); if (exec->hadException()) break; } else { @@ -551,7 +551,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) args.append(jsNumber(matchPos)); args.append(sourceVal); - replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec); + replacementString = call(exec, replacement, callType, callData, jsUndefined(), args).toString(exec); } size_t matchEnd = matchPos + matchLen;