Commit 30637108 authored by Sven Panne's avatar Sven Panne

Polish Maybe API a bit, removing useless creativity and fixing some signatures.

BUG=v8:3929
LOG=y
R=dcarney@chromium.org

Review URL: https://codereview.chromium.org/967243002

Cr-Commit-Position: refs/heads/master@{#26936}
parent 502898ef
......@@ -81,6 +81,8 @@ class ImplementationUtilities;
class Int32;
class Integer;
class Isolate;
template <class T>
class Maybe;
class Name;
class Number;
class NumberObject;
......@@ -973,47 +975,6 @@ class V8_EXPORT EscapableHandleScope : public HandleScope {
};
/**
* A simple Maybe type, representing an object which may or may not have a
* value.
*/
template <class T>
class Maybe {
public:
Maybe() : has_value(false) {}
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;
};
// Convenience wrapper.
template <class T>
inline Maybe<T> maybe(T t) {
return Maybe<T>(t);
}
// --- Special objects ---
......@@ -5750,8 +5711,12 @@ class V8_EXPORT V8 {
int* index);
static Local<Value> GetEternal(Isolate* isolate, int index);
static void CheckIsJust(bool is_just);
template <class T> friend class Handle;
template <class T> friend class Local;
template <class T>
friend class Maybe;
template <class T> friend class Eternal;
template <class T> friend class PersistentBase;
template <class T, class M> friend class Persistent;
......@@ -5759,6 +5724,56 @@ class V8_EXPORT V8 {
};
/**
* A simple Maybe type, representing an object which may or may not have a
* value.
*/
template <class T>
class Maybe {
public:
// TODO(dcarney): remove this constructor, it makes no sense.
Maybe(bool has, const T& t) : has_value(has), value(t) {}
V8_INLINE bool IsJust() const { return has_value; }
V8_INLINE T FromJust() const {
#ifdef V8_ENABLE_CHECKS
V8::CheckIsJust(IsJust());
#endif
return value;
}
V8_INLINE T FromMaybe(const T& default_value) const {
return has_value ? value : default_value;
}
// TODO(dcarney): make private.
bool has_value;
T value;
private:
template <class U>
friend Maybe<U> Nothing();
template <class U>
friend Maybe<U> Just(const U& u);
Maybe() : has_value(false) {}
explicit Maybe(const T& t) : has_value(true), value(t) {}
};
template <class T>
inline Maybe<T> Nothing() {
return Maybe<T>();
}
template <class T>
inline Maybe<T> Just(const T& t) {
return Maybe<T>(t);
}
/**
* An external exception handler.
*/
......
......@@ -471,6 +471,11 @@ Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
}
void V8::CheckIsJust(bool is_just) {
Utils::ApiCheck(is_just, "v8::FromJust", "Maybe value is Nothing.");
}
// --- H a n d l e s ---
......@@ -2996,7 +3001,7 @@ void v8::RegExp::CheckCast(v8::Value* that) {
Maybe<bool> Value::BooleanValue(Local<Context> context) const {
return maybe(Utils::OpenHandle(this)->BooleanValue());
return Just(Utils::OpenHandle(this)->BooleanValue());
}
......@@ -3007,13 +3012,13 @@ bool Value::BooleanValue() const {
Maybe<double> Value::NumberValue(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return maybe(obj->Number());
if (obj->IsNumber()) return Just(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());
EXCEPTION_BAILOUT_CHECK(isolate, Nothing<double>());
return Just(num->Number());
}
......@@ -3021,7 +3026,7 @@ double Value::NumberValue() const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return obj->Number();
return NumberValue(ContextFromHeapObject(obj))
.From(std::numeric_limits<double>::quiet_NaN());
.FromMaybe(std::numeric_limits<double>::quiet_NaN());
}
......@@ -3035,13 +3040,10 @@ Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
EXCEPTION_PREAMBLE(isolate);
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()));
EXCEPTION_BAILOUT_CHECK(isolate, Nothing<int64_t>());
}
return Just(num->IsSmi() ? static_cast<int64_t>(i::Smi::cast(*num)->value())
: static_cast<int64_t>(num->Number()));
}
......@@ -3054,53 +3056,47 @@ int64_t Value::IntegerValue() const {
return static_cast<int64_t>(obj->Number());
}
}
return IntegerValue(ContextFromHeapObject(obj)).From(0);
return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0);
}
Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return maybe(NumberToInt32(*obj));
if (obj->IsNumber()) return Just(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 maybe(i::Smi::cast(*num)->value());
} else {
return maybe(static_cast<int32_t>(num->Number()));
}
EXCEPTION_BAILOUT_CHECK(isolate, Nothing<int32_t>());
return Just(num->IsSmi() ? i::Smi::cast(*num)->value()
: 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);
return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0);
}
Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) return maybe(NumberToUint32(*obj));
if (obj->IsNumber()) return Just(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()));
}
EXCEPTION_BAILOUT_CHECK(isolate, Nothing<uint32_t>());
return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value())
: 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);
return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0);
}
......@@ -3589,7 +3585,7 @@ bool v8::Object::Has(v8::Handle<Value> key) {
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
Maybe<bool> maybe;
Maybe<bool> maybe = Nothing<bool>();
// Check if the given key is an array index.
uint32_t index;
if (key_obj->ToArrayIndex(&index)) {
......@@ -3803,8 +3799,9 @@ static Local<Value> GetPropertyByLookup(i::LookupIterator* it) {
static Maybe<PropertyAttribute> GetPropertyAttributesByLookup(
i::LookupIterator* it) {
Maybe<PropertyAttributes> attr = i::JSReceiver::GetPropertyAttributes(it);
if (!it->IsFound()) return Maybe<PropertyAttribute>();
return Maybe<PropertyAttribute>(static_cast<PropertyAttribute>(attr.value));
return it->IsFound() ? Just<PropertyAttribute>(
static_cast<PropertyAttribute>(attr.value))
: Nothing<PropertyAttribute>();
}
......@@ -3831,12 +3828,12 @@ v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate,
"v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()",
return Maybe<PropertyAttribute>());
return Nothing<PropertyAttribute>());
ENTER_V8(isolate);
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::PrototypeIterator iter(isolate, self_obj);
if (iter.IsAtEnd()) return Maybe<PropertyAttribute>();
if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
i::Handle<i::Object> proto = i::PrototypeIterator::GetCurrent(iter);
i::LookupIterator it(self_obj, key_obj, i::Handle<i::JSReceiver>::cast(proto),
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
......@@ -3861,7 +3858,7 @@ Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetRealNamedPropertyAttributes()",
return Maybe<PropertyAttribute>());
return Nothing<PropertyAttribute>());
ENTER_V8(isolate);
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
......
......@@ -2073,8 +2073,7 @@ class BinaryOperation FINAL : public Expression {
return TypeFeedbackId(local_id(1));
}
Maybe<int> fixed_right_arg() const {
return has_fixed_right_arg_ ? Maybe<int>(fixed_right_arg_value_)
: Maybe<int>();
return has_fixed_right_arg_ ? Just(fixed_right_arg_value_) : Nothing<int>();
}
void set_fixed_right_arg(Maybe<int> arg) {
has_fixed_right_arg_ = arg.has_value;
......
......@@ -131,7 +131,7 @@ static Maybe<PropertyAttributes> UnscopableLookup(LookupIterator* it) {
MaybeHandle<Object> maybe_unscopables =
Object::GetProperty(receiver, unscopables_symbol);
if (!maybe_unscopables.ToHandle(&unscopables)) {
return Maybe<PropertyAttributes>();
return Nothing<PropertyAttributes>();
}
if (!unscopables->IsSpecObject()) return attrs;
Handle<Object> blacklist;
......@@ -139,10 +139,9 @@ static Maybe<PropertyAttributes> UnscopableLookup(LookupIterator* it) {
Object::GetProperty(unscopables, it->name());
if (!maybe_blacklist.ToHandle(&blacklist)) {
DCHECK(isolate->has_pending_exception());
return Maybe<PropertyAttributes>();
return Nothing<PropertyAttributes>();
}
if (!blacklist->IsUndefined()) return maybe(ABSENT);
return attrs;
return blacklist->IsUndefined() ? attrs : Just(ABSENT);
}
static void GetAttributesAndBindingFlags(VariableMode mode,
......@@ -254,7 +253,7 @@ Handle<Object> Context::Lookup(Handle<String> name,
// Context extension objects needs to behave as if they have no
// prototype. So even if we want to follow prototype chains, we need
// to only do a local lookup for context extension objects.
Maybe<PropertyAttributes> maybe;
Maybe<PropertyAttributes> maybe = Nothing<PropertyAttributes>();
if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
object->IsJSContextExtensionObject()) {
maybe = JSReceiver::GetOwnPropertyAttributes(object, name);
......
......@@ -45,7 +45,7 @@ STATIC_CONST_MEMBER_DEFINITION const int BinaryOpICState::LAST_TOKEN;
BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
: isolate_(isolate) {
: fixed_right_arg_(Nothing<int>()), isolate_(isolate) {
op_ =
static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
fixed_right_arg_ =
......
......@@ -63,6 +63,7 @@ class BinaryOpICState FINAL BASE_EMBEDDED {
left_kind_(NONE),
right_kind_(NONE),
result_kind_(NONE),
fixed_right_arg_(Nothing<int>()),
isolate_(isolate) {
DCHECK_LE(FIRST_TOKEN, op);
DCHECK_LE(op, LAST_TOKEN);
......
......@@ -6961,8 +6961,7 @@ Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
return JSProxy::HasPropertyWithHandler(proxy, name);
}
Maybe<PropertyAttributes> result = GetPropertyAttributes(object, name);
if (!result.has_value) return Maybe<bool>();
return maybe(result.value != ABSENT);
return result.has_value ? Just(result.value != ABSENT) : Nothing<bool>();
}
......@@ -6973,8 +6972,7 @@ Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
return JSProxy::HasPropertyWithHandler(proxy, name);
}
Maybe<PropertyAttributes> result = GetOwnPropertyAttributes(object, name);
if (!result.has_value) return Maybe<bool>();
return maybe(result.value != ABSENT);
return result.has_value ? Just(result.value != ABSENT) : Nothing<bool>();
}
......@@ -7033,8 +7031,7 @@ Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
}
Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver(
Handle<JSObject>::cast(object), object, index, true);
if (!result.has_value) return Maybe<bool>();
return maybe(result.value != ABSENT);
return result.has_value ? Just(result.value != ABSENT) : Nothing<bool>();
}
......@@ -7046,8 +7043,7 @@ Maybe<bool> JSReceiver::HasOwnElement(Handle<JSReceiver> object,
}
Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver(
Handle<JSObject>::cast(object), object, index, false);
if (!result.has_value) return Maybe<bool>();
return maybe(result.value != ABSENT);
return result.has_value ? Just(result.value != ABSENT) : Nothing<bool>();
}
......
This diff is collapsed.
......@@ -772,7 +772,7 @@ RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
// Fast case: either the key is a real named property or it is not
// an array index and there are no interceptors or hidden
// prototypes.
Maybe<bool> maybe;
Maybe<bool> maybe = Nothing<bool>();
if (key_is_array_index) {
maybe = JSObject::HasOwnElement(js_obj, index);
} else {
......
......@@ -279,7 +279,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
DCHECK(op < BinaryOpICState::FIRST_TOKEN ||
op > BinaryOpICState::LAST_TOKEN);
*left = *right = *result = Type::None(zone());
*fixed_right_arg = Maybe<int>();
*fixed_right_arg = Nothing<int>();
*allocation_site = Handle<AllocationSite>::null();
return;
}
......
......@@ -655,7 +655,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
Type* type;
Type* left_type;
Type* right_type;
Maybe<int> fixed_right_arg;
Maybe<int> fixed_right_arg = Nothing<int>();
Handle<AllocationSite> allocation_site;
oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
&left_type, &right_type, &type, &fixed_right_arg,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment