Changeset 91164 in webkit
- Timestamp:
- Jul 16, 2011 10:04:36 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r91158 r91164 1 2011-07-16 Gavin Barraclough <barraclough@apple.com> 2 3 https://bugs.webkit.org/show_bug.cgi?id=64657 4 Converted this value not preserved when accessed via direct eval. 5 6 Reviewed by Oliver Hunt. 7 8 Added test case. 9 10 * fast/js/read-modify-eval-expected.txt: 11 * fast/js/script-tests/read-modify-eval.js: 12 (primitiveThisTest): 13 1 14 2011-07-16 Enrica Casucci <enrica@apple.com> 2 15 -
trunk/LayoutTests/fast/js/read-modify-eval-expected.txt
r29997 r91164 19 19 PASS postIncTest(); is true 20 20 PASS postDecTest(); is true 21 PASS primitiveThisTest.call(1); is true 22 PASS strictThisTest.call(1); is true 21 23 PASS successfullyParsed is true 22 24 -
trunk/LayoutTests/fast/js/script-tests/read-modify-eval.js
r48651 r91164 108 108 } 109 109 110 function primitiveThisTest() 111 { 112 // Test that conversion of this is persistant over multiple calls to eval, 113 // even where 'this' is not directly used within the function. 114 eval('this.value = "Seekrit message";'); 115 return eval('this.value') === "Seekrit message"; 116 } 117 118 function strictThisTest() 119 { 120 // In a strict mode function primitive this values are not converted, so 121 // the property access in the first eval is writing a value to a temporary 122 // object, and should not be observed by the second eval. 123 "use strict"; 124 eval('this.value = "Seekrit message";'); 125 return eval('this.value') === undefined; 126 } 127 110 128 shouldBeTrue('multTest();'); 111 129 shouldBeTrue('divTest();'); … … 125 143 shouldBeTrue('postDecTest();'); 126 144 145 shouldBeTrue('primitiveThisTest.call(1);'); 146 shouldBeTrue('strictThisTest.call(1);'); 147 127 148 successfullyParsed = true; -
trunk/Source/JavaScriptCore/ChangeLog
r91160 r91164 1 2011-07-16 Gavin Barraclough <barraclough@apple.com> 2 3 https://bugs.webkit.org/show_bug.cgi?id=64657 4 Converted this value not preserved when accessed via direct eval. 5 6 Reviewed by Oliver Hunt. 7 8 Upon entry into a non-strict function, primitive this values should be boxed as Object types 9 (or substituted with the global object) - which is done by op_convert_this. However we only 10 do so where this is used lexically within the function (we omit the conversion op if not). 11 The problem comes if a direct eval (running within the function's scope) accesses the this 12 value. 13 14 We are safe in the case of a single eval, since the this object will be converted within 15 callEval, however the converted value is not preserved, and a new wrapper object is allocated 16 each time eval is invoked. This is inefficient and incorrect, since any changes to the wrapper 17 object will be lost between eval statements. 18 19 * bytecompiler/BytecodeGenerator.cpp: 20 (JSC::BytecodeGenerator::BytecodeGenerator): 21 - If a function uses eval, we always need to convert this. 22 * interpreter/Interpreter.cpp: 23 (JSC::Interpreter::execute): 24 - Don't convert primitive values here - this is too late! 25 (JSC::Interpreter::privateExecute): 26 - Changed op_convert_this to call new isPrimitive method. 27 * jit/JITStubs.cpp: 28 (JSC::DEFINE_STUB_FUNCTION): 29 - Changed op_convert_this to call new isPrimitive method. 30 * runtime/JSCell.h: 31 (JSC::JSCell::JSValue::isPrimitive): 32 - Added JSValue::isPrimitive. 33 * runtime/JSValue.h: 34 - Added JSValue::isPrimitive. 35 1 36 2011-07-16 Filip Pizlo <fpizlo@apple.com> 2 37 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r91095 r91164 414 414 instructions().append(m_thisRegister.index()); 415 415 instructions().append(funcProto->index()); 416 } else if (functionBody->usesThis() || m_shouldEmitDebugHooks) { 417 if (!codeBlock->isStrictMode()) { 418 emitOpcode(op_convert_this); 419 instructions().append(m_thisRegister.index()); 420 } 416 } else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) { 417 emitOpcode(op_convert_this); 418 instructions().append(m_thisRegister.index()); 421 419 } 422 420 } -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r91095 r91164 1241 1241 ASSERT(codeBlock->m_numParameters == 1); // 1 parameter for 'this'. 1242 1242 newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->m_numParameters, 0); 1243 newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = thisValue .toThisObject(newCallFrame);1243 newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = thisValue; 1244 1244 1245 1245 Profiler** profiler = Profiler::enabledProfilerReference(); … … 4622 4622 int thisRegister = vPC[1].u.operand; 4623 4623 JSValue thisVal = callFrame->r(thisRegister).jsValue(); 4624 if ( !thisVal.isCell() || thisVal.isString())4624 if (thisVal.isPrimitive()) 4625 4625 callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toThisObject(callFrame)); 4626 4626 -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r91095 r91164 1281 1281 CallFrame* callFrame = stackFrame.callFrame; 1282 1282 1283 ASSERT( !v1.isCell() || v1.isString());1283 ASSERT(v1.isPrimitive()); 1284 1284 1285 1285 JSObject* result = v1.toThisObject(callFrame); -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r90273 r91164 209 209 } 210 210 211 inline bool JSValue::isPrimitive() const 212 { 213 return !isCell() || asCell()->isString(); 214 } 215 211 216 inline bool JSValue::isGetterSetter() const 212 217 { -
trunk/Source/JavaScriptCore/runtime/JSValue.h
r91095 r91164 153 153 bool isNumber() const; 154 154 bool isString() const; 155 bool isPrimitive() const; 155 156 bool isGetterSetter() const; 156 157 bool isObject() const;
Note: See TracChangeset
for help on using the changeset viewer.