Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/V8Binding.h

Issue 2709983004: WIP bindings: Add support for the record<K,V> WebIDL type. (Closed)
Patch Set: Rebased patch using NativeValueTraits for IDL types Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Ericsson AB. All rights reserved. 3 * Copyright (C) 2012 Ericsson AB. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } else { 754 } else {
755 exceptionState.throwTypeError("Invalid Array element type"); 755 exceptionState.throwTypeError("Invalid Array element type");
756 return VectorType(); 756 return VectorType();
757 } 757 }
758 } 758 }
759 return result; 759 return result;
760 } 760 }
761 761
762 // Converts a JavaScript value to an array as per the Web IDL specification: 762 // Converts a JavaScript value to an array as per the Web IDL specification:
763 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array 763 // http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
764 template <typename VectorType> 764 template <typename VectorType,
765 typename ValueType = typename VectorType::ValueType>
765 VectorType toImplArray(v8::Local<v8::Value> value, 766 VectorType toImplArray(v8::Local<v8::Value> value,
766 int argumentIndex, 767 int argumentIndex,
767 v8::Isolate* isolate, 768 v8::Isolate* isolate,
768 ExceptionState& exceptionState) { 769 ExceptionState& exceptionState) {
769 typedef typename VectorType::ValueType ValueType;
770 typedef NativeValueTraits<ValueType> TraitsType; 770 typedef NativeValueTraits<ValueType> TraitsType;
771 771
772 uint32_t length = 0; 772 uint32_t length = 0;
773 if (value->IsArray()) { 773 if (value->IsArray()) {
774 length = v8::Local<v8::Array>::Cast(value)->Length(); 774 length = v8::Local<v8::Array>::Cast(value)->Length();
775 } else if (!toV8Sequence(value, length, isolate, exceptionState)) { 775 } else if (!toV8Sequence(value, length, isolate, exceptionState)) {
776 if (!exceptionState.hadException()) 776 if (!exceptionState.hadException())
777 exceptionState.throwTypeError( 777 exceptionState.throwTypeError(
778 ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex)); 778 ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex));
779 return VectorType(); 779 return VectorType();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 if (!v8Call(lengthValue->Uint32Value(isolate->GetCurrentContext()), 896 if (!v8Call(lengthValue->Uint32Value(isolate->GetCurrentContext()),
897 sequenceLength, block)) { 897 sequenceLength, block)) {
898 exceptionState.rethrowV8Exception(block.Exception()); 898 exceptionState.rethrowV8Exception(block.Exception());
899 return false; 899 return false;
900 } 900 }
901 901
902 length = sequenceLength; 902 length = sequenceLength;
903 return true; 903 return true;
904 } 904 }
905 905
906 WARN_UNUSED_RESULT CORE_EXPORT v8::MaybeLocal<v8::String> getStringValueInArray(
Yuki 2017/03/02 07:47:28 nit: I'm on the fence whether the name of |getStri
907 v8::Local<v8::Context> context,
908 v8::Local<v8::Array> array,
909 uint32_t index);
910
911 CORE_EXPORT bool isPropertyEnumerable(v8::Isolate* isolate,
912 v8::Local<v8::Value> descriptor,
913 ExceptionState& exceptionState);
914
915 // Converts a JavaScript value |O| to an IDL record<K, V> value.
916 // In C++, a record is represented as a Vector<std::pair<k, v>> (or a
917 // HeapVector if v is a type that uses Oilpain).
918 // See https://heycam.github.io/webidl/#es-record.
919 template <typename KeyType, typename ValueType, typename VectorType>
920 VectorType toImplRecord(v8::Isolate* isolate,
921 v8::Local<v8::Value> originalValue,
922 ExceptionState& exceptionState) {
923 // "1. If Type(O) is not Object, throw a TypeError."
924 if (!originalValue->IsObject()) {
925 exceptionState.throwTypeError(
926 "Only objects can be converted to record<K,V> types");
927 return VectorType();
928 }
929 v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(originalValue);
930 v8::TryCatch block(isolate);
931
932 // "3. Let keys be ? O.[[OwnPropertyKeys]]()."
933 v8::Local<v8::Array> keys;
934 // While we could pass v8::ONLY_ENUMERABLE below, doing so breaks
935 // web-platform-tests' headers-record.html and deviates from the spec
936 // algorithm.
937 // Symbols are being skipped due to
938 // https://github.com/heycam/webidl/issues/294.
939 if (!v8Object
940 ->GetOwnPropertyNames(isolate->GetCurrentContext(),
941 static_cast<v8::PropertyFilter>(
942 v8::PropertyFilter::ALL_PROPERTIES |
943 v8::PropertyFilter::SKIP_SYMBOLS))
944 .ToLocal(&keys)) {
945 exceptionState.rethrowV8Exception(block.Exception());
946 return VectorType();
947 }
948 if (keys->Length() > VectorType::maxCapacity()) {
949 exceptionState.throwRangeError("Array length exceeds supported limit.");
950 return VectorType();
951 }
952
953 // "2. Let result be a new empty instance of record<K, V>."
954 VectorType result;
955 result.reserveInitialCapacity(keys->Length());
956
957 // The conversion algorithm needs a data structure with fast insertion at the
958 // end while at the same time requiring fast checks for previous insert of a
959 // given key. |seenKeys| is a key/position in |result| map that aids in the
960 // latter part.
961 HashMap<String, size_t> seenKeys;
962
963 for (uint32_t i = 0; i < keys->Length(); ++i) {
964 // "4. Repeat, for each element key of keys in List order:"
965 v8::Local<v8::String> key;
966 if (!getStringValueInArray(isolate->GetCurrentContext(), keys, i)
967 .ToLocal(&key)) {
968 exceptionState.rethrowV8Exception(block.Exception());
Yuki 2017/03/02 07:47:28 Not directly related to your CL, we may want an ut
969 return VectorType();
970 }
971
972 // "4.1. Let desc be ? O.[[GetOwnProperty]](key)."
973 v8::Local<v8::Value> desc;
974 if (!v8Object->GetOwnPropertyDescriptor(isolate->GetCurrentContext(), key)
975 .ToLocal(&desc)) {
976 exceptionState.rethrowV8Exception(block.Exception());
977 return VectorType();
978 }
979
980 // "4.2. If desc is not undefined and desc.[[Enumerable]] is true:"
981 if (!isPropertyEnumerable(isolate, desc, exceptionState)) {
982 if (exceptionState.hadException())
983 return VectorType();
984 continue;
985 }
986
987 // "4.2.1. Let typedKey be key converted to an IDL value of type K."
988 String typedKey =
989 NativeValueTraits<KeyType>::nativeValue(isolate, key, exceptionState);
990 if (exceptionState.hadException())
991 return VectorType();
992
993 // "4.2.2. Let value be ? Get(O, key)."
994 v8::Local<v8::Value> value;
995 if (!v8Object->Get(isolate->GetCurrentContext(), key).ToLocal(&value)) {
996 exceptionState.rethrowV8Exception(block.Exception());
997 return VectorType();
998 }
999
1000 // "4.2.3. Let typedValue be value converted to an IDL value of type V."
1001 typename VectorType::ValueType::second_type typedValue =
1002 NativeValueTraits<ValueType>::nativeValue(isolate, value,
1003 exceptionState);
1004 if (exceptionState.hadException())
1005 return VectorType();
1006
1007 if (seenKeys.contains(typedKey)) {
1008 // "4.2.4. If typedKey is already a key in result, set its value to
1009 // typedValue.
1010 // Note: This can happen when O is a proxy object."
1011 const size_t pos = seenKeys.at(typedKey);
1012 result[pos] = std::make_pair(typedKey, typedValue);
1013 } else {
1014 // "4.2.5. Otherwise, append to result a mapping (typedKey, typedValue)."
1015 const size_t pos = result.size(); // We can take this shortcut because
1016 // we are always appending.
1017 seenKeys.set(typedKey, pos);
1018 result.uncheckedAppend(std::make_pair(typedKey, typedValue));
1019 }
1020 }
1021 // "5. Return result."
1022 return result;
1023 }
1024
906 template <> 1025 template <>
907 struct NativeValueTraits<String> { 1026 struct NativeValueTraits<String> {
908 static inline String nativeValue(v8::Isolate* isolate, 1027 static inline String nativeValue(v8::Isolate* isolate,
909 v8::Local<v8::Value> value, 1028 v8::Local<v8::Value> value,
910 ExceptionState& exceptionState) { 1029 ExceptionState& exceptionState) {
911 V8StringResource<> stringValue(value); 1030 V8StringResource<> stringValue(value);
912 if (!stringValue.prepare(exceptionState)) 1031 if (!stringValue.prepare(exceptionState))
913 return String(); 1032 return String();
914 return stringValue; 1033 return stringValue;
915 } 1034 }
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 // If the argument isn't an object, this will crash. 1279 // If the argument isn't an object, this will crash.
1161 CORE_EXPORT v8::Local<v8::Value> freezeV8Object(v8::Local<v8::Value>, 1280 CORE_EXPORT v8::Local<v8::Value> freezeV8Object(v8::Local<v8::Value>,
1162 v8::Isolate*); 1281 v8::Isolate*);
1163 1282
1164 CORE_EXPORT v8::Local<v8::Value> fromJSONString(v8::Isolate*, 1283 CORE_EXPORT v8::Local<v8::Value> fromJSONString(v8::Isolate*,
1165 const String& stringifiedJSON, 1284 const String& stringifiedJSON,
1166 ExceptionState&); 1285 ExceptionState&);
1167 } // namespace blink 1286 } // namespace blink
1168 1287
1169 #endif // V8Binding_h 1288 #endif // V8Binding_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698