JSDOMConvertRecord.h [plain text]
#pragma once
#include "IDLTypes.h"
#include "JSDOMConvertStrings.h"
#include <runtime/ObjectConstructor.h>
namespace WebCore {
namespace Detail {
template<typename IDLStringType>
struct IdentifierConverter;
template<> struct IdentifierConverter<IDLDOMString> {
static String convert(JSC::ExecState&, const JSC::Identifier& identifier)
{
return identifier.string();
}
};
template<> struct IdentifierConverter<IDLByteString> {
static String convert(JSC::ExecState& state, const JSC::Identifier& identifier)
{
return identifierToByteString(state, identifier);
}
};
template<> struct IdentifierConverter<IDLUSVString> {
static String convert(JSC::ExecState& state, const JSC::Identifier& identifier)
{
return identifierToUSVString(state, identifier);
}
};
}
template<typename K, typename V> struct Converter<IDLRecord<K, V>> : DefaultConverter<IDLRecord<K, V>> {
using ReturnType = typename IDLRecord<K, V>::ImplementationType;
using KeyType = typename K::ImplementationType;
using ValueType = typename V::ImplementationType;
static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
{
auto& vm = state.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
if (value.isUndefinedOrNull())
return { };
if (!value.isObject()) {
throwTypeError(&state, scope);
return { };
}
JSC::JSObject* object = JSC::asObject(value);
ReturnType result;
JSC::PropertyNameArray keys(&vm, JSC::PropertyNameMode::Strings);
object->getOwnPropertyNames(object, &state, keys, JSC::EnumerationMode());
RETURN_IF_EXCEPTION(scope, { });
for (auto& key : keys) {
JSC::PropertyDescriptor descriptor;
bool didGetDescriptor = object->getOwnPropertyDescriptor(&state, key, descriptor);
RETURN_IF_EXCEPTION(scope, { });
if (!didGetDescriptor)
continue;
if (!descriptor.value().isUndefined() && descriptor.enumerable()) {
auto typedKey = Detail::IdentifierConverter<K>::convert(state, key);
auto subValue = object->get(&state, key);
RETURN_IF_EXCEPTION(scope, { });
auto typedValue = Converter<V>::convert(state, subValue);
RETURN_IF_EXCEPTION(scope, { });
result.append({ typedKey, typedValue });
}
}
return result;
}
};
template<typename K, typename V> struct JSConverter<IDLRecord<K, V>> {
static constexpr bool needsState = true;
static constexpr bool needsGlobalObject = true;
template<typename MapType>
static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const MapType& map)
{
auto& vm = state.vm();
auto result = constructEmptyObject(&state, globalObject.objectPrototype());
for (const auto& keyValuePair : map) {
auto esValue = toJS<V>(state, globalObject, keyValuePair.value);
bool created = result->putDirect(vm, JSC::Identifier::fromString(&vm, keyValuePair.key), esValue);
ASSERT_UNUSED(created, created);
}
return result;
}
};
}