Reviewers: dcarney,

Message:
Here are some contexts:
https://codereview.chromium.org/993333002/#msg5
https://codereview.chromium.org/873983003/

In short, I think it's OK to add Cast() to Int32 and Uint32 and it will
make Blink and other embedders happy (less empty checks). WDYT?


Description:
Add Cast() for Int32 and Uint32

It should be possible to cast a Value to Int32 without throwing an exception
when IsInt32() is true. Same for Uint32.

BUG=chromium:462402
LOG=Y

Please review this at https://codereview.chromium.org/1003663002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+64, -24 lines):
  M include/v8.h
  M src/api.cc
  M src/objects.h
  M src/objects-inl.h


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index fc8ff5a3ff3097dc7ccf3ae4fe1d82f4760a5555..db625eeb4242be3d594628fdf8f2f450d0ef894e 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2465,8 +2465,11 @@ class V8_EXPORT Integer : public Number {
 class V8_EXPORT Int32 : public Integer {
  public:
   int32_t Value() const;
+  V8_INLINE static Int32* Cast(v8::Value* obj);
+
  private:
   Int32();
+  static void CheckCast(v8::Value* obj);
 };


@@ -2476,8 +2479,11 @@ class V8_EXPORT Int32 : public Integer {
 class V8_EXPORT Uint32 : public Integer {
  public:
   uint32_t Value() const;
+  V8_INLINE static Uint32* Cast(v8::Value* obj);
+
  private:
   Uint32();
+  static void CheckCast(v8::Value* obj);
 };


@@ -7364,6 +7370,22 @@ Integer* Integer::Cast(v8::Value* value) {
 }


+Int32* Int32::Cast(v8::Value* value) {
+#ifdef V8_ENABLE_CHECKS
+  CheckCast(value);
+#endif
+  return static_cast<Int32*>(value);
+}
+
+
+Uint32* Uint32::Cast(v8::Value* value) {
+#ifdef V8_ENABLE_CHECKS
+  CheckCast(value);
+#endif
+  return static_cast<Uint32*>(value);
+}
+
+
 Date* Date::Cast(v8::Value* value) {
 #ifdef V8_ENABLE_CHECKS
   CheckCast(value);
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index f285980f6b654d289e82f62bd4963b3c1ccab1a9..2658a8ebb950ef2d4f37fd58fcffb931ad054513 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2675,28 +2675,10 @@ bool Value::IsExternal() const {
 }


-bool Value::IsInt32() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (obj->IsSmi()) return true;
-  if (obj->IsNumber()) {
-    return i::IsInt32Double(obj->Number());
-  }
-  return false;
-}
+bool Value::IsInt32() const { return Utils::OpenHandle(this)->IsInt32(); }


-bool Value::IsUint32() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
-  if (obj->IsNumber()) {
-    double value = obj->Number();
-    return !i::IsMinusZero(value) &&
-        value >= 0 &&
-        value <= i::kMaxUInt32 &&
-        value == i::FastUI2D(i::FastD2UI(value));
-  }
-  return false;
-}
+bool Value::IsUint32() const { return Utils::OpenHandle(this)->IsUint32(); }


 static bool CheckConstructor(i::Isolate* isolate,
@@ -2973,6 +2955,20 @@ void v8::Integer::CheckCast(v8::Value* that) {
 }


+void v8::Int32::CheckCast(v8::Value* that) {
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  Utils::ApiCheck(obj->IsInt32(), "v8::Int32::Cast()",
+                  "Could not convert to 32-bit signed integer");
+}
+
+
+void v8::Uint32::CheckCast(v8::Value* that) {
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  Utils::ApiCheck(obj->IsUint32(), "v8::Uint32::Cast()",
+                  "Could not convert to 32-bit unsigned integer");
+}
+
+
 void v8::Array::CheckCast(Value* that) {
   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   Utils::ApiCheck(obj->IsJSArray(),
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 779fd39ef96f9c9b78456d0c22a1cb87efc05a15..2781ccff2e0530643a5d87a1473afefd22bec920 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -635,6 +635,26 @@ bool Object::IsNumber() const {
 }


+bool Object::IsInt32() const {
+  if (IsSmi()) return true;
+  if (IsNumber()) {
+    return IsInt32Double(Number());
+  }
+  return false;
+}
+
+
+bool Object::IsUint32() const {
+  if (IsSmi()) return Smi::cast(this)->value() >= 0;
+  if (IsNumber()) {
+    double value = Number();
+    return !i::IsMinusZero(value) && value >= 0 && value <= kMaxUInt32 &&
+           value == FastUI2D(i::FastD2UI(value));
+  }
+  return false;
+}
+
+
 TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
 TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)

@@ -1091,11 +1111,11 @@ bool Object::IsArgumentsMarker() const {
 }


-double Object::Number() {
+double Object::Number() const {
   DCHECK(IsNumber());
   return IsSmi()
-    ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
-    : reinterpret_cast<HeapNumber*>(this)->value();
+ ? static_cast<double>(reinterpret_cast<const Smi*>(this)->value())
+             : reinterpret_cast<const HeapNumber*>(this)->value();
 }


Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index ab7778ffba5c302580064068085c476833b76cde..382ee15df65819a11207d7a0f88e978f44db6bb7 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1052,9 +1052,11 @@ class Object {
   INLINE(bool IsFiller() const);

   // Extract the number.
-  inline double Number();
+  inline double Number() const;
   INLINE(bool IsNaN() const);
   INLINE(bool IsMinusZero() const);
+  INLINE(bool IsInt32() const);
+  INLINE(bool IsUint32() const);
   bool ToInt32(int32_t* value);
   bool ToUint32(uint32_t* value);



--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to