JavaScriptCore:

        Reviewed by Anders.

        - http://bugs.webkit.org/show_bug.cgi?id=17067
          eliminate attributes parameter from JSObject::put for speed/clarity

        * API/JSCallbackObject.h: Removed attribute arguments.
        * API/JSCallbackObjectFunctions.h:
        (KJS::JSCallbackObject<Base>::put): Ditto.
        * API/JSObjectRef.cpp:
        (JSObjectSetProperty): Use initializeVariable or putDirect when necessary
        to set attribute values.
        * JavaScriptCore.exp: Updated.
        * bindings/objc/objc_runtime.h: Removed attribute arguments.
        * bindings/objc/objc_runtime.mm:
        (ObjcFallbackObjectImp::put): Ditto.
        * bindings/runtime_array.cpp:
        (RuntimeArray::put): Ditto.
        * bindings/runtime_array.h: Ditto.
        * bindings/runtime_object.cpp:
        (RuntimeObjectImp::put): Ditto.
        * bindings/runtime_object.h: Ditto. Also removed canPut which was only
        called from one place in WebCore that can use hasProperty instead.

        * kjs/Activation.h: Removed attribute argument from put and added the new
        initializeVariable function that's used to put variables in variable objects.
        Also made isActivationObject a const member.

        * kjs/JSGlobalObject.cpp:
        (KJS::JSGlobalObject::put): Removed attribute argument.
        (KJS::JSGlobalObject::initializeVariable): Added. Used to give variables
        their initial values, which can include the read-only property.
        (KJS::JSGlobalObject::reset): Removed obsolete comments about flags.
        Removed Internal flag, which is no longer needed.
        * kjs/JSGlobalObject.h: More of the same.

        * kjs/JSVariableObject.h: Added pure virtual initializeVariable function.
        (KJS::JSVariableObject::symbolTablePut): Removed checkReadOnly flag; we always
        check read-only.
        (KJS::JSVariableObject::symbolTableInitializeVariable): Added.

        * kjs/array_instance.cpp:
        (KJS::ArrayInstance::put): Removed attribute argument.
        * kjs/array_instance.h: Ditto.

        * kjs/function.cpp:
        (KJS::FunctionImp::put): Ditto.
        (KJS::Arguments::put): Ditto.
        (KJS::ActivationImp::put): Ditto.
        (KJS::ActivationImp::initializeVariable): Added.
        * kjs/function.h: Removed attribute arguments.

        * kjs/function_object.cpp:
        (KJS::FunctionObjectImp::construct): Removed Internal flag.

        * kjs/lookup.h:
        (KJS::lookupPut): Removed attributes argument. Also changed to use putDirect
        instead of calling JSObject::put.
        (KJS::cacheGlobalObject): Ditto.

        * kjs/nodes.cpp:
        (KJS::ConstDeclNode::handleSlowCase): Call initializeVariable to initialize
        the constant.
        (KJS::ConstDeclNode::evaluateSingle): Ditto.
        (KJS::TryNode::execute): Use putDirect to set up the new object.
        (KJS::FunctionBodyNode::processDeclarations): Removed Internal.
        (KJS::ProgramNode::processDeclarations): Ditto.
        (KJS::EvalNode::processDeclarations): Call initializeVariable to initialize
        the variables and functions.
        (KJS::FuncDeclNode::makeFunction): Removed Internal.
        (KJS::FuncExprNode::evaluate): Ditto.

        * kjs/object.cpp: Removed canPut, which was only being used in one code path,
        not the normal high speed one.
        (KJS::JSObject::put): Removed attribute argument. Moved the logic from
        canPut here, in the one code ath that was still using it.
        * kjs/object.h: Removed Internal attribute, ad canPut function. Removed the
        attributes argument to the put function. Made isActivationObject const.

        * kjs/regexp_object.cpp:
        (KJS::RegExpImp::put): Removed attributes argument.
        (KJS::RegExpImp::putValueProperty): Ditto.
        (KJS::RegExpObjectImp::put): Ditto.
        (KJS::RegExpObjectImp::putValueProperty): Ditto.
        * kjs/regexp_object.h: Ditto.

        * kjs/string_object.cpp:
        (KJS::StringInstance::put): Removed attributes argument.
        * kjs/string_object.h: Ditto.

