Title: [97905] trunk
Revision
97905
Author
[email protected]
Date
2011-10-19 18:18:03 -0700 (Wed, 19 Oct 2011)

Log Message

Poisoning of strict caller,arguments inappropriately poisoning "in"
https://bugs.webkit.org/show_bug.cgi?id=63398

Reviewed by Oliver Hunt.

Source/_javascript_Core: 

This fixes the problem by correctly implementing the spec -
the error should actually be being thrown from a standard JS getter/setter.
This implements spec correct behaviour for strict mode JS functions & bound
functions, I'll follow up with a patch to do the same for arguments.

* runtime/JSBoundFunction.cpp:
(JSC::JSBoundFunction::finishCreation):
    - Add the poisoned caller/arguments properties.
* runtime/JSBoundFunction.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::finishCreation):
(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::getOwnPropertyDescriptor):
(JSC::JSFunction::put):
    - If the caller/arguments are accessed on a strict mode function, lazily add the ThrowTypeError getter.
* runtime/JSFunction.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::createThrowTypeError):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::throwTypeErrorGetterSetter):
    - Add a ThrowTypeError type, per ES5 13.2.3.
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncThrowTypeError):
* runtime/JSGlobalObjectFunctions.h:
    - Implementation of ThrowTypeError.
* runtime/JSObject.cpp:
(JSC::JSObject::initializeGetterSetterProperty):
* runtime/JSObject.h:
    - This function adds a new property (must not exist already) that is an initialized getter/setter.

LayoutTests: 

* fast/js/basic-strict-mode-expected.txt:
* fast/js/script-tests/basic-strict-mode.js:
    - Add tests.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (97904 => 97905)


--- trunk/LayoutTests/ChangeLog	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/LayoutTests/ChangeLog	2011-10-20 01:18:03 UTC (rev 97905)
@@ -1,3 +1,14 @@
+2011-10-19  Gavin Barraclough  <[email protected]>
+
+        Poisoning of strict caller,arguments inappropriately poisoning "in"
+        https://bugs.webkit.org/show_bug.cgi?id=63398
+
+        Reviewed by Oliver Hunt.
+
+        * fast/js/basic-strict-mode-expected.txt:
+        * fast/js/script-tests/basic-strict-mode.js:
+            - Add tests.
+
 2011-10-19  Erik Arvidsson  <[email protected]>
 
         Fix test breakage after r97881

Modified: trunk/LayoutTests/fast/js/basic-strict-mode-expected.txt (97904 => 97905)


--- trunk/LayoutTests/fast/js/basic-strict-mode-expected.txt	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/LayoutTests/fast/js/basic-strict-mode-expected.txt	2011-10-20 01:18:03 UTC (rev 97905)
@@ -56,16 +56,20 @@
 PASS (function(){(function (){'use strict'; with(1){};})}) threw exception SyntaxError: 'with' statements are not valid in strict mode.
 PASS (function (){'use strict'; arguments.callee; })() threw exception TypeError: Unable to access callee of strict mode function.
 PASS (function (){'use strict'; arguments.caller; })() threw exception TypeError: Unable to access caller of strict mode function.
-PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
-PASS (function f(){'use strict'; f.caller; })() threw exception TypeError: Cannot access caller property of a strict mode function.
-PASS (function f(){'use strict'; f.arguments=5; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
-PASS (function f(){'use strict'; f.caller=5; })() threw exception TypeError: Cannot access caller property of a strict mode function.
+PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: Type error.
+PASS (function f(){'use strict'; f.caller; })() threw exception TypeError: Type error.
+PASS (function f(){'use strict'; f.arguments=5; })() threw exception TypeError: Type error.
+PASS (function f(){'use strict'; f.caller=5; })() threw exception TypeError: Type error.
 PASS (function (arg){'use strict'; arguments.callee; })() threw exception TypeError: Unable to access callee of strict mode function.
 PASS (function (arg){'use strict'; arguments.caller; })() threw exception TypeError: Unable to access caller of strict mode function.
-PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
-PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: Cannot access caller property of a strict mode function.
-PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
-PASS (function f(arg){'use strict'; f.caller=5; })() threw exception TypeError: Cannot access caller property of a strict mode function.
+PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: Type error.
+PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: Type error.
+PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: Type error.
+PASS (function f(arg){'use strict'; f.caller=5; })() threw exception TypeError: Type error.
+PASS "caller" in function(){"use strict"} is true
+PASS (function(){"use strict";}).hasOwnProperty("caller") is true
+PASS "arguments" in function(){"use strict"} is true
+PASS (function(){"use strict";}).hasOwnProperty("arguments") is true
 PASS 'use strict'; (function (){with(1){};}) threw exception SyntaxError: 'with' statements are not valid in strict mode.
 PASS (function(){'use strict'; (function (){with(1){};})}) threw exception SyntaxError: 'with' statements are not valid in strict mode.
 PASS 'use strict'; (function (){var a; delete a;}) threw exception SyntaxError: Cannot delete unqualified property 'a' in strict mode.

Modified: trunk/LayoutTests/fast/js/script-tests/basic-strict-mode.js (97904 => 97905)


--- trunk/LayoutTests/fast/js/script-tests/basic-strict-mode.js	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/LayoutTests/fast/js/script-tests/basic-strict-mode.js	2011-10-20 01:18:03 UTC (rev 97905)
@@ -74,6 +74,13 @@
 shouldThrow("(function f(arg){'use strict'; f.caller; })()");
 shouldThrow("(function f(arg){'use strict'; f.arguments=5; })()");
 shouldThrow("(function f(arg){'use strict'; f.caller=5; })()");
+
+// arguments/caller poisoning should be visible but not throw with 'in' & 'hasOwnProperty'.
+shouldBeTrue('"caller" in function(){"use strict"}');
+shouldBeTrue('(function(){"use strict";}).hasOwnProperty("caller")');
+shouldBeTrue('"arguments" in function(){"use strict"}');
+shouldBeTrue('(function(){"use strict";}).hasOwnProperty("arguments")');
+ 
 shouldBeSyntaxError("'use strict'; (function (){with(1){};})");
 shouldBeSyntaxError("'use strict'; (function (){var a; delete a;})");
 shouldBeSyntaxError("'use strict'; var a; (function (){ delete a;})");

Modified: trunk/Source/_javascript_Core/ChangeLog (97904 => 97905)


--- trunk/Source/_javascript_Core/ChangeLog	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-10-20 01:18:03 UTC (rev 97905)
@@ -1,3 +1,41 @@
+2011-10-19  Gavin Barraclough  <[email protected]>
+
+        Poisoning of strict caller,arguments inappropriately poisoning "in"
+        https://bugs.webkit.org/show_bug.cgi?id=63398
+
+        Reviewed by Oliver Hunt.
+
+        This fixes the problem by correctly implementing the spec -
+        the error should actually be being thrown from a standard JS getter/setter.
+        This implements spec correct behaviour for strict mode JS functions & bound
+        functions, I'll follow up with a patch to do the same for arguments.
+
+        * runtime/JSBoundFunction.cpp:
+        (JSC::JSBoundFunction::finishCreation):
+            - Add the poisoned caller/arguments properties.
+        * runtime/JSBoundFunction.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::finishCreation):
+        (JSC::JSFunction::getOwnPropertySlot):
+        (JSC::JSFunction::getOwnPropertyDescriptor):
+        (JSC::JSFunction::put):
+            - If the caller/arguments are accessed on a strict mode function, lazily add the ThrowTypeError getter.
+        * runtime/JSFunction.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::createThrowTypeError):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::throwTypeErrorGetterSetter):
+            - Add a ThrowTypeError type, per ES5 13.2.3.
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncThrowTypeError):
+        * runtime/JSGlobalObjectFunctions.h:
+            - Implementation of ThrowTypeError.
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::initializeGetterSetterProperty):
+        * runtime/JSObject.h:
+            - This function adds a new property (must not exist already) that is an initialized getter/setter.
+
 2011-10-19  Yuqiang Xian  <[email protected]>
 
         DFG JIT 32_64 - improve double boxing/unboxing

