From c7ed0707a3221a69ebb89d64270cbaf039c7a201 Mon Sep 17 00:00:00 2001 From: "christian.plesner.hansen@gmail.com" Date: Thu, 23 Oct 2008 08:25:23 +0000 Subject: [PATCH] - Added const in a few places. - Changed WeakReferenceCallback to take a Persistent instead of a Persistent. - 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 --- include/v8.h | 50 ++++++++-------- src/api.cc | 99 +++++++++++--------------------- src/debug.cc | 2 +- src/debug.h | 2 +- src/handles.cc | 2 +- src/objects-inl.h | 5 ++ src/objects.cc | 35 ++++++----- src/objects.h | 2 + src/runtime.cc | 27 ++++----- test/cctest/test-api.cc | 17 ++++-- test/cctest/test-heap.cc | 4 +- test/cctest/test-mark-compact.cc | 2 +- 12 files changed, 112 insertions(+), 135 deletions(-) diff --git a/include/v8.h b/include/v8.h index c683fb91bd..d463393fd8 100644 --- a/include/v8.h +++ b/include/v8.h @@ -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, +typedef void (*WeakReferenceCallback)(Persistent 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 ResourceName(); - inline Handle ResourceLineOffset(); - inline Handle ResourceColumnOffset(); + inline Handle ResourceName() const; + inline Handle ResourceLineOffset() const; + inline Handle ResourceColumnOffset() const; private: Handle resource_name_; Handle resource_line_offset_; @@ -559,16 +559,7 @@ class EXPORT Message { Local Get(); Local 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 GetScriptResourceName(); - - // TODO(1240903): Remove this when no longer used in WebKit V8 - // bindings. - Handle GetSourceData(); + Handle 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 ToBoolean(); Local ToNumber(); Local ToString(); @@ -991,6 +987,14 @@ class EXPORT Uint32 : public Integer { class EXPORT Date : public Value { public: static Local 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 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 Exception(); + Local 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 Message(); + Local Message() const; /** * Clears any exceptions that may have been caught by this try/catch block. @@ -2373,17 +2377,17 @@ Local HandleScope::Close(Handle value) { return Local(reinterpret_cast(after)); } -Handle ScriptOrigin::ResourceName() { +Handle ScriptOrigin::ResourceName() const { return resource_name_; } -Handle ScriptOrigin::ResourceLineOffset() { +Handle ScriptOrigin::ResourceLineOffset() const { return resource_line_offset_; } -Handle ScriptOrigin::ResourceColumnOffset() { +Handle ScriptOrigin::ResourceColumnOffset() const { return resource_column_offset_; } diff --git a/src/api.cc b/src/api.cc index b694007520..b4dd60edba 100644 --- a/src/api.cc +++ b/src/api.cc @@ -1084,12 +1084,12 @@ v8::TryCatch::~TryCatch() { } -bool v8::TryCatch::HasCaught() { +bool v8::TryCatch::HasCaught() const { return !reinterpret_cast(exception_)->IsTheHole(); } -v8::Local v8::TryCatch::Exception() { +v8::Local v8::TryCatch::Exception() const { if (HasCaught()) { // Check for out of memory exception. i::Object* exception = reinterpret_cast(exception_); @@ -1100,7 +1100,7 @@ v8::Local v8::TryCatch::Exception() { } -v8::Local v8::TryCatch::Message() { +v8::Local v8::TryCatch::Message() const { if (HasCaught() && message_ != i::Smi::FromInt(0)) { i::Object* message = reinterpret_cast(message_); return v8::Utils::MessageToLocal(i::Handle(message)); @@ -1139,7 +1139,7 @@ Local Message::Get() { } -v8::Handle Message::GetScriptResourceName() { +v8::Handle Message::GetScriptResourceName() { if (IsDeadCheck("v8::Message::GetScriptResourceName()")) { return Local(); } @@ -1150,22 +1150,10 @@ v8::Handle Message::GetScriptResourceName() { i::Handle script = i::Handle::cast(GetProperty(obj, "script")); i::Handle resource_name(i::Script::cast(script->value())->name()); - if (!resource_name->IsString()) { - return Local(); - } - Local result = - Utils::ToLocal(i::Handle::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 Message::GetSourceData() { - Handle data = GetScriptResourceName(); - if (data.IsEmpty()) return v8::Undefined(); - return data; -} - static i::Handle CallV8HeapFunction(const char* name, i::Handle recv, int argc, @@ -1268,53 +1256,6 @@ Local Message::GetSourceLine() { } -char* Message::GetUnderline(char* source_line, char underline_char) { - if (IsDeadCheck("v8::Message::GetUnderline()")) return 0; - HandleScope scope; - - i::Handle data_obj = Utils::OpenHandle(this); - int start_pos = static_cast(GetProperty(data_obj, "startPos")->Number()); - int end_pos = static_cast(GetProperty(data_obj, "endPos")->Number()); - EXCEPTION_PREAMBLE(); - i::Handle start_col_obj = CallV8HeapFunction( - "GetPositionInLine", - data_obj, - &has_pending_exception); - EXCEPTION_BAILOUT_CHECK(0); - int start_col = static_cast(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(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 obj = Utils::OpenHandle(this); + return obj->HasSpecificClassOf(i::Heap::Date_symbol()); +} + + Local Value::ToString() { if (IsDeadCheck("v8::Value::ToString()")) return Local(); 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 obj = Utils::OpenHandle(that); + ApiCheck(obj->HasSpecificClassOf(i::Heap::Date_symbol()), + "v8::Date::Cast()", + "Could not convert to date"); + return static_cast(that); +} + + bool Value::BooleanValue() { if (IsDeadCheck("v8::Value::BooleanValue()")) return false; LOG_API("BooleanValue"); @@ -2462,7 +2420,7 @@ i::Handle NewExternalAsciiStringHandle( } -static void DisposeExternalString(v8::Persistent obj, +static void DisposeExternalString(v8::Persistent obj, void* parameter) { v8::String::ExternalStringResource* resource = reinterpret_cast(parameter); @@ -2473,7 +2431,7 @@ static void DisposeExternalString(v8::Persistent obj, } -static void DisposeExternalAsciiString(v8::Persistent obj, +static void DisposeExternalAsciiString(v8::Persistent obj, void* parameter) { v8::String::ExternalAsciiStringResource* resource = reinterpret_cast(parameter); @@ -2534,6 +2492,15 @@ Local v8::Date::New(double time) { } +double v8::Date::NumberValue() { + if (IsDeadCheck("v8::Date::NumberValue()")) return 0; + LOG_API("Date::NumberValue"); + i::Handle obj = Utils::OpenHandle(this); + i::Handle jsvalue = i::Handle::cast(obj); + return jsvalue->value()->Number(); +} + + Local v8::Array::New(int length) { EnsureInitialized("v8::Array::New()"); LOG_API("Array::New"); diff --git a/src/debug.cc b/src/debug.cc index d43ada40ad..33fafe716a 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -451,7 +451,7 @@ Code* Debug::debug_break_return_entry_ = NULL; Code* Debug::debug_break_return_ = NULL; -void Debug::HandleWeakDebugInfo(v8::Persistent obj, void* data) { +void Debug::HandleWeakDebugInfo(v8::Persistent obj, void* data) { DebugInfoListNode* node = reinterpret_cast(data); RemoveDebugInfo(node->debug_info()); #ifdef DEBUG diff --git a/src/debug.h b/src/debug.h index efcbf0ad08..69e2aaa834 100644 --- a/src/debug.h +++ b/src/debug.h @@ -248,7 +248,7 @@ class Debug { static const int kEstimatedNofDebugInfoEntries = 16; static const int kEstimatedNofBreakPointsInFunction = 16; - static void HandleWeakDebugInfo(v8::Persistent obj, void* data); + static void HandleWeakDebugInfo(v8::Persistent obj, void* data); friend class Debugger; friend Handle GetDebuggedFunctions(); // Found in test-debug.cc diff --git a/src/handles.cc b/src/handles.cc index 222876d794..1a600db212 100644 --- a/src/handles.cc +++ b/src/handles.cc @@ -248,7 +248,7 @@ Handle Copy(Handle 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 handle, void*) { +static void ClearWrapperCache(Persistent handle, void*) { Handle cache = Utils::OpenHandle(*handle); JSValue* wrapper = JSValue::cast(*cache); Proxy* proxy = Script::cast(wrapper->value())->wrapper(); diff --git a/src/objects-inl.h b/src/objects-inl.h index 152d1c3169..da6e005c84 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -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); } diff --git a/src/objects.cc b/src/objects.cc index e5b7643269..0bf936c828 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3719,36 +3719,33 @@ static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { // int-sized blocks of characters. template static inline bool CompareRawStringContents(Vector a, Vector 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(pa); uint32_t pb_addr = reinterpret_cast(pb); - if ((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask) != 0) { - VectorIterator ia(a); - VectorIterator ib(b); - return CompareStringContents(&ia, &ib); + if ((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask) == 0) { +#endif + 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(pa + i); + uint32_t wb = *reinterpret_cast(pb + i); + if (wa != wb) { + return false; + } + } +#ifndef CAN_READ_UNALIGNED } #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(pa + i); - uint32_t wb = *reinterpret_cast(pb + i); - if (wa != wb) { - return false; - } - } // Compare the remaining characters that didn't fit into a block. for (; i < length; i++) { if (a[i] != b[i]) { diff --git a/src/objects.h b/src/objects.h index 3e9e9661bc..381bc5d592 100644 --- a/src/objects.h +++ b/src/objects.h @@ -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. diff --git a/src/runtime.cc b/src/runtime.cc index b7e3ad93c0..35aa3e7761 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -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())); } diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 55a844f181..ccbaa9911c 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -1219,7 +1219,7 @@ bool message_received; static void check_message(v8::Handle message, v8::Handle 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 message, v8::Handle 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