WebCore:

        Reviewed by Anders.

        - http://bugs.webkit.org/show_bug.cgi?id=17067
          eliminate attributes parameter from JSObject::put for speed/clarity

        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
        (WebCore::JSCSSStyleDeclaration::customPut): Remove attributes argument.

        * bindings/js/JSCanvasPixelArrayCustom.cpp:
        (WebCore::JSCanvasPixelArray::indexGetter): Use early exit idiom.
        (WebCore::JSCanvasPixelArray::indexSetter): Moved length check into the
        CanvasPixelArray object, for consistency with the getter. Removed attributes
        argument.

        * bindings/js/JSDOMWindowCustom.cpp:
        (WebCore::JSDOMWindow::customPut): Removed special case for variable
        initialization, which is not needed since that does use put any more.
        Removed attributes argument.

        * bindings/js/JSEventTargetBase.h:
        (WebCore::JSEventTargetBase::putValueProperty): Removed attributes argument.
        (WebCore::JSEventTargetBase::put): Ditto.
        (WebCore::JSEventTargetPrototype::self): Removed Internal flag.
        * bindings/js/JSEventTargetNode.cpp:
        (WebCore::JSEventTargetNode::put): Removed attributes argument.
        (WebCore::JSEventTargetNode::putValueProperty): Ditto.
        * bindings/js/JSEventTargetNode.h: Ditto.
        * bindings/js/JSHTMLAppletElementCustom.cpp:
        (WebCore::JSHTMLAppletElement::customPut): Ditto.
        * bindings/js/JSHTMLEmbedElementCustom.cpp:
        (WebCore::JSHTMLEmbedElement::customPut): Ditto.
        * bindings/js/JSHTMLInputElementBase.cpp:
        (WebCore::JSHTMLInputElementBase::put): Ditto.
        (WebCore::JSHTMLInputElementBase::putValueProperty): Ditto.
        * bindings/js/JSHTMLInputElementBase.h: Ditto.
        * bindings/js/JSHTMLObjectElementCustom.cpp:
        (WebCore::JSHTMLObjectElement::customPut): Ditto.
        * bindings/js/JSHTMLOptionsCollectionCustom.cpp:
        (WebCore::JSHTMLOptionsCollection::indexSetter): Ditto.
        * bindings/js/JSHTMLSelectElementCustom.cpp:
        (WebCore::JSHTMLSelectElement::indexSetter): Ditto.
        * bindings/js/JSHistoryCustom.cpp:
        (WebCore::JSHistory::customPut): Ditto.
        * bindings/js/JSLocation.cpp:
        (WebCore::JSLocation::put): Ditto.
        * bindings/js/JSLocation.h: Ditto.
        * bindings/js/JSXMLHttpRequest.cpp:
        (WebCore::JSXMLHttpRequest::put): Ditto.
        (WebCore::JSXMLHttpRequest::putValueProperty): Ditto.
        * bindings/js/JSXMLHttpRequest.h: Ditto.

        * bindings/js/kjs_dom.cpp:
        (WebCore::getRuntimeObject): Changed return type to JSObject*.
        * bindings/js/kjs_dom.h: Ditto.

        * bindings/js/kjs_events.cpp:
        (WebCore::JSClipboard::put): Removed attributes argument.
        (WebCore::JSClipboard::putValueProperty): Ditto.
        * bindings/js/kjs_events.h: Ditto.

        * bindings/js/kjs_html.cpp:
        (WebCore::runtimeObjectGetter): Updated for change to getRuntimeObject to
        return a JSObject. Used early exit idiom.
        (WebCore::runtimeObjectPropertyGetter): Ditto.
        (WebCore::runtimeObjectCustomGetOwnPropertySlot): Ditto.
        (WebCore::runtimeObjectCustomPut): Use hasProperty to check for properties
        that we should put with the property syntax instead of canPut.
        (WebCore::runtimeObjectImplementsCall): Ditto.
        (WebCore::runtimeObjectCallAsFunction): Ditto.
        * bindings/js/kjs_html.h: Removed attributes argument to runtimeObjectCustomPut.

        * bindings/js/kjs_window.cpp:
        (KJS::Window::put): Removed attributes argument.
        * bindings/js/kjs_window.h: Ditto.

        * bindings/scripts/CodeGeneratorJS.pm: Removed attributes argument from put,
        putValueProperty, customPut, and indexSetter.

        * html/CanvasPixelArray.h:
        (WebCore::CanvasPixelArray::set): Added index checking here, as in the get
        function. Before, the checking was done in the JavaScript bindings for set.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@30534 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/Activation.h b/JavaScriptCore/kjs/Activation.h
index 0fdd2cc..9291089 100644
--- a/JavaScriptCore/kjs/Activation.h
+++ b/JavaScriptCore/kjs/Activation.h
@@ -58,7 +58,8 @@
         void init(ExecState*);
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        virtual void put(ExecState*, const Identifier&, JSValue*, int attr = None);
+        virtual void put(ExecState*, const Identifier&, JSValue*);
+        virtual void initializeVariable(ExecState*, const Identifier&, JSValue*, unsigned attributes);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
 
         virtual const ClassInfo* classInfo() const { return &info; }
