convert Value::*Value() function to return Maybe results
BUG=v8:3929 LOG=Y Review URL: https://codereview.chromium.org/959223002 Cr-Commit-Position: refs/heads/master@{#26914}
This commit is contained in:
parent
627ffe9af2
commit
8d839ead04
34
include/v8.h
34
include/v8.h
@ -977,12 +977,31 @@ class V8_EXPORT EscapableHandleScope : public HandleScope {
|
||||
* A simple Maybe type, representing an object which may or may not have a
|
||||
* value.
|
||||
*/
|
||||
template<class T>
|
||||
struct Maybe {
|
||||
template <class T>
|
||||
class Maybe {
|
||||
public:
|
||||
Maybe() : has_value(false) {}
|
||||
explicit Maybe(T t) : has_value(true), value(t) {}
|
||||
Maybe(bool has, T t) : has_value(has), value(t) {}
|
||||
explicit Maybe(const T& t) : has_value(true), value(t) {}
|
||||
// TODO(dcarney): remove this constructor, it makes no sense.
|
||||
Maybe(bool has, const T& t) : has_value(has), value(t) {}
|
||||
|
||||
V8_INLINE bool HasValue() const { return has_value; }
|
||||
|
||||
V8_WARN_UNUSED_RESULT V8_INLINE bool ToValue(T* out) const {
|
||||
*out = has_value ? value : T();
|
||||
return has_value;
|
||||
}
|
||||
|
||||
V8_INLINE T ToValueChecked() const {
|
||||
// TODO(dcarney): add DCHECK.
|
||||
return value;
|
||||
}
|
||||
|
||||
V8_INLINE T From(const T& default_value) const {
|
||||
return has_value ? value : default_value;
|
||||
}
|
||||
|
||||
// TODO(dcarney): make private.
|
||||
bool has_value;
|
||||
T value;
|
||||
};
|
||||
@ -1921,6 +1940,13 @@ class V8_EXPORT Value : public Data {
|
||||
*/
|
||||
Local<Uint32> ToArrayIndex() const;
|
||||
|
||||
Maybe<bool> BooleanValue(Local<Context> context) const;
|
||||
Maybe<double> NumberValue(Local<Context> context) const;
|
||||
Maybe<int64_t> IntegerValue(Local<Context> context) const;
|
||||
Maybe<uint32_t> Uint32Value(Local<Context> context) const;
|
||||
Maybe<int32_t> Int32Value(Local<Context> context) const;
|
||||
|
||||
// TODO(dcarney): deprecate all these.
|
||||
bool BooleanValue() const;
|
||||
double NumberValue() const;
|
||||
int64_t IntegerValue() const;
|
||||
|
155
src/api.cc
155
src/api.cc
@ -2643,6 +2643,12 @@ bool Value::IsSetIterator() const {
|
||||
} while (false);
|
||||
|
||||
|
||||
static Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) {
|
||||
return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate())
|
||||
->GetCurrentContext();
|
||||
}
|
||||
|
||||
|
||||
MaybeLocal<String> Value::ToString(Local<Context> context) const {
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsString()) return ToApiHandle<String>(obj);
|
||||
@ -2989,51 +2995,115 @@ void v8::RegExp::CheckCast(v8::Value* that) {
|
||||
}
|
||||
|
||||
|
||||
Maybe<bool> Value::BooleanValue(Local<Context> context) const {
|
||||
return maybe(Utils::OpenHandle(this)->BooleanValue());
|
||||
}
|
||||
|
||||
|
||||
bool Value::BooleanValue() const {
|
||||
return Utils::OpenHandle(this)->BooleanValue();
|
||||
}
|
||||
|
||||
|
||||
Maybe<double> Value::NumberValue(Local<Context> context) const {
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) return maybe(obj->Number());
|
||||
CONTEXT_SCOPE_GET_ISOLATE(context, "NumberValue");
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
i::Handle<i::Object> num;
|
||||
has_pending_exception = !i::Execution::ToNumber(isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, Maybe<double>());
|
||||
return maybe(num->Number());
|
||||
}
|
||||
|
||||
|
||||
double Value::NumberValue() const {
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) return obj->Number();
|
||||
return NumberValue(ContextFromHeapObject(obj))
|
||||
.From(std::numeric_limits<double>::quiet_NaN());
|
||||
}
|
||||
|
||||
|
||||
Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> num;
|
||||
if (obj->IsNumber()) {
|
||||
num = obj;
|
||||
} else {
|
||||
i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
||||
LOG_API(isolate, "NumberValue");
|
||||
ENTER_V8(isolate);
|
||||
CONTEXT_SCOPE_GET_ISOLATE(context, "IntegerValue");
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
has_pending_exception = !i::Execution::ToNumber(
|
||||
isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, std::numeric_limits<double>::quiet_NaN());
|
||||
has_pending_exception =
|
||||
!i::Execution::ToInteger(isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, Maybe<int64_t>());
|
||||
}
|
||||
if (num->IsSmi()) {
|
||||
return maybe(static_cast<int64_t>(i::Smi::cast(*num)->value()));
|
||||
} else {
|
||||
return maybe(static_cast<int64_t>(num->Number()));
|
||||
}
|
||||
return num->Number();
|
||||
}
|
||||
|
||||
|
||||
int64_t Value::IntegerValue() const {
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> num;
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) {
|
||||
num = obj;
|
||||
} else {
|
||||
i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
||||
LOG_API(isolate, "IntegerValue");
|
||||
ENTER_V8(isolate);
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
has_pending_exception = !i::Execution::ToInteger(
|
||||
isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, 0);
|
||||
if (obj->IsSmi()) {
|
||||
return i::Smi::cast(*obj)->value();
|
||||
} else {
|
||||
return static_cast<int64_t>(obj->Number());
|
||||
}
|
||||
}
|
||||
return IntegerValue(ContextFromHeapObject(obj)).From(0);
|
||||
}
|
||||
|
||||
|
||||
Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) return maybe(NumberToInt32(*obj));
|
||||
CONTEXT_SCOPE_GET_ISOLATE(context, "Int32Value");
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
i::Handle<i::Object> num;
|
||||
has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, Maybe<int32_t>());
|
||||
if (num->IsSmi()) {
|
||||
return i::Smi::cast(*num)->value();
|
||||
return maybe(i::Smi::cast(*num)->value());
|
||||
} else {
|
||||
return static_cast<int64_t>(num->Number());
|
||||
return maybe(static_cast<int32_t>(num->Number()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32_t Value::Int32Value() const {
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) return NumberToInt32(*obj);
|
||||
return Int32Value(ContextFromHeapObject(obj)).From(0);
|
||||
}
|
||||
|
||||
|
||||
Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) return maybe(NumberToUint32(*obj));
|
||||
CONTEXT_SCOPE_GET_ISOLATE(context, "Uint32Value");
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
i::Handle<i::Object> num;
|
||||
has_pending_exception = !i::Execution::ToUint32(isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, Maybe<uint32_t>());
|
||||
if (num->IsSmi()) {
|
||||
return maybe(static_cast<uint32_t>(i::Smi::cast(*num)->value()));
|
||||
} else {
|
||||
return maybe(static_cast<uint32_t>(num->Number()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t Value::Uint32Value() const {
|
||||
auto obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) return NumberToUint32(*obj);
|
||||
return Uint32Value(ContextFromHeapObject(obj)).From(0);
|
||||
}
|
||||
|
||||
|
||||
Local<Uint32> Value::ToArrayIndex() const {
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
if (obj->IsSmi()) {
|
||||
@ -3063,27 +3133,6 @@ Local<Uint32> Value::ToArrayIndex() const {
|
||||
}
|
||||
|
||||
|
||||
int32_t Value::Int32Value() const {
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) {
|
||||
return NumberToInt32(*obj);
|
||||
} else {
|
||||
i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
||||
LOG_API(isolate, "Int32Value (slow)");
|
||||
ENTER_V8(isolate);
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
i::Handle<i::Object> num;
|
||||
has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, 0);
|
||||
if (num->IsSmi()) {
|
||||
return i::Smi::cast(*num)->value();
|
||||
} else {
|
||||
return static_cast<int32_t>(num->Number());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Value::Equals(Handle<Value> that) const {
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
|
||||
i::Handle<i::Object> other = Utils::OpenHandle(*that);
|
||||
@ -3164,28 +3213,6 @@ bool Value::SameValue(Handle<Value> that) const {
|
||||
}
|
||||
|
||||
|
||||
uint32_t Value::Uint32Value() const {
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
if (obj->IsNumber()) {
|
||||
return NumberToUint32(*obj);
|
||||
} else {
|
||||
i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
||||
LOG_API(isolate, "Uint32Value");
|
||||
ENTER_V8(isolate);
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
i::Handle<i::Object> num;
|
||||
has_pending_exception = !i::Execution::ToUint32(
|
||||
isolate, obj).ToHandle(&num);
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, 0);
|
||||
if (num->IsSmi()) {
|
||||
return i::Smi::cast(*num)->value();
|
||||
} else {
|
||||
return static_cast<uint32_t>(num->Number());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
ON_BAILOUT(isolate, "v8::Object::Set()", return false);
|
||||
|
Loading…
Reference in New Issue
Block a user