#include "CopiedSpaceInlines.h"
#include "Error.h"
#include "ExceptionHelpers.h"
-#include "JSFunction.h"
#include "JSArray.h"
+#include "JSCInlines.h"
+#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "JSGlobalObjectFunctions.h"
#include "Lookup.h"
#include "ObjectPrototype.h"
-#include "JSCInlines.h"
#include "PropertyDescriptor.h"
#include "PropertyNameArray.h"
#include "StackVisitor.h"
+#include "Symbol.h"
namespace JSC {
-static EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState*);
-static EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorSetPrototypeOf(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorIs(ExecState*);
}
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ObjectConstructor);
-const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::objectConstructorTable, CREATE_METHOD_TABLE(ObjectConstructor) };
+const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_info, &objectConstructorTable, CREATE_METHOD_TABLE(ObjectConstructor) };
/* Source for ObjectConstructor.lut.h
@begin objectConstructorTable
getPrototypeOf objectConstructorGetPrototypeOf DontEnum|Function 1
+ setPrototypeOf objectConstructorSetPrototypeOf DontEnum|Function 2
getOwnPropertyDescriptor objectConstructorGetOwnPropertyDescriptor DontEnum|Function 2
getOwnPropertyNames objectConstructorGetOwnPropertyNames DontEnum|Function 1
keys objectConstructorKeys DontEnum|Function 1
isSealed objectConstructorIsSealed DontEnum|Function 1
isFrozen objectConstructorIsFrozen DontEnum|Function 1
isExtensible objectConstructorIsExtensible DontEnum|Function 1
+ is objectConstructorIs DontEnum|Function 2
+ assign objectConstructorAssign DontEnum|Function 2
@end
*/
{
}
-void ObjectConstructor::finishCreation(VM& vm, ObjectPrototype* objectPrototype)
+void ObjectConstructor::finishCreation(VM& vm, JSGlobalObject* globalObject, ObjectPrototype* objectPrototype)
{
- Base::finishCreation(vm, Identifier(&vm, "Object").string());
+ Base::finishCreation(vm, objectPrototype->classInfo()->className);
// ECMA 15.2.3.1
putDirectWithoutTransition(vm, vm.propertyNames->prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+
+ if (!globalObject->runtimeFlags().isSymbolDisabled())
+ JSC_NATIVE_FUNCTION("getOwnPropertySymbols", objectConstructorGetOwnPropertySymbols, DontEnum, 1);
+
+ JSC_NATIVE_FUNCTION(vm.propertyNames->getPrototypeOfPrivateName, objectConstructorGetPrototypeOf, DontEnum, 1);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->getOwnPropertyNamesPrivateName, objectConstructorGetOwnPropertyNames, DontEnum, 1);
+}
+
+JSFunction* ObjectConstructor::addDefineProperty(ExecState* exec, JSGlobalObject* globalObject)
+{
+ VM& vm = exec->vm();
+ JSFunction* definePropertyFunction = JSFunction::create(vm, globalObject, 3, vm.propertyNames->defineProperty.string(), objectConstructorDefineProperty);
+ putDirectWithoutTransition(vm, vm.propertyNames->defineProperty, definePropertyFunction, DontEnum);
+ return definePropertyFunction;
}
bool ObjectConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
{
- return getStaticFunctionSlot<JSObject>(exec, ExecState::objectConstructorTable(exec->vm()), jsCast<ObjectConstructor*>(object), propertyName, slot);
+ return getStaticFunctionSlot<JSObject>(exec, objectConstructorTable, jsCast<ObjectConstructor*>(object), propertyName, slot);
}
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec)
return StackVisitor::Continue;
}
- if (m_object->allowsAccessFrom(visitor->callFrame()))
- m_result = JSValue::encode(m_object->prototype());
- return StackVisitor::Done;
-}
+ if (m_object->allowsAccessFrom(visitor->callFrame()))
+ m_result = JSValue::encode(m_object->prototype());
+ return StackVisitor::Done;
+ }
private:
bool m_hasSkippedFirstFrame;
EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec)
{
- if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested prototype of a value that is not an object.")));
- JSObject* object = asObject(exec->argument(0));
+ JSObject* object = exec->argument(0).toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
ObjectConstructorGetPrototypeOfFunctor functor(object);
exec->iterate(functor);
return functor.result();
}
+EncodedJSValue JSC_HOST_CALL objectConstructorSetPrototypeOf(ExecState* exec)
+{
+ JSValue objectValue = exec->argument(0);
+ if (objectValue.isUndefinedOrNull())
+ return throwVMTypeError(exec);
+
+ JSValue protoValue = exec->argument(1);
+ if (!protoValue.isObject() && !protoValue.isNull())
+ return throwVMTypeError(exec);
+
+ JSObject* object = objectValue.toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(objectValue);
+
+ if (!checkProtoSetterAccessAllowed(exec, object))
+ return JSValue::encode(objectValue);
+
+ if (!object->isExtensible())
+ return throwVMError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
+
+ if (!object->setPrototypeWithCycleCheck(exec, protoValue)) {
+ exec->vm().throwException(exec, createError(exec, ASCIILiteral("cyclic __proto__ value")));
+ return JSValue::encode(jsUndefined());
+ }
+
+ return JSValue::encode(objectValue);
+}
+
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec)
{
- if (!exec->argument(0).isObject())
- 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);
+ JSObject* object = exec->argument(0).toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
+ auto propertyName = exec->argument(1).toPropertyKey(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
- JSObject* object = asObject(exec->argument(0));
PropertyDescriptor descriptor;
- if (!object->getOwnPropertyDescriptor(exec, Identifier(exec, propertyName), descriptor))
+ if (!object->getOwnPropertyDescriptor(exec, propertyName, descriptor))
return JSValue::encode(jsUndefined());
if (exec->hadException())
return JSValue::encode(jsUndefined());
// FIXME: Use the enumeration cache.
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec)
{
- if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property names of a value that is not an object.")));
+ JSObject* object = exec->argument(0).toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
PropertyNameArray properties(exec);
- asObject(exec->argument(0))->methodTable(exec->vm())->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, IncludeDontEnumProperties);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include));
JSArray* names = constructEmptyArray(exec, 0);
size_t numProperties = properties.size();
for (size_t i = 0; i < numProperties; i++)
return JSValue::encode(names);
}
+// FIXME: Use the enumeration cache.
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertySymbols(ExecState* exec)
+{
+ JSObject* object = exec->argument(0).toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
+ PropertyNameArray properties(exec);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
+ JSArray* names = constructEmptyArray(exec, 0);
+ size_t numProperties = properties.size();
+ for (size_t i = 0; i < numProperties; i++) {
+ auto impl = properties[i].impl();
+ if (impl->isSymbol() && !exec->propertyNames().isPrivateName(*impl))
+ names->push(exec, Symbol::create(exec->vm(), static_cast<SymbolImpl&>(*impl)));
+ }
+ return JSValue::encode(names);
+}
+
// FIXME: Use the enumeration cache.
EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec)
{
- if (!exec->argument(0).isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested keys of a value that is not an object.")));
+ JSObject* object = exec->argument(0).toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
PropertyNameArray properties(exec);
- asObject(exec->argument(0))->methodTable(exec->vm())->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, ExcludeDontEnumProperties);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode());
JSArray* keys = constructEmptyArray(exec, 0);
size_t numProperties = properties.size();
for (size_t i = 0; i < numProperties; i++)
if (!exec->argument(0).isObject())
return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
JSObject* O = asObject(exec->argument(0));
- String propertyName = exec->argument(1).toString(exec)->value(exec);
+ auto propertyName = exec->argument(1).toPropertyKey(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
PropertyDescriptor descriptor;
return JSValue::encode(jsNull());
ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
ASSERT(!exec->hadException());
- O->methodTable(exec->vm())->defineOwnProperty(O, exec, Identifier(exec, propertyName), descriptor, true);
+ O->methodTable(exec->vm())->defineOwnProperty(O, exec, propertyName, descriptor, true);
return JSValue::encode(O);
}
static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* properties)
{
PropertyNameArray propertyNames(exec);
- asObject(properties)->methodTable(exec->vm())->getOwnPropertyNames(asObject(properties), exec, propertyNames, ExcludeDontEnumProperties);
+ asObject(properties)->methodTable(exec->vm())->getOwnPropertyNames(asObject(properties), exec, propertyNames, EnumerationMode(DontEnumPropertiesMode::Exclude, SymbolPropertiesMode::Include));
size_t numProperties = propertyNames.size();
Vector<PropertyDescriptor> descriptors;
MarkedArgumentBuffer markBuffer;
}
}
for (size_t i = 0; i < numProperties; i++) {
- object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyNames[i], descriptors[i], true);
+ Identifier propertyName = propertyNames[i];
+ if (exec->propertyNames().isPrivateName(propertyName))
+ continue;
+ object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyName, descriptors[i], true);
if (exec->hadException())
return jsNull();
}
EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
{
- // 1. If Type(O) is not Object throw a TypeError exception.
+ // 1. If Type(O) is not Object, return O.
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.seal can only be called on Objects.")));
+ return JSValue::encode(obj);
JSObject* object = asObject(obj);
if (isJSFinalObject(object)) {
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
- object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
PropertyNameArray::const_iterator end = properties.end();
for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ Identifier propertyName = *iter;
+ if (exec->propertyNames().isPrivateName(propertyName))
+ continue;
// a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
PropertyDescriptor desc;
- if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+ if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
continue;
// b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
desc.setConfigurable(false);
// c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
- object->methodTable(exec->vm())->defineOwnProperty(object, exec, *iter, desc, true);
+ object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyName, desc, true);
if (exec->hadException())
return JSValue::encode(obj);
}
return JSValue::encode(obj);
}
-EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
+JSObject* objectConstructorFreeze(ExecState* exec, JSObject* object)
{
- // 1. If Type(O) is not Object throw a TypeError exception.
- JSValue obj = exec->argument(0);
- if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.freeze can only be called on Objects.")));
- JSObject* object = asObject(obj);
-
if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType())) {
object->freeze(exec->vm());
- return JSValue::encode(obj);
+ return object;
}
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
- object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
PropertyNameArray::const_iterator end = properties.end();
for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ Identifier propertyName = *iter;
+ if (exec->propertyNames().isPrivateName(propertyName))
+ continue;
// a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
PropertyDescriptor desc;
- if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+ if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
continue;
// b. If IsDataDescriptor(desc) is true, then
// i. If desc.[[Writable]] is true, set desc.[[Writable]] to false.
// c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
desc.setConfigurable(false);
// d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
- object->methodTable(exec->vm())->defineOwnProperty(object, exec, *iter, desc, true);
+ object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyName, desc, true);
if (exec->hadException())
- return JSValue::encode(obj);
+ return object;
}
// 3. Set the [[Extensible]] internal property of O to false.
object->preventExtensions(exec->vm());
// 4. Return O.
- return JSValue::encode(obj);
+ return object;
+}
+
+EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
+{
+ // 1. If Type(O) is not Object, return O.
+ JSValue obj = exec->argument(0);
+ if (!obj.isObject())
+ return JSValue::encode(obj);
+ return JSValue::encode(objectConstructorFreeze(exec, asObject(obj)));
}
EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState* exec)
{
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.preventExtensions can only be called on Objects.")));
+ return JSValue::encode(obj);
asObject(obj)->preventExtensions(exec->vm());
return JSValue::encode(obj);
}
EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
{
- // 1. If Type(O) is not Object throw a TypeError exception.
+ // 1. If Type(O) is not Object, return true.
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isSealed can only be called on Objects.")));
+ return JSValue::encode(jsBoolean(true));
JSObject* object = asObject(obj);
if (isJSFinalObject(object))
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
- object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
PropertyNameArray::const_iterator end = properties.end();
for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ Identifier propertyName = *iter;
+ if (exec->propertyNames().isPrivateName(propertyName))
+ continue;
// a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
PropertyDescriptor desc;
- if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+ if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
continue;
// b. If desc.[[Configurable]] is true, then return false.
if (desc.configurable())
EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
{
- // 1. If Type(O) is not Object throw a TypeError exception.
+ // 1. If Type(O) is not Object, return true.
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isFrozen can only be called on Objects.")));
+ return JSValue::encode(jsBoolean(true));
JSObject* object = asObject(obj);
if (isJSFinalObject(object))
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
- object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
PropertyNameArray::const_iterator end = properties.end();
for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ Identifier propertyName = *iter;
+ if (exec->propertyNames().isPrivateName(propertyName))
+ continue;
// a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
PropertyDescriptor desc;
- if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
+ if (!object->getOwnPropertyDescriptor(exec, propertyName, desc))
continue;
// b. If IsDataDescriptor(desc) is true then
// i. If desc.[[Writable]] is true, return false. c. If desc.[[Configurable]] is true, then return false.
{
JSValue obj = exec->argument(0);
if (!obj.isObject())
- return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isExtensible can only be called on Objects.")));
+ return JSValue::encode(jsBoolean(false));
return JSValue::encode(jsBoolean(asObject(obj)->isExtensible()));
}
+EncodedJSValue JSC_HOST_CALL objectConstructorIs(ExecState* exec)
+{
+ return JSValue::encode(jsBoolean(sameValue(exec, exec->argument(0), exec->argument(1))));
+}
+
} // namespace JSC