@@ -67,7 +68,7 @@
         virtual void mark();
         void markChildren();
 
-        virtual bool isActivationObject() { return true; }
+        virtual bool isActivationObject() const { return true; }
     
         bool isOnStack() const { return d()->isOnStack; }
         bool needsPop() const { return d()->isOnStack || d()->leftRelic; }
diff --git a/JavaScriptCore/kjs/JSGlobalObject.cpp b/JavaScriptCore/kjs/JSGlobalObject.cpp
index 1c51cb8..aaf11e3 100644
--- a/JavaScriptCore/kjs/JSGlobalObject.cpp
+++ b/JavaScriptCore/kjs/JSGlobalObject.cpp
@@ -152,11 +152,24 @@
     return JSVariableObject::getOwnPropertySlot(exec, propertyName, slot);
 }
 
-void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
+void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
-    if (symbolTablePut(propertyName, value, !(attr & ~DontDelete)))
+    if (symbolTablePut(propertyName, value))
         return;
-    return JSVariableObject::put(exec, propertyName, value, attr);
+    return JSVariableObject::put(exec, propertyName, value);
+}
+
+void JSGlobalObject::initializeVariable(ExecState* exec, const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    if (symbolTableInitializeVariable(propertyName, value, attributes))
+        return;
+
+    JSValue* valueBefore = getDirect(propertyName);
+    JSVariableObject::put(exec, propertyName, value);
+    if (!valueBefore) {
+        if (JSValue* valueAfter = getDirect(propertyName))
+            putDirect(propertyName, valueAfter, attributes);
+    }
 }
 
 static inline JSObject* lastInPrototypeChain(JSObject* object)
@@ -274,11 +287,7 @@
 
     // Set global constructors
 
-    // FIXME: kjs_window.cpp checks Internal/DontEnum as a performance hack, to
-    // see that these values can be put directly without a check for override
-    // properties.
-
-    // FIXME: These properties should be handled by a static hash table.
+    // FIXME: These properties could be handled by a static hash table.
 
     putDirect("Object", d()->objectConstructor, DontEnum);
     putDirect("Function", d()->functionConstructor, DontEnum);
@@ -289,12 +298,12 @@
     putDirect("Date", d()->dateConstructor, DontEnum);
     putDirect("RegExp", d()->regExpConstructor, DontEnum);
     putDirect("Error", d()->errorConstructor, DontEnum);
-    putDirect("EvalError", d()->evalErrorConstructor, Internal);
-    putDirect("RangeError", d()->rangeErrorConstructor, Internal);
-    putDirect("ReferenceError", d()->referenceErrorConstructor, Internal);
-    putDirect("SyntaxError", d()->syntaxErrorConstructor, Internal);
-    putDirect("TypeError", d()->typeErrorConstructor, Internal);
-    putDirect("URIError", d()->URIErrorConstructor, Internal);
+    putDirect("EvalError", d()->evalErrorConstructor);
+    putDirect("RangeError", d()->rangeErrorConstructor);
+    putDirect("ReferenceError", d()->referenceErrorConstructor);
+    putDirect("SyntaxError", d()->syntaxErrorConstructor);
+    putDirect("TypeError", d()->typeErrorConstructor);
+    putDirect("URIError", d()->URIErrorConstructor);
 
     // Set global values.
 
diff --git a/JavaScriptCore/kjs/JSGlobalObject.h b/JavaScriptCore/kjs/JSGlobalObject.h
index 9fd2eb4..d6c055e 100644
--- a/JavaScriptCore/kjs/JSGlobalObject.h
+++ b/JavaScriptCore/kjs/JSGlobalObject.h
@@ -149,7 +149,8 @@
         virtual ~JSGlobalObject();
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        virtual void put(ExecState*, const Identifier&, JSValue*, int attr = None);
+        virtual void put(ExecState*, const Identifier&, JSValue*);
+        virtual void initializeVariable(ExecState*, const Identifier&, JSValue*, unsigned attributes);
 
         // Linked list of all global objects.
         static JSGlobalObject* head() { return s_head; }
diff --git a/JavaScriptCore/kjs/JSVariableObject.h b/JavaScriptCore/kjs/JSVariableObject.h
index e82013b..e22e9c6 100644
--- a/JavaScriptCore/kjs/JSVariableObject.h
+++ b/JavaScriptCore/kjs/JSVariableObject.h
@@ -42,6 +42,8 @@
         
         void saveLocalStorage(SavedProperties&) const;
         void restoreLocalStorage(const SavedProperties&);
+
+        virtual void initializeVariable(ExecState*, const Identifier&, JSValue*, unsigned attributes) = 0;
         
         virtual bool deleteProperty(ExecState*, const Identifier&);
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -77,7 +79,8 @@
         }
 
         bool symbolTableGet(const Identifier&, PropertySlot&);
