diff --git a/native_mate/converter.h b/native_mate/converter.h index 0ee0c0e6e59c..86dc5e5d21c4 100644 --- a/native_mate/converter.h +++ b/native_mate/converter.h @@ -15,6 +15,20 @@ namespace mate { +template +bool SetProperty(v8::Isolate* isolate, + v8::Local object, + KeyType key, + v8::Local value) { + auto maybe = object->Set(isolate->GetCurrentContext(), key, value); + return !maybe.IsNothing() && maybe.FromJust(); +} + +template +struct ToV8ReturnsMaybe { + static const bool value = false; +}; + template struct Converter {}; @@ -241,18 +255,59 @@ struct Converter > { } }; +template +struct ToV8ReturnsMaybe> { + static const bool value = true; +}; + // Convenience functions that deduce T. template -v8::Local ConvertToV8(v8::Isolate* isolate, - const T& input) { +v8::Local ConvertToV8(v8::Isolate* isolate, const T& input) { return Converter::ToV8(isolate, input); } inline v8::Local ConvertToV8(v8::Isolate* isolate, - const char* input) { + const char* input) { return Converter::ToV8(isolate, input); } +template +v8::MaybeLocal ConvertToV8(v8::Local context, + const T& input) { + return Converter::ToV8(context, input); +} + +template::value> struct ToV8Traits; + +template +struct ToV8Traits { + static bool TryConvertToV8(v8::Isolate* isolate, + const T& input, + v8::Local* output) { + auto maybe = ConvertToV8(isolate->GetCurrentContext(), input); + if (maybe.IsEmpty()) + return false; + *output = maybe.ToLocalChecked(); + return true; + } +}; + +template +struct ToV8Traits { + static bool TryConvertToV8(v8::Isolate* isolate, + const T& input, + v8::Local* output) { + *output = ConvertToV8(isolate, input); + return true; + } +}; + +template +bool TryConvertToV8(v8::Isolate* isolate, + T input, + v8::Local* output) { + return ToV8Traits::TryConvertToV8(isolate, input, output); +} inline v8::Local StringToV8( v8::Isolate* isolate, const base::StringPiece& input) { diff --git a/native_mate/dictionary.h b/native_mate/dictionary.h index c15f8f902fdd..05b6b86463ab 100644 --- a/native_mate/dictionary.h +++ b/native_mate/dictionary.h @@ -10,6 +10,15 @@ namespace mate { +namespace internal { + +// Returns true if |maybe| is both a value, and that value is true. +inline bool IsTrue(v8::Maybe maybe) { + return maybe.IsJust() && maybe.FromJust(); +} + +} // namespace internal + // Dictionary is useful when writing bindings for a function that either // receives an arbitrary JavaScript object as an argument or returns an // arbitrary JavaScript object as a result. For example, Dictionary is useful @@ -32,27 +41,44 @@ class Dictionary { template bool Get(const base::StringPiece& key, T* out) const { - v8::Local val = GetHandle()->Get(StringToV8(isolate_, key)); + // Check for existence before getting, otherwise this method will always + // returns true when T == v8::Local. + v8::Local context = isolate_->GetCurrentContext(); + v8::Local v8_key = StringToV8(isolate_, key); + if (!internal::IsTrue(GetHandle()->Has(context, v8_key))) + return false; + + v8::Local val; + if (!GetHandle()->Get(context, v8_key).ToLocal(&val)) + return false; return ConvertFromV8(isolate_, val, out); } template bool GetHidden(const base::StringPiece& key, T* out) const { - v8::Local val = GetHandle()->GetHiddenValue( - StringToV8(isolate_, key)); + v8::Local val = + GetHandle()->GetHiddenValue(StringToV8(isolate_, key)); return ConvertFromV8(isolate_, val, out); } template bool Set(const base::StringPiece& key, T val) { - return GetHandle()->Set(StringToV8(isolate_, key), - ConvertToV8(isolate_, val)); + v8::Local v8_value; + if (!TryConvertToV8(isolate_, val, &v8_value)) + return false; + v8::Maybe result = + GetHandle()->Set(isolate_->GetCurrentContext(), + StringToV8(isolate_, key), + v8_value); + return !result.IsNothing() && result.FromJust(); } template bool SetHidden(const base::StringPiece& key, T val) { - return GetHandle()->SetHiddenValue(StringToV8(isolate_, key), - ConvertToV8(isolate_, val)); + v8::Local v8_value; + if (!TryConvertToV8(isolate_, val, &v8_value)) + return false; + return GetHandle()->SetHiddenValue(StringToV8(isolate_, key), v8_value); } template