summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-api.cc
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2013-06-11 23:45:46 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2013-06-11 23:46:00 +0200
commit6dd78074a3c0a7579ca5e919021587c22ff763ae (patch)
treee225460f8e76126f4e4b2e1809dbd4c9c2ba511b /deps/v8/test/cctest/test-api.cc
parent9ae1d182ba98629ac7c7b9100022ac93133494b7 (diff)
downloadnode-new-6dd78074a3c0a7579ca5e919021587c22ff763ae.tar.gz
v8: upgrade to v3.19.13
Diffstat (limited to 'deps/v8/test/cctest/test-api.cc')
-rwxr-xr-x[-rw-r--r--]deps/v8/test/cctest/test-api.cc1257
1 files changed, 683 insertions, 574 deletions
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index c8f67de0ab..5d3a79d6bb 100644..100755
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -32,14 +32,10 @@
#include <unistd.h> // getpid
#endif // WIN32
-// TODO(dcarney): remove
-#define V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
-#define V8_ALLOW_ACCESS_TO_PERSISTENT_IMPLICIT
-#define V8_ALLOW_ACCESS_TO_PERSISTENT_ARROW
-
#include "v8.h"
#include "api.h"
+#include "arguments.h"
#include "isolate.h"
#include "compilation-cache.h"
#include "execution.h"
@@ -600,6 +596,7 @@ TEST(MakingExternalAsciiStringConditions) {
THREADED_TEST(UsingExternalString) {
+ i::Factory* factory = i::Isolate::Current()->factory();
{
v8::HandleScope scope(v8::Isolate::GetCurrent());
uint16_t* two_byte_string = AsciiToTwoByteString("test string");
@@ -610,7 +607,7 @@ THREADED_TEST(UsingExternalString) {
HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
- FACTORY->InternalizedStringFromString(istring);
+ factory->InternalizedStringFromString(istring);
CHECK(isymbol->IsInternalizedString());
}
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -619,6 +616,7 @@ THREADED_TEST(UsingExternalString) {
THREADED_TEST(UsingExternalAsciiString) {
+ i::Factory* factory = i::Isolate::Current()->factory();
{
v8::HandleScope scope(v8::Isolate::GetCurrent());
const char* one_byte_string = "test string";
@@ -629,7 +627,7 @@ THREADED_TEST(UsingExternalAsciiString) {
HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
- FACTORY->InternalizedStringFromString(istring);
+ factory->InternalizedStringFromString(istring);
CHECK(isymbol->IsInternalizedString());
}
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -809,8 +807,16 @@ template<typename T>
static void CheckReturnValue(const T& t) {
v8::ReturnValue<v8::Value> rv = t.GetReturnValue();
i::Object** o = *reinterpret_cast<i::Object***>(&rv);
- CHECK_EQ(t.GetIsolate(), v8::Isolate::GetCurrent());
+ CHECK_EQ(v8::Isolate::GetCurrent(), t.GetIsolate());
+ CHECK_EQ(t.GetIsolate(), rv.GetIsolate());
+ CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
+ // Verify reset
+ bool is_runtime = (*o)->IsTheHole();
+ rv.Set(true);
+ CHECK(!(*o)->IsTheHole() && !(*o)->IsUndefined());
+ rv.Set(v8::Handle<v8::Object>());
CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
+ CHECK_EQ(is_runtime, (*o)->IsTheHole());
}
static v8::Handle<Value> handle_call(const v8::Arguments& args) {
@@ -820,6 +826,10 @@ static v8::Handle<Value> handle_call(const v8::Arguments& args) {
return v8_num(102);
}
+static v8::Handle<Value> handle_call_2(const v8::Arguments& args) {
+ return handle_call(args);
+}
+
static v8::Handle<Value> handle_call_indirect(const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
CheckReturnValue(args);
@@ -828,6 +838,10 @@ static v8::Handle<Value> handle_call_indirect(const v8::Arguments& args) {
return v8::Handle<Value>();
}
+static v8::Handle<Value> handle_call_indirect_2(const v8::Arguments& args) {
+ return handle_call_indirect(args);
+}
+
static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) {
ApiTestFuzzer::Fuzz();
CheckReturnValue(info);
@@ -835,6 +849,9 @@ static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) {
info.GetReturnValue().Set(v8_num(102));
}
+static void handle_callback_2(const v8::FunctionCallbackInfo<Value>& info) {
+ return handle_callback(info);
+}
static v8::Handle<Value> construct_call(const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
@@ -894,7 +911,8 @@ static void Return239Callback(
template<typename Handler>
-static void TestFunctionTemplateInitializer(Handler handler) {
+static void TestFunctionTemplateInitializer(Handler handler,
+ Handler handler_2) {
// Test constructor calls.
{
LocalContext env;
@@ -914,7 +932,7 @@ static void TestFunctionTemplateInitializer(Handler handler) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- fun_templ->SetCallHandler(handler);
+ fun_templ->SetCallHandler(handler_2);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("obj()");
@@ -952,9 +970,9 @@ static void TestFunctionTemplateAccessor(Constructor constructor,
THREADED_TEST(FunctionTemplate) {
- TestFunctionTemplateInitializer(handle_call);
- TestFunctionTemplateInitializer(handle_call_indirect);
- TestFunctionTemplateInitializer(handle_callback);
+ TestFunctionTemplateInitializer(handle_call, handle_call_2);
+ TestFunctionTemplateInitializer(handle_call_indirect, handle_call_indirect_2);
+ TestFunctionTemplateInitializer(handle_callback, handle_callback_2);
TestFunctionTemplateAccessor(construct_call, Return239);
TestFunctionTemplateAccessor(construct_call_indirect, Return239Indirect);
@@ -1014,47 +1032,72 @@ template<typename T>
void FastReturnValueCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
// constant return values
-static const int32_t kFastReturnValueInt32 = 471;
-static const uint32_t kFastReturnValueUint32 = 571;
+static int32_t fast_return_value_int32 = 471;
+static uint32_t fast_return_value_uint32 = 571;
static const double kFastReturnValueDouble = 2.7;
// variable return values
static bool fast_return_value_bool = false;
-static bool fast_return_value_void_is_null = false;
+enum ReturnValueOddball {
+ kNullReturnValue,
+ kUndefinedReturnValue,
+ kEmptyStringReturnValue
+};
+static ReturnValueOddball fast_return_value_void;
+static bool fast_return_value_object_is_empty = false;
template<>
void FastReturnValueCallback<int32_t>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(info.GetIsolate(), kFastReturnValueInt32);
+ CheckReturnValue(info);
+ info.GetReturnValue().Set(fast_return_value_int32);
}
template<>
void FastReturnValueCallback<uint32_t>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(info.GetIsolate(), kFastReturnValueUint32);
+ CheckReturnValue(info);
+ info.GetReturnValue().Set(fast_return_value_uint32);
}
template<>
void FastReturnValueCallback<double>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(info.GetIsolate(), kFastReturnValueDouble);
+ CheckReturnValue(info);
+ info.GetReturnValue().Set(kFastReturnValueDouble);
}
template<>
void FastReturnValueCallback<bool>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(info.GetIsolate(), fast_return_value_bool);
+ CheckReturnValue(info);
+ info.GetReturnValue().Set(fast_return_value_bool);
}
template<>
void FastReturnValueCallback<void>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- if (fast_return_value_void_is_null) {
- info.GetReturnValue().SetNull(info.GetIsolate());
- } else {
- info.GetReturnValue().SetUndefined(info.GetIsolate());
+ CheckReturnValue(info);
+ switch (fast_return_value_void) {
+ case kNullReturnValue:
+ info.GetReturnValue().SetNull();
+ break;
+ case kUndefinedReturnValue:
+ info.GetReturnValue().SetUndefined();
+ break;
+ case kEmptyStringReturnValue:
+ info.GetReturnValue().SetEmptyString();
+ break;
}
}
+template<>
+void FastReturnValueCallback<Object>(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Handle<v8::Object> object;
+ if (!fast_return_value_object_is_empty) object = Object::New();
+ info.GetReturnValue().Set(object);
+}
+
template<typename T>
Handle<Value> TestFastReturnValues() {
LocalContext env;
@@ -1068,16 +1111,29 @@ Handle<Value> TestFastReturnValues() {
}
THREADED_TEST(FastReturnValues) {
+ LocalContext env;
v8::HandleScope scope(v8::Isolate::GetCurrent());
v8::Handle<v8::Value> value;
- // check int_32
- value = TestFastReturnValues<int32_t>();
- CHECK(value->IsInt32());
- CHECK_EQ(kFastReturnValueInt32, value->Int32Value());
- // check uint32_t
- value = TestFastReturnValues<uint32_t>();
- CHECK(value->IsInt32());
- CHECK_EQ(kFastReturnValueUint32, value->Int32Value());
+ // check int32_t and uint32_t
+ int32_t int_values[] = {
+ 0, 234, -723,
+ i::Smi::kMinValue, i::Smi::kMaxValue
+ };
+ for (size_t i = 0; i < ARRAY_SIZE(int_values); i++) {
+ for (int modifier = -1; modifier <= 1; modifier++) {
+ int int_value = int_values[i] + modifier;
+ // check int32_t
+ fast_return_value_int32 = int_value;
+ value = TestFastReturnValues<int32_t>();
+ CHECK(value->IsInt32());
+ CHECK(fast_return_value_int32 == value->Int32Value());
+ // check uint32_t
+ fast_return_value_uint32 = static_cast<uint32_t>(int_value);
+ value = TestFastReturnValues<uint32_t>();
+ CHECK(value->IsUint32());
+ CHECK(fast_return_value_uint32 == value->Uint32Value());
+ }
+ }
// check double
value = TestFastReturnValues<double>();
CHECK(value->IsNumber());
@@ -1090,15 +1146,34 @@ THREADED_TEST(FastReturnValues) {
CHECK_EQ(fast_return_value_bool, value->ToBoolean()->Value());
}
// check oddballs
- for (int i = 0; i < 2; i++) {
- fast_return_value_void_is_null = i == 0;
+ ReturnValueOddball oddballs[] = {
+ kNullReturnValue,
+ kUndefinedReturnValue,
+ kEmptyStringReturnValue
+ };
+ for (size_t i = 0; i < ARRAY_SIZE(oddballs); i++) {
+ fast_return_value_void = oddballs[i];
value = TestFastReturnValues<void>();
- if (fast_return_value_void_is_null) {
- CHECK(value->IsNull());
- } else {
- CHECK(value->IsUndefined());
+ switch (fast_return_value_void) {
+ case kNullReturnValue:
+ CHECK(value->IsNull());
+ break;
+ case kUndefinedReturnValue:
+ CHECK(value->IsUndefined());
+ break;
+ case kEmptyStringReturnValue:
+ CHECK(value->IsString());
+ CHECK_EQ(0, v8::String::Cast(*value)->Length());
+ break;
}
}
+ // check handles
+ fast_return_value_object_is_empty = false;
+ value = TestFastReturnValues<Object>();
+ CHECK(value->IsObject());
+ fast_return_value_object_is_empty = true;
+ value = TestFastReturnValues<Object>();
+ CHECK(value->IsUndefined());
}
@@ -1975,88 +2050,90 @@ THREADED_TEST(IndexedPropertyHandlerGetter) {
v8::Handle<v8::Object> bottom;
-static v8::Handle<Value> CheckThisIndexedPropertyHandler(
+static void CheckThisIndexedPropertyHandler(
uint32_t index,
- const AccessorInfo& info) {
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<Value>();
}
-static v8::Handle<Value> CheckThisNamedPropertyHandler(
+static void CheckThisNamedPropertyHandler(
Local<String> name,
- const AccessorInfo& info) {
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<Value>();
}
-
-v8::Handle<Value> CheckThisIndexedPropertySetter(uint32_t index,
- Local<Value> value,
- const AccessorInfo& info) {
+void CheckThisIndexedPropertySetter(
+ uint32_t index,
+ Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<Value>();
}
-v8::Handle<Value> CheckThisNamedPropertySetter(Local<String> property,
- Local<Value> value,
- const AccessorInfo& info) {
+void CheckThisNamedPropertySetter(
+ Local<String> property,
+ Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<Value>();
}
-v8::Handle<v8::Integer> CheckThisIndexedPropertyQuery(
+void CheckThisIndexedPropertyQuery(
uint32_t index,
- const AccessorInfo& info) {
+ const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<v8::Integer>();
}
-v8::Handle<v8::Integer> CheckThisNamedPropertyQuery(Local<String> property,
- const AccessorInfo& info) {
+void CheckThisNamedPropertyQuery(
+ Local<String> property,
+ const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<v8::Integer>();
}
-v8::Handle<v8::Boolean> CheckThisIndexedPropertyDeleter(
+void CheckThisIndexedPropertyDeleter(
uint32_t index,
- const AccessorInfo& info) {
+ const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<v8::Boolean>();
}
-v8::Handle<v8::Boolean> CheckThisNamedPropertyDeleter(
+void CheckThisNamedPropertyDeleter(
Local<String> property,
- const AccessorInfo& info) {
+ const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<v8::Boolean>();
}
-v8::Handle<v8::Array> CheckThisIndexedPropertyEnumerator(
- const AccessorInfo& info) {
+void CheckThisIndexedPropertyEnumerator(
+ const v8::PropertyCallbackInfo<v8::Array>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<v8::Array>();
}
-v8::Handle<v8::Array> CheckThisNamedPropertyEnumerator(
- const AccessorInfo& info) {
+void CheckThisNamedPropertyEnumerator(
+ const v8::PropertyCallbackInfo<v8::Array>& info) {
+ CheckReturnValue(info);
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
- return v8::Handle<v8::Array>();
}
@@ -2493,7 +2570,20 @@ THREADED_TEST(SymbolProperties) {
}
-THREADED_TEST(ArrayBuffer) {
+class ScopedArrayBufferContents {
+ public:
+ explicit ScopedArrayBufferContents(
+ const v8::ArrayBuffer::Contents& contents)
+ : contents_(contents) {}
+ ~ScopedArrayBufferContents() { free(contents_.Data()); }
+ void* Data() const { return contents_.Data(); }
+ size_t ByteLength() const { return contents_.ByteLength(); }
+ private:
+ const v8::ArrayBuffer::Contents contents_;
+};
+
+
+THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
i::FLAG_harmony_array_buffer = true;
i::FLAG_harmony_typed_arrays = true;
@@ -2502,10 +2592,15 @@ THREADED_TEST(ArrayBuffer) {
v8::HandleScope handle_scope(isolate);
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(1024);
+ CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
+ CHECK(!ab->IsExternal());
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
- CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
- uint8_t* data = static_cast<uint8_t*>(ab->Data());
+ ScopedArrayBufferContents ab_contents(ab->Externalize());
+ CHECK(ab->IsExternal());
+
+ CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength()));
+ uint8_t* data = static_cast<uint8_t*>(ab_contents.Data());
ASSERT(data != NULL);
env->Global()->Set(v8_str("ab"), ab);
@@ -2523,27 +2618,72 @@ THREADED_TEST(ArrayBuffer) {
data[1] = 0x11;
result = CompileRun("u8[0] + u8[1]");
CHECK_EQ(0xDD, result->Int32Value());
+}
+
- result = CompileRun("var ab1 = new ArrayBuffer(2);"
- "var u8_a = new Uint8Array(ab1);"
- "u8_a[0] = 0xAA;"
- "u8_a[1] = 0xFF; u8_a.buffer");
+THREADED_TEST(ArrayBuffer_JSInternalToExternal) {
+ i::FLAG_harmony_array_buffer = true;
+ i::FLAG_harmony_typed_arrays = true;
+
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+
+ v8::Handle<v8::Value> result =
+ CompileRun("var ab1 = new ArrayBuffer(2);"
+ "var u8_a = new Uint8Array(ab1);"
+ "u8_a[0] = 0xAA;"
+ "u8_a[1] = 0xFF; u8_a.buffer");
Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::Cast(*result);
CHECK_EQ(2, static_cast<int>(ab1->ByteLength()));
- uint8_t* ab1_data = static_cast<uint8_t*>(ab1->Data());
- CHECK_EQ(0xAA, ab1_data[0]);
+ CHECK(!ab1->IsExternal());
+ ScopedArrayBufferContents ab1_contents(ab1->Externalize());
+ CHECK(ab1->IsExternal());
+
+ result = CompileRun("ab1.byteLength");
+ CHECK_EQ(2, result->Int32Value());
+ result = CompileRun("u8_a[0]");
+ CHECK_EQ(0xAA, result->Int32Value());
+ result = CompileRun("u8_a[1]");
+ CHECK_EQ(0xFF, result->Int32Value());
+ result = CompileRun("var u8_b = new Uint8Array(ab1);"
+ "u8_b[0] = 0xBB;"
+ "u8_a[0]");
+ CHECK_EQ(0xBB, result->Int32Value());
+ result = CompileRun("u8_b[1]");
+ CHECK_EQ(0xFF, result->Int32Value());
+
+ CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength()));
+ uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data());
+ CHECK_EQ(0xBB, ab1_data[0]);
CHECK_EQ(0xFF, ab1_data[1]);
ab1_data[0] = 0xCC;
ab1_data[1] = 0x11;
result = CompileRun("u8_a[0] + u8_a[1]");
CHECK_EQ(0xDD, result->Int32Value());
+}
+
+
+THREADED_TEST(ArrayBuffer_External) {
+ i::FLAG_harmony_array_buffer = true;
+ i::FLAG_harmony_typed_arrays = true;
- uint8_t* my_data = new uint8_t[100];
- memset(my_data, 0, 100);
- Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(my_data, 100);
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ i::ScopedVector<uint8_t> my_data(100);
+ memset(my_data.start(), 0, 100);
+ Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(my_data.start(), 100);
CHECK_EQ(100, static_cast<int>(ab3->ByteLength()));
- CHECK_EQ(my_data, ab3->Data());
+ CHECK(ab3->IsExternal());
+
env->Global()->Set(v8_str("ab3"), ab3);
+
+ v8::Handle<v8::Value> result = CompileRun("ab3.byteLength");
+ CHECK_EQ(100, result->Int32Value());
+
result = CompileRun("var u8_b = new Uint8Array(ab3);"
"u8_b[0] = 0xBB;"
"u8_b[1] = 0xCC;"
@@ -2555,12 +2695,121 @@ THREADED_TEST(ArrayBuffer) {
my_data[1] = 0x11;
result = CompileRun("u8_b[0] + u8_b[1]");
CHECK_EQ(0xDD, result->Int32Value());
+}
- delete[] my_data;
+
+static void CheckIsNeutered(v8::Handle<v8::TypedArray> ta) {
+ CHECK_EQ(0, static_cast<int>(ta->ByteLength()));
+ CHECK_EQ(0, static_cast<int>(ta->Length()));
+ CHECK_EQ(0, static_cast<int>(ta->ByteOffset()));
}
+template <typename TypedArray, int kElementSize>
+static Handle<TypedArray> CreateAndCheck(Handle<v8::ArrayBuffer> ab,
+ int byteOffset,
+ int length) {
+ v8::Handle<TypedArray> ta = TypedArray::New(ab, byteOffset, length);
+ CHECK_EQ(byteOffset, static_cast<int>(ta->ByteOffset()));
+ CHECK_EQ(length, static_cast<int>(ta->Length()));
+ CHECK_EQ(length * kElementSize, static_cast<int>(ta->ByteLength()));
+ return ta;
+}
+THREADED_TEST(ArrayBuffer_NeuteringApi) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(1024);
+
+ v8::Handle<v8::Uint8Array> u8a =
+ CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023);
+ v8::Handle<v8::Uint8ClampedArray> u8c =
+ CreateAndCheck<v8::Uint8ClampedArray, 1>(buffer, 1, 1023);
+ v8::Handle<v8::Int8Array> i8a =
+ CreateAndCheck<v8::Int8Array, 1>(buffer, 1, 1023);
+
+ v8::Handle<v8::Uint16Array> u16a =
+ CreateAndCheck<v8::Uint16Array, 2>(buffer, 2, 511);
+ v8::Handle<v8::Int16Array> i16a =
+ CreateAndCheck<v8::Int16Array, 2>(buffer, 2, 511);
+
+ v8::Handle<v8::Uint32Array> u32a =
+ CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255);
+ v8::Handle<v8::Int32Array> i32a =
+ CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255);
+
+ v8::Handle<v8::Float32Array> f32a =
+ CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255);
+ v8::Handle<v8::Float64Array> f64a =
+ CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127);
+
+ ScopedArrayBufferContents contents(buffer->Externalize());
+ buffer->Neuter();
+ CHECK_EQ(0, static_cast<int>(buffer->ByteLength()));
+ CheckIsNeutered(u8a);
+ CheckIsNeutered(u8c);
+ CheckIsNeutered(i8a);
+ CheckIsNeutered(u16a);
+ CheckIsNeutered(i16a);
+ CheckIsNeutered(u32a);
+ CheckIsNeutered(i32a);
+ CheckIsNeutered(f32a);
+ CheckIsNeutered(f64a);
+}
+
+THREADED_TEST(ArrayBuffer_NeuteringScript) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ CompileRun(
+ "var ab = new ArrayBuffer(1024);"
+ "var u8a = new Uint8Array(ab, 1, 1023);"
+ "var u8c = new Uint8ClampedArray(ab, 1, 1023);"
+ "var i8a = new Int8Array(ab, 1, 1023);"
+ "var u16a = new Uint16Array(ab, 2, 511);"
+ "var i16a = new Int16Array(ab, 2, 511);"
+ "var u32a = new Uint32Array(ab, 4, 255);"
+ "var i32a = new Int32Array(ab, 4, 255);"
+ "var f32a = new Float32Array(ab, 4, 255);"
+ "var f64a = new Float64Array(ab, 8, 127);");
+
+ v8::Handle<v8::ArrayBuffer> ab(v8::ArrayBuffer::Cast(*CompileRun("ab")));
+
+ v8::Handle<v8::Uint8Array> u8a(v8::Uint8Array::Cast(*CompileRun("u8a")));
+ v8::Handle<v8::Uint8ClampedArray> u8c(
+ v8::Uint8ClampedArray::Cast(*CompileRun("u8c")));
+ v8::Handle<v8::Int8Array> i8a(v8::Int8Array::Cast(*CompileRun("i8a")));
+
+ v8::Handle<v8::Uint16Array> u16a(
+ v8::Uint16Array::Cast(*CompileRun("u16a")));
+ v8::Handle<v8::Int16Array> i16a(
+ v8::Int16Array::Cast(*CompileRun("i16a")));
+ v8::Handle<v8::Uint32Array> u32a(
+ v8::Uint32Array::Cast(*CompileRun("u32a")));
+ v8::Handle<v8::Int32Array> i32a(
+ v8::Int32Array::Cast(*CompileRun("i32a")));
+ v8::Handle<v8::Float32Array> f32a(
+ v8::Float32Array::Cast(*CompileRun("f32a")));
+ v8::Handle<v8::Float64Array> f64a(
+ v8::Float64Array::Cast(*CompileRun("f64a")));
+
+ ScopedArrayBufferContents contents(ab->Externalize());
+ ab->Neuter();
+ CHECK_EQ(0, static_cast<int>(ab->ByteLength()));
+ CheckIsNeutered(u8a);
+ CheckIsNeutered(u8c);
+ CheckIsNeutered(i8a);
+ CheckIsNeutered(u16a);
+ CheckIsNeutered(i16a);
+ CheckIsNeutered(u32a);
+ CheckIsNeutered(i32a);
+ CheckIsNeutered(f32a);
+ CheckIsNeutered(f64a);
+}
+
THREADED_TEST(HiddenProperties) {
@@ -2708,71 +2957,75 @@ THREADED_TEST(GlobalHandle) {
v8::Persistent<String> global;
{
v8::HandleScope scope(isolate);
- Local<String> str = v8_str("str");
- global = v8::Persistent<String>::New(isolate, str);
+ global.Reset(isolate, v8_str("str"));
}
- CHECK_EQ(global->Length(), 3);
- global.Dispose(isolate);
-
{
v8::HandleScope scope(isolate);
- Local<String> str = v8_str("str");
- global = v8::Persistent<String>::New(isolate, str);
+ CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 3);
}
- CHECK_EQ(global->Length(), 3);
- global.Dispose(isolate);
+ global.Dispose();
+ global.Clear();
+ {
+ v8::HandleScope scope(isolate);
+ global.Reset(isolate, v8_str("str"));
+ }
+ {
+ v8::HandleScope scope(isolate);
+ CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 3);
+ }
+ global.Dispose();
}
THREADED_TEST(ResettingGlobalHandle) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::internal::GlobalHandles* global_handles = NULL;
- int initial_handle_count = 0;
v8::Persistent<String> global;
{
v8::HandleScope scope(isolate);
- Local<String> str = v8_str("str");
- global_handles =
- reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
- initial_handle_count = global_handles->NumberOfGlobalHandles();
- global = v8::Persistent<String>::New(isolate, str);
+ global.Reset(isolate, v8_str("str"));
}
- CHECK_EQ(global->Length(), 3);
- CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count + 1);
+ v8::internal::GlobalHandles* global_handles =
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
+ int initial_handle_count = global_handles->NumberOfGlobalHandles();
{
v8::HandleScope scope(isolate);
- Local<String> str = v8_str("longer");
- global.Reset(isolate, str);
+ CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 3);
+ }
+ {
+ v8::HandleScope scope(isolate);
+ global.Reset(isolate, v8_str("longer"));
}
- CHECK_EQ(global->Length(), 6);
- CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count + 1);
- global.Dispose(isolate);
CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count);
+ {
+ v8::HandleScope scope(isolate);
+ CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 6);
+ }
+ global.Dispose(isolate);
+ CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count - 1);
}
THREADED_TEST(ResettingGlobalHandleToEmpty) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::internal::GlobalHandles* global_handles = NULL;
- int initial_handle_count = 0;
v8::Persistent<String> global;
{
v8::HandleScope scope(isolate);
- Local<String> str = v8_str("str");
- global_handles =
- reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
- initial_handle_count = global_handles->NumberOfGlobalHandles();
- global = v8::Persistent<String>::New(isolate, str);
+ global.Reset(isolate, v8_str("str"));
+ }
+ v8::internal::GlobalHandles* global_handles =
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
+ int initial_handle_count = global_handles->NumberOfGlobalHandles();
+ {
+ v8::HandleScope scope(isolate);
+ CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 3);
}
- CHECK_EQ(global->Length(), 3);
- CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count + 1);
{
v8::HandleScope scope(isolate);
Local<String> empty;
global.Reset(isolate, empty);
}
CHECK(global.IsEmpty());
- CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count);
+ CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count - 1);
}
@@ -2787,7 +3040,7 @@ THREADED_TEST(ClearAndLeakGlobal) {
global_handles =
reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
initial_handle_count = global_handles->NumberOfGlobalHandles();
- global = v8::Persistent<String>::New(isolate, str);
+ global.Reset(isolate, str);
}
CHECK_EQ(global_handles->NumberOfGlobalHandles(), initial_handle_count + 1);
String* str = global.ClearAndLeak();
@@ -2800,6 +3053,24 @@ THREADED_TEST(ClearAndLeakGlobal) {
}
+THREADED_TEST(GlobalHandleUpcast) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope scope(isolate);
+ v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
+ v8::Persistent<String> global_string(isolate, local);
+#ifdef V8_USE_UNSAFE_HANDLES
+ v8::Persistent<Value> global_value =
+ v8::Persistent<Value>::Cast(global_string);
+#else
+ v8::Persistent<Value>& global_value =
+ v8::Persistent<Value>::Cast(global_string);
+#endif
+ CHECK(v8::Local<v8::Value>::New(isolate, global_value)->IsString());
+ CHECK(global_string == v8::Persistent<String>::Cast(global_value));
+ global_string.Dispose();
+}
+
+
THREADED_TEST(LocalHandle) {
v8::HandleScope scope(v8::Isolate::GetCurrent());
v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
@@ -2823,7 +3094,7 @@ class WeakCallCounter {
static void WeakPointerCallback(v8::Isolate* isolate,
- Persistent<Object>* handle,
+ Persistent<Value>* handle,
WeakCallCounter* counter) {
CHECK_EQ(1234, counter->id());
counter->increment();
@@ -2831,129 +3102,48 @@ static void WeakPointerCallback(v8::Isolate* isolate,
}
-THREADED_TEST(OldApiObjectGroups) {
+THREADED_TEST(ApiObjectGroups) {
LocalContext env;
v8::Isolate* iso = env->GetIsolate();
HandleScope scope(iso);
- Persistent<Object> g1s1;
- Persistent<Object> g1s2;
- Persistent<Object> g1c1;
- Persistent<Object> g2s1;
- Persistent<Object> g2s2;
- Persistent<Object> g2c1;
+ Persistent<Value> g1s1;
+ Persistent<Value> g1s2;
+ Persistent<Value> g1c1;
+ Persistent<Value> g2s1;
+ Persistent<Value> g2s2;
+ Persistent<Value> g2c1;
WeakCallCounter counter(1234);
{
HandleScope scope(iso);
- g1s1 = Persistent<Object>::New(iso, Object::New());
- g1s2 = Persistent<Object>::New(iso, Object::New());
- g1c1 = Persistent<Object>::New(iso, Object::New());
+ g1s1.Reset(iso, Object::New());
+ g1s2.Reset(iso, Object::New());
+ g1c1.Reset(iso, Object::New());
g1s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g1s2.MakeWeak(iso, &counter, &WeakPointerCallback);
g1c1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g2s1 = Persistent<Object>::New(iso, Object::New());
- g2s2 = Persistent<Object>::New(iso, Object::New());
- g2c1 = Persistent<Object>::New(iso, Object::New());
+ g2s1.Reset(iso, Object::New());
+ g2s2.Reset(iso, Object::New());
+ g2c1.Reset(iso, Object::New());
g2s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g2s2.MakeWeak(iso, &counter, &WeakPointerCallback);
g2c1.MakeWeak(iso, &counter, &WeakPointerCallback);
}
- Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root.
+ Persistent<Value> root(iso, g1s1); // make a root.
// Connect group 1 and 2, make a cycle.
- CHECK(g1s2->Set(0, Handle<Object>(*g2s2)));
- CHECK(g2s1->Set(0, Handle<Object>(*g1s1)));
-
- {
- Persistent<Value> g1_objects[] = { g1s1, g1s2 };
- Persistent<Value> g1_children[] = { g1c1 };
- Persistent<Value> g2_objects[] = { g2s1, g2s2 };
- Persistent<Value> g2_children[] = { g2c1 };
- V8::AddObjectGroup(g1_objects, 2);
- V8::AddImplicitReferences(g1s1, g1_children, 1);
- V8::AddObjectGroup(g2_objects, 2);
- V8::AddImplicitReferences(g2s1, g2_children, 1);
- }
- // Do a single full GC, ensure incremental marking is stopped.
- HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
- // All object should be alive.
- CHECK_EQ(0, counter.NumberOfWeakCalls());
-
- // Weaken the root.
- root.MakeWeak(iso, &counter, &WeakPointerCallback);
- // But make children strong roots---all the objects (except for children)
- // should be collectable now.
- g1c1.ClearWeak(iso);
- g2c1.ClearWeak(iso);
-
- // Groups are deleted, rebuild groups.
- {
- Persistent<Value> g1_objects[] = { g1s1, g1s2 };
- Persistent<Value> g1_children[] = { g1c1 };
- Persistent<Value> g2_objects[] = { g2s1, g2s2 };
- Persistent<Value> g2_children[] = { g2c1 };
- V8::AddObjectGroup(g1_objects, 2);
- V8::AddImplicitReferences(g1s1, g1_children, 1);
- V8::AddObjectGroup(g2_objects, 2);
- V8::AddImplicitReferences(g2s1, g2_children, 1);
- }
-
- HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
- // All objects should be gone. 5 global handles in total.
- CHECK_EQ(5, counter.NumberOfWeakCalls());
-
- // And now make children weak again and collect them.
- g1c1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g2c1.MakeWeak(iso, &counter, &WeakPointerCallback);
-
- HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
- CHECK_EQ(7, counter.NumberOfWeakCalls());
-}
-
-
-THREADED_TEST(ApiObjectGroups) {
- LocalContext env;
- v8::Isolate* iso = env->GetIsolate();
- HandleScope scope(iso);
-
- Persistent<Object> g1s1;
- Persistent<Object> g1s2;
- Persistent<Object> g1c1;
- Persistent<Object> g2s1;
- Persistent<Object> g2s2;
- Persistent<Object> g2c1;
-
- WeakCallCounter counter(1234);
-
{
HandleScope scope(iso);
- g1s1 = Persistent<Object>::New(iso, Object::New());
- g1s2 = Persistent<Object>::New(iso, Object::New());
- g1c1 = Persistent<Object>::New(iso, Object::New());
- g1s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g1s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- g1c1.MakeWeak(iso, &counter, &WeakPointerCallback);
-
- g2s1 = Persistent<Object>::New(iso, Object::New());
- g2s2 = Persistent<Object>::New(iso, Object::New());
- g2c1 = Persistent<Object>::New(iso, Object::New());
- g2s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g2s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- g2c1.MakeWeak(iso, &counter, &WeakPointerCallback);
+ CHECK(Local<Object>::New(iso, g1s2.As<Object>())->
+ Set(0, Local<Value>(*g2s2)));
+ CHECK(Local<Object>::New(iso, g2s1.As<Object>())->
+ Set(0, Local<Value>(*g1s1)));
}
- Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root.
-
- // Connect group 1 and 2, make a cycle.
- CHECK(g1s2->Set(0, Local<Value>(*g2s2)));
- CHECK(g2s1->Set(0, Local<Value>(*g1s1)));
-
{
UniqueId id1(reinterpret_cast<intptr_t>(*g1s1));
UniqueId id2(reinterpret_cast<intptr_t>(*g2s2));
@@ -3005,112 +3195,6 @@ THREADED_TEST(ApiObjectGroups) {
}
-THREADED_TEST(OldApiObjectGroupsCycle) {
- LocalContext env;
- v8::Isolate* iso = env->GetIsolate();
- HandleScope scope(iso);
-
- WeakCallCounter counter(1234);
-
- Persistent<Object> g1s1;
- Persistent<Object> g1s2;
- Persistent<Object> g2s1;
- Persistent<Object> g2s2;
- Persistent<Object> g3s1;
- Persistent<Object> g3s2;
- Persistent<Object> g4s1;
- Persistent<Object> g4s2;
-
- {
- HandleScope scope(iso);
- g1s1 = Persistent<Object>::New(iso, Object::New());
- g1s2 = Persistent<Object>::New(iso, Object::New());
- g1s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g1s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- CHECK(g1s1.IsWeak(iso));
- CHECK(g1s2.IsWeak(iso));
-
- g2s1 = Persistent<Object>::New(iso, Object::New());
- g2s2 = Persistent<Object>::New(iso, Object::New());
- g2s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g2s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- CHECK(g2s1.IsWeak(iso));
- CHECK(g2s2.IsWeak(iso));
-
- g3s1 = Persistent<Object>::New(iso, Object::New());
- g3s2 = Persistent<Object>::New(iso, Object::New());
- g3s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g3s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- CHECK(g3s1.IsWeak(iso));
- CHECK(g3s2.IsWeak(iso));
-
- g4s1 = Persistent<Object>::New(iso, Object::New());
- g4s2 = Persistent<Object>::New(iso, Object::New());
- g4s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g4s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- CHECK(g4s1.IsWeak(iso));
- CHECK(g4s2.IsWeak(iso));
- }
-
- Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root.
-
- // Connect groups. We're building the following cycle:
- // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
- // groups.
- {
- Persistent<Value> g1_objects[] = { g1s1, g1s2 };
- Persistent<Value> g1_children[] = { g2s1 };
- Persistent<Value> g2_objects[] = { g2s1, g2s2 };
- Persistent<Value> g2_children[] = { g3s1 };
- Persistent<Value> g3_objects[] = { g3s1, g3s2 };
- Persistent<Value> g3_children[] = { g4s1 };
- Persistent<Value> g4_objects[] = { g4s1, g4s2 };
- Persistent<Value> g4_children[] = { g1s1 };
- V8::AddObjectGroup(g1_objects, 2);
- V8::AddImplicitReferences(g1s1, g1_children, 1);
- V8::AddObjectGroup(g2_objects, 2);
- V8::AddImplicitReferences(g2s1, g2_children, 1);
- V8::AddObjectGroup(g3_objects, 2);
- V8::AddImplicitReferences(g3s1, g3_children, 1);
- V8::AddObjectGroup(iso, g4_objects, 2);
- V8::AddImplicitReferences(g4s1, g4_children, 1);
- }
- // Do a single full GC
- HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
- // All object should be alive.
- CHECK_EQ(0, counter.NumberOfWeakCalls());
-
- // Weaken the root.
- root.MakeWeak(iso, &counter, &WeakPointerCallback);
-
- // Groups are deleted, rebuild groups.
- {
- Persistent<Value> g1_objects[] = { g1s1, g1s2 };
- Persistent<Value> g1_children[] = { g2s1 };
- Persistent<Value> g2_objects[] = { g2s1, g2s2 };
- Persistent<Value> g2_children[] = { g3s1 };
- Persistent<Value> g3_objects[] = { g3s1, g3s2 };
- Persistent<Value> g3_children[] = { g4s1 };
- Persistent<Value> g4_objects[] = { g4s1, g4s2 };
- Persistent<Value> g4_children[] = { g1s1 };
- V8::AddObjectGroup(g1_objects, 2);
- V8::AddImplicitReferences(g1s1, g1_children, 1);
- V8::AddObjectGroup(g2_objects, 2);
- V8::AddImplicitReferences(g2s1, g2_children, 1);
- V8::AddObjectGroup(g3_objects, 2);
- V8::AddImplicitReferences(g3s1, g3_children, 1);
- V8::AddObjectGroup(g4_objects, 2);
- V8::AddImplicitReferences(g4s1, g4_children, 1);
- }
-
- HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
-
- // All objects should be gone. 9 global handles in total.
- CHECK_EQ(9, counter.NumberOfWeakCalls());
-}
-
-
THREADED_TEST(ApiObjectGroupsCycle) {
LocalContext env;
v8::Isolate* iso = env->GetIsolate();
@@ -3118,47 +3202,47 @@ THREADED_TEST(ApiObjectGroupsCycle) {
WeakCallCounter counter(1234);
- Persistent<Object> g1s1;
- Persistent<Object> g1s2;
- Persistent<Object> g2s1;
- Persistent<Object> g2s2;
- Persistent<Object> g3s1;
- Persistent<Object> g3s2;
- Persistent<Object> g4s1;
- Persistent<Object> g4s2;
+ Persistent<Value> g1s1;
+ Persistent<Value> g1s2;
+ Persistent<Value> g2s1;
+ Persistent<Value> g2s2;
+ Persistent<Value> g3s1;
+ Persistent<Value> g3s2;
+ Persistent<Value> g4s1;
+ Persistent<Value> g4s2;
{
HandleScope scope(iso);
- g1s1 = Persistent<Object>::New(iso, Object::New());
- g1s2 = Persistent<Object>::New(iso, Object::New());
+ g1s1.Reset(iso, Object::New());
+ g1s2.Reset(iso, Object::New());
g1s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g1s2.MakeWeak(iso, &counter, &WeakPointerCallback);
CHECK(g1s1.IsWeak(iso));
CHECK(g1s2.IsWeak(iso));
- g2s1 = Persistent<Object>::New(iso, Object::New());
- g2s2 = Persistent<Object>::New(iso, Object::New());
+ g2s1.Reset(iso, Object::New());
+ g2s2.Reset(iso, Object::New());
g2s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g2s2.MakeWeak(iso, &counter, &WeakPointerCallback);
CHECK(g2s1.IsWeak(iso));
CHECK(g2s2.IsWeak(iso));
- g3s1 = Persistent<Object>::New(iso, Object::New());
- g3s2 = Persistent<Object>::New(iso, Object::New());
+ g3s1.Reset(iso, Object::New());
+ g3s2.Reset(iso, Object::New());
g3s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g3s2.MakeWeak(iso, &counter, &WeakPointerCallback);
CHECK(g3s1.IsWeak(iso));
CHECK(g3s2.IsWeak(iso));
- g4s1 = Persistent<Object>::New(iso, Object::New());
- g4s2 = Persistent<Object>::New(iso, Object::New());
+ g4s1.Reset(iso, Object::New());
+ g4s2.Reset(iso, Object::New());
g4s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g4s2.MakeWeak(iso, &counter, &WeakPointerCallback);
CHECK(g4s1.IsWeak(iso));
CHECK(g4s2.IsWeak(iso));
}
- Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root.
+ Persistent<Value> root(iso, g1s1); // make a root.
// Connect groups. We're building the following cycle:
// G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
@@ -3221,103 +3305,6 @@ THREADED_TEST(ApiObjectGroupsCycle) {
// TODO(mstarzinger): This should be a THREADED_TEST but causes failures
// on the buildbots, so was made non-threaded for the time being.
-TEST(OldApiObjectGroupsCycleForScavenger) {
- i::FLAG_stress_compaction = false;
- i::FLAG_gc_global = false;
- LocalContext env;
- v8::Isolate* iso = env->GetIsolate();
- HandleScope scope(iso);
-
- WeakCallCounter counter(1234);
-
- Persistent<Object> g1s1;
- Persistent<Object> g1s2;
- Persistent<Object> g2s1;
- Persistent<Object> g2s2;
- Persistent<Object> g3s1;
- Persistent<Object> g3s2;
-
- {
- HandleScope scope(iso);
- g1s1 = Persistent<Object>::New(iso, Object::New());
- g1s2 = Persistent<Object>::New(iso, Object::New());
- g1s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g1s2.MakeWeak(iso, &counter, &WeakPointerCallback);
-
- g2s1 = Persistent<Object>::New(iso, Object::New());
- g2s2 = Persistent<Object>::New(iso, Object::New());
- g2s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g2s2.MakeWeak(iso, &counter, &WeakPointerCallback);
-
- g3s1 = Persistent<Object>::New(iso, Object::New());
- g3s2 = Persistent<Object>::New(iso, Object::New());
- g3s1.MakeWeak(iso, &counter, &WeakPointerCallback);
- g3s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- }
-
- // Make a root.
- Persistent<Object> root = Persistent<Object>::New(iso, g1s1);
- root.MarkPartiallyDependent(iso);
-
- // Connect groups. We're building the following cycle:
- // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
- // groups.
- {
- g1s1.MarkPartiallyDependent(iso);
- g1s2.MarkPartiallyDependent(iso);
- g2s1.MarkPartiallyDependent(iso);
- g2s2.MarkPartiallyDependent(iso);
- g3s1.MarkPartiallyDependent(iso);
- g3s2.MarkPartiallyDependent(iso);
- Persistent<Value> g1_objects[] = { g1s1, g1s2 };
- Persistent<Value> g2_objects[] = { g2s1, g2s2 };
- Persistent<Value> g3_objects[] = { g3s1, g3s2 };
- V8::AddObjectGroup(g1_objects, 2);
- g1s1->Set(v8_str("x"), Handle<Object>(*g2s1));
- V8::AddObjectGroup(g2_objects, 2);
- g2s1->Set(v8_str("x"), Handle<Object>(*g3s1));
- V8::AddObjectGroup(g3_objects, 2);
- g3s1->Set(v8_str("x"), Handle<Object>(*g1s1));
- }
-
- HEAP->CollectGarbage(i::NEW_SPACE);
-
- // All objects should be alive.
- CHECK_EQ(0, counter.NumberOfWeakCalls());
-
- // Weaken the root.
- root.MakeWeak(iso, &counter, &WeakPointerCallback);
- root.MarkPartiallyDependent(iso);
-
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- // Groups are deleted, rebuild groups.
- {
- g1s1.MarkPartiallyDependent(isolate);
- g1s2.MarkPartiallyDependent(isolate);
- g2s1.MarkPartiallyDependent(isolate);
- g2s2.MarkPartiallyDependent(isolate);
- g3s1.MarkPartiallyDependent(isolate);
- g3s2.MarkPartiallyDependent(isolate);
- Persistent<Value> g1_objects[] = { g1s1, g1s2 };
- Persistent<Value> g2_objects[] = { g2s1, g2s2 };
- Persistent<Value> g3_objects[] = { g3s1, g3s2 };
- V8::AddObjectGroup(g1_objects, 2);
- g1s1->Set(v8_str("x"), Handle<Object>(*g2s1));
- V8::AddObjectGroup(g2_objects, 2);
- g2s1->Set(v8_str("x"), Handle<Object>(*g3s1));
- V8::AddObjectGroup(g3_objects, 2);
- g3s1->Set(v8_str("x"), Handle<Object>(*g1s1));
- }
-
- HEAP->CollectGarbage(i::NEW_SPACE);
-
- // All objects should be gone. 7 global handles in total.
- CHECK_EQ(7, counter.NumberOfWeakCalls());
-}
-
-
-// TODO(mstarzinger): This should be a THREADED_TEST but causes failures
-// on the buildbots, so was made non-threaded for the time being.
TEST(ApiObjectGroupsCycleForScavenger) {
i::FLAG_stress_compaction = false;
i::FLAG_gc_global = false;
@@ -3327,39 +3314,40 @@ TEST(ApiObjectGroupsCycleForScavenger) {
WeakCallCounter counter(1234);
- Persistent<Object> g1s1;
- Persistent<Object> g1s2;
- Persistent<Object> g2s1;
- Persistent<Object> g2s2;
- Persistent<Object> g3s1;
- Persistent<Object> g3s2;
+ Persistent<Value> g1s1;
+ Persistent<Value> g1s2;
+ Persistent<Value> g2s1;
+ Persistent<Value> g2s2;
+ Persistent<Value> g3s1;
+ Persistent<Value> g3s2;
{
HandleScope scope(iso);
- g1s1 = Persistent<Object>::New(iso, Object::New());
- g1s2 = Persistent<Object>::New(iso, Object::New());
+ g1s1.Reset(iso, Object::New());
+ g1s2.Reset(iso, Object::New());
g1s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g1s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- g2s1 = Persistent<Object>::New(iso, Object::New());
- g2s2 = Persistent<Object>::New(iso, Object::New());
+ g2s1.Reset(iso, Object::New());
+ g2s2.Reset(iso, Object::New());
g2s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g2s2.MakeWeak(iso, &counter, &WeakPointerCallback);
- g3s1 = Persistent<Object>::New(iso, Object::New());
- g3s2 = Persistent<Object>::New(iso, Object::New());
+ g3s1.Reset(iso, Object::New());
+ g3s2.Reset(iso, Object::New());
g3s1.MakeWeak(iso, &counter, &WeakPointerCallback);
g3s2.MakeWeak(iso, &counter, &WeakPointerCallback);
}
// Make a root.
- Persistent<Object> root = Persistent<Object>::New(iso, g1s1);
+ Persistent<Value> root(iso, g1s1);
root.MarkPartiallyDependent(iso);
// Connect groups. We're building the following cycle:
// G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
// groups.
{
+ HandleScope handle_scope(iso);
g1s1.MarkPartiallyDependent(iso);
g1s2.MarkPartiallyDependent(iso);
g2s1.MarkPartiallyDependent(iso);
@@ -3368,13 +3356,16 @@ TEST(ApiObjectGroupsCycleForScavenger) {
g3s2.MarkPartiallyDependent(iso);
iso->SetObjectGroupId(g1s1, UniqueId(1));
iso->SetObjectGroupId(g1s2, UniqueId(1));
- g1s1->Set(v8_str("x"), Local<Value>(*g2s1));
+ Local<Object>::New(iso, g1s1.As<Object>())->Set(v8_str("x"),
+ Local<Value>(*g2s1));
iso->SetObjectGroupId(g2s1, UniqueId(2));
iso->SetObjectGroupId(g2s2, UniqueId(2));
- g2s1->Set(v8_str("x"), Local<Value>(*g3s1));
+ Local<Object>::New(iso, g2s1.As<Object>())->Set(v8_str("x"),
+ Local<Value>(*g3s1));
iso->SetObjectGroupId(g3s1, UniqueId(3));
iso->SetObjectGroupId(g3s2, UniqueId(3));
- g3s1->Set(v8_str("x"), Local<Value>(*g1s1));
+ Local<Object>::New(iso, g3s1.As<Object>())->Set(v8_str("x"),
+ Local<Value>(*g1s1));
}
v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
@@ -3391,6 +3382,7 @@ TEST(ApiObjectGroupsCycleForScavenger) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
// Groups are deleted, rebuild groups.
{
+ HandleScope handle_scope(iso);
g1s1.MarkPartiallyDependent(isolate);
g1s2.MarkPartiallyDependent(isolate);
g2s1.MarkPartiallyDependent(isolate);
@@ -3399,13 +3391,16 @@ TEST(ApiObjectGroupsCycleForScavenger) {
g3s2.MarkPartiallyDependent(isolate);
iso->SetObjectGroupId(g1s1, UniqueId(1));
iso->SetObjectGroupId(g1s2, UniqueId(1));
- g1s1->Set(v8_str("x"), Local<Value>(*g2s1));
+ Local<Object>::New(iso, g1s1.As<Object>())->Set(v8_str("x"),
+ Local<Value>(*g2s1));
iso->SetObjectGroupId(g2s1, UniqueId(2));
iso->SetObjectGroupId(g2s2, UniqueId(2));
- g2s1->Set(v8_str("x"), Local<Value>(*g3s1));
+ Local<Object>::New(iso, g2s1.As<Object>())->Set(v8_str("x"),
+ Local<Value>(*g3s1));
iso->SetObjectGroupId(g3s1, UniqueId(3));
iso->SetObjectGroupId(g3s2, UniqueId(3));
- g3s1->Set(v8_str("x"), Local<Value>(*g1s1));
+ Local<Object>::New(iso, g3s1.As<Object>())->Set(v8_str("x"),
+ Local<Value>(*g1s1));
}
heap->CollectGarbage(i::NEW_SPACE);
@@ -4544,9 +4539,8 @@ THREADED_TEST(Equality) {
CHECK(!v8::False()->StrictEquals(v8::Undefined()));
v8::Handle<v8::Object> obj = v8::Object::New();
- v8::Persistent<v8::Object> alias =
- v8::Persistent<v8::Object>::New(isolate, obj);
- CHECK(alias->StrictEquals(obj));
+ v8::Persistent<v8::Object> alias(isolate, obj);
+ CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj));
alias.Dispose(isolate);
}
@@ -4845,7 +4839,7 @@ static void SetXValue(Local<String> name,
CHECK_EQ(info.Data(), v8_str("donut"));
CHECK_EQ(name, v8_str("x"));
CHECK(xValue.IsEmpty());
- xValue = v8::Persistent<Value>::New(info.GetIsolate(), value);
+ xValue.Reset(info.GetIsolate(), value);
}
@@ -4861,7 +4855,7 @@ THREADED_TEST(SimplePropertyWrite) {
script->Run();
CHECK_EQ(v8_num(4), Handle<Value>(*xValue));
xValue.Dispose(context->GetIsolate());
- xValue = v8::Persistent<Value>();
+ xValue.Clear();
}
}
@@ -4878,7 +4872,7 @@ THREADED_TEST(SetterOnly) {
script->Run();
CHECK_EQ(v8_num(4), Handle<Value>(*xValue));
xValue.Dispose(context->GetIsolate());
- xValue = v8::Persistent<Value>();
+ xValue.Clear();
}
}
@@ -5741,15 +5735,14 @@ template <typename T> static void USE(T) { }
static inline void PersistentHandles(v8::Isolate* isolate) {
USE(PersistentHandles);
Local<String> str = v8_str("foo");
- v8::Persistent<String> p_str = v8::Persistent<String>::New(isolate, str);
- USE(p_str);
+ v8::Persistent<String> p_str(isolate, str);
+ p_str.Dispose();
Local<Script> scr = Script::Compile(v8_str(""));
- v8::Persistent<Script> p_scr = v8::Persistent<Script>::New(isolate, scr);
- USE(p_scr);
+ v8::Persistent<Script> p_scr(isolate, scr);
+ p_scr.Dispose();
Local<ObjectTemplate> templ = ObjectTemplate::New();
- v8::Persistent<ObjectTemplate> p_templ =
- v8::Persistent<ObjectTemplate>::New(isolate, templ);
- USE(p_templ);
+ v8::Persistent<ObjectTemplate> p_templ(isolate, templ);
+ p_templ.Dispose();
}
@@ -6253,10 +6246,7 @@ class Whammy {
explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
~Whammy() { script_.Dispose(isolate_); }
v8::Handle<Script> getScript() {
- if (script_.IsEmpty()) {
- script_ = v8::Persistent<Script>::New(isolate_,
- v8_compile("({}).blammo"));
- }
+ if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
return Local<Script>(*script_);
}
@@ -6280,19 +6270,18 @@ v8::Handle<Value> WhammyPropertyGetter(Local<String> name,
Whammy* whammy =
static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
- v8::Persistent<v8::Object> prev = whammy->objects_[whammy->cursor_];
+ v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_];
v8::Handle<v8::Object> obj = v8::Object::New();
- v8::Persistent<v8::Object> global =
- v8::Persistent<v8::Object>::New(info.GetIsolate(), obj);
if (!prev.IsEmpty()) {
- prev->Set(v8_str("next"), obj);
+ v8::Local<v8::Object>::New(info.GetIsolate(), prev)
+ ->Set(v8_str("next"), obj);
prev.MakeWeak<Value, Snorkel>(info.GetIsolate(),
new Snorkel(),
&HandleWeakReference);
whammy->objects_[whammy->cursor_].Clear();
}
- whammy->objects_[whammy->cursor_] = global;
+ whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj);
whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount;
return whammy->getScript()->Run();
}
@@ -6345,8 +6334,8 @@ THREADED_TEST(IndependentWeakHandle) {
{
v8::HandleScope handle_scope(iso);
- object_a = v8::Persistent<v8::Object>::New(iso, v8::Object::New());
- object_b = v8::Persistent<v8::Object>::New(iso, v8::Object::New());
+ object_a.Reset(iso, v8::Object::New());
+ object_b.Reset(iso, v8::Object::New());
}
bool object_a_disposed = false;
@@ -6410,7 +6399,7 @@ THREADED_TEST(GCFromWeakCallbacks) {
v8::Persistent<v8::Object> object;
{
v8::HandleScope handle_scope(isolate);
- object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ object.Reset(isolate, v8::Object::New());
}
bool disposed = false;
object.MakeWeak(isolate, &disposed, gc_forcing_callback[inner_gc]);
@@ -6439,10 +6428,11 @@ THREADED_TEST(IndependentHandleRevival) {
v8::Persistent<v8::Object> object;
{
v8::HandleScope handle_scope(isolate);
- object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
- object->Set(v8_str("x"), v8::Integer::New(1));
+ v8::Local<v8::Object> o = v8::Object::New();
+ object.Reset(isolate, o);
+ o->Set(v8_str("x"), v8::Integer::New(1));
v8::Local<String> y_str = v8_str("y");
- object->Set(y_str, y_str);
+ o->Set(y_str, y_str);
}
bool revived = false;
object.MakeWeak(isolate, &revived, &RevivingCallback);
@@ -6452,9 +6442,10 @@ THREADED_TEST(IndependentHandleRevival) {
HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
{
v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object);
v8::Local<String> y_str = v8_str("y");
- CHECK_EQ(v8::Integer::New(1), object->Get(v8_str("x")));
- CHECK(object->Get(y_str)->Equals(y_str));
+ CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x")));
+ CHECK(o->Get(y_str)->Equals(y_str));
}
}
@@ -11982,7 +11973,7 @@ static v8::Handle<Value> ThrowInJSNoCatch(const v8::Arguments& args) {
v8::HandleScope scope(args.GetIsolate());
v8::Handle<Value> value = CompileRun(code);
CHECK(value.IsEmpty());
- return v8_str("foo");
+ return scope.Close(v8_str("foo"));
}
}
@@ -12150,7 +12141,7 @@ void NewPersistentHandleCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void*) {
v8::HandleScope scope(isolate);
- bad_handle = v8::Persistent<v8::Object>::New(isolate, some_object);
+ bad_handle.Reset(isolate, some_object);
handle->Dispose(isolate);
}
@@ -12162,9 +12153,9 @@ THREADED_TEST(NewPersistentHandleFromWeakCallback) {
v8::Persistent<v8::Object> handle1, handle2;
{
v8::HandleScope scope(isolate);
- some_object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
- handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
- handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ some_object.Reset(isolate, v8::Object::New());
+ handle1.Reset(isolate, v8::Object::New());
+ handle2.Reset(isolate, v8::Object::New());
}
// Note: order is implementation dependent alas: currently
// global handle nodes are processed by PostGarbageCollectionProcessing
@@ -12196,11 +12187,11 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
v8::Persistent<v8::Object> handle1, handle2;
{
v8::HandleScope scope(isolate);
- handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
- handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ handle1.Reset(isolate, v8::Object::New());
+ handle2.Reset(isolate, v8::Object::New());
}
handle1.MakeWeak<v8::Value, void>(isolate, NULL, DisposeAndForceGcCallback);
- to_be_disposed = handle2;
+ to_be_disposed.Reset(isolate, handle2);
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -12226,9 +12217,9 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
v8::Persistent<v8::Object> handle1, handle2, handle3;
{
v8::HandleScope scope(isolate);
- handle3 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
- handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
- handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ handle3.Reset(isolate, v8::Object::New());
+ handle2.Reset(isolate, v8::Object::New());
+ handle1.Reset(isolate, v8::Object::New());
}
handle2.MakeWeak<v8::Value, void>(isolate, NULL, DisposingCallback);
handle3.MakeWeak<v8::Value, void>(isolate, NULL, HandleCreatingCallback);
@@ -12282,9 +12273,10 @@ THREADED_TEST(NestedHandleScopeAndContexts) {
static i::Handle<i::JSFunction>* foo_ptr = NULL;
-static int foo_count = 0;
+static int foo_entry_count = 0;
static i::Handle<i::JSFunction>* bar_ptr = NULL;
-static int bar_count = 0;
+static int bar_entry_count = 0;
+static int bar_caller_count = 0;
static void entry_hook(uintptr_t function,
@@ -12294,14 +12286,21 @@ static void entry_hook(uintptr_t function,
CHECK(code != NULL);
if (bar_ptr != NULL && code == (*bar_ptr)->code())
- ++bar_count;
+ ++bar_entry_count;
if (foo_ptr != NULL && code == (*foo_ptr)->code())
- ++foo_count;
+ ++foo_entry_count;
- // TODO(siggi): Verify return_addr_location.
- // This can be done by capturing JitCodeEvents, but requires an ordered
- // collection.
+ // Let's check whether bar is the caller.
+ if (bar_ptr != NULL) {
+ const v8::internal::byte* caller =
+ *reinterpret_cast<v8::internal::byte**>(return_addr_location);
+
+ if ((*bar_ptr)->code()->instruction_start() <= caller &&
+ (*bar_ptr)->code()->instruction_end() > caller) {
+ ++bar_caller_count;
+ }
+ }
}
@@ -12372,17 +12371,20 @@ TEST(SetFunctionEntryHook) {
CHECK(v8::V8::SetFunctionEntryHook(NULL));
// Reset the entry count to zero and set the entry hook.
- bar_count = 0;
- foo_count = 0;
+ bar_entry_count = 0;
+ bar_caller_count = 0;
+ foo_entry_count = 0;
CHECK(v8::V8::SetFunctionEntryHook(entry_hook));
RunLoopInNewEnv();
- CHECK_EQ(2, bar_count);
- CHECK_EQ(200, foo_count);
+ CHECK_EQ(2, bar_entry_count);
+ CHECK_EQ(200, bar_caller_count);
+ CHECK_EQ(200, foo_entry_count);
// Clear the entry hook and count.
- bar_count = 0;
- foo_count = 0;
+ bar_entry_count = 0;
+ bar_caller_count = 0;
+ foo_entry_count = 0;
v8::V8::SetFunctionEntryHook(NULL);
// Clear the compilation cache to make sure we don't reuse the
@@ -12391,8 +12393,9 @@ TEST(SetFunctionEntryHook) {
// Verify that entry hooking is now disabled.
RunLoopInNewEnv();
- CHECK_EQ(0u, bar_count);
- CHECK_EQ(0u, foo_count);
+ CHECK_EQ(0u, bar_entry_count);
+ CHECK_EQ(0u, bar_caller_count);
+ CHECK_EQ(0u, foo_entry_count);
}
@@ -12667,10 +12670,13 @@ THREADED_TEST(DisposeEnteredContext) {
}
v8::HandleScope scope(isolate);
{
- inner->Enter();
- inner.Dispose(inner->GetIsolate());
+ // Don't want a handle here, so do this unsafely
+ v8::Handle<v8::Context> inner_local =
+ *reinterpret_cast<v8::Handle<v8::Context>*>(&inner);
+ inner_local->Enter();
+ inner.Dispose();
inner.Clear();
- inner->Exit();
+ inner_local->Exit();
}
}
@@ -12687,10 +12693,10 @@ THREADED_TEST(Regress54) {
v8::HandleScope inner(isolate);
v8::Handle<v8::ObjectTemplate> local = v8::ObjectTemplate::New();
local->SetInternalFieldCount(1);
- templ =
- v8::Persistent<v8::ObjectTemplate>::New(isolate, inner.Close(local));
+ templ.Reset(isolate, inner.Close(local));
}
- v8::Handle<v8::Object> result = templ->NewInstance();
+ v8::Handle<v8::Object> result =
+ v8::Local<v8::ObjectTemplate>::New(isolate, templ)->NewInstance();
CHECK_EQ(1, result->InternalFieldCount());
}
@@ -13705,6 +13711,7 @@ THREADED_TEST(MorphCompositeStringTest) {
uint16_t* two_byte_string = AsciiToTwoByteString(c_string);
{
LocalContext env;
+ i::Factory* factory = i::Isolate::Current()->factory();
v8::HandleScope scope(env->GetIsolate());
AsciiVectorResource ascii_resource(
i::Vector<const char>(c_string, i::StrLength(c_string)));
@@ -13713,9 +13720,9 @@ THREADED_TEST(MorphCompositeStringTest) {
i::StrLength(c_string)));
Local<String> lhs(v8::Utils::ToLocal(
- FACTORY->NewExternalStringFromAscii(&ascii_resource)));
+ factory->NewExternalStringFromAscii(&ascii_resource)));
Local<String> rhs(v8::Utils::ToLocal(
- FACTORY->NewExternalStringFromAscii(&ascii_resource)));
+ factory->NewExternalStringFromAscii(&ascii_resource)));
env->Global()->Set(v8_str("lhs"), lhs);
env->Global()->Set(v8_str("rhs"), rhs);
@@ -13802,6 +13809,8 @@ class RegExpStringModificationTest {
uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {}
~RegExpStringModificationTest() { delete block_; }
void RunTest() {
+ i::Factory* factory = i::Isolate::Current()->factory();
+
regexp_success_ = false;
morph_success_ = false;
@@ -13814,11 +13823,11 @@ class RegExpStringModificationTest {
// Create the input string for the regexp - the one we are going to change
// properties of.
- input_ = FACTORY->NewExternalStringFromAscii(&ascii_resource_);
+ input_ = factory->NewExternalStringFromAscii(&ascii_resource_);
// Inject the input as a global variable.
i::Handle<i::String> input_name =
- FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5));
+ factory->NewStringFromAscii(i::Vector<const char>("input", 5));
i::Isolate::Current()->native_context()->global_object()->SetProperty(
*input_name,
*input_,
@@ -14312,12 +14321,13 @@ THREADED_TEST(Regress16276) {
THREADED_TEST(PixelArray) {
LocalContext context;
+ i::Factory* factory = i::Isolate::Current()->factory();
v8::HandleScope scope(context->GetIsolate());
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
i::Handle<i::ExternalPixelArray> pixels =
i::Handle<i::ExternalPixelArray>::cast(
- FACTORY->NewExternalArray(kElementCount,
+ factory->NewExternalArray(kElementCount,
v8::kExternalPixelArray,
pixel_data));
// Force GC to trigger verification.
@@ -14734,12 +14744,13 @@ static v8::Handle<Value> NotHandledIndexedPropertySetter(
THREADED_TEST(PixelArrayWithInterceptor) {
LocalContext context;
+ i::Factory* factory = i::Isolate::Current()->factory();
v8::HandleScope scope(context->GetIsolate());
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
i::Handle<i::ExternalPixelArray> pixels =
i::Handle<i::ExternalPixelArray>::cast(
- FACTORY->NewExternalArray(kElementCount,
+ factory->NewExternalArray(kElementCount,
v8::kExternalPixelArray,
pixel_data));
for (int i = 0; i < kElementCount; i++) {
@@ -15101,6 +15112,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
int64_t low,
int64_t high) {
LocalContext context;
+ i::Factory* factory = i::Isolate::Current()->factory();
v8::HandleScope scope(context->GetIsolate());
const int kElementCount = 40;
int element_size = ExternalArrayElementSize(array_type);
@@ -15108,7 +15120,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
static_cast<ElementType*>(malloc(kElementCount * element_size));
i::Handle<ExternalArrayClass> array =
i::Handle<ExternalArrayClass>::cast(
- FACTORY->NewExternalArray(kElementCount, array_type, array_data));
+ factory->NewExternalArray(kElementCount, array_type, array_data));
// Force GC to trigger verification.
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
for (int i = 0; i < kElementCount; i++) {
@@ -15460,12 +15472,14 @@ void TypedArrayTestHelper(v8::ExternalArrayType array_type,
i::FLAG_harmony_array_buffer = true;
i::FLAG_harmony_typed_arrays = true;
+ i::ScopedVector<ElementType> backing_store(kElementCount+2);
+
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
- Local<v8::ArrayBuffer> ab =
- v8::ArrayBuffer::New((kElementCount+2)*sizeof(ElementType));
+ Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(
+ backing_store.start(), (kElementCount+2)*sizeof(ElementType));
Local<TypedArray> ta =
TypedArray::New(ab, 2*sizeof(ElementType), kElementCount);
CHECK_EQ(kElementCount, static_cast<int>(ta->Length()));
@@ -15474,7 +15488,7 @@ void TypedArrayTestHelper(v8::ExternalArrayType array_type,
static_cast<int>(ta->ByteLength()));
CHECK_EQ(ab, ta->Buffer());
- ElementType* data = static_cast<ElementType*>(ab->Data()) + 2;
+ ElementType* data = backing_store.start() + 2;
for (int i = 0; i < kElementCount; i++) {
data[i] = static_cast<ElementType>(i);
}
@@ -15941,8 +15955,13 @@ TEST(SourceURLInStackTrace) {
"}\n"
"foo();\n"
"}\n"
- "eval('(' + outer +')()//@ sourceURL=eval_url');";
- CHECK(CompileRun(source)->IsUndefined());
+ "eval('(' + outer +')()%s');";
+
+ i::ScopedVector<char> code(1024);
+ i::OS::SNPrintF(code, source, "//# sourceURL=eval_url");
+ CHECK(CompileRun(code.start())->IsUndefined());
+ i::OS::SNPrintF(code, source, "//@ sourceURL=eval_url");
+ CHECK(CompileRun(code.start())->IsUndefined());
}
@@ -15982,9 +16001,13 @@ TEST(InlineScriptWithSourceURLInStackTrace) {
"}\n"
"foo();\n"
"}\n"
- "outer()\n"
- "//@ sourceURL=source_url";
- CHECK(CompileRunWithOrigin(source, "url", 0, 1)->IsUndefined());
+ "outer()\n%s";
+
+ i::ScopedVector<char> code(1024);
+ i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
+ i::OS::SNPrintF(code, source, "//@ sourceURL=source_url");
+ CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
}
@@ -16024,16 +16047,21 @@ TEST(DynamicWithSourceURLInStackTrace) {
"}\n"
"foo();\n"
"}\n"
- "outer()\n"
- "//@ sourceURL=source_url";
- CHECK(CompileRunWithOrigin(source, "url", 0, 0)->IsUndefined());
+ "outer()\n%s";
+
+ i::ScopedVector<char> code(1024);
+ i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined());
+ i::OS::SNPrintF(code, source, "//@ sourceURL=source_url");
+ CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined());
}
static void CreateGarbageInOldSpace() {
+ i::Factory* factory = i::Isolate::Current()->factory();
v8::HandleScope scope(v8::Isolate::GetCurrent());
i::AlwaysAllocateScope always_allocate;
for (int i = 0; i < 1000; i++) {
- FACTORY->NewFixedArray(1000, i::TENURED);
+ factory->NewFixedArray(1000, i::TENURED);
}
}
@@ -17039,6 +17067,73 @@ THREADED_TEST(TwoByteStringInAsciiCons) {
}
+TEST(ContainsOnlyOneByte) {
+ v8::V8::Initialize();
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope scope(isolate);
+ // Make a buffer long enough that it won't automatically be converted.
+ const int length = 512;
+ // Ensure word aligned assignment.
+ const int aligned_length = length*sizeof(uintptr_t)/sizeof(uint16_t);
+ i::SmartArrayPointer<uintptr_t>
+ aligned_contents(new uintptr_t[aligned_length]);
+ uint16_t* string_contents = reinterpret_cast<uint16_t*>(*aligned_contents);
+ // Set to contain only one byte.
+ for (int i = 0; i < length-1; i++) {
+ string_contents[i] = 0x41;
+ }
+ string_contents[length-1] = 0;
+ // Simple case.
+ Handle<String> string;
+ string = String::NewExternal(new TestResource(string_contents));
+ CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
+ // Counter example.
+ string = String::NewFromTwoByte(isolate, string_contents);
+ CHECK(string->IsOneByte() && string->ContainsOnlyOneByte());
+ // Test left right and balanced cons strings.
+ Handle<String> base = String::NewFromUtf8(isolate, "a");
+ Handle<String> left = base;
+ Handle<String> right = base;
+ for (int i = 0; i < 1000; i++) {
+ left = String::Concat(base, left);
+ right = String::Concat(right, base);
+ }
+ Handle<String> balanced = String::Concat(left, base);
+ balanced = String::Concat(balanced, right);
+ Handle<String> cons_strings[] = {left, balanced, right};
+ Handle<String> two_byte =
+ String::NewExternal(new TestResource(string_contents));
+ for (size_t i = 0; i < ARRAY_SIZE(cons_strings); i++) {
+ // Base assumptions.
+ string = cons_strings[i];
+ CHECK(string->IsOneByte() && string->ContainsOnlyOneByte());
+ // Test left and right concatentation.
+ string = String::Concat(two_byte, cons_strings[i]);
+ CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
+ string = String::Concat(cons_strings[i], two_byte);
+ CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
+ }
+ // Set bits in different positions
+ // for strings of different lengths and alignments.
+ for (int alignment = 0; alignment < 7; alignment++) {
+ for (int size = 2; alignment + size < length; size *= 2) {
+ int zero_offset = size + alignment;
+ string_contents[zero_offset] = 0;
+ for (int i = 0; i < size; i++) {
+ int shift = 8 + (i % 7);
+ string_contents[alignment + i] = 1 << shift;
+ string =
+ String::NewExternal(new TestResource(string_contents + alignment));
+ CHECK_EQ(size, string->Length());
+ CHECK(!string->ContainsOnlyOneByte());
+ string_contents[alignment + i] = 0x41;
+ }
+ string_contents[zero_offset] = 0x41;
+ }
+ }
+}
+
+
// Failed access check callback that performs a GC on each invocation.
void FailedAccessCheckCallbackGC(Local<v8::Object> target,
v8::AccessType type,
@@ -17251,7 +17346,9 @@ TEST(RunTwoIsolatesOnSingleThread) {
{
v8::HandleScope scope(isolate1);
- v8::Context::Scope cscope(isolate1, context1);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(isolate1, context1);
+ v8::Context::Scope context_scope(context);
// Run something in new isolate.
CompileRun("var foo = 'isolate 1';");
ExpectString("function f() { return foo; }; f()", "isolate 1");
@@ -17265,7 +17362,9 @@ TEST(RunTwoIsolatesOnSingleThread) {
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(isolate2);
context2.Reset(isolate2, Context::New(isolate2));
- v8::Context::Scope cscope(isolate2, context2);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(isolate2, context2);
+ v8::Context::Scope context_scope(context);
// Run something in new isolate.
CompileRun("var foo = 'isolate 2';");
@@ -17274,7 +17373,9 @@ TEST(RunTwoIsolatesOnSingleThread) {
{
v8::HandleScope scope(isolate1);
- v8::Context::Scope cscope(isolate1, context1);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(isolate1, context1);
+ v8::Context::Scope context_scope(context);
// Now again in isolate 1
ExpectString("function f() { return foo; }; f()", "isolate 1");
}
@@ -17292,7 +17393,9 @@ TEST(RunTwoIsolatesOnSingleThread) {
{
v8::HandleScope scope(v8::Isolate::GetCurrent());
- v8::Context::Scope cscope(v8::Isolate::GetCurrent(), context_default);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), context_default);
+ v8::Context::Scope context_scope(context);
// Variables in other isolates should be not available, verify there
// is an exception.
ExpectTrue("function f() {"
@@ -17312,22 +17415,26 @@ TEST(RunTwoIsolatesOnSingleThread) {
{
v8::Isolate::Scope iscope(isolate2);
v8::HandleScope scope(v8::Isolate::GetCurrent());
- v8::Context::Scope cscope(isolate2, context2);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(isolate2, context2);
+ v8::Context::Scope context_scope(context);
ExpectString("function f() { return foo; }; f()", "isolate 2");
}
{
v8::HandleScope scope(v8::Isolate::GetCurrent());
- v8::Context::Scope cscope(v8::Isolate::GetCurrent(), context1);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), context1);
+ v8::Context::Scope context_scope(context);
ExpectString("function f() { return foo; }; f()", "isolate 1");
}
{
v8::Isolate::Scope iscope(isolate2);
- context2.Dispose(context2->GetIsolate());
+ context2.Dispose();
}
- context1.Dispose(context1->GetIsolate());
+ context1.Dispose();
isolate1->Exit();
v8::V8::SetFatalErrorHandler(StoringErrorCallback);
@@ -17344,7 +17451,9 @@ TEST(RunTwoIsolatesOnSingleThread) {
// Check that default isolate still runs.
{
v8::HandleScope scope(v8::Isolate::GetCurrent());
- v8::Context::Scope cscope(v8::Isolate::GetCurrent(), context_default);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), context_default);
+ v8::Context::Scope context_scope(context);
ExpectTrue("function f() { return isDefaultIsolate; }; f()");
}
}
@@ -17692,23 +17801,25 @@ TEST(DontDeleteCellLoadICAPI) {
class Visitor42 : public v8::PersistentHandleVisitor {
public:
- explicit Visitor42(v8::Persistent<v8::Object> object)
+ explicit Visitor42(v8::Persistent<v8::Object>* object)
: counter_(0), object_(object) { }
- virtual void VisitPersistentHandle(Persistent<Value> value,
+ virtual void VisitPersistentHandle(Persistent<Value>* value,
uint16_t class_id) {
- if (class_id == 42) {
- CHECK(value->IsObject());
- v8::Persistent<v8::Object> visited =
- v8::Persistent<v8::Object>::Cast(value);
- CHECK_EQ(42, visited.WrapperClassId(v8::Isolate::GetCurrent()));
- CHECK_EQ(Handle<Value>(*object_), Handle<Value>(*visited));
- ++counter_;
- }
+ if (class_id != 42) return;
+ CHECK_EQ(42, value->WrapperClassId());
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::Value> handle = v8::Local<v8::Value>::New(isolate, *value);
+ v8::Handle<v8::Value> object =
+ v8::Local<v8::Object>::New(isolate, *object_);
+ CHECK(handle->IsObject());
+ CHECK_EQ(Handle<Object>::Cast(handle), object);
+ ++counter_;
}
int counter_;
- v8::Persistent<v8::Object> object_;
+ v8::Persistent<v8::Object>* object_;
};
@@ -17716,13 +17827,12 @@ TEST(PersistentHandleVisitor) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object> object =
- v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object(isolate, v8::Object::New());
CHECK_EQ(0, object.WrapperClassId(isolate));
object.SetWrapperClassId(isolate, 42);
CHECK_EQ(42, object.WrapperClassId(isolate));
- Visitor42 visitor(object);
+ Visitor42 visitor(&object);
v8::V8::VisitHandlesWithClassIds(&visitor);
CHECK_EQ(1, visitor.counter_);
@@ -17734,8 +17844,7 @@ TEST(WrapperClassId) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object> object =
- v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object(isolate, v8::Object::New());
CHECK_EQ(0, object.WrapperClassId(isolate));
object.SetWrapperClassId(isolate, 65535);
CHECK_EQ(65535, object.WrapperClassId(isolate));
@@ -17747,21 +17856,19 @@ TEST(PersistentHandleInNewSpaceVisitor) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object> object1 =
- v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object1(isolate, v8::Object::New());
CHECK_EQ(0, object1.WrapperClassId(isolate));
object1.SetWrapperClassId(isolate, 42);
CHECK_EQ(42, object1.WrapperClassId(isolate));
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
- v8::Persistent<v8::Object> object2 =
- v8::Persistent<v8::Object>::New(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object2(isolate, v8::Object::New());
CHECK_EQ(0, object2.WrapperClassId(isolate));
object2.SetWrapperClassId(isolate, 42);
CHECK_EQ(42, object2.WrapperClassId(isolate));
- Visitor42 visitor(object2);
+ Visitor42 visitor(&object2);
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
CHECK_EQ(1, visitor.counter_);
@@ -18709,18 +18816,19 @@ static void CountingErrorCallback(const char* location, const char* message) {
TEST(StaticGetters) {
LocalContext context;
+ i::Factory* factory = i::Isolate::Current()->factory();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
- i::Handle<i::Object> undefined_value = FACTORY->undefined_value();
+ i::Handle<i::Object> undefined_value = factory->undefined_value();
CHECK(*v8::Utils::OpenHandle(*v8::Undefined()) == *undefined_value);
CHECK(*v8::Utils::OpenHandle(*v8::Undefined(isolate)) == *undefined_value);
- i::Handle<i::Object> null_value = FACTORY->null_value();
+ i::Handle<i::Object> null_value = factory->null_value();
CHECK(*v8::Utils::OpenHandle(*v8::Null()) == *null_value);
CHECK(*v8::Utils::OpenHandle(*v8::Null(isolate)) == *null_value);
- i::Handle<i::Object> true_value = FACTORY->true_value();
+ i::Handle<i::Object> true_value = factory->true_value();
CHECK(*v8::Utils::OpenHandle(*v8::True()) == *true_value);
CHECK(*v8::Utils::OpenHandle(*v8::True(isolate)) == *true_value);
- i::Handle<i::Object> false_value = FACTORY->false_value();
+ i::Handle<i::Object> false_value = factory->false_value();
CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value);
CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value);
@@ -18771,9 +18879,10 @@ TEST(IsolateEmbedderData) {
TEST(StringEmpty) {
LocalContext context;
+ i::Factory* factory = i::Isolate::Current()->factory();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
- i::Handle<i::Object> empty_string = FACTORY->empty_string();
+ i::Handle<i::Object> empty_string = factory->empty_string();
CHECK(*v8::Utils::OpenHandle(*v8::String::Empty()) == *empty_string);
CHECK(*v8::Utils::OpenHandle(*v8::String::Empty(isolate)) == *empty_string);