- Added const in a few places.
authorchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Oct 2008 08:25:23 +0000 (08:25 +0000)
committerchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Oct 2008 08:25:23 +0000 (08:25 +0000)
- Changed WeakReferenceCallback to take a Persistent<Value> instead of
  a Persistent<Object>.
- Removed Message::GetUnderline and Message::GetScriptData.
- Added Value::IsDate, Date::Cast and Date::Value.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@564 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

12 files changed:
include/v8.h
src/api.cc
src/debug.cc
src/debug.h
src/handles.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/runtime.cc
test/cctest/test-api.cc
test/cctest/test-heap.cc
test/cctest/test-mark-compact.cc

index c683fb9..d463393 100644 (file)
@@ -128,7 +128,7 @@ class Data;
  * \param object the weak global object to be reclaimed by the garbage collector
  * \param parameter the value passed in when making the weak global object
  */
-typedef void (*WeakReferenceCallback)(Persistent<Object> object,
+typedef void (*WeakReferenceCallback)(Persistent<Value> object,
                                       void* parameter);
 
 
@@ -512,9 +512,9 @@ class EXPORT ScriptOrigin {
       : resource_name_(resource_name),
         resource_line_offset_(resource_line_offset),
         resource_column_offset_(resource_column_offset) { }
-  inline Handle<Value> ResourceName();
-  inline Handle<Integer> ResourceLineOffset();
-  inline Handle<Integer> ResourceColumnOffset();
+  inline Handle<Value> ResourceName() const;
+  inline Handle<Integer> ResourceLineOffset() const;
+  inline Handle<Integer> ResourceColumnOffset() const;
  private:
   Handle<Value> resource_name_;
   Handle<Integer> resource_line_offset_;
@@ -559,16 +559,7 @@ class EXPORT Message {
   Local<String> Get();
   Local<String> GetSourceLine();
 
-  // TODO(1241256): Rewrite (or remove) this method.  We don't want to
-  // deal with ownership of the returned string and we want to use
-  // JavaScript data structures exclusively.
-  char* GetUnderline(char* source_line, char underline_char);
-
-  Handle<String> GetScriptResourceName();
-
-  // TODO(1240903): Remove this when no longer used in WebKit V8
-  // bindings.
-  Handle<Value> GetSourceData();
+  Handle<Value> GetScriptResourceName();
 
   /**
    * Returns the number, 1-based, of the line where the error occurred.
@@ -676,6 +667,11 @@ class EXPORT Value : public Data {
    */
   bool IsInt32();
 
+  /**
+   * Returns true if this value is a Date.
+   */
+  bool IsDate();
+
   Local<Boolean> ToBoolean();
   Local<Number> ToNumber();
   Local<String> ToString();
@@ -991,6 +987,14 @@ class EXPORT Uint32 : public Integer {
 class EXPORT Date : public Value {
  public:
   static Local<Value> New(double time);
+
+  /**
+   * A specialization of Value::NumberValue that is more efficient
+   * because we know the structure of this object.
+   */
+  double NumberValue();
+
+  static Date* Cast(v8::Value* obj);
 };
 
 
@@ -1745,11 +1749,11 @@ Handle<Boolean> EXPORT False();
 class EXPORT ResourceConstraints {
  public:
   ResourceConstraints();
-  int max_young_space_size() { return max_young_space_size_; }
+  int max_young_space_size() const { return max_young_space_size_; }
   void set_max_young_space_size(int value) { max_young_space_size_ = value; }
-  int max_old_space_size() { return max_old_space_size_; }
+  int max_old_space_size() const { return max_old_space_size_; }
   void set_max_old_space_size(int value) { max_old_space_size_ = value; }
-  uint32_t* stack_limit() { return stack_limit_; }
+  uint32_t* stack_limit() const { return stack_limit_; }
   void set_stack_limit(uint32_t* value) { stack_limit_ = value; }
  private:
   int max_young_space_size_;
@@ -1980,7 +1984,7 @@ class EXPORT TryCatch {
   /**
    * Returns true if an exception has been caught by this try/catch block.
    */
-  bool HasCaught();
+  bool HasCaught() const;
 
   /**
    * Returns the exception caught by this try/catch block.  If no exception has
@@ -1988,7 +1992,7 @@ class EXPORT TryCatch {
    *
    * The returned handle is valid until this TryCatch block has been destroyed.
    */
-  Local<Value> Exception();
+  Local<Value> Exception() const;
 
   /**
    * Returns the message associated with this exception.  If there is
@@ -1997,7 +2001,7 @@ class EXPORT TryCatch {
    * The returned handle is valid until this TryCatch block has been
    * destroyed.
    */
-  Local<v8::Message> Message();
+  Local<v8::Message> Message() const;
 
   /**
    * Clears any exceptions that may have been caught by this try/catch block.
@@ -2373,17 +2377,17 @@ Local<T> HandleScope::Close(Handle<T> value) {
   return Local<T>(reinterpret_cast<T*>(after));
 }
 
-Handle<Value> ScriptOrigin::ResourceName() {
+Handle<Value> ScriptOrigin::ResourceName() const {
   return resource_name_;
 }
 
 
-Handle<Integer> ScriptOrigin::ResourceLineOffset() {
+Handle<Integer> ScriptOrigin::ResourceLineOffset() const {
   return resource_line_offset_;
 }
 
 
-Handle<Integer> ScriptOrigin::ResourceColumnOffset() {
+Handle<Integer> ScriptOrigin::ResourceColumnOffset() const {
   return resource_column_offset_;
 }
 
index b694007..b4dd60e 100644 (file)
@@ -1084,12 +1084,12 @@ v8::TryCatch::~TryCatch() {
 }
 
 
-bool v8::TryCatch::HasCaught() {
+bool v8::TryCatch::HasCaught() const {
   return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
 }
 
 
-v8::Local<Value> v8::TryCatch::Exception() {
+v8::Local<Value> v8::TryCatch::Exception() const {
   if (HasCaught()) {
     // Check for out of memory exception.
     i::Object* exception = reinterpret_cast<i::Object*>(exception_);
@@ -1100,7 +1100,7 @@ v8::Local<Value> v8::TryCatch::Exception() {
 }
 
 
-v8::Local<v8::Message> v8::TryCatch::Message() {
+v8::Local<v8::Message> v8::TryCatch::Message() const {
   if (HasCaught() && message_ != i::Smi::FromInt(0)) {
     i::Object* message = reinterpret_cast<i::Object*>(message_);
     return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
@@ -1139,7 +1139,7 @@ Local<String> Message::Get() {
 }
 
 
-v8::Handle<String> Message::GetScriptResourceName() {
+v8::Handle<Value> Message::GetScriptResourceName() {
   if (IsDeadCheck("v8::Message::GetScriptResourceName()")) {
     return Local<String>();
   }
@@ -1150,22 +1150,10 @@ v8::Handle<String> Message::GetScriptResourceName() {
   i::Handle<i::JSValue> script =
       i::Handle<i::JSValue>::cast(GetProperty(obj, "script"));
   i::Handle<i::Object> resource_name(i::Script::cast(script->value())->name());
-  if (!resource_name->IsString()) {
-    return Local<String>();
-  }
-  Local<String> result =
-      Utils::ToLocal(i::Handle<i::String>::cast(resource_name));
-  return scope.Close(result);
+  return scope.Close(Utils::ToLocal(resource_name));
 }
 
 
-// TODO(1240903): Remove this when no longer used in WebKit V8 bindings.
-Handle<Value> Message::GetSourceData() {
-  Handle<String> data = GetScriptResourceName();
-  if (data.IsEmpty()) return v8::Undefined();
-  return data;
-}
-
 static i::Handle<i::Object> CallV8HeapFunction(const char* name,
                                                i::Handle<i::Object> recv,
                                                int argc,
@@ -1268,53 +1256,6 @@ Local<String> Message::GetSourceLine() {
 }
 
 
-char* Message::GetUnderline(char* source_line, char underline_char) {
-  if (IsDeadCheck("v8::Message::GetUnderline()")) return 0;
-  HandleScope scope;
-
-  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
-  int start_pos = static_cast<int>(GetProperty(data_obj, "startPos")->Number());
-  int end_pos = static_cast<int>(GetProperty(data_obj, "endPos")->Number());
-  EXCEPTION_PREAMBLE();
-  i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
-      "GetPositionInLine",
-      data_obj,
-      &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(0);
-  int start_col = static_cast<int>(start_col_obj->Number());
-  int end_col = start_col + (end_pos - start_pos);
-
-  // Any tabs before or between the selected columns have to be
-  // expanded into spaces.  We assume that a tab character advances
-  // the cursor up until the next 8-character boundary and at least
-  // one character.
-  int real_start_col = 0;
-  for (int i = 0; i < start_col; i++) {
-    real_start_col++;
-    if (source_line[i] == '\t') {
-      real_start_col++;
-      while (real_start_col % 8 != 0)
-        real_start_col++;
-    }
-  }
-  int real_end_col = real_start_col;
-  for (int i = start_col; i < end_col; i++) {
-    real_end_col++;
-    if (source_line[i] == '\t') {
-      while (real_end_col % 8 != 0)
-        real_end_col++;
-    }
-  }
-  char* result = i::NewArray<char>(real_end_col + 1);
-  for (int i = 0; i < real_start_col; i++)
-    result[i] = ' ';
-  for (int i = real_start_col; i < real_end_col; i++)
-    result[i] = underline_char;
-  result[real_end_col] = '\0';
-  return result;
-}
-
-
 void Message::PrintCurrentStackTrace(FILE* out) {
   if (IsDeadCheck("v8::Message::PrintCurrentStackTrace()")) return;
   i::Top::PrintCurrentStackTrace(out);
@@ -1401,6 +1342,13 @@ bool Value::IsInt32() {
 }
 
 
+bool Value::IsDate() {
+  if (IsDeadCheck("v8::Value::IsDate()")) return false;
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  return obj->HasSpecificClassOf(i::Heap::Date_symbol());
+}
+
+
 Local<String> Value::ToString() {
   if (IsDeadCheck("v8::Value::ToString()")) return Local<String>();
   LOG_API("ToString");
@@ -1561,6 +1509,16 @@ v8::Array* v8::Array::Cast(Value* that) {
 }
 
 
+v8::Date* v8::Date::Cast(v8::Value* that) {
+  if (IsDeadCheck("v8::Date::Cast()")) return 0;
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  ApiCheck(obj->HasSpecificClassOf(i::Heap::Date_symbol()),
+           "v8::Date::Cast()",
+           "Could not convert to date");
+  return static_cast<v8::Date*>(that);
+}
+
+
 bool Value::BooleanValue() {
   if (IsDeadCheck("v8::Value::BooleanValue()")) return false;
   LOG_API("BooleanValue");
@@ -2462,7 +2420,7 @@ i::Handle<i::String> NewExternalAsciiStringHandle(
 }
 
 
-static void DisposeExternalString(v8::Persistent<v8::Object> obj,
+static void DisposeExternalString(v8::Persistent<v8::Value> obj,
                                   void* parameter) {
   v8::String::ExternalStringResource* resource =
     reinterpret_cast<v8::String::ExternalStringResource*>(parameter);
@@ -2473,7 +2431,7 @@ static void DisposeExternalString(v8::Persistent<v8::Object> obj,
 }
 
 
-static void DisposeExternalAsciiString(v8::Persistent<v8::Object> obj,
+static void DisposeExternalAsciiString(v8::Persistent<v8::Value> obj,
                                        void* parameter) {
   v8::String::ExternalAsciiStringResource* resource =
     reinterpret_cast<v8::String::ExternalAsciiStringResource*>(parameter);
@@ -2534,6 +2492,15 @@ Local<v8::Value> v8::Date::New(double time) {
 }
 
 
+double v8::Date::NumberValue() {
+  if (IsDeadCheck("v8::Date::NumberValue()")) return 0;
+  LOG_API("Date::NumberValue");
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+  return jsvalue->value()->Number();
+}
+
+
 Local<v8::Array> v8::Array::New(int length) {
   EnsureInitialized("v8::Array::New()");
   LOG_API("Array::New");
index d43ada4..33fafe7 100644 (file)
@@ -451,7 +451,7 @@ Code* Debug::debug_break_return_entry_ = NULL;
 Code* Debug::debug_break_return_ = NULL;
 
 
-void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Object> obj, void* data) {
+void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
   DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data);
   RemoveDebugInfo(node->debug_info());
 #ifdef DEBUG
index efcbf0a..69e2aaa 100644 (file)
@@ -248,7 +248,7 @@ class Debug {
   static const int kEstimatedNofDebugInfoEntries = 16;
   static const int kEstimatedNofBreakPointsInFunction = 16;
 
-  static void HandleWeakDebugInfo(v8::Persistent<v8::Object> obj, void* data);
+  static void HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data);
 
   friend class Debugger;
   friend Handle<FixedArray> GetDebuggedFunctions();  // Found in test-debug.cc
index 222876d..1a600db 100644 (file)
@@ -248,7 +248,7 @@ Handle<JSObject> Copy(Handle<JSObject> obj) {
 // collector will call the weak callback on the global handle
 // associated with the wrapper and get rid of both the wrapper and the
 // handle.
-static void ClearWrapperCache(Persistent<v8::Object> handle, void*) {
+static void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
   Handle<Object> cache = Utils::OpenHandle(*handle);
   JSValue* wrapper = JSValue::cast(*cache);
   Proxy* proxy = Script::cast(wrapper->value())->wrapper();
index 152d1c3..da6e005 100644 (file)
@@ -475,6 +475,11 @@ Object* Object::ToSmi() {
 }
 
 
+bool Object::HasSpecificClassOf(String* name) {
+  return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
+}
+
+
 Object* Object::GetElement(uint32_t index) {
   return GetElementWithReceiver(this, index);
 }
index e5b7643..0bf936c 100644 (file)
@@ -3719,36 +3719,33 @@ static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) {
 // int-sized blocks of characters.
 template <typename Char>
 static inline bool CompareRawStringContents(Vector<Char> a, Vector<Char> b) {
-  // Lint complains about taking sizeof a type rather than a variable.
-  // That's just stupid in this case so I'm turning it off.
-  const int kStepSize = sizeof(int) / sizeof(Char);  // NOLINT
   int length = a.length();
   ASSERT_EQ(length, b.length());
-  int endpoint = length - kStepSize;
   const Char* pa = a.start();
   const Char* pb = b.start();
+  int i = 0;
 #ifndef CAN_READ_UNALIGNED
   // If this architecture isn't comfortable reading unaligned ints
-  // then we have to check that the strings are alingned and fall back
-  // to the standard comparison if they are not.
+  // then we have to check that the strings are aligned before
+  // comparing them blockwise.
   const int kAlignmentMask = sizeof(uint32_t) - 1;  // NOLINT
   uint32_t pa_addr = reinterpret_cast<uint32_t>(pa);
   uint32_t pb_addr = reinterpret_cast<uint32_t>(pb);
-  if ((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask) != 0) {
-    VectorIterator<Char> ia(a);
-    VectorIterator<Char> ib(b);
-    return CompareStringContents(&ia, &ib);
-  }
+  if ((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask) == 0) {
 #endif
-  int i;
-  // Compare blocks until we reach near the end of the string.
-  for (i = 0; i <= endpoint; i += kStepSize) {
-    uint32_t wa = *reinterpret_cast<const uint32_t*>(pa + i);
-    uint32_t wb = *reinterpret_cast<const uint32_t*>(pb + i);
-    if (wa != wb) {
-      return false;
+    const int kStepSize = sizeof(int) / sizeof(Char);  // NOLINT
+    int endpoint = length - kStepSize;
+    // Compare blocks until we reach near the end of the string.
+    for (; i <= endpoint; i += kStepSize) {
+      uint32_t wa = *reinterpret_cast<const uint32_t*>(pa + i);
+      uint32_t wb = *reinterpret_cast<const uint32_t*>(pb + i);
+      if (wa != wb) {
+        return false;
+      }
     }
+#ifndef CAN_READ_UNALIGNED
   }
+#endif
   // Compare the remaining characters that didn't fit into a block.
   for (; i < length; i++) {
     if (a[i] != b[i]) {
index 3e9e966..381bc5d 100644 (file)
@@ -657,6 +657,8 @@ class Object BASE_EMBEDDED {
   // Extract the number.
   inline double Number();
 
+  inline bool HasSpecificClassOf(String* name);
+
   Object* ToObject();             // ECMA-262 9.9.
   Object* ToBoolean();            // ECMA-262 9.2.
 
index b7e3ad9..35aa3e7 100644 (file)
@@ -221,53 +221,46 @@ static Object* Runtime_ClassOf(Arguments args) {
   return JSObject::cast(obj)->class_name();
 }
 
-inline static Object* HasSpecificClassOf(Arguments args, String* name) {
-  NoHandleAllocation ha;
-  ASSERT(args.length() == 1);
-  Object* obj = args[0];
-  if (obj->IsJSObject() && (JSObject::cast(obj)->class_name() == name)) {
-    return Heap::true_value();
-  }
-  return Heap::false_value();
-}
 
 static Object* Runtime_HasStringClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::String_symbol());
+  return Heap::ToBoolean(args[0]->HasSpecificClassOf(Heap::String_symbol()));
 }
 
 
 static Object* Runtime_HasDateClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::Date_symbol());
+  return Heap::ToBoolean(args[0]->HasSpecificClassOf(Heap::Date_symbol()));
 }
 
 
 static Object* Runtime_HasArrayClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::Array_symbol());
+  return Heap::ToBoolean(args[0]->HasSpecificClassOf(Heap::Array_symbol()));
 }
 
 
 static Object* Runtime_HasFunctionClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::function_class_symbol());
+  return Heap::ToBoolean(
+             args[0]->HasSpecificClassOf(Heap::function_class_symbol()));
 }
 
 
 static Object* Runtime_HasNumberClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::Number_symbol());
+  return Heap::ToBoolean(args[0]->HasSpecificClassOf(Heap::Number_symbol()));
 }
 
 
 static Object* Runtime_HasBooleanClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::Boolean_symbol());
+  return Heap::ToBoolean(args[0]->HasSpecificClassOf(Heap::Boolean_symbol()));
 }
 
 
 static Object* Runtime_HasArgumentsClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::Arguments_symbol());
+  return Heap::ToBoolean(
+             args[0]->HasSpecificClassOf(Heap::Arguments_symbol()));
 }
 
 
 static Object* Runtime_HasRegExpClass(Arguments args) {
-  return HasSpecificClassOf(args, Heap::RegExp_symbol());
+  return Heap::ToBoolean(args[0]->HasSpecificClassOf(Heap::RegExp_symbol()));
 }
 
 
index 55a844f..ccbaa99 100644 (file)
@@ -1219,7 +1219,7 @@ bool message_received;
 static void check_message(v8::Handle<v8::Message> message,
                           v8::Handle<Value> data) {
   CHECK_EQ(5.76, data->NumberValue());
-  CHECK_EQ(6.75, message->GetSourceData()->NumberValue());
+  CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
   message_received = true;
 }
 
@@ -2365,8 +2365,8 @@ TEST(RegexpOutOfMemory) {
 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
                                              v8::Handle<Value> data) {
   CHECK_EQ(v8::Undefined(), data);
-  CHECK(message->GetScriptResourceName().IsEmpty());
-  CHECK_EQ(v8::Undefined(), message->GetSourceData());
+  CHECK(message->GetScriptResourceName()->IsUndefined());
+  CHECK_EQ(v8::Undefined(), message->GetScriptResourceName());
   message->GetLineNumber();
   message->GetSourceLine();
 }
@@ -2410,7 +2410,7 @@ class Whammy {
   v8::Persistent<Script> script_;
 };
 
-static void HandleWeakReference(v8::Persistent<v8::Object> obj, void* data) {
+static void HandleWeakReference(v8::Persistent<v8::Value> obj, void* data) {
   Snorkel* snorkel = reinterpret_cast<Snorkel*>(data);
   delete snorkel;
   obj.ClearWeak();
@@ -5024,3 +5024,12 @@ THREADED_TEST(CallbackFunctionName) {
   v8::String::AsciiValue name(value);
   CHECK_EQ("asdf", *name);
 }
+
+
+THREADED_TEST(DateAccess) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::Handle<v8::Value> date = v8::Date::New(1224744689038.0);
+  CHECK(date->IsDate());
+  CHECK_EQ(1224744689038.0, v8::Handle<v8::Date>::Cast(date)->NumberValue());
+}
index 0d6bb3b..0a4f90f 100644 (file)
@@ -306,7 +306,7 @@ TEST(GlobalHandles) {
 
 static bool WeakPointerCleared = false;
 
-static void TestWeakGlobalHandleCallback(v8::Persistent<v8::Object> handle,
+static void TestWeakGlobalHandleCallback(v8::Persistent<v8::Value> handle,
                                          void* id) {
   USE(handle);
   if (1234 == reinterpret_cast<int>(id)) WeakPointerCleared = true;
@@ -377,7 +377,7 @@ TEST(WeakGlobalHandlesMark) {
 }
 
 static void TestDeleteWeakGlobalHandleCallback(
-    v8::Persistent<v8::Object> handle,
+    v8::Persistent<v8::Value> handle,
     void* id) {
   if (1234 == reinterpret_cast<int>(id)) WeakPointerCleared = true;
   handle.Dispose();
index 36b286a..d468c24 100644 (file)
@@ -244,7 +244,7 @@ TEST(GCCallback) {
 
 
 static int NumberOfWeakCalls = 0;
-static void WeakPointerCallback(v8::Persistent<v8::Object> handle, void* id) {
+static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) {
   NumberOfWeakCalls++;
 }