-        bool symbolTablePut(const Identifier&, JSValue*, bool checkReadOnly);
+        bool symbolTablePut(const Identifier&, JSValue*);
+        bool symbolTableInitializeVariable(const Identifier&, JSValue*, unsigned attributes);
 
         JSVariableObjectData* d;
     };
@@ -104,18 +107,29 @@
         return false;
     }
 
-    inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value, bool checkReadOnly)
+    inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value)
     {
         size_t index = symbolTable().get(propertyName.ustring().rep());
         if (index == missingSymbolMarker())
             return false;
         LocalStorageEntry& entry = d->localStorage[index];
-        if (checkReadOnly && (entry.attributes & ReadOnly))
+        if (entry.attributes & ReadOnly)
             return true;
         entry.value = value;
         return true;
     }
 
+    inline bool JSVariableObject::symbolTableInitializeVariable(const Identifier& propertyName, JSValue* value, unsigned attributes)
+    {
+        size_t index = symbolTable().get(propertyName.ustring().rep());
+        if (index == missingSymbolMarker())
+            return false;
+        LocalStorageEntry& entry = d->localStorage[index];
+        entry.value = value;
+        entry.attributes = attributes;
+        return true;
+    }
+
 } // namespace KJS
 
 #endif // JSVariableObject_h
diff --git a/JavaScriptCore/kjs/array_instance.cpp b/JavaScriptCore/kjs/array_instance.cpp
index 212a6b5..1118f40 100644
--- a/JavaScriptCore/kjs/array_instance.cpp
+++ b/JavaScriptCore/kjs/array_instance.cpp
@@ -184,12 +184,12 @@
 }
 
 // ECMA 15.4.5.1
-void ArrayInstance::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attributes)
+void ArrayInstance::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
     bool isArrayIndex;
     unsigned i = propertyName.toArrayIndex(&isArrayIndex);
     if (isArrayIndex) {
-        put(exec, i, value, attributes);
+        put(exec, i, value);
         return;
     }
 
@@ -203,13 +203,13 @@
         return;
     }
 
-    JSObject::put(exec, propertyName, value, attributes);
+    JSObject::put(exec, propertyName, value);
 }
 
-void ArrayInstance::put(ExecState* exec, unsigned i, JSValue* value, int attributes)
+void ArrayInstance::put(ExecState* exec, unsigned i, JSValue* value)
 {
     if (i > maxArrayIndex) {
-        put(exec, Identifier::from(i), value, attributes);
+        put(exec, Identifier::from(i), value);
         return;
     }
 
diff --git a/JavaScriptCore/kjs/array_instance.h b/JavaScriptCore/kjs/array_instance.h
index 913d0cd..d7efdde 100644
--- a/JavaScriptCore/kjs/array_instance.h
+++ b/JavaScriptCore/kjs/array_instance.h
@@ -36,8 +36,8 @@
 
     virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
     virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
-    virtual void put(ExecState*, const Identifier& propertyName, JSValue*, int attributes = None);
-    virtual void put(ExecState*, unsigned propertyName, JSValue*, int attributes = None);
+    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
+    virtual void put(ExecState*, unsigned propertyName, JSValue*);
     virtual bool deleteProperty(ExecState *, const Identifier& propertyName);
     virtual bool deleteProperty(ExecState *, unsigned propertyName);
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
diff --git a/JavaScriptCore/kjs/function.cpp b/JavaScriptCore/kjs/function.cpp
index 4ba54fd..b996122 100644
--- a/JavaScriptCore/kjs/function.cpp
+++ b/JavaScriptCore/kjs/function.cpp
@@ -148,11 +148,11 @@
     return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot);
 }
 
-void FunctionImp::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
+void FunctionImp::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
         return;
-    InternalFunctionImp::put(exec, propertyName, value, attr);
+    InternalFunctionImp::put(exec, propertyName, value);
 }
 
 bool FunctionImp::deleteProperty(ExecState* exec, const Identifier& propertyName)
@@ -320,13 +320,12 @@
   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
 }
 
-void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
+void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
-  if (indexToNameMap.isMapped(propertyName)) {
-    _activationObject->put(exec, indexToNameMap[propertyName], value, attr);
-  } else {
-    JSObject::put(exec, propertyName, value, attr);
-  }
+    if (indexToNameMap.isMapped(propertyName))
+        _activationObject->put(exec, indexToNameMap[propertyName], value);
+    else
+        JSObject::put(exec, propertyName, value);
 }
 
 bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName) 
@@ -417,18 +416,28 @@
     return JSVariableObject::deleteProperty(exec, propertyName);
 }
 
