summaryrefslogtreecommitdiff
path: root/Source/WebCore/bindings/js/JSDOMConvertRecord.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/bindings/js/JSDOMConvertRecord.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/bindings/js/JSDOMConvertRecord.h')
-rw-r--r--Source/WebCore/bindings/js/JSDOMConvertRecord.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/Source/WebCore/bindings/js/JSDOMConvertRecord.h b/Source/WebCore/bindings/js/JSDOMConvertRecord.h
new file mode 100644
index 000000000..db1dabf8d
--- /dev/null
+++ b/Source/WebCore/bindings/js/JSDOMConvertRecord.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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);
+
+ // 1. Let result be a new empty instance of record<K, V>.
+ // 2. If Type(O) is Undefined or Null, return result.
+ if (value.isUndefinedOrNull())
+ return { };
+
+ // 3. If Type(O) is not Object, throw a TypeError.
+ if (!value.isObject()) {
+ throwTypeError(&state, scope);
+ return { };
+ }
+
+ JSC::JSObject* object = JSC::asObject(value);
+
+ ReturnType result;
+
+ // 4. Let keys be ? O.[[OwnPropertyKeys]]().
+ JSC::PropertyNameArray keys(&vm, JSC::PropertyNameMode::Strings);
+ object->getOwnPropertyNames(object, &state, keys, JSC::EnumerationMode());
+ RETURN_IF_EXCEPTION(scope, { });
+
+ // 5. Repeat, for each element key of keys in List order:
+ for (auto& key : keys) {
+ // 1. Let desc be ? O.[[GetOwnProperty]](key).
+ JSC::PropertyDescriptor descriptor;
+ bool didGetDescriptor = object->getOwnPropertyDescriptor(&state, key, descriptor);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ if (!didGetDescriptor)
+ continue;
+
+ // 2. If desc is not undefined and desc.[[Enumerable]] is true:
+
+ // FIXME: Do we need to check for enumerable / undefined, or is this handled by the default
+ // enumeration mode?
+
+ if (!descriptor.value().isUndefined() && descriptor.enumerable()) {
+ // 1. Let typedKey be key converted to an IDL value of type K.
+ auto typedKey = Detail::IdentifierConverter<K>::convert(state, key);
+
+ // 2. Let value be ? Get(O, key).
+ auto subValue = object->get(&state, key);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ // 3. Let typedValue be value converted to an IDL value of type V.
+ auto typedValue = Converter<V>::convert(state, subValue);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ // 4. If typedKey is already a key in result, set its value to typedValue.
+ // Note: This can happen when O is a proxy object.
+ // FIXME: Handle this case.
+
+ // 5. Otherwise, append to result a mapping (typedKey, typedValue).
+ result.append({ typedKey, typedValue });
+ }
+ }
+
+ // 6. Return result.
+ 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();
+
+ // 1. Let result be ! ObjectCreate(%ObjectPrototype%).
+ auto result = constructEmptyObject(&state);
+
+ // 2. Repeat, for each mapping (key, value) in D:
+ for (const auto& keyValuePair : map) {
+ // 1. Let esKey be key converted to an ECMAScript value.
+ // Note, this step is not required, as we need the key to be
+ // an Identifier, not a JSValue.
+
+ // 2. Let esValue be value converted to an ECMAScript value.
+ auto esValue = toJS<V>(state, globalObject, keyValuePair.value);
+
+ // 3. Let created be ! CreateDataProperty(result, esKey, esValue).
+ bool created = result->putDirect(vm, JSC::Identifier::fromString(&vm, keyValuePair.key), esValue);
+
+ // 4. Assert: created is true.
+ ASSERT_UNUSED(created, created);
+ }
+
+ // 3. Return result.
+ return result;
+ }
+};
+
+} // namespace WebCore