Modified: trunk/Source/_javascript_Core/runtime/JSBoundFunction.cpp (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSBoundFunction.cpp	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSBoundFunction.cpp	2011-10-20 01:18:03 UTC (rev 97905)
@@ -96,43 +96,6 @@
     return m_targetFunction->hasInstance(exec, value, proto);
 }
 
-bool JSBoundFunction::getOwnPropertySlotVirtual(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
-    return getOwnPropertySlot(this, exec, propertyName, slot);
-}
-
-bool JSBoundFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
-    if (propertyName == exec->propertyNames().arguments) {
-        throwTypeError(exec, StrictModeArgumentsAccessError);
-        slot.setValue(jsNull());
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().caller) {
-        throwTypeError(exec, StrictModeCallerAccessError);
-        slot.setValue(jsNull());
-        return true;
-    }
-
-    return Base::getOwnPropertySlot(cell, exec, propertyName, slot);
-}
-
-bool JSBoundFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
-{
-    if (propertyName == exec->propertyNames().arguments) {
-        createDescriptorForThrowingProperty(exec, descriptor, StrictModeArgumentsAccessError);
-        return true;
-    }
-    
-    if (propertyName == exec->propertyNames().caller) {
-        createDescriptorForThrowingProperty(exec, descriptor, StrictModeCallerAccessError);
-        return true;
-    }
-    
-    return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
-}
-
 JSBoundFunction::JSBoundFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs)
     : Base(exec, globalObject, structure)
     , m_targetFunction(exec->globalData(), this, targetFunction)
@@ -145,6 +108,9 @@
 {
     Base::finishCreation(exec, executable, length, name);
     ASSERT(inherits(&s_info));
+
+    initializeGetterSetterProperty(exec, exec->propertyNames().arguments, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+    initializeGetterSetterProperty(exec, exec->propertyNames().caller, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
 }
 
 void JSBoundFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)

Modified: trunk/Source/_javascript_Core/runtime/JSBoundFunction.h (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSBoundFunction.h	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSBoundFunction.h	2011-10-20 01:18:03 UTC (rev 97905)
@@ -39,10 +39,6 @@
 
     static JSBoundFunction* create(ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const Identifier&);
 
-    virtual bool getOwnPropertySlotVirtual(ExecState*, const Identifier&, PropertySlot&);
-    static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
-    virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
-
     virtual bool hasInstance(ExecState*, JSValue value, JSValue proto);
 
     JSObject* targetFunction() { return m_targetFunction.get(); }

Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2011-10-20 01:18:03 UTC (rev 97905)
@@ -97,7 +97,8 @@
     Base::finishCreation(exec->globalData());
     ASSERT(inherits(&s_info));
     m_executable.set(exec->globalData(), this, executable);
-    putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
+    if (!name.isNull())
+        putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.ustring()), DontDelete | ReadOnly | DontEnum);
     putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
 }
 
@@ -117,9 +118,6 @@
     ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);
 }
 