-void ActivationImp::put(ExecState*, const Identifier& propertyName, JSValue* value, int attr)
+void ActivationImp::put(ExecState*, const Identifier& propertyName, JSValue* value)
 {
-    // If any bits other than DontDelete are set, then we bypass the read-only check.
-    bool checkReadOnly = !(attr & ~DontDelete);
-    if (symbolTablePut(propertyName, value, checkReadOnly))
+    if (symbolTablePut(propertyName, value))
         return;
 
     // We don't call through to JSObject because __proto__ and getter/setter 
     // properties are non-standard extensions that other implementations do not
     // expose in the activation object.
     ASSERT(!_prop.hasGetterSetterProperties());
-    _prop.put(propertyName, value, attr, checkReadOnly);
+    _prop.put(propertyName, value, 0, true);
+}
+
+void ActivationImp::initializeVariable(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    if (symbolTableInitializeVariable(propertyName, value, attributes))
+        return;
+
+    // We don't call through to JSObject because __proto__ and getter/setter 
+    // properties are non-standard extensions that other implementations do not
+    // expose in the activation object.
+    ASSERT(!_prop.hasGetterSetterProperties());
+    _prop.put(propertyName, value, attributes, true);
 }
 
 void ActivationImp::markChildren()
diff --git a/JavaScriptCore/kjs/function.h b/JavaScriptCore/kjs/function.h
index a45221e..be3e136 100644
--- a/JavaScriptCore/kjs/function.h
+++ b/JavaScriptCore/kjs/function.h
@@ -61,7 +61,7 @@
     FunctionImp(ExecState*, const Identifier& name, FunctionBodyNode*, const ScopeChain&);
 
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-    virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
+    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
 
     virtual bool implementsConstruct() const { return true; }
@@ -112,7 +112,7 @@
     Arguments(ExecState*, FunctionImp* func, const List& args, ActivationImp* act);
     virtual void mark();
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-    virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
+    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
diff --git a/JavaScriptCore/kjs/function_object.cpp b/JavaScriptCore/kjs/function_object.cpp
index 1e83b8b..73d2ba9 100644
--- a/JavaScriptCore/kjs/function_object.cpp
+++ b/JavaScriptCore/kjs/function_object.cpp
@@ -225,7 +225,7 @@
     JSObject* objCons = exec->lexicalGlobalObject()->objectConstructor();
     JSObject* prototype = objCons->construct(exec, exec->emptyList());
     prototype->putDirect(exec->propertyNames().constructor, fimp, DontEnum);
-    fimp->putDirect(exec->propertyNames().prototype, prototype, Internal | DontDelete);
+    fimp->putDirect(exec->propertyNames().prototype, prototype, DontDelete);
     return fimp;
 }
 
diff --git a/JavaScriptCore/kjs/lookup.h b/JavaScriptCore/kjs/lookup.h
index 199c9d9..d477f88 100644
--- a/JavaScriptCore/kjs/lookup.h
+++ b/JavaScriptCore/kjs/lookup.h
@@ -232,8 +232,7 @@
    */
   template <class ThisImp>
   inline bool lookupPut(ExecState* exec, const Identifier& propertyName,
-                        JSValue* value, int attr,
-                        const HashTable* table, ThisImp* thisObj)
+                        JSValue* value, const HashTable* table, ThisImp* thisObj)
   {
     const HashEntry* entry = Lookup::findEntry(table, propertyName);
 
@@ -241,9 +240,9 @@
       return false;
 
     if (entry->attr & Function) // function: put as override property
-      thisObj->JSObject::put(exec, propertyName, value, attr);
+      thisObj->putDirect(propertyName, value);
     else if (!(entry->attr & ReadOnly))
-      thisObj->putValueProperty(exec, entry->value.intValue, value, attr);
+      thisObj->putValueProperty(exec, entry->value.intValue, value);
 
     return true;
   }
@@ -256,11 +255,10 @@
    */
   template <class ThisImp, class ParentImp>
   inline void lookupPut(ExecState* exec, const Identifier& propertyName,
-                        JSValue* value, int attr,
-                        const HashTable* table, ThisImp* thisObj)
+                        JSValue* value, const HashTable* table, ThisImp* thisObj)
   {
-    if (!lookupPut<ThisImp>(exec, propertyName, value, attr, table, thisObj))
-      thisObj->ParentImp::put(exec, propertyName, value, attr); // not found: forward to parent
+    if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
+      thisObj->ParentImp::put(exec, propertyName, value); // not found: forward to parent
   }
 
   /**
@@ -280,7 +278,7 @@
       return static_cast<JSObject* >(obj);
     }
     JSObject* newObject = new ClassCtor(exec);
-    globalObject->putDirect(propertyName, newObject, Internal | DontEnum);
+    globalObject->putDirect(propertyName, newObject, DontEnum);
     return newObject;
   }
 
diff --git a/JavaScriptCore/kjs/nodes.cpp b/JavaScriptCore/kjs/nodes.cpp
index 57bae46..f852eb7 100644
--- a/JavaScriptCore/kjs/nodes.cpp
+++ b/JavaScriptCore/kjs/nodes.cpp
@@ -3568,15 +3568,12 @@
         base = *iter;
         if (base->getPropertySlot(exec, m_ident, slot))
             break;
-
         ++iter;
     } while (iter != end);
 
-    unsigned flags = 0;
-    base->getPropertyAttributes(m_ident, flags);
-    flags |= ReadOnly;
+    ASSERT(base->isActivationObject() || base->isGlobalObject());
 
-    base->put(exec, m_ident, val, flags);
+    static_cast<JSVariableObject*>(base)->initializeVariable(exec, m_ident, val, ReadOnly);
 }
 
 // ECMA 12.2
@@ -3584,7 +3581,7 @@
 {
     ASSERT(exec->variableObject()->hasOwnProperty(exec, m_ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations.
     const ScopeChain& chain = exec->scopeChain();
-    JSObject* variableObject = exec->variableObject();
+    JSVariableObject* variableObject = exec->variableObject();
 
     ASSERT(!chain.isEmpty());
 
@@ -3593,11 +3590,10 @@
     if (m_init) {
         if (inGlobalScope) {
             JSValue* val = m_init->evaluate(exec);
-            int flags = Internal;
+            unsigned attributes = ReadOnly;
             if (exec->codeType() != EvalCode)
-                flags |= DontDelete;
-            flags |= ReadOnly;
-            variableObject->put(exec, m_ident, val, flags);
+                attributes |= DontDelete;
+            variableObject->initializeVariable(exec, m_ident, val, attributes);
         } else {
             JSValue* val = m_init->evaluate(exec);
             KJS_CHECKEXCEPTIONVOID
@@ -3608,11 +3604,7 @@
             if (chain.top() != variableObject)
                 return handleSlowCase(exec, chain, val);
 
-            unsigned flags = 0;
-            variableObject->getPropertyAttributes(m_ident, flags);
-            flags |= ReadOnly;
-
-            variableObject->put(exec, m_ident, val, flags);
+            variableObject->initializeVariable(exec, m_ident, val, ReadOnly);
         }
     }
 }
@@ -4303,7 +4295,7 @@
 
     if (m_catchBlock && exec->completionType() == Throw) {
         JSObject* obj = new JSObject;
-        obj->put(exec, m_exceptionIdent, result, DontDelete);
+        obj->putDirect(m_exceptionIdent, result, DontDelete);
         exec->dynamicGlobalObject()->tearOffActivation(exec);
         exec->pushScope(obj);
         result = m_catchBlock->execute(exec);
@@ -4485,7 +4477,7 @@
     if (totalSize > localStorage.capacity()) // Doing this check inline avoids function call overhead.
         localStorage.reserveCapacity(totalSize);
 
-    int minAttributes = Internal | DontDelete;
+    int minAttributes = DontDelete;
 
     // In order for our localStorage indexes to be correct, we must match the
     // order of addition in initializeSymbolTable().
@@ -4532,7 +4524,7 @@
     // leave uninitialized entries, which would crash GC during the mark phase.
     localStorage.reserveCapacity(localStorage.size() + m_varStack.size() + m_functionStack.size());
 
-    int minAttributes = Internal | DontDelete;
+    int minAttributes = DontDelete;
 
     // In order for our localStorage indexes to be correct, we must match the
     // order of addition in initializeSymbolTable().
@@ -4577,21 +4569,19 @@
 
     JSVariableObject* variableObject = exec->variableObject();
 
-    int minAttributes = Internal;
-
     for (i = 0, size = m_varStack.size(); i < size; ++i) {
         Identifier& ident = m_varStack[i].first;
         if (variableObject->hasProperty(exec, ident))
             continue;
-        int attributes = minAttributes;
+        int attributes = 0;
         if (m_varStack[i].second & DeclarationStacks::IsConstant)
-            attributes |= ReadOnly;
-        variableObject->put(exec, ident, jsUndefined(), attributes);
+            attributes = ReadOnly;
+        variableObject->initializeVariable(exec, ident, jsUndefined(), attributes);
     }
 
     for (i = 0, size = m_functionStack.size(); i < size; ++i) {
-        FuncDeclNode* node = m_functionStack[i];
-        variableObject->put(exec, node->m_ident, node->makeFunction(exec), minAttributes);
+        FuncDeclNode* funcDecl = m_functionStack[i];
+        variableObject->initializeVariable(exec, funcDecl->m_ident, funcDecl->makeFunction(exec), 0);
     }
 }
 
@@ -4670,7 +4660,7 @@
 
     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
-    func->putDirect(exec->propertyNames().prototype, proto, Internal | DontDelete);
+    func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
     func->putDirect(exec->propertyNames().length, jsNumber(m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
     return func;
 }
@@ -4707,10 +4697,10 @@
     FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain());
     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
-    func->putDirect(exec->propertyNames().prototype, proto, Internal | DontDelete);
+    func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
 
     if (named) {
-        functionScopeObject->putDirect(m_ident, func, Internal | ReadOnly | (exec->codeType() == EvalCode ? 0 : DontDelete));
+        functionScopeObject->putDirect(m_ident, func, ReadOnly | (exec->codeType() == EvalCode ? 0 : DontDelete));
         exec->popScope();
     }
 
diff --git a/JavaScriptCore/kjs/object.cpp b/JavaScriptCore/kjs/object.cpp
index 8c6a154..9f1c2cf 100644
--- a/JavaScriptCore/kjs/object.cpp
+++ b/JavaScriptCore/kjs/object.cpp
@@ -204,7 +204,7 @@
 }
 
 // ECMA 8.6.2.2
-void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *value, int attr)
+void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *value)
 {
   ASSERT(value);
 
@@ -220,10 +220,6 @@
     return;
   }
 
-  // The put calls from JavaScript execution either have no attributes set, or in some cases
-  // have DontDelete set. For those calls, respect the ReadOnly flag.
-  bool checkReadOnly = !(attr & ~DontDelete);
-
   // Check if there are any setters or getters in the prototype chain
   JSObject *obj = this;
   bool hasGettersOrSetters = false;
@@ -240,12 +236,12 @@
   }
   
   if (hasGettersOrSetters) {
-    if (checkReadOnly && !canPut(exec, propertyName))
-      return;
+    unsigned attributes;
+    if (_prop.get(propertyName, attributes) && attributes & ReadOnly)
+        return;
 
     obj = this;
     while (true) {
-      unsigned attributes;
       if (JSValue *gs = obj->_prop.get(propertyName, attributes)) {
         if (attributes & GetterSetter) {
           JSObject *setterFunc = static_cast<GetterSetterImp *>(gs)->getSetter();
@@ -274,29 +270,12 @@
     }
   }
   
-  _prop.put(propertyName, value, attr, checkReadOnly);
+  _prop.put(propertyName, value, 0, true);
 }
 
-void JSObject::put(ExecState *exec, unsigned propertyName,
-                     JSValue *value, int attr)
+void JSObject::put(ExecState* exec, unsigned propertyName, JSValue* value)
 {
-  put(exec, Identifier::from(propertyName), value, attr);
-}
-
-// ECMA 8.6.2.3
-bool JSObject::canPut(ExecState *, const Identifier &propertyName) const
-{
-  unsigned attributes;
-    
-  // Don't look in the prototype here. We can always put an override
-  // in the object, even if the prototype has a ReadOnly property.
-  // Also, there is no need to check the static property table, as this
-  // would have been done by the subclass already.
-
-  if (!_prop.get(propertyName, attributes))
-    return true;
-
-  return !(attributes & ReadOnly);
+    put(exec, Identifier::from(propertyName), value);
 }
 
 // ECMA 8.6.2.4
diff --git a/JavaScriptCore/kjs/object.h b/JavaScriptCore/kjs/object.h
index 8a914ff..2d4e010 100644
--- a/JavaScriptCore/kjs/object.h
+++ b/JavaScriptCore/kjs/object.h
@@ -47,9 +47,8 @@
                    ReadOnly     = 1 << 1, // property can be only read, not written
                    DontEnum     = 1 << 2, // property doesn't appear in (for .. in ..)
                    DontDelete   = 1 << 3, // property can't be deleted
-                   Internal     = 1 << 4, // an internal property, set to bypass checks
-                   Function     = 1 << 5, // property is a function - only used by static hashtables
-                   GetterSetter = 1 << 6 }; // property is a getter or setter
+                   Function     = 1 << 4, // property is a function - only used by static hashtables
+                   GetterSetter = 1 << 5 }; // property is a getter or setter
 
   /**
    * Class Information
@@ -243,24 +242,8 @@
      * @param propertyName The name of the property to set
      * @param propertyValue The value to set
      */
