Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (272363 => 272364)
--- trunk/Source/_javascript_Core/ChangeLog 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-02-04 10:42:19 UTC (rev 272364)
@@ -1,3 +1,29 @@
+2021-02-04 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Implement Object.entries in C++
+ https://bugs.webkit.org/show_bug.cgi?id=221380
+
+ Reviewed by Alexey Shvayka.
+
+ This patch implements Object.entries in C++ because it is more efficient.
+ It is not using dynamic feature (like, calling a callback). And in C++,
+ we can avoid JSArray allocations for @Object.@getOwnPropertyNames.
+
+ This patch also removes unnecessary JS private functions, @propertyIsEnumerable,
+ and @getOwnPropertyNames.
+
+ * builtins/BuiltinNames.h:
+ * builtins/ObjectConstructor.js:
+ (entries): Deleted.
+ * bytecode/LinkTimeConstant.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSGlobalObjectFunctions.h:
+ * runtime/ObjectConstructor.cpp:
+ (JSC::ObjectConstructor::finishCreation):
+ (JSC::JSC_DEFINE_HOST_FUNCTION):
+
2021-02-03 Yusuke Suzuki <ysuz...@apple.com>
[JSC] Insert PhantomLocal just before SetLocal for |this| to ensure liveness
Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.h (272363 => 272364)
--- trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2021-02-04 10:42:19 UTC (rev 272364)
@@ -66,7 +66,6 @@
macro(create) \
macro(defineProperty) \
macro(defaultPromiseThen) \
- macro(getOwnPropertyNames) \
macro(Set) \
macro(throwTypeErrorFunction) \
macro(typedArrayLength) \
@@ -169,7 +168,6 @@
macro(makeBoundFunction) \
macro(hasOwnLengthProperty) \
macro(importModule) \
- macro(propertyIsEnumerable) \
macro(copyDataProperties) \
macro(meta) \
macro(webAssemblyCompileStreamingInternal) \
@@ -177,6 +175,7 @@
macro(instanceFieldInitializer) \
macro(hasOwnPropertyFunction) \
macro(createPrivateSymbol) \
+ macro(entries) \
namespace Symbols {
Modified: trunk/Source/_javascript_Core/builtins/ObjectConstructor.js (272363 => 272364)
--- trunk/Source/_javascript_Core/builtins/ObjectConstructor.js 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/builtins/ObjectConstructor.js 2021-02-04 10:42:19 UTC (rev 272364)
@@ -25,22 +25,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-function entries(object)
-{
- "use strict";
-
- var obj = @toObject(object, "Object.entries requires that input parameter not be null or undefined");
- var names = @Object.@getOwnPropertyNames(obj);
- var properties = [];
- for (var i = 0, length = names.length; i < length; ++i) {
- var name = names[i];
- if (@propertyIsEnumerable(obj, name))
- @arrayPush(properties, [name, obj[name]]);
- }
-
- return properties;
-}
-
function fromEntries(iterable)
{
"use strict";
Modified: trunk/Source/_javascript_Core/bytecode/LinkTimeConstant.h (272363 => 272364)
--- trunk/Source/_javascript_Core/bytecode/LinkTimeConstant.h 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/bytecode/LinkTimeConstant.h 2021-02-04 10:42:19 UTC (rev 272364)
@@ -44,7 +44,6 @@
v(setBucketNext, nullptr) \
v(setBucketKey, nullptr) \
v(setPrototypeDirect, nullptr) \
- v(propertyIsEnumerable, nullptr) \
v(copyDataProperties, nullptr) \
v(enqueueJob, nullptr) \
v(makeTypeError, nullptr) \
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (272363 => 272364)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2021-02-04 10:42:19 UTC (rev 272364)
@@ -1187,9 +1187,6 @@
m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::importModule)].initLater([] (const Initializer<JSCell>& init) {
init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), globalFuncImportModule));
});
- m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::propertyIsEnumerable)].initLater([] (const Initializer<JSCell>& init) {
- init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), globalFuncPropertyIsEnumerable));
- });
m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::copyDataProperties)].initLater([] (const Initializer<JSCell>& init) {
init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 2, String(), globalFuncCopyDataProperties));
});
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (272363 => 272364)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2021-02-04 10:42:19 UTC (rev 272364)
@@ -815,22 +815,6 @@
return JSValue::encode(promise);
}
-JSC_DEFINE_HOST_FUNCTION(globalFuncPropertyIsEnumerable, (JSGlobalObject* globalObject, CallFrame* callFrame))
-{
- VM& vm = globalObject->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
-
- RELEASE_ASSERT(callFrame->argumentCount() == 2);
- JSObject* object = jsCast<JSObject*>(callFrame->uncheckedArgument(0));
- auto propertyName = callFrame->uncheckedArgument(1).toPropertyKey(globalObject);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
-
- scope.release();
- PropertyDescriptor descriptor;
- bool enumerable = object->getOwnPropertyDescriptor(globalObject, propertyName, descriptor) && descriptor.enumerable();
- return JSValue::encode(jsBoolean(enumerable));
-}
-
static bool canPerformFastPropertyEnumerationForCopyDataProperties(Structure* structure)
{
if (structure->typeInfo().overridesGetOwnPropertySlot())
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h (272363 => 272364)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2021-02-04 10:42:19 UTC (rev 272364)
@@ -56,7 +56,6 @@
JSC_DECLARE_HOST_FUNCTION(globalFuncBuiltinLog);
JSC_DECLARE_HOST_FUNCTION(globalFuncBuiltinDescribe);
JSC_DECLARE_HOST_FUNCTION(globalFuncImportModule);
-JSC_DECLARE_HOST_FUNCTION(globalFuncPropertyIsEnumerable);
JSC_DECLARE_HOST_FUNCTION(globalFuncCopyDataProperties);
JSC_DECLARE_HOST_FUNCTION(globalFuncDateTimeFormat);
Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (272363 => 272364)
--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2021-02-04 09:11:28 UTC (rev 272363)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2021-02-04 10:42:19 UTC (rev 272364)
@@ -32,6 +32,7 @@
namespace JSC {
static JSC_DECLARE_HOST_FUNCTION(objectConstructorAssign);
+static JSC_DECLARE_HOST_FUNCTION(objectConstructorEntries);
static JSC_DECLARE_HOST_FUNCTION(objectConstructorValues);
static JSC_DECLARE_HOST_FUNCTION(objectConstructorGetPrototypeOf);
static JSC_DECLARE_HOST_FUNCTION(objectConstructorSetPrototypeOf);
@@ -76,7 +77,7 @@
is objectConstructorIs DontEnum|Function 2 ObjectIsIntrinsic
assign objectConstructorAssign DontEnum|Function 2
values objectConstructorValues DontEnum|Function 1
- entries JSBuiltin DontEnum|Function 1
+ entries objectConstructorEntries DontEnum|Function 1
fromEntries JSBuiltin DontEnum|Function 1
@end
*/
@@ -98,7 +99,6 @@
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().createPrivateName(), objectConstructorCreate, static_cast<unsigned>(PropertyAttribute::DontEnum), 2);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().definePropertyPrivateName(), objectConstructorDefineProperty, static_cast<unsigned>(PropertyAttribute::DontEnum), 3);
- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getOwnPropertyNamesPrivateName(), objectConstructorGetOwnPropertyNames, static_cast<unsigned>(PropertyAttribute::DontEnum), 1);
}
// ES 19.1.1.1 Object([value])
@@ -388,6 +388,65 @@
return JSValue::encode(target);
}
+JSC_DEFINE_HOST_FUNCTION(objectConstructorEntries, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSValue targetValue = callFrame->argument(0);
+ if (targetValue.isUndefinedOrNull())
+ return throwVMTypeError(globalObject, scope, "Object.entries requires that input parameter not be null or undefined"_s);
+ JSObject* target = targetValue.toObject(globalObject);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ JSArray* entries = constructEmptyArray(globalObject, nullptr);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ PropertyNameArray properties(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
+ target->methodTable(vm)->getOwnPropertyNames(target, globalObject, properties, DontEnumPropertiesMode::Include);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ unsigned index = 0;
+ auto append = [&] (JSGlobalObject* globalObject, PropertyName propertyName) {
+ PropertySlot slot(target, PropertySlot::InternalMethodType::GetOwnProperty);
+ bool hasProperty = target->methodTable(vm)->getOwnPropertySlot(target, globalObject, propertyName, slot);
+ RETURN_IF_EXCEPTION(scope, void());
+ if (!hasProperty)
+ return;
+ if (slot.attributes() & PropertyAttribute::DontEnum)
+ return;
+
+ JSValue value;
+ if (LIKELY(!slot.isTaintedByOpaqueObject()))
+ value = slot.getValue(globalObject, propertyName);
+ else
+ value = target->get(globalObject, propertyName);
+ RETURN_IF_EXCEPTION(scope, void());
+
+ JSString* key = jsOwnedString(vm, propertyName.uid());
+ JSArray* entry = nullptr;
+ {
+ ObjectInitializationScope initializationScope(vm);
+ if ((entry = JSArray::tryCreateUninitializedRestricted(initializationScope, nullptr, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 2))) {
+ entry->initializeIndex(initializationScope, 0, key);
+ entry->initializeIndex(initializationScope, 1, value);
+ }
+ }
+ if (!entry) {
+ throwOutOfMemoryError(globalObject, scope);
+ return;
+ }
+ entries->putDirectIndex(globalObject, index++, entry);
+ };
+
+ for (const auto& propertyName : properties) {
+ append(globalObject, propertyName);
+ RETURN_IF_EXCEPTION(scope, { });
+ }
+
+ return JSValue::encode(entries);
+}
+
JSC_DEFINE_HOST_FUNCTION(objectConstructorValues, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
VM& vm = globalObject->vm();
@@ -407,7 +466,7 @@
RETURN_IF_EXCEPTION(scope, { });
unsigned index = 0;
- auto addValue = [&] (PropertyName propertyName) {
+ auto append = [&] (JSGlobalObject* globalObject, PropertyName propertyName) {
PropertySlot slot(target, PropertySlot::InternalMethodType::GetOwnProperty);
bool hasProperty = target->methodTable(vm)->getOwnPropertySlot(target, globalObject, propertyName, slot);
RETURN_IF_EXCEPTION(scope, void());
@@ -426,12 +485,8 @@
values->putDirectIndex(globalObject, index++, value);
};
- for (unsigned i = 0, numProperties = properties.size(); i < numProperties; i++) {
- const auto& propertyName = properties[i];
- if (propertyName.isSymbol())
- continue;
-
- addValue(propertyName);
+ for (const auto& propertyName : properties) {
+ append(globalObject, propertyName);
RETURN_IF_EXCEPTION(scope, { });
}