diff options
Diffstat (limited to 'src/bun.js/bindings/webcore/JSDOMFormData.cpp')
-rw-r--r-- | src/bun.js/bindings/webcore/JSDOMFormData.cpp | 140 |
1 files changed, 72 insertions, 68 deletions
diff --git a/src/bun.js/bindings/webcore/JSDOMFormData.cpp b/src/bun.js/bindings/webcore/JSDOMFormData.cpp index fb725faa3..09a0a6c08 100644 --- a/src/bun.js/bindings/webcore/JSDOMFormData.cpp +++ b/src/bun.js/bindings/webcore/JSDOMFormData.cpp @@ -504,74 +504,7 @@ JSC_DEFINE_HOST_FUNCTION(jsDOMFormDataPrototypeFunction_set, (JSGlobalObject * l **/ static inline JSC::EncodedJSValue jsDOMFormDataPrototypeFunction_toJSONBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSDOMFormData>::ClassParameter castedThis) { - auto& vm = JSC::getVM(lexicalGlobalObject); - auto throwScope = DECLARE_THROW_SCOPE(vm); - - auto& impl = castedThis->wrapped(); - size_t size = impl.count(); - JSObject* obj; - if (size == 0) { - obj = constructEmptyObject(lexicalGlobalObject); - RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); - RELEASE_AND_RETURN(throwScope, JSValue::encode(obj)); - } else if (size < 64) { - obj = constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), size + 1); - } else { - obj = constructEmptyObject(lexicalGlobalObject); - } - - obj->putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(vm, String("FormData"_s)), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); - - auto iter = impl.items(); - WTF::HashSet<String> seenKeys; - - auto toJSValue = [&](const DOMFormData::FormDataEntryValue& entry) -> JSValue { - return toJS<IDLNullable<IDLUnion<IDLUSVString, IDLInterface<Blob>>>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, entry); - }; - - for (auto& entry : iter) { - auto& key = entry.name; - auto& value = entry.data; - auto ident = Identifier::fromString(vm, key); - if (seenKeys.contains(key)) { - JSValue jsValue = obj->getDirect(vm, ident); - if (jsValue.isString() || jsValue.inherits<JSBlob>()) { - // Make sure this runs before the deferral scope is called. - JSValue resultValue = toJSValue(value); - ensureStillAliveHere(resultValue); - - JSC::JSArray* array = nullptr; - - { - GCDeferralContext deferralContext(lexicalGlobalObject->vm()); - JSC::ObjectInitializationScope initializationScope(lexicalGlobalObject->vm()); - - array = JSC::JSArray::tryCreateUninitializedRestricted( - initializationScope, &deferralContext, - lexicalGlobalObject->arrayStructureForIndexingTypeDuringAllocation(JSC::ArrayWithContiguous), - 2); - RELEASE_ASSERT(array); - - array->initializeIndex(initializationScope, 0, jsValue); - array->initializeIndex(initializationScope, 1, resultValue); - } - - obj->putDirect(vm, ident, array, 0); - } else if (jsValue.isObject() && jsValue.getObject()->inherits<JSC::JSArray>()) { - JSC::JSArray* array = jsCast<JSC::JSArray*>(jsValue.getObject()); - array->push(lexicalGlobalObject, toJSValue(value)); - RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); - - } else { - RELEASE_ASSERT_NOT_REACHED(); - } - } else { - seenKeys.add(key); - obj->putDirect(vm, ident, toJSValue(value), 0); - } - } - - RELEASE_AND_RETURN(throwScope, JSValue::encode(obj)); + return JSValue::encode(getInternalProperties(lexicalGlobalObject->vm(), lexicalGlobalObject, castedThis)); } JSC_DEFINE_HOST_FUNCTION(jsDOMFormDataPrototypeFunction_toJSON, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) @@ -672,6 +605,77 @@ JSC_DEFINE_HOST_FUNCTION(jsDOMFormDataPrototypeFunction_forEach, (JSC::JSGlobalO return IDLOperation<JSDOMFormData>::call<jsDOMFormDataPrototypeFunction_forEachCaller>(*lexicalGlobalObject, *callFrame, "forEach"); } +JSC::JSValue getInternalProperties(JSC::VM& vm, JSGlobalObject* lexicalGlobalObject, JSDOMFormData* castedThis) +{ + auto throwScope = DECLARE_THROW_SCOPE(vm); + + auto& impl = castedThis->wrapped(); + size_t size = impl.count(); + JSObject* obj; + if (size == 0) { + obj = constructEmptyObject(lexicalGlobalObject); + RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_AND_RETURN(throwScope, obj); + } else if (size < 64) { + obj = constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), size + 1); + } else { + obj = constructEmptyObject(lexicalGlobalObject); + } + + obj->putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(vm, String("FormData"_s)), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); + + auto iter = impl.items(); + WTF::HashSet<String> seenKeys; + + auto toJSValue = [&](const DOMFormData::FormDataEntryValue& entry) -> JSValue { + return toJS<IDLNullable<IDLUnion<IDLUSVString, IDLInterface<Blob>>>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, entry); + }; + + for (auto& entry : iter) { + auto& key = entry.name; + auto& value = entry.data; + auto ident = Identifier::fromString(vm, key); + if (seenKeys.contains(key)) { + JSValue jsValue = obj->getDirect(vm, ident); + if (jsValue.isString() || jsValue.inherits<JSBlob>()) { + // Make sure this runs before the deferral scope is called. + JSValue resultValue = toJSValue(value); + ensureStillAliveHere(resultValue); + + JSC::JSArray* array = nullptr; + + { + GCDeferralContext deferralContext(lexicalGlobalObject->vm()); + JSC::ObjectInitializationScope initializationScope(lexicalGlobalObject->vm()); + + array = JSC::JSArray::tryCreateUninitializedRestricted( + initializationScope, &deferralContext, + lexicalGlobalObject->arrayStructureForIndexingTypeDuringAllocation(JSC::ArrayWithContiguous), + 2); + RELEASE_ASSERT(array); + + array->initializeIndex(initializationScope, 0, jsValue); + array->initializeIndex(initializationScope, 1, resultValue); + } + + obj->putDirect(vm, ident, array, 0); + } else if (jsValue.isObject() && jsValue.getObject()->inherits<JSC::JSArray>()) { + JSC::JSArray* array = jsCast<JSC::JSArray*>(jsValue.getObject()); + array->push(lexicalGlobalObject, toJSValue(value)); + RETURN_IF_EXCEPTION(throwScope, {}); + + } else { + RELEASE_ASSERT_NOT_REACHED(); + } + } else { + seenKeys.add(key); + obj->putDirect(vm, ident, toJSValue(value), 0); + } + } + + RELEASE_AND_RETURN(throwScope, obj); +} + JSC::GCClient::IsoSubspace* JSDOMFormData::subspaceForImpl(JSC::VM& vm) { return WebCore::subspaceForImpl<JSDOMFormData, UseCustomHeapCellType::No>( |