Diff
Modified: trunk/LayoutTests/ChangeLog (109823 => 109824)
--- trunk/LayoutTests/ChangeLog 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/LayoutTests/ChangeLog 2012-03-06 01:18:42 UTC (rev 109824)
@@ -1,3 +1,22 @@
+2012-03-05 Gavin Barraclough <barraclo...@apple.com>
+
+ putByIndex should throw in strict mode
+ https://bugs.webkit.org/show_bug.cgi?id=80335
+
+ Reviewed by Filip Pizlo.
+
+ * fast/js/primitive-property-access-edge-cases-expected.txt:
+ * fast/js/script-tests/primitive-property-access-edge-cases.js:
+ (checkNumericGet.Object.defineProperty):
+ (checkNumericSet.Object.defineProperty):
+ (checkNumericGetStrict.Object.defineProperty):
+ (checkNumericSetStrict.Object.defineProperty):
+ (checkNumericRead):
+ (checkNumericWrite):
+ (checkNumericReadStrict):
+ (checkNumericWriteStrict):
+ - Added test cases.
+
2012-03-05 Stephen Chenney <schen...@chromium.org>
[Chromium] SVG Composite of Offset crashes
Modified: trunk/LayoutTests/fast/js/primitive-property-access-edge-cases-expected.txt (109823 => 109824)
--- trunk/LayoutTests/fast/js/primitive-property-access-edge-cases-expected.txt 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/LayoutTests/fast/js/primitive-property-access-edge-cases-expected.txt 2012-03-06 01:18:42 UTC (rev 109824)
@@ -27,6 +27,28 @@
PASS checkWriteStrict(1, Number) threw exception TypeError: Attempted to assign to readonly property..
PASS checkWriteStrict('hello', String) threw exception TypeError: Attempted to assign to readonly property..
PASS checkWriteStrict(true, Boolean) threw exception TypeError: Attempted to assign to readonly property..
+PASS checkNumericGet(1, Number) is true
+PASS checkNumericGet('hello', String) is true
+PASS checkNumericGet(true, Boolean) is true
+PASS checkNumericSet(1, Number) is true
+PASS checkNumericSet('hello', String) is true
+PASS checkNumericSet(true, Boolean) is true
+PASS checkNumericGetStrict(1, Number) is true
+PASS checkNumericGetStrict('hello', String) is true
+PASS checkNumericGetStrict(true, Boolean) is true
+PASS checkNumericSetStrict(1, Number) is true
+PASS checkNumericSetStrict(true, Boolean) is true
+PASS checkNumericRead(1, Number) is true
+PASS checkNumericRead('hello', String) is true
+PASS checkNumericRead(true, Boolean) is true
+PASS checkNumericWrite(1, Number) is true
+PASS checkNumericWrite('hello', String) is true
+PASS checkNumericWrite(true, Boolean) is true
+PASS checkNumericReadStrict(1, Number) is true
+PASS checkNumericReadStrict('hello', String) is true
+PASS checkNumericReadStrict(true, Boolean) is true
+PASS checkNumericWriteStrict(1, Number) threw exception TypeError: Attempted to assign to readonly property..
+PASS checkNumericWriteStrict(true, Boolean) threw exception TypeError: Attempted to assign to readonly property..
PASS didNotCrash is true
PASS successfullyParsed is true
Modified: trunk/LayoutTests/fast/js/script-tests/primitive-property-access-edge-cases.js (109823 => 109824)
--- trunk/LayoutTests/fast/js/script-tests/primitive-property-access-edge-cases.js 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/LayoutTests/fast/js/script-tests/primitive-property-access-edge-cases.js 2012-03-06 01:18:42 UTC (rev 109824)
@@ -126,4 +126,90 @@
shouldThrow("checkWriteStrict('hello', String)");
shouldThrow("checkWriteStrict(true, Boolean)");
+function checkNumericGet(x, constructor)
+{
+ checkOkay = false;
+ Object.defineProperty(constructor.prototype, 42, { get: function() { checkOkay = typeof this === 'object'; }, configurable: true });
+ x[42];
+ delete constructor.prototype[42];
+ return checkOkay;
+}
+
+function checkNumericSet(x, constructor)
+{
+ checkOkay = false;
+ Object.defineProperty(constructor.prototype, 42, { set: function() { checkOkay = typeof this === 'object'; }, configurable: true });
+ x[42] = null;
+ delete constructor.prototype[42];
+ return checkOkay;
+}
+
+function checkNumericGetStrict(x, constructor)
+{
+ checkOkay = false;
+ Object.defineProperty(constructor.prototype, 42, { get: function() { "use strict"; checkOkay = typeof this !== 'object'; }, configurable: true });
+ x[42];
+ delete constructor.prototype[42];
+ return checkOkay;
+}
+
+function checkNumericSetStrict(x, constructor)
+{
+ checkOkay = false;
+ Object.defineProperty(constructor.prototype, 42, { set: function() { "use strict"; checkOkay = typeof this !== 'object'; }, configurable: true });
+ x[42] = null;
+ delete constructor.prototype[42];
+ return checkOkay;
+}
+
+shouldBeTrue("checkNumericGet(1, Number)");
+shouldBeTrue("checkNumericGet('hello', String)");
+shouldBeTrue("checkNumericGet(true, Boolean)");
+shouldBeTrue("checkNumericSet(1, Number)");
+shouldBeTrue("checkNumericSet('hello', String)");
+shouldBeTrue("checkNumericSet(true, Boolean)");
+shouldBeTrue("checkNumericGetStrict(1, Number)");
+shouldBeTrue("checkNumericGetStrict('hello', String)");
+shouldBeTrue("checkNumericGetStrict(true, Boolean)");
+shouldBeTrue("checkNumericSetStrict(1, Number)");
+//shouldBeTrue("checkNumericSetStrict('hello', String)"); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=80335
+shouldBeTrue("checkNumericSetStrict(true, Boolean)");
+
+function checkNumericRead(x, constructor)
+{
+ return x[42] === undefined;
+}
+
+function checkNumericWrite(x, constructor)
+{
+ x[42] = null;
+ return x[42] === undefined;
+}
+
+function checkNumericReadStrict(x, constructor)
+{
+ "use strict";
+ return x[42] === undefined;
+}
+
+function checkNumericWriteStrict(x, constructor)
+{
+ "use strict";
+ x[42] = null;
+ return x[42] === undefined;
+}
+
+shouldBeTrue("checkNumericRead(1, Number)");
+shouldBeTrue("checkNumericRead('hello', String)");
+shouldBeTrue("checkNumericRead(true, Boolean)");
+shouldBeTrue("checkNumericWrite(1, Number)");
+shouldBeTrue("checkNumericWrite('hello', String)");
+shouldBeTrue("checkNumericWrite(true, Boolean)");
+shouldBeTrue("checkNumericReadStrict(1, Number)");
+shouldBeTrue("checkNumericReadStrict('hello', String)");
+shouldBeTrue("checkNumericReadStrict(true, Boolean)");
+shouldThrow("checkNumericWriteStrict(1, Number)");
+//shouldThrow("checkNumericWriteStrict('hello', String)"); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=80335
+shouldThrow("checkNumericWriteStrict(true, Boolean)");
+
shouldBeTrue("didNotCrash");
Modified: trunk/Source/_javascript_Core/ChangeLog (109823 => 109824)
--- trunk/Source/_javascript_Core/ChangeLog 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-03-06 01:18:42 UTC (rev 109824)
@@ -1,3 +1,35 @@
+2012-03-05 Gavin Barraclough <barraclo...@apple.com>
+
+ putByIndex should throw in strict mode
+ https://bugs.webkit.org/show_bug.cgi?id=80335
+
+ Reviewed by Filip Pizlo.
+
+ We'll need to pass an additional parameter.
+
+ Part 1 - rename JSValue::put() for integer indices to JSValue::putByIndex()
+ to match the method in the MethodTable, make this take a parameter indicating
+ whether the put should throw. This fixes the cases where the base of the put
+ is a primitive.
+
+ * dfg/DFGOperations.cpp:
+ (DFG):
+ (JSC::DFG::putByVal):
+ (JSC::DFG::operationPutByValInternal):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/JSObject.h:
+ (JSC::JSValue::putByIndex):
+ * runtime/JSValue.cpp:
+ (JSC):
+ * runtime/JSValue.h:
+ (JSValue):
+
2012-03-05 Sam Weinig <s...@webkit.org>
Add support for hosting layers in the window server in WebKit2
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (109823 => 109824)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-03-06 01:18:42 UTC (rev 109824)
@@ -146,6 +146,7 @@
namespace JSC { namespace DFG {
+template<bool strict>
static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
{
JSGlobalData* globalData = &exec->globalData();
@@ -175,7 +176,7 @@
}
}
- baseValue.put(exec, index, value);
+ baseValue.putByIndex(exec, index, value, strict);
}
template<bool strict>
@@ -189,7 +190,7 @@
JSValue value = JSValue::decode(encodedValue);
if (LIKELY(property.isUInt32())) {
- putByVal(exec, baseValue, property.asUInt32(), value);
+ putByVal<strict>(exec, baseValue, property.asUInt32(), value);
return;
}
@@ -197,7 +198,7 @@
double propertyAsDouble = property.asDouble();
uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
if (propertyAsDouble == propertyAsUInt32) {
- putByVal(exec, baseValue, propertyAsUInt32, value);
+ putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
return;
}
}
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (109823 => 109824)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-03-06 01:18:42 UTC (rev 109824)
@@ -1158,7 +1158,7 @@
break;
}
case JSONPPathEntryTypeLookup: {
- baseObject.put(callFrame, JSONPPath.last().m_pathIndex, JSONPValue);
+ baseObject.putByIndex(callFrame, JSONPPath.last().m_pathIndex, JSONPValue, slot.isStrictMode());
if (callFrame->hadException())
return jsUndefined();
break;
@@ -3790,9 +3790,9 @@
else if (jsValue.isDouble())
jsByteArray->setIndex(i, jsValue.asDouble());
else
- baseValue.put(callFrame, i, jsValue);
+ baseValue.putByIndex(callFrame, i, jsValue, codeBlock->isStrictMode());
} else
- baseValue.put(callFrame, i, callFrame->r(value).jsValue());
+ baseValue.putByIndex(callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -3855,7 +3855,9 @@
unsigned property = vPC[2].u.operand;
int value = vPC[3].u.operand;
- callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue());
+ JSValue arrayValue = callFrame->r(base).jsValue();
+ ASSERT(isJSArray(arrayValue));
+ asArray(arrayValue)->putDirectIndex(callFrame, property, callFrame->r(value).jsValue(), false);
vPC += OPCODE_LENGTH(op_put_by_index);
NEXT_INSTRUCTION();
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (109823 => 109824)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-03-06 01:18:42 UTC (rev 109824)
@@ -2568,9 +2568,9 @@
}
}
- baseValue.put(callFrame, i, value);
+ baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else
- baseValue.put(callFrame, i, value);
+ baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -2611,7 +2611,7 @@
if (!isJSByteArray(baseValue))
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val));
- baseValue.put(callFrame, i, value);
+ baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -3402,7 +3402,9 @@
CallFrame* callFrame = stackFrame.callFrame;
unsigned property = stackFrame.args[1].int32();
- stackFrame.args[0].jsValue().put(callFrame, property, stackFrame.args[2].jsValue());
+ JSValue arrayValue = stackFrame.args[0].jsValue();
+ ASSERT(isJSArray(arrayValue));
+ asArray(arrayValue)->putDirectIndex(callFrame, property, stackFrame.args[2].jsValue(), false);
}
DEFINE_STUB_FUNCTION(void*, op_switch_imm)
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (109823 => 109824)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2012-03-06 01:18:42 UTC (rev 109824)
@@ -1059,7 +1059,7 @@
LLINT_END();
}
}
- baseValue.put(exec, i, value);
+ baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
LLINT_END();
}
@@ -1099,7 +1099,9 @@
LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
{
LLINT_BEGIN();
- LLINT_OP_C(1).jsValue().put(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
+ JSValue arrayValue = LLINT_OP_C(1).jsValue();
+ ASSERT(isJSArray(arrayValue));
+ asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue(), false);
LLINT_END();
}
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (109823 => 109824)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2012-03-06 01:18:42 UTC (rev 109824)
@@ -840,11 +840,11 @@
asCell()->methodTable()->put(asCell(), exec, propertyName, value, slot);
}
-inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
+inline void JSValue::putByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
if (UNLIKELY(!isCell())) {
- JSObject* thisObject = synthesizeObject(exec);
- thisObject->methodTable()->putByIndex(thisObject, exec, propertyName, value);
+ PutPropertySlot slot(shouldThrow);
+ putToPrimitive(exec, Identifier::from(exec, propertyName), value, slot);
return;
}
asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value);
Modified: trunk/Source/_javascript_Core/runtime/JSValue.cpp (109823 => 109824)
--- trunk/Source/_javascript_Core/runtime/JSValue.cpp 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/runtime/JSValue.cpp 2012-03-06 01:18:42 UTC (rev 109824)
@@ -91,19 +91,6 @@
return exec->globalThisValue();
}
-JSObject* JSValue::synthesizeObject(ExecState* exec) const
-{
- ASSERT(!isCell());
- if (isNumber())
- return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
- if (isBoolean())
- return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
-
- ASSERT(isUndefinedOrNull());
- throwError(exec, createNotAnObjectError(exec, *this));
- return JSNotAnObject::create(exec);
-}
-
JSObject* JSValue::synthesizePrototype(ExecState* exec) const
{
if (isCell()) {
Modified: trunk/Source/_javascript_Core/runtime/JSValue.h (109823 => 109824)
--- trunk/Source/_javascript_Core/runtime/JSValue.h 2012-03-06 01:18:12 UTC (rev 109823)
+++ trunk/Source/_javascript_Core/runtime/JSValue.h 2012-03-06 01:18:42 UTC (rev 109824)
@@ -222,7 +222,7 @@
JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
void putToPrimitive(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- void put(ExecState*, unsigned propertyName, JSValue);
+ void putByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
JSObject* toThisObject(ExecState*) const;
@@ -253,8 +253,6 @@
JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
JS_EXPORT_PRIVATE JSObject* toThisObjectSlowCase(ExecState*) const;
- JSObject* synthesizeObject(ExecState*) const;
-
#if USE(JSVALUE32_64)
/*
* On 32-bit platforms USE(JSVALUE32_64) should be defined, and we use a NaN-encoded