Changeset 271343 in webkit for trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
- Timestamp:
- Jan 8, 2021, 8:31:12 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r267594 r271343 840 840 } 841 841 842 JSC_DEFINE_HOST_FUNCTION(globalFuncOwnKeys, (JSGlobalObject* globalObject, CallFrame* callFrame)) 843 { 844 VM& vm = globalObject->vm(); 845 auto scope = DECLARE_THROW_SCOPE(vm); 846 JSObject* object = callFrame->argument(0).toObject(globalObject); 847 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 848 RELEASE_AND_RETURN(scope, JSValue::encode(ownPropertyKeys(globalObject, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include, WTF::nullopt))); 842 static bool canPerformFastPropertyEnumerationForCopyDataProperties(Structure* structure) 843 { 844 if (structure->typeInfo().overridesGetOwnPropertySlot()) 845 return false; 846 if (structure->typeInfo().overridesAnyFormOfGetOwnPropertyNames()) 847 return false; 848 // FIXME: Indexed properties can be handled. 849 // https://bugs.webkit.org/show_bug.cgi?id=185358 850 if (hasIndexedProperties(structure->indexingType())) 851 return false; 852 if (structure->hasGetterSetterProperties()) 853 return false; 854 if (structure->hasCustomGetterSetterProperties()) 855 return false; 856 if (structure->isUncacheableDictionary()) 857 return false; 858 return true; 859 }; 860 861 // https://tc39.es/ecma262/#sec-copydataproperties 862 JSC_DEFINE_HOST_FUNCTION(globalFuncCopyDataProperties, (JSGlobalObject* globalObject, CallFrame* callFrame)) 863 { 864 VM& vm = globalObject->vm(); 865 auto scope = DECLARE_THROW_SCOPE(vm); 866 867 JSFinalObject* target = jsCast<JSFinalObject*>(callFrame->uncheckedArgument(0)); 868 ASSERT(target->isStructureExtensible(vm)); 869 870 JSValue sourceValue = callFrame->uncheckedArgument(1); 871 if (sourceValue.isUndefinedOrNull()) 872 return JSValue::encode(jsUndefined()); 873 874 JSObject* source = sourceValue.toObject(globalObject); 875 scope.assertNoException(); 876 877 JSSet* excludedSet = nullptr; 878 if (callFrame->argumentCount() > 2) 879 excludedSet = jsCast<JSSet*>(callFrame->uncheckedArgument(2)); 880 881 auto isPropertyNameExcluded = [&] (JSGlobalObject* globalObject, PropertyName propertyName) -> bool { 882 ASSERT(!propertyName.isPrivateName()); 883 if (!excludedSet) 884 return false; 885 886 JSValue propertyNameValue = identifierToJSValue(vm, Identifier::fromUid(vm, propertyName.uid())); 887 RETURN_IF_EXCEPTION(scope, false); 888 return excludedSet->has(globalObject, propertyNameValue); 889 }; 890 891 if (!source->staticPropertiesReified(vm)) { 892 source->reifyAllStaticProperties(globalObject); 893 RETURN_IF_EXCEPTION(scope, { }); 894 } 895 896 if (canPerformFastPropertyEnumerationForCopyDataProperties(source->structure(vm))) { 897 Vector<RefPtr<UniquedStringImpl>, 8> properties; 898 MarkedArgumentBuffer values; 899 900 // FIXME: It doesn't seem like we should have to do this in two phases, but 901 // we're running into crashes where it appears that source is transitioning 902 // under us, and even ends up in a state where it has a null butterfly. My 903 // leading hypothesis here is that we fire some value replacement watchpoint 904 // that ends up transitioning the structure underneath us. 905 // https://bugs.webkit.org/show_bug.cgi?id=187837 906 907 source->structure(vm)->forEachProperty(vm, [&] (const PropertyMapEntry& entry) -> bool { 908 PropertyName propertyName(entry.key); 909 if (propertyName.isPrivateName()) 910 return true; 911 912 bool excluded = isPropertyNameExcluded(globalObject, propertyName); 913 RETURN_IF_EXCEPTION(scope, false); 914 if (excluded) 915 return true; 916 if (entry.attributes & PropertyAttribute::DontEnum) 917 return true; 918 919 properties.append(entry.key); 920 values.appendWithCrashOnOverflow(source->getDirect(entry.offset)); 921 return true; 922 }); 923 924 RETURN_IF_EXCEPTION(scope, { }); 925 926 for (size_t i = 0; i < properties.size(); ++i) { 927 // FIXME: We could put properties in a batching manner to accelerate CopyDataProperties more. 928 // https://bugs.webkit.org/show_bug.cgi?id=185358 929 target->putDirect(vm, properties[i].get(), values.at(i)); 930 } 931 } else { 932 PropertyNameArray propertyNames(vm, PropertyNameMode::StringsAndSymbols, PrivateSymbolMode::Exclude); 933 source->methodTable(vm)->getOwnPropertyNames(source, globalObject, propertyNames, DontEnumPropertiesMode::Include); 934 RETURN_IF_EXCEPTION(scope, { }); 935 936 for (const auto& propertyName : propertyNames) { 937 bool excluded = isPropertyNameExcluded(globalObject, propertyName); 938 RETURN_IF_EXCEPTION(scope, false); 939 if (excluded) 940 continue; 941 942 PropertySlot slot(source, PropertySlot::InternalMethodType::GetOwnProperty); 943 bool hasProperty = source->methodTable(vm)->getOwnPropertySlot(source, globalObject, propertyName, slot); 944 RETURN_IF_EXCEPTION(scope, { }); 945 if (!hasProperty) 946 continue; 947 if (slot.attributes() & PropertyAttribute::DontEnum) 948 continue; 949 950 JSValue value; 951 if (LIKELY(!slot.isTaintedByOpaqueObject())) 952 value = slot.getValue(globalObject, propertyName); 953 else 954 value = source->get(globalObject, propertyName); 955 RETURN_IF_EXCEPTION(scope, { }); 956 957 target->putDirectMayBeIndex(globalObject, propertyName, value); 958 } 959 } 960 961 return JSValue::encode(jsUndefined()); 849 962 } 850 963
Note:
See TracChangeset
for help on using the changeset viewer.