| Index: src/api.cc
 | 
| diff --git a/src/api.cc b/src/api.cc
 | 
| index 5fdc10eb2eb619198b58eea5c476a49e012a7d24..89b576819ceeedf5f776f5d78e6183b6c510b160 100644
 | 
| --- a/src/api.cc
 | 
| +++ b/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;
 | 
| +    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 maybe(i::Smi::cast(*num)->value());
 | 
|    } 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);
 | 
| +    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 i::Smi::cast(*num)->value();
 | 
| +    return maybe(static_cast<uint32_t>(i::Smi::cast(*num)->value()));
 | 
|    } else {
 | 
| -    return static_cast<int64_t>(num->Number());
 | 
| +    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);
 | 
| 
 |