-    virtual void put(ExecState* exec, const Identifier &propertyName, JSValue* value, int attr = None);
-    virtual void put(ExecState* exec, unsigned propertyName, JSValue* value, int attr = None);
-
-    /**
-     * Used to check whether or not a particular property is allowed to be set
-     * on an object
-     *
-     * See ECMA 8.6.2.3
-     *
-     * @param exec The current execution state
-     * @param propertyName The name of the property
-     * @return true if the property can be set, otherwise false
-     */
-    /**
-     * Implementation of the [[CanPut]] internal property (implemented by all
-     * Objects)
-     */
-    virtual bool canPut(ExecState *exec, const Identifier &propertyName) const;
+    virtual void put(ExecState*, const Identifier& propertyName, JSValue* value);
+    virtual void put(ExecState*, unsigned propertyName, JSValue* value);
 
     /**
      * Checks if a property is enumerable, that is if it doesn't have the DontEnum
@@ -447,7 +430,7 @@
     void saveProperties(SavedProperties &p) const { _prop.save(p); }
     void restoreProperties(const SavedProperties &p) { _prop.restore(p); }
 
-    virtual bool isActivationObject() { return false; }
+    virtual bool isActivationObject() const { return false; }
     virtual bool isGlobalObject() const { return false; }
 
   protected:
diff --git a/JavaScriptCore/kjs/regexp_object.cpp b/JavaScriptCore/kjs/regexp_object.cpp
index 20ec7ea..871d764 100644
--- a/JavaScriptCore/kjs/regexp_object.cpp
+++ b/JavaScriptCore/kjs/regexp_object.cpp
@@ -173,12 +173,12 @@
     return 0;
 }
 
-void RegExpImp::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attributes)
+void RegExpImp::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
-    lookupPut<RegExpImp, JSObject>(exec, propertyName, value, attributes, &RegExpImpTable, this);
+    lookupPut<RegExpImp, JSObject>(exec, propertyName, value, &RegExpImpTable, this);
 }
 
-void RegExpImp::putValueProperty(ExecState* exec, int token, JSValue* value, int)
+void RegExpImp::putValueProperty(ExecState* exec, int token, JSValue* value)
 {
     UNUSED_PARAM(token);
     ASSERT(token == LastIndex);
@@ -410,12 +410,12 @@
   return jsString("");
 }
 
-void RegExpObjectImp::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
+void RegExpObjectImp::put(ExecState *exec, const Identifier &propertyName, JSValue *value)
 {
-  lookupPut<RegExpObjectImp, InternalFunctionImp>(exec, propertyName, value, attr, &RegExpObjectImpTable, this);
+    lookupPut<RegExpObjectImp, InternalFunctionImp>(exec, propertyName, value, &RegExpObjectImpTable, this);
 }
 
-void RegExpObjectImp::putValueProperty(ExecState *exec, int token, JSValue *value, int)
+void RegExpObjectImp::putValueProperty(ExecState *exec, int token, JSValue *value)
 {
   switch (token) {
     case Input:
diff --git a/JavaScriptCore/kjs/regexp_object.h b/JavaScriptCore/kjs/regexp_object.h
index 1ce2f16..c69e8f7 100644
--- a/JavaScriptCore/kjs/regexp_object.h
+++ b/JavaScriptCore/kjs/regexp_object.h
@@ -53,8 +53,8 @@
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
         bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         JSValue* getValueProperty(ExecState*, int token) const;
-        void put(ExecState*, const Identifier&, JSValue*, int attributes = None);
-        void putValueProperty(ExecState*, int token, JSValue*, int attributes);
+        void put(ExecState*, const Identifier&, JSValue*);
+        void putValueProperty(ExecState*, int token, JSValue*);
 
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
@@ -79,8 +79,8 @@
         virtual JSObject* construct(ExecState*, const List&);
         JSObject* createRegExpImp(ExecState*, PassRefPtr<RegExp>);
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
-        virtual void put(ExecState*, const Identifier&, JSValue*, int attributes = None);
-        void putValueProperty(ExecState*, int token, JSValue*, int attributes);
+        virtual void put(ExecState*, const Identifier&, JSValue*);
+        void putValueProperty(ExecState*, int token, JSValue*);
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         JSValue* getValueProperty(ExecState*, int token) const;
         virtual const ClassInfo* classInfo() const { return &info; }
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index 37535f0..04d8ebb 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -108,11 +108,11 @@
     return JSObject::getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
 }
 
-void StringInstance::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
+void StringInstance::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
-  if (propertyName == exec->propertyNames().length)
-    return;
-  JSObject::put(exec, propertyName, value, attr);
+    if (propertyName == exec->propertyNames().length)
+        return;
+    JSObject::put(exec, propertyName, value);
 }
 
 bool StringInstance::deleteProperty(ExecState *exec, const Identifier &propertyName)
diff --git a/JavaScriptCore/kjs/string_object.h b/JavaScriptCore/kjs/string_object.h
index 3bc9cb2..8508788 100644
--- a/JavaScriptCore/kjs/string_object.h
+++ b/JavaScriptCore/kjs/string_object.h
@@ -38,7 +38,7 @@
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
 
-    virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*, int attr = None);
+    virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*);
     virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName);
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);