* \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);
: 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_;
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.
*/
bool IsInt32();
+ /**
+ * Returns true if this value is a Date.
+ */
+ bool IsDate();
+
Local<Boolean> ToBoolean();
Local<Number> ToNumber();
Local<String> ToString();
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);
};
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_;
/**
* 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
*
* 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
* 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.
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_;
}
}
-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_);
}
-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));
}
-v8::Handle<String> Message::GetScriptResourceName() {
+v8::Handle<Value> Message::GetScriptResourceName() {
if (IsDeadCheck("v8::Message::GetScriptResourceName()")) {
return Local<String>();
}
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,
}
-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);
}
+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");
}
+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");
}
-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);
}
-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);
}
+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");
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
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
// 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();
}
+bool Object::HasSpecificClassOf(String* name) {
+ return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
+}
+
+
Object* Object::GetElement(uint32_t index) {
return GetElementWithReceiver(this, index);
}
// 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]) {
// Extract the number.
inline double Number();
+ inline bool HasSpecificClassOf(String* name);
+
Object* ToObject(); // ECMA-262 9.9.
Object* ToBoolean(); // ECMA-262 9.2.
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()));
}
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;
}
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();
}
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();
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());
+}
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;
}
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();
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++;
}