#include "config.h"
#include "ObjectConstructor.h"
+#include "ButterflyInlines.h"
+#include "CopiedSpaceInlines.h"
#include "Error.h"
#include "ExceptionHelpers.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Lookup.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "PropertyDescriptor.h"
#include "PropertyNameArray.h"
namespace JSC {
-ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor);
-
static EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*);
void ObjectConstructor::finishCreation(ExecState* exec, ObjectPrototype* objectPrototype)
{
- Base::finishCreation(exec->globalData(), Identifier(exec, "Object"));
+ Base::finishCreation(exec->vm(), Identifier(exec, "Object").string());
// ECMA 15.2.3.1
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
-bool ObjectConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
+bool ObjectConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
{
return getStaticFunctionSlot<JSObject>(exec, ExecState::objectConstructorTable(exec), jsCast<ObjectConstructor*>(cell), propertyName, slot);
}
-bool ObjectConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+bool ObjectConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
{
return getStaticFunctionDescriptor<JSObject>(exec, ExecState::objectConstructorTable(exec), jsCast<ObjectConstructor*>(object), propertyName, descriptor);
}
-// ECMA 15.2.2
-static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
+static ALWAYS_INLINE JSObject* constructObject(ExecState* exec)
{
+ JSGlobalObject* globalObject = exec->callee()->globalObject();
+ ArgList args(exec);
JSValue arg = args.at(0);
if (arg.isUndefinedOrNull())
- return constructEmptyObject(exec, globalObject);
+ return constructEmptyObject(exec, globalObject->objectPrototype());
return arg.toObject(exec, globalObject);
}
static EncodedJSValue JSC_HOST_CALL constructWithObjectConstructor(ExecState* exec)
{
- ArgList args(exec);
- return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
+ return JSValue::encode(constructObject(exec));
}
ConstructType ObjectConstructor::getConstructData(JSCell*, ConstructData& constructData)
static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec)
{
- ArgList args(exec);
- return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
+ return JSValue::encode(constructObject(exec));
}
CallType ObjectConstructor::getCallData(JSCell*, CallData& callData)
EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec)
{
if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, "Requested prototype of a value that is not an object."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested prototype of a value that is not an object.")));
JSObject* object = asObject(exec->argument(0));
if (!object->allowsAccessFrom(exec->trueCallerFrame()))
return JSValue::encode(jsUndefined());
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec)
{
if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, "Requested property descriptor of a value that is not an object."));
- UString propertyName = exec->argument(1).toString(exec)->value(exec);
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property descriptor of a value that is not an object.")));
+ String propertyName = exec->argument(1).toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
JSObject* object = asObject(exec->argument(0));
JSObject* description = constructEmptyObject(exec);
if (!descriptor.isAccessorDescriptor()) {
- description->putDirect(exec->globalData(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
- description->putDirect(exec->globalData(), exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
} else {
ASSERT(descriptor.getter());
ASSERT(descriptor.setter());
- description->putDirect(exec->globalData(), exec->propertyNames().get, descriptor.getter(), 0);
- description->putDirect(exec->globalData(), exec->propertyNames().set, descriptor.setter(), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().get, descriptor.getter(), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().set, descriptor.setter(), 0);
}
- description->putDirect(exec->globalData(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
- description->putDirect(exec->globalData(), exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);
return JSValue::encode(description);
}
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec)
{
if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, "Requested property names of a value that is not an object."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property names of a value that is not an object.")));
PropertyNameArray properties(exec);
asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, IncludeDontEnumProperties);
- JSArray* names = constructEmptyArray(exec);
+ JSArray* names = constructEmptyArray(exec, 0);
size_t numProperties = properties.size();
for (size_t i = 0; i < numProperties; i++)
- names->push(exec, jsOwnedString(exec, properties[i].ustring()));
+ names->push(exec, jsOwnedString(exec, properties[i].string()));
return JSValue::encode(names);
}
EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec)
{
if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, "Requested keys of a value that is not an object."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested keys of a value that is not an object.")));
PropertyNameArray properties(exec);
asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, ExcludeDontEnumProperties);
- JSArray* keys = constructEmptyArray(exec);
+ JSArray* keys = constructEmptyArray(exec, 0);
size_t numProperties = properties.size();
for (size_t i = 0; i < numProperties; i++)
- keys->push(exec, jsOwnedString(exec, properties[i].ustring()));
+ keys->push(exec, jsOwnedString(exec, properties[i].string()));
return JSValue::encode(keys);
}
static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
{
if (!in.isObject()) {
- throwError(exec, createTypeError(exec, "Property description must be an object."));
+ throwError(exec, createTypeError(exec, ASCIILiteral("Property description must be an object.")));
return false;
}
JSObject* description = asObject(in);
if (!get.isUndefined()) {
CallData callData;
if (getCallData(get, callData) == CallTypeNone) {
- throwError(exec, createTypeError(exec, "Getter must be a function."));
+ throwError(exec, createTypeError(exec, ASCIILiteral("Getter must be a function.")));
return false;
}
}
if (!set.isUndefined()) {
CallData callData;
if (getCallData(set, callData) == CallTypeNone) {
- throwError(exec, createTypeError(exec, "Setter must be a function."));
+ throwError(exec, createTypeError(exec, ASCIILiteral("Setter must be a function.")));
return false;
}
}
return true;
if (desc.value()) {
- throwError(exec, createTypeError(exec, "Invalid property. 'value' present on property with getter or setter."));
+ throwError(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'value' present on property with getter or setter.")));
return false;
}
if (desc.writablePresent()) {
- throwError(exec, createTypeError(exec, "Invalid property. 'writable' present on property with getter or setter."));
+ throwError(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'writable' present on property with getter or setter.")));
return false;
}
return true;
EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec)
{
if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, "Properties can only be defined on Objects."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
JSObject* O = asObject(exec->argument(0));
- UString propertyName = exec->argument(1).toString(exec)->value(exec);
+ String propertyName = exec->argument(1).toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
PropertyDescriptor descriptor;
EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec)
{
if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, "Properties can only be defined on Objects."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
return JSValue::encode(defineProperties(exec, asObject(exec->argument(0)), exec->argument(1).toObject(exec)));
}
EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec)
{
if (!exec->argument(0).isObject() && !exec->argument(0).isNull())
- return throwVMError(exec, createTypeError(exec, "Object prototype may only be an Object or null."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null.")));
JSValue proto = exec->argument(0);
- JSObject* newObject = proto.isObject() ? constructEmptyObject(exec, asObject(proto)->inheritorID(exec->globalData())) : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
+ JSObject* newObject = proto.isObject()
+ ? constructEmptyObject(exec, asObject(proto))
+ : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
if (exec->argument(1).isUndefined())
return JSValue::encode(newObject);
if (!exec->argument(1).isObject())
- return throwVMError(exec, createTypeError(exec, "Property descriptor list must be an Object."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Property descriptor list must be an Object.")));
return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1))));
}
// 1. If Type(O) is not Object throw a TypeError exception.
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, "Object.seal can only be called on Objects."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.seal can only be called on Objects.")));
JSObject* object = asObject(obj);
if (isJSFinalObject(object)) {
- object->seal(exec->globalData());
+ object->seal(exec->vm());
return JSValue::encode(obj);
}
}
// 3. Set the [[Extensible]] internal property of O to false.
- object->preventExtensions(exec->globalData());
+ object->preventExtensions(exec->vm());
// 4. Return O.
return JSValue::encode(obj);
// 1. If Type(O) is not Object throw a TypeError exception.
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, "Object.freeze can only be called on Objects."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.freeze can only be called on Objects.")));
JSObject* object = asObject(obj);
- if (isJSFinalObject(object)) {
- object->freeze(exec->globalData());
+ if (isJSFinalObject(object) && !hasIndexedProperties(object->structure()->indexingType())) {
+ object->freeze(exec->vm());
return JSValue::encode(obj);
}
}
// 3. Set the [[Extensible]] internal property of O to false.
- object->preventExtensions(exec->globalData());
+ object->preventExtensions(exec->vm());
// 4. Return O.
return JSValue::encode(obj);
{
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, "Object.preventExtensions can only be called on Objects."));
- asObject(obj)->preventExtensions(exec->globalData());
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.preventExtensions can only be called on Objects.")));
+ asObject(obj)->preventExtensions(exec->vm());
return JSValue::encode(obj);
}
// 1. If Type(O) is not Object throw a TypeError exception.
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, "Object.isSealed can only be called on Objects."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isSealed can only be called on Objects.")));
JSObject* object = asObject(obj);
if (isJSFinalObject(object))
- return JSValue::encode(jsBoolean(object->isSealed(exec->globalData())));
+ return JSValue::encode(jsBoolean(object->isSealed(exec->vm())));
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
// 1. If Type(O) is not Object throw a TypeError exception.
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, "Object.isFrozen can only be called on Objects."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isFrozen can only be called on Objects.")));
JSObject* object = asObject(obj);
if (isJSFinalObject(object))
- return JSValue::encode(jsBoolean(object->isFrozen(exec->globalData())));
+ return JSValue::encode(jsBoolean(object->isFrozen(exec->vm())));
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
{
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, "Object.isExtensible can only be called on Objects."));
+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isExtensible can only be called on Objects.")));
return JSValue::encode(jsBoolean(asObject(obj)->isExtensible()));
}