-const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function";
-const char* StrictModeArgumentsAccessError = "Cannot access arguments property of a strict mode function";
-
 void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message)
 {
     JSValue thrower = createTypeErrorFunction(exec, message);
@@ -224,11 +222,14 @@
 
     if (propertyName == exec->propertyNames().arguments) {
         if (thisObject->jsExecutable()->isStrictMode()) {
-            throwTypeError(exec, StrictModeArgumentsAccessError);
-            slot.setValue(jsNull());
-            return true;
+            bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
+            if (!result) {
+                thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+                result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
+                ASSERT(result);
+            }
+            return result;
         }
-   
         slot.setCacheableCustom(thisObject, argumentsGetter);
         return true;
     }
@@ -240,9 +241,13 @@
 
     if (propertyName == exec->propertyNames().caller) {
         if (thisObject->jsExecutable()->isStrictMode()) {
-            throwTypeError(exec, StrictModeCallerAccessError);
-            slot.setValue(jsNull());
-            return true;
+            bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
+            if (!result) {
+                thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+                result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
+                ASSERT(result);
+            }
+            return result;
         }
         slot.setCacheableCustom(thisObject, callerGetter);
         return true;
@@ -263,10 +268,16 @@
     }
     
     if (propertyName == exec->propertyNames().arguments) {
-        if (jsExecutable()->isStrictMode())
-            createDescriptorForThrowingProperty(exec, descriptor, StrictModeArgumentsAccessError);
-        else
-            descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
+        if (jsExecutable()->isStrictMode()) {
+            bool result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+            if (!result) {
+                initializeGetterSetterProperty(exec, propertyName, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+                result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+                ASSERT(result);
+            }
+            return result;
+        }
+        descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
         return true;
     }
     
@@ -276,10 +287,16 @@
     }
     
     if (propertyName == exec->propertyNames().caller) {
-        if (jsExecutable()->isStrictMode())
-            createDescriptorForThrowingProperty(exec, descriptor, StrictModeCallerAccessError);
-        else
-            descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
+        if (jsExecutable()->isStrictMode()) {
+            bool result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+            if (!result) {
+                initializeGetterSetterProperty(exec, propertyName, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+                result = Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+                ASSERT(result);
+            }
+            return result;
+        }
+        descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
         return true;
     }
     
@@ -318,15 +335,12 @@
         PropertySlot slot;
         thisObject->getOwnPropertySlotVirtual(exec, propertyName, slot);
     }
-    if (thisObject->jsExecutable()->isStrictMode()) {
-        if (propertyName == exec->propertyNames().arguments) {
-            throwTypeError(exec, StrictModeArgumentsAccessError);
-            return;
-        }
-        if (propertyName == exec->propertyNames().caller) {
-            throwTypeError(exec, StrictModeCallerAccessError);
-            return;
-        }
+    if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) {
+        // This will trigger the property to be reified, if this is not already the case!
+        bool okay = thisObject->hasProperty(exec, propertyName);
+        ASSERT_UNUSED(okay, okay);
+        Base::put(thisObject, exec, propertyName, value, slot);
+        return;
     }
     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
         return;

Modified: trunk/Source/_javascript_Core/runtime/JSFunction.h (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSFunction.h	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.h	2011-10-20 01:18:03 UTC (rev 97905)
@@ -41,9 +41,6 @@
 
     EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
 
-    extern const char* StrictModeCallerAccessError;
-    extern const char* StrictModeArgumentsAccessError;
-
     void createDescriptorForThrowingProperty(ExecState*, PropertyDescriptor&, const char* message);
 
     class JSFunction : public JSNonFinalObject {

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2011-10-20 01:18:03 UTC (rev 97905)
@@ -47,6 +47,7 @@
 #include "ErrorPrototype.h"
 #include "FunctionConstructor.h"
 #include "FunctionPrototype.h"
+#include "GetterSetter.h"
 #include "JSBoundFunction.h"
 #include "JSFunction.h"
 #include "JSGlobalObjectFunctions.h"
@@ -305,6 +306,15 @@
     resetPrototype(exec->globalData(), prototype);
 }
 
+void JSGlobalObject::createThrowTypeError(ExecState* exec)
+{
+    JSFunction* thrower = JSFunction::create(exec, this, 0, Identifier(), globalFuncThrowTypeError);
+    GetterSetter* getterSetter = GetterSetter::create(exec);
+    getterSetter->setGetter(exec->globalData(), thrower);
+    getterSetter->setSetter(exec->globalData(), thrower);
+    m_throwTypeErrorGetterSetter.set(exec->globalData(), this, getterSetter);
+}
+
 // Set prototype, and also insert the object prototype at the end of the chain.
 void JSGlobalObject::resetPrototype(JSGlobalData& globalData, JSValue prototype)
 {
@@ -339,6 +349,7 @@
     visitIfNeeded(visitor, &thisObject->m_evalFunction);
     visitIfNeeded(visitor, &thisObject->m_callFunction);
     visitIfNeeded(visitor, &thisObject->m_applyFunction);
+    visitIfNeeded(visitor, &thisObject->m_throwTypeErrorGetterSetter);
 
     visitIfNeeded(visitor, &thisObject->m_objectPrototype);
     visitIfNeeded(visitor, &thisObject->m_functionPrototype);

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2011-10-20 01:18:03 UTC (rev 97905)
@@ -42,6 +42,7 @@
     class Debugger;
     class ErrorConstructor;
     class FunctionPrototype;
+    class GetterSetter;
     class GlobalCodeBlock;
     class NativeErrorConstructor;
     class ProgramCodeBlock;
@@ -90,6 +91,7 @@
         WriteBarrier<JSFunction> m_evalFunction;
         WriteBarrier<JSFunction> m_callFunction;
         WriteBarrier<JSFunction> m_applyFunction;
+        WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter;
 
         WriteBarrier<ObjectPrototype> m_objectPrototype;
         WriteBarrier<FunctionPrototype> m_functionPrototype;
@@ -212,6 +214,12 @@
         JSFunction* evalFunction() const { return m_evalFunction.get(); }
         JSFunction* callFunction() const { return m_callFunction.get(); }
         JSFunction* applyFunction() const { return m_applyFunction.get(); }
+        GetterSetter* throwTypeErrorGetterSetter(ExecState* exec)
+        {
+            if (!m_throwTypeErrorGetterSetter)
+                createThrowTypeError(exec);
+            return m_throwTypeErrorGetterSetter.get();
+        }
 
         ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
         FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
@@ -321,6 +329,8 @@
         void init(JSObject* thisValue);
         void reset(JSValue prototype);
 
+        void createThrowTypeError(ExecState*);
+
         void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count);
         static void clearRareData(JSCell*);
     };

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2011-10-20 01:18:03 UTC (rev 97905)
@@ -594,4 +594,9 @@
     return JSValue::encode(jsString(exec, builder.toUString()));
 }
 
+EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState* exec)
+{
+    return throwVMTypeError(exec);
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h	2011-10-20 01:18:03 UTC (rev 97905)
@@ -47,6 +47,7 @@
     EncodedJSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState*);
     EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState*);
     EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState*);
+    EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState*);
 
     static const double mantissaOverflowLowerBound = 9007199254740992.0;
     double parseIntOverflow(const char*, int length, int radix);

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2011-10-20 01:18:03 UTC (rev 97905)
@@ -396,6 +396,28 @@
     getterSetter->setGetter(globalData, getterFunction);
 }
 
+void JSObject::initializeGetterSetterProperty(ExecState* exec, const Identifier& propertyName, GetterSetter* getterSetter, unsigned attributes)
+{
+    // Set an inital property on an object; the property must not already exist & the attribute flags must be set correctly.
+    ASSERT(structure()->get(exec->globalData(), propertyName) == WTF::notFound);
+    ASSERT(static_cast<bool>(getterSetter->getter()) == static_cast<bool>(attributes & Getter));
+    ASSERT(static_cast<bool>(getterSetter->setter()) == static_cast<bool>(attributes & Setter));
+
+    JSGlobalData& globalData = exec->globalData();
+    PutPropertySlot slot;
+    putDirectInternal(globalData, propertyName, getterSetter, attributes | Getter, true, slot, 0);
+
+    // putDirect will change our Structure if we add a new property. For
+    // getters and setters, though, we also need to change our Structure
+    // if we override an existing non-getter or non-setter.
+    if (slot.type() != PutPropertySlot::NewProperty) {
+        if (!structure()->isDictionary())
+            setStructure(exec->globalData(), Structure::getterSetterTransition(globalData, structure()));
+    }
+
+    structure()->setHasGetterSetterProperties(true);
+}
+
 void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes)
 {
     if (propertyName == exec->propertyNames().underscoreProto) {

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (97904 => 97905)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2011-10-20 00:53:21 UTC (rev 97904)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2011-10-20 01:18:03 UTC (rev 97905)
@@ -45,7 +45,8 @@
             return value.asCell();
         return 0;
     }
-    
+
+    class GetterSetter;
     class HashEntry;
     class InternalFunction;
     class MarkedBlock;
@@ -190,6 +191,7 @@
         void putUndefinedAtDirectOffset(size_t offset) { propertyStorage()[offset].setUndefined(); }
 
         void fillGetterPropertySlot(PropertySlot&, WriteBarrierBase<Unknown>* location);
+        void initializeGetterSetterProperty(ExecState*, const Identifier&, GetterSetter*, unsigned attributes);
 
         virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0);
         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to