#include <climits>
#include <csignal>
-#include <string>
#include <map>
+#include <string>
-#include "v8.h"
+#include "src/v8.h"
#if V8_OS_POSIX
#include <unistd.h> // NOLINT
#endif
-#include "api.h"
-#include "arguments.h"
-#include "cctest.h"
-#include "compilation-cache.h"
-#include "cpu-profiler.h"
-#include "execution.h"
-#include "isolate.h"
-#include "objects.h"
-#include "parser.h"
-#include "platform.h"
-#include "snapshot.h"
-#include "unicode-inl.h"
-#include "utils.h"
-#include "vm-state.h"
+#include "include/v8-util.h"
+#include "src/api.h"
+#include "src/arguments.h"
+#include "src/base/platform/platform.h"
+#include "src/compilation-cache.h"
+#include "src/cpu-profiler.h"
+#include "src/execution.h"
+#include "src/isolate.h"
+#include "src/objects.h"
+#include "src/parser.h"
+#include "src/snapshot.h"
+#include "src/unicode-inl.h"
+#include "src/utils.h"
+#include "src/vm-state.h"
+#include "test/cctest/cctest.h"
static const bool kLogThreading = false;
using ::v8::Handle;
using ::v8::HandleScope;
using ::v8::Local;
+using ::v8::Name;
using ::v8::Message;
using ::v8::MessageCallback;
using ::v8::Object;
using ::v8::Script;
using ::v8::StackTrace;
using ::v8::String;
+using ::v8::Symbol;
using ::v8::TryCatch;
using ::v8::Undefined;
using ::v8::UniqueId;
void RunWithProfiler(void (*test)()) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Local<v8::String> profile_name = v8::String::New("my_profile1");
+ v8::Local<v8::String> profile_name =
+ v8::String::NewFromUtf8(env->GetIsolate(), "my_profile1");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
- cpu_profiler->StartCpuProfiling(profile_name);
+ cpu_profiler->StartProfiling(profile_name);
(*test)();
- cpu_profiler->DeleteAllCpuProfiles();
-}
-
-
-static void ExpectString(const char* code, const char* expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsString());
- String::Utf8Value utf8(result);
- CHECK_EQ(expected, *utf8);
-}
-
-
-static void ExpectInt32(const char* code, int expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsInt32());
- CHECK_EQ(expected, result->Int32Value());
-}
-
-
-static void ExpectBoolean(const char* code, bool expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsBoolean());
- CHECK_EQ(expected, result->BooleanValue());
-}
-
-
-static void ExpectTrue(const char* code) {
- ExpectBoolean(code, true);
-}
-
-
-static void ExpectFalse(const char* code) {
- ExpectBoolean(code, false);
-}
-
-
-static void ExpectObject(const char* code, Local<Value> expected) {
- Local<Value> result = CompileRun(code);
- CHECK(result->Equals(expected));
-}
-
-
-static void ExpectUndefined(const char* code) {
- Local<Value> result = CompileRun(code);
- CHECK(result->IsUndefined());
+ reinterpret_cast<i::CpuProfiler*>(cpu_profiler)->DeleteAllProfiles();
}
signature_callback_count++;
CHECK_EQ(signature_expected_receiver, args.Holder());
CHECK_EQ(signature_expected_receiver, args.This());
- v8::Handle<v8::Array> result = v8::Array::New(args.Length());
+ v8::Handle<v8::Array> result =
+ v8::Array::New(args.GetIsolate(), args.Length());
for (int i = 0; i < args.Length(); i++)
- result->Set(v8::Integer::New(i), args[i]);
+ result->Set(v8::Integer::New(args.GetIsolate(), i), args[i]);
args.GetReturnValue().Set(result);
}
static void SignatureCallback(
const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
- v8::Handle<v8::Array> result = v8::Array::New(args.Length());
+ v8::Handle<v8::Array> result =
+ v8::Array::New(args.GetIsolate(), args.Length());
for (int i = 0; i < args.Length(); i++) {
- result->Set(v8::Integer::New(i), args[i]);
+ result->Set(v8::Integer::New(args.GetIsolate(), i), args[i]);
}
args.GetReturnValue().Set(result);
}
// Tests that call v8::V8::Dispose() cannot be threaded.
-TEST(InitializeAndDisposeOnce) {
+UNINITIALIZED_TEST(InitializeAndDisposeOnce) {
CHECK(v8::V8::Initialize());
CHECK(v8::V8::Dispose());
}
// Tests that call v8::V8::Dispose() cannot be threaded.
-TEST(InitializeAndDisposeMultiple) {
+UNINITIALIZED_TEST(InitializeAndDisposeMultiple) {
for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
- // TODO(mstarzinger): This should fail gracefully instead of asserting.
- // for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
+ for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
}
CHECK(!undef.IsEmpty());
CHECK(undef->IsUndefined());
- const char* c_source = "1 + 2 + 3";
- Local<String> source = String::New(c_source);
- Local<Script> script = Script::Compile(source);
+ const char* source = "1 + 2 + 3";
+ Local<Script> script = v8_compile(source);
CHECK_EQ(6, script->Run()->Int32Value());
local_env->Exit();
v8::HandleScope scope(CcTest::isolate());
v8::Handle<Context> env = Context::New(CcTest::isolate());
- CHECK(!env->InContext());
+ CHECK(!env->GetIsolate()->InContext());
CHECK(env->GetIsolate() == CcTest::isolate());
env->Enter();
- CHECK(env->InContext());
+ CHECK(env->GetIsolate()->InContext());
CHECK(env->GetIsolate() == CcTest::isolate());
env->Exit();
- CHECK(!env->InContext());
+ CHECK(!env->GetIsolate()->InContext());
CHECK(env->GetIsolate() == CcTest::isolate());
}
static void TestSignature(const char* loop_js, Local<Value> receiver) {
i::ScopedVector<char> source(200);
- i::OS::SNPrintF(source,
- "for (var i = 0; i < 10; i++) {"
- " %s"
- "}",
- loop_js);
+ i::SNPrintF(source,
+ "for (var i = 0; i < 10; i++) {"
+ " %s"
+ "}",
+ loop_js);
signature_callback_count = 0;
signature_expected_receiver = receiver;
bool expected_to_throw = receiver.IsEmpty();
THREADED_TEST(ReceiverSignature) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
// Setup templates.
- v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New();
- v8::Handle<v8::Signature> sig = v8::Signature::New(fun);
+ v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::Signature> sig = v8::Signature::New(isolate, fun);
v8::Handle<v8::FunctionTemplate> callback_sig =
v8::FunctionTemplate::New(
- IncrementingSignatureCallback, Local<Value>(), sig);
+ isolate, IncrementingSignatureCallback, Local<Value>(), sig);
v8::Handle<v8::FunctionTemplate> callback =
- v8::FunctionTemplate::New(IncrementingSignatureCallback);
- v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New();
+ v8::FunctionTemplate::New(isolate, IncrementingSignatureCallback);
+ v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New(isolate);
sub_fun->Inherit(fun);
- v8::Handle<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> unrel_fun =
+ v8::FunctionTemplate::New(isolate);
// Install properties.
v8::Handle<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate();
fun_proto->Set(v8_str("prop_sig"), callback_sig);
const char* test_objects[] = {
"fun_instance", "sub_fun_instance", "obj", "unrel" };
unsigned bad_signature_start_offset = 2;
- for (unsigned i = 0; i < ARRAY_SIZE(test_objects); i++) {
+ for (unsigned i = 0; i < arraysize(test_objects); i++) {
i::ScopedVector<char> source(200);
- i::OS::SNPrintF(
+ i::SNPrintF(
source, "var test_object = %s; test_object", test_objects[i]);
Local<Value> test_object = CompileRun(source.start());
TestSignature("test_object.prop();", test_object);
THREADED_TEST(ArgumentSignature) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::Handle<v8::FunctionTemplate> cons = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> cons = v8::FunctionTemplate::New(isolate);
cons->SetClassName(v8_str("Cons"));
- v8::Handle<v8::Signature> sig =
- v8::Signature::New(v8::Handle<v8::FunctionTemplate>(), 1, &cons);
+ v8::Handle<v8::Signature> sig = v8::Signature::New(
+ isolate, v8::Handle<v8::FunctionTemplate>(), 1, &cons);
v8::Handle<v8::FunctionTemplate> fun =
- v8::FunctionTemplate::New(SignatureCallback, v8::Handle<Value>(), sig);
+ v8::FunctionTemplate::New(isolate,
+ SignatureCallback,
+ v8::Handle<Value>(),
+ sig);
env->Global()->Set(v8_str("Cons"), cons->GetFunction());
env->Global()->Set(v8_str("Fun1"), fun->GetFunction());
v8::Handle<Value> value3 = CompileRun("Fun1() == '';");
CHECK(value3->IsTrue());
- v8::Handle<v8::FunctionTemplate> cons1 = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> cons1 = v8::FunctionTemplate::New(isolate);
cons1->SetClassName(v8_str("Cons1"));
- v8::Handle<v8::FunctionTemplate> cons2 = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> cons2 = v8::FunctionTemplate::New(isolate);
cons2->SetClassName(v8_str("Cons2"));
- v8::Handle<v8::FunctionTemplate> cons3 = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> cons3 = v8::FunctionTemplate::New(isolate);
cons3->SetClassName(v8_str("Cons3"));
v8::Handle<v8::FunctionTemplate> args[3] = { cons1, cons2, cons3 };
- v8::Handle<v8::Signature> wsig =
- v8::Signature::New(v8::Handle<v8::FunctionTemplate>(), 3, args);
+ v8::Handle<v8::Signature> wsig = v8::Signature::New(
+ isolate, v8::Handle<v8::FunctionTemplate>(), 3, args);
v8::Handle<v8::FunctionTemplate> fun2 =
- v8::FunctionTemplate::New(SignatureCallback, v8::Handle<Value>(), wsig);
+ v8::FunctionTemplate::New(isolate,
+ SignatureCallback,
+ v8::Handle<Value>(),
+ wsig);
env->Global()->Set(v8_str("Cons1"), cons1->GetFunction());
env->Global()->Set(v8_str("Cons2"), cons2->GetFunction());
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- Local<v8::Object> obj = v8::Object::New();
+ Local<v8::Object> obj = v8::Object::New(isolate);
Local<Value> foo_before = obj->Get(v8_str("foo"));
CHECK(foo_before->IsUndefined());
Local<String> bar_str = v8_str("bar");
THREADED_TEST(AccessElement) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<v8::Object> obj = v8::Object::New();
+ Local<v8::Object> obj = v8::Object::New(env->GetIsolate());
Local<Value> before = obj->Get(1);
CHECK(before->IsUndefined());
Local<String> bar_str = v8_str("bar");
THREADED_TEST(Script) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- const char* c_source = "1 + 2 + 3";
- Local<String> source = String::New(c_source);
- Local<Script> script = Script::Compile(source);
+ const char* source = "1 + 2 + 3";
+ Local<Script> script = v8_compile(source);
CHECK_EQ(6, script->Run()->Int32Value());
}
-static uint16_t* AsciiToTwoByteString(const char* source) {
- int array_length = i::StrLength(source) + 1;
- uint16_t* converted = i::NewArray<uint16_t>(array_length);
- for (int i = 0; i < array_length; i++) converted[i] = source[i];
- return converted;
-}
-
-
class TestResource: public String::ExternalStringResource {
public:
- explicit TestResource(uint16_t* data, int* counter = NULL)
- : data_(data), length_(0), counter_(counter) {
+ explicit TestResource(uint16_t* data, int* counter = NULL,
+ bool owning_data = true)
+ : data_(data), length_(0), counter_(counter), owning_data_(owning_data) {
while (data[length_]) ++length_;
}
~TestResource() {
- i::DeleteArray(data_);
+ if (owning_data_) i::DeleteArray(data_);
if (counter_ != NULL) ++*counter_;
}
size_t length() const {
return length_;
}
+
private:
uint16_t* data_;
size_t length_;
int* counter_;
+ bool owning_data_;
};
-class TestAsciiResource: public String::ExternalAsciiStringResource {
+class TestOneByteResource : public String::ExternalOneByteStringResource {
public:
- explicit TestAsciiResource(const char* data, int* counter = NULL)
- : data_(data), length_(strlen(data)), counter_(counter) { }
-
- ~TestAsciiResource() {
- i::DeleteArray(data_);
+ explicit TestOneByteResource(const char* data, int* counter = NULL,
+ size_t offset = 0)
+ : orig_data_(data),
+ data_(data + offset),
+ length_(strlen(data) - offset),
+ counter_(counter) {}
+
+ ~TestOneByteResource() {
+ i::DeleteArray(orig_data_);
if (counter_ != NULL) ++*counter_;
}
size_t length() const {
return length_;
}
+
private:
+ const char* orig_data_;
const char* data_;
size_t length_;
int* counter_;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
TestResource* resource = new TestResource(two_byte_source, &dispose_count);
- Local<String> source = String::NewExternal(resource);
- Local<Script> script = Script::Compile(source);
+ Local<String> source = String::NewExternal(env->GetIsolate(), resource);
+ Local<Script> script = v8_compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
}
-THREADED_TEST(ScriptUsingAsciiStringResource) {
+THREADED_TEST(ScriptUsingOneByteStringResource) {
int dispose_count = 0;
const char* c_source = "1 + 2 * 3";
{
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- TestAsciiResource* resource = new TestAsciiResource(i::StrDup(c_source),
- &dispose_count);
- Local<String> source = String::NewExternal(resource);
- CHECK(source->IsExternalAscii());
+ TestOneByteResource* resource =
+ new TestOneByteResource(i::StrDup(c_source), &dispose_count);
+ Local<String> source = String::NewExternal(env->GetIsolate(), resource);
+ CHECK(source->IsExternalOneByte());
CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
- source->GetExternalAsciiStringResource());
+ source->GetExternalOneByteStringResource());
String::Encoding encoding = String::UNKNOWN_ENCODING;
CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
source->GetExternalStringResourceBase(&encoding));
- CHECK_EQ(String::ASCII_ENCODING, encoding);
- Local<Script> script = Script::Compile(source);
+ CHECK_EQ(String::ONE_BYTE_ENCODING, encoding);
+ Local<Script> script = v8_compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
{
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<String> source = String::New(two_byte_source);
+ Local<String> source =
+ String::NewFromTwoByte(env->GetIsolate(), two_byte_source);
// Trigger GCs so that the newly allocated string moves to old gen.
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
CHECK_EQ(source->IsExternal(), false);
- CHECK_EQ(source->IsExternalAscii(), false);
+ CHECK_EQ(source->IsExternalOneByte(), false);
String::Encoding encoding = String::UNKNOWN_ENCODING;
CHECK_EQ(NULL, source->GetExternalStringResourceBase(&encoding));
- CHECK_EQ(String::ASCII_ENCODING, encoding);
+ CHECK_EQ(String::ONE_BYTE_ENCODING, encoding);
bool success = source->MakeExternal(new TestResource(two_byte_source,
&dispose_count));
CHECK(success);
- Local<Script> script = Script::Compile(source);
+ Local<Script> script = v8_compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
}
-THREADED_TEST(ScriptMakingExternalAsciiString) {
+THREADED_TEST(ScriptMakingExternalOneByteString) {
int dispose_count = 0;
const char* c_source = "1 + 2 * 3";
{
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
bool success = source->MakeExternal(
- new TestAsciiResource(i::StrDup(c_source), &dispose_count));
+ new TestOneByteResource(i::StrDup(c_source), &dispose_count));
CHECK(success);
- Local<Script> script = Script::Compile(source);
+ Local<Script> script = v8_compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
uint16_t* two_byte_string = AsciiToTwoByteString("s1");
- Local<String> small_string = String::New(two_byte_string);
+ Local<String> small_string =
+ String::NewFromTwoByte(env->GetIsolate(), two_byte_string);
i::DeleteArray(two_byte_string);
// We should refuse to externalize newly created small string.
CHECK(small_string->CanMakeExternal());
two_byte_string = AsciiToTwoByteString("small string 2");
- small_string = String::New(two_byte_string);
+ small_string = String::NewFromTwoByte(env->GetIsolate(), two_byte_string);
i::DeleteArray(two_byte_string);
// We should refuse externalizing newly created small string.
buf[buf_size - 1] = '\0';
two_byte_string = AsciiToTwoByteString(buf);
- Local<String> large_string = String::New(two_byte_string);
+ Local<String> large_string =
+ String::NewFromTwoByte(env->GetIsolate(), two_byte_string);
i::DeleteArray(buf);
i::DeleteArray(two_byte_string);
// Large strings should be immediately accepted.
}
-TEST(MakingExternalAsciiStringConditions) {
+TEST(MakingExternalOneByteStringConditions) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
- Local<String> small_string = String::New("s1");
+ Local<String> small_string = String::NewFromUtf8(env->GetIsolate(), "s1");
// We should refuse to externalize newly created small string.
CHECK(!small_string->CanMakeExternal());
// Trigger GCs so that the newly allocated string moves to old gen.
// Old space strings should be accepted.
CHECK(small_string->CanMakeExternal());
- small_string = String::New("small string 2");
+ small_string = String::NewFromUtf8(env->GetIsolate(), "small string 2");
// We should refuse externalizing newly created small string.
CHECK(!small_string->CanMakeExternal());
for (int i = 0; i < 100; i++) {
char* buf = i::NewArray<char>(buf_size);
memset(buf, 'a', buf_size);
buf[buf_size - 1] = '\0';
- Local<String> large_string = String::New(buf);
+ Local<String> large_string = String::NewFromUtf8(env->GetIsolate(), buf);
i::DeleteArray(buf);
// Large strings should be immediately accepted.
CHECK(large_string->CanMakeExternal());
}
-TEST(MakingExternalUnalignedAsciiString) {
+TEST(MakingExternalUnalignedOneByteString) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
// Turn into external string with unaligned resource data.
- int dispose_count = 0;
const char* c_cons = "_abcdefghijklmnopqrstuvwxyz";
- bool success = cons->MakeExternal(
- new TestAsciiResource(i::StrDup(c_cons) + 1, &dispose_count));
+ bool success =
+ cons->MakeExternal(new TestOneByteResource(i::StrDup(c_cons), NULL, 1));
CHECK(success);
const char* c_slice = "_bcdefghijklmnopqrstuvwxyz";
- success = slice->MakeExternal(
- new TestAsciiResource(i::StrDup(c_slice) + 1, &dispose_count));
+ success =
+ slice->MakeExternal(new TestOneByteResource(i::StrDup(c_slice), NULL, 1));
CHECK(success);
// Trigger GCs and force evacuation.
{
v8::HandleScope scope(CcTest::isolate());
uint16_t* two_byte_string = AsciiToTwoByteString("test string");
- Local<String> string =
- String::NewExternal(new TestResource(two_byte_string));
+ Local<String> string = String::NewExternal(
+ CcTest::isolate(), new TestResource(two_byte_string));
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
// Trigger GCs so that the newly allocated string moves to old gen.
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
- factory->InternalizedStringFromString(istring);
+ factory->InternalizeString(istring);
CHECK(isymbol->IsInternalizedString());
}
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
}
-THREADED_TEST(UsingExternalAsciiString) {
+THREADED_TEST(UsingExternalOneByteString) {
i::Factory* factory = CcTest::i_isolate()->factory();
{
v8::HandleScope scope(CcTest::isolate());
const char* one_byte_string = "test string";
Local<String> string = String::NewExternal(
- new TestAsciiResource(i::StrDup(one_byte_string)));
+ CcTest::isolate(), new TestOneByteResource(i::StrDup(one_byte_string)));
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
// Trigger GCs so that the newly allocated string moves to old gen.
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
- factory->InternalizedStringFromString(istring);
+ factory->InternalizeString(istring);
CHECK(isymbol->IsInternalizedString());
}
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
}
+class DummyResource : public v8::String::ExternalStringResource {
+ public:
+ virtual const uint16_t* data() const { return string_; }
+ virtual size_t length() const { return 1 << 30; }
+
+ private:
+ uint16_t string_[10];
+};
+
+
+class DummyOneByteResource : public v8::String::ExternalOneByteStringResource {
+ public:
+ virtual const char* data() const { return string_; }
+ virtual size_t length() const { return 1 << 30; }
+
+ private:
+ char string_[10];
+};
+
+
+THREADED_TEST(NewExternalForVeryLongString) {
+ {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::TryCatch try_catch;
+ DummyOneByteResource r;
+ v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), &r);
+ CHECK(str.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ String::Utf8Value exception_value(try_catch.Exception());
+ CHECK_EQ("RangeError: Invalid string length", *exception_value);
+ }
+
+ {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::TryCatch try_catch;
+ DummyResource r;
+ v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), &r);
+ CHECK(str.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ String::Utf8Value exception_value(try_catch.Exception());
+ CHECK_EQ("RangeError: Invalid string length", *exception_value);
+ }
+}
+
+
THREADED_TEST(ScavengeExternalString) {
i::FLAG_stress_compaction = false;
i::FLAG_gc_global = false;
{
v8::HandleScope scope(CcTest::isolate());
uint16_t* two_byte_string = AsciiToTwoByteString("test string");
- Local<String> string =
- String::NewExternal(new TestResource(two_byte_string,
- &dispose_count));
+ Local<String> string = String::NewExternal(
+ CcTest::isolate(), new TestResource(two_byte_string, &dispose_count));
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
in_new_space = CcTest::heap()->InNewSpace(*istring);
}
-THREADED_TEST(ScavengeExternalAsciiString) {
+THREADED_TEST(ScavengeExternalOneByteString) {
i::FLAG_stress_compaction = false;
i::FLAG_gc_global = false;
int dispose_count = 0;
v8::HandleScope scope(CcTest::isolate());
const char* one_byte_string = "test string";
Local<String> string = String::NewExternal(
- new TestAsciiResource(i::StrDup(one_byte_string), &dispose_count));
+ CcTest::isolate(),
+ new TestOneByteResource(i::StrDup(one_byte_string), &dispose_count));
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
in_new_space = CcTest::heap()->InNewSpace(*istring);
}
-class TestAsciiResourceWithDisposeControl: public TestAsciiResource {
+class TestOneByteResourceWithDisposeControl : public TestOneByteResource {
public:
// Only used by non-threaded tests, so it can use static fields.
static int dispose_calls;
static int dispose_count;
- TestAsciiResourceWithDisposeControl(const char* data, bool dispose)
- : TestAsciiResource(data, &dispose_count),
- dispose_(dispose) { }
+ TestOneByteResourceWithDisposeControl(const char* data, bool dispose)
+ : TestOneByteResource(data, &dispose_count), dispose_(dispose) {}
void Dispose() {
++dispose_calls;
};
-int TestAsciiResourceWithDisposeControl::dispose_count = 0;
-int TestAsciiResourceWithDisposeControl::dispose_calls = 0;
+int TestOneByteResourceWithDisposeControl::dispose_count = 0;
+int TestOneByteResourceWithDisposeControl::dispose_calls = 0;
TEST(ExternalStringWithDisposeHandling) {
const char* c_source = "1 + 2 * 3";
// Use a stack allocated external string resource allocated object.
- TestAsciiResourceWithDisposeControl::dispose_count = 0;
- TestAsciiResourceWithDisposeControl::dispose_calls = 0;
- TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false);
+ TestOneByteResourceWithDisposeControl::dispose_count = 0;
+ TestOneByteResourceWithDisposeControl::dispose_calls = 0;
+ TestOneByteResourceWithDisposeControl res_stack(i::StrDup(c_source), false);
{
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<String> source = String::NewExternal(&res_stack);
- Local<Script> script = Script::Compile(source);
+ Local<String> source = String::NewExternal(env->GetIsolate(), &res_stack);
+ Local<Script> script = v8_compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
CcTest::heap()->CollectAllAvailableGarbage();
- CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
+ CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
CcTest::heap()->CollectAllAvailableGarbage();
- CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
- CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
+ CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_calls);
+ CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count);
// Use a heap allocated external string resource allocated object.
- TestAsciiResourceWithDisposeControl::dispose_count = 0;
- TestAsciiResourceWithDisposeControl::dispose_calls = 0;
- TestAsciiResource* res_heap =
- new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true);
+ TestOneByteResourceWithDisposeControl::dispose_count = 0;
+ TestOneByteResourceWithDisposeControl::dispose_calls = 0;
+ TestOneByteResource* res_heap =
+ new TestOneByteResourceWithDisposeControl(i::StrDup(c_source), true);
{
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<String> source = String::NewExternal(res_heap);
- Local<Script> script = Script::Compile(source);
+ Local<String> source = String::NewExternal(env->GetIsolate(), res_heap);
+ Local<Script> script = v8_compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
CcTest::heap()->CollectAllAvailableGarbage();
- CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
+ CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
CcTest::heap()->CollectAllAvailableGarbage();
- CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
- CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count);
+ CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_calls);
+ CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_count);
}
Local<String> left = v8_str(one_byte_string_1);
uint16_t* two_byte_source = AsciiToTwoByteString(two_byte_string_1);
- Local<String> right = String::New(two_byte_source);
+ Local<String> right =
+ String::NewFromTwoByte(env->GetIsolate(), two_byte_source);
i::DeleteArray(two_byte_source);
Local<String> source = String::Concat(left, right);
right = String::NewExternal(
- new TestAsciiResource(i::StrDup(one_byte_extern_1)));
+ env->GetIsolate(),
+ new TestOneByteResource(i::StrDup(one_byte_extern_1)));
source = String::Concat(source, right);
right = String::NewExternal(
+ env->GetIsolate(),
new TestResource(AsciiToTwoByteString(two_byte_extern_1)));
source = String::Concat(source, right);
right = v8_str(one_byte_string_2);
source = String::Concat(source, right);
two_byte_source = AsciiToTwoByteString(two_byte_string_2);
- right = String::New(two_byte_source);
+ right = String::NewFromTwoByte(env->GetIsolate(), two_byte_source);
i::DeleteArray(two_byte_source);
source = String::Concat(source, right);
right = String::NewExternal(
+ env->GetIsolate(),
new TestResource(AsciiToTwoByteString(two_byte_extern_2)));
source = String::Concat(source, right);
- Local<Script> script = Script::Compile(source);
+ Local<Script> script = v8_compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(68, value->Int32Value());
// If CPU profiler is active check that when API callback is invoked
// VMState is set to EXTERNAL.
if (isolate->cpu_profiler()->is_profiling()) {
- CHECK_EQ(i::EXTERNAL, isolate->current_vm_state());
+ CHECK_EQ(v8::EXTERNAL, isolate->current_vm_state());
CHECK(isolate->external_callback_scope());
CHECK_EQ(callback, isolate->external_callback_scope()->callback());
}
// Test constructor calls.
{
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(handler);
+ v8::FunctionTemplate::New(isolate, handler);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("obj()");
// the previous one.
{
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
fun_templ->SetCallHandler(handler_2);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
v8::HandleScope scope(env->GetIsolate());
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(constructor);
+ v8::FunctionTemplate::New(env->GetIsolate(), constructor);
fun_templ->SetClassName(v8_str("funky"));
fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), accessor);
Local<Function> fun = fun_templ->GetFunction();
template<typename Callback>
static void TestSimpleCallback(Callback callback) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
- object_template->Set("callback", v8::FunctionTemplate::New(callback));
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
+ object_template->Set(isolate, "callback",
+ v8::FunctionTemplate::New(isolate, callback));
v8::Local<v8::Object> object = object_template->NewInstance();
(*env)->Global()->Set(v8_str("callback_object"), object);
v8::Handle<v8::Script> script;
void FastReturnValueCallback<Object>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Handle<v8::Object> object;
- if (!fast_return_value_object_is_empty) object = Object::New();
+ if (!fast_return_value_object_is_empty) {
+ object = Object::New(info.GetIsolate());
+ }
info.GetReturnValue().Set(object);
}
template<typename T>
Handle<Value> TestFastReturnValues() {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::EscapableHandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
v8::FunctionCallback callback = &FastReturnValueCallback<T>;
- object_template->Set("callback", v8::FunctionTemplate::New(callback));
+ object_template->Set(isolate, "callback",
+ v8::FunctionTemplate::New(isolate, callback));
v8::Local<v8::Object> object = object_template->NewInstance();
(*env)->Global()->Set(v8_str("callback_object"), object);
- return scope.Close(CompileRun("callback_object.callback()"));
+ return scope.Escape(CompileRun("callback_object.callback()"));
}
0, 234, -723,
i::Smi::kMinValue, i::Smi::kMaxValue
};
- for (size_t i = 0; i < ARRAY_SIZE(int_values); i++) {
+ for (size_t i = 0; i < arraysize(int_values); i++) {
for (int modifier = -1; modifier <= 1; modifier++) {
int int_value = int_values[i] + modifier;
// check int32_t
kUndefinedReturnValue,
kEmptyStringReturnValue
};
- for (size_t i = 0; i < ARRAY_SIZE(oddballs); i++) {
+ for (size_t i = 0; i < arraysize(oddballs); i++) {
fast_return_value_void = oddballs[i];
value = TestFastReturnValues<void>();
switch (fast_return_value_void) {
THREADED_TEST(FunctionTemplateSetLength) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
{
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(
- handle_callback, Handle<v8::Value>(), Handle<v8::Signature>(), 23);
+ Local<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate,
+ handle_callback,
+ Handle<v8::Value>(),
+ Handle<v8::Signature>(),
+ 23);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("obj.length");
}
{
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(handle_callback);
+ v8::FunctionTemplate::New(isolate, handle_callback);
fun_templ->SetLength(22);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
{
// Without setting length it defaults to 0.
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(handle_callback);
+ v8::FunctionTemplate::New(isolate, handle_callback);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
Local<Script> script = v8_compile("obj.length");
static void TestExternalPointerWrapping() {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- v8::Handle<v8::Value> data = v8::External::New(expected_ptr);
+ v8::Handle<v8::Value> data =
+ v8::External::New(isolate, expected_ptr);
- v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::Handle<v8::Object> obj = v8::Object::New(isolate);
obj->Set(v8_str("func"),
- v8::FunctionTemplate::New(callback, data)->GetFunction());
+ v8::FunctionTemplate::New(isolate, callback, data)->GetFunction());
env->Global()->Set(v8_str("obj"), obj);
CHECK(CompileRun(
THREADED_TEST(FindInstanceInPrototypeChain) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New();
- Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New();
- Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New(isolate);
+ Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New(isolate);
+ Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New(isolate);
derived->Inherit(base);
Local<v8::Function> base_function = base->GetFunction();
THREADED_TEST(TinyInteger) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::Isolate* isolate = CcTest::isolate();
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
int32_t value = 239;
- Local<v8::Integer> value_obj = v8::Integer::New(value);
+ Local<v8::Integer> value_obj = v8::Integer::New(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
- value_obj = v8::Integer::New(value, isolate);
+ value_obj = v8::Integer::New(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
- Local<v8::Integer> value_obj = v8::Integer::New(value);
+ Local<v8::Integer> value_obj = v8::Integer::New(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
- value_obj = v8::Integer::New(value, isolate);
+ value_obj = v8::Integer::New(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
CHECK(value > i::Smi::kMaxValue);
CHECK(!i::Smi::IsValid(value));
- Local<v8::Integer> value_obj = v8::Integer::New(value);
+ Local<v8::Integer> value_obj = v8::Integer::New(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
- value_obj = v8::Integer::New(value, isolate);
+ value_obj = v8::Integer::New(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
uint32_t value = 239;
- Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
+ Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
- value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
- Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
+ Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
- value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
CHECK(value > static_cast<uint32_t>(i::Smi::kMaxValue));
CHECK(!i::Smi::IsValid(value));
- Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
+ Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
- value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
uint32_t value = INT32_MAX_AS_UINT + 1;
CHECK(value > INT32_MAX_AS_UINT); // No overflow.
- Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
+ Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
- value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ value_obj = v8::Integer::NewFromUnsigned(isolate, value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
+THREADED_TEST(IsGeneratorFunctionOrObject) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ CompileRun("function *gen() { yield 1; }\nfunction func() {}");
+ v8::Handle<Value> gen = CompileRun("gen");
+ v8::Handle<Value> genObj = CompileRun("gen()");
+ v8::Handle<Value> object = CompileRun("{a:42}");
+ v8::Handle<Value> func = CompileRun("func");
+
+ CHECK(gen->IsGeneratorFunction());
+ CHECK(gen->IsFunction());
+ CHECK(!gen->IsGeneratorObject());
+
+ CHECK(!genObj->IsGeneratorFunction());
+ CHECK(!genObj->IsFunction());
+ CHECK(genObj->IsGeneratorObject());
+
+ CHECK(!object->IsGeneratorFunction());
+ CHECK(!object->IsFunction());
+ CHECK(!object->IsGeneratorObject());
+
+ CHECK(!func->IsGeneratorFunction());
+ CHECK(func->IsFunction());
+ CHECK(!func->IsGeneratorObject());
+}
+
+
+THREADED_TEST(ArgumentsObject) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::Handle<Value> arguments_object =
+ CompileRun("var out = 0; (function(){ out = arguments; })(1,2,3); out;");
+ CHECK(arguments_object->IsArgumentsObject());
+ v8::Handle<Value> array = CompileRun("[1,2,3]");
+ CHECK(!array->IsArgumentsObject());
+ v8::Handle<Value> object = CompileRun("{a:42}");
+ CHECK(!object->IsArgumentsObject());
+}
+
+
+THREADED_TEST(IsMapOrSet) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::Handle<Value> map = CompileRun("new Map()");
+ v8::Handle<Value> set = CompileRun("new Set()");
+ v8::Handle<Value> weak_map = CompileRun("new WeakMap()");
+ v8::Handle<Value> weak_set = CompileRun("new WeakSet()");
+ CHECK(map->IsMap());
+ CHECK(set->IsSet());
+ CHECK(weak_map->IsWeakMap());
+ CHECK(weak_set->IsWeakSet());
+
+ CHECK(!map->IsSet());
+ CHECK(!map->IsWeakMap());
+ CHECK(!map->IsWeakSet());
+
+ CHECK(!set->IsMap());
+ CHECK(!set->IsWeakMap());
+ CHECK(!set->IsWeakSet());
+
+ CHECK(!weak_map->IsMap());
+ CHECK(!weak_map->IsSet());
+ CHECK(!weak_map->IsWeakSet());
+
+ CHECK(!weak_set->IsMap());
+ CHECK(!weak_set->IsSet());
+ CHECK(!weak_set->IsWeakMap());
+
+ v8::Handle<Value> object = CompileRun("{a:42}");
+ CHECK(!object->IsMap());
+ CHECK(!object->IsSet());
+ CHECK(!object->IsWeakMap());
+ CHECK(!object->IsWeakSet());
+}
+
+
THREADED_TEST(StringObject) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CHECK(!as_boxed.IsEmpty());
double the_number = as_boxed->ValueOf();
CHECK_EQ(42.0, the_number);
- v8::Handle<v8::Value> new_boxed_number = v8::NumberObject::New(43);
+ v8::Handle<v8::Value> new_boxed_number =
+ v8::NumberObject::New(env->GetIsolate(), 43);
CHECK(new_boxed_number->IsNumberObject());
as_boxed = new_boxed_number.As<v8::NumberObject>();
the_number = as_boxed->ValueOf();
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<Value> primitive_false = Boolean::New(false);
+ Local<Value> primitive_false = Boolean::New(env->GetIsolate(), false);
CHECK(primitive_false->IsBoolean());
CHECK(!primitive_false->IsBooleanObject());
CHECK(!primitive_false->BooleanValue());
CHECK(!false_boolean_object->IsTrue());
CHECK(!false_boolean_object->IsFalse());
- Local<Value> primitive_true = Boolean::New(true);
+ Local<Value> primitive_true = Boolean::New(env->GetIsolate(), true);
CHECK(primitive_true->IsBoolean());
CHECK(!primitive_true->IsBooleanObject());
CHECK(primitive_true->BooleanValue());
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
double PI = 3.1415926;
- Local<v8::Number> pi_obj = v8::Number::New(PI);
+ Local<v8::Number> pi_obj = v8::Number::New(env->GetIsolate(), PI);
CHECK_EQ(PI, pi_obj->NumberValue());
}
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
double PI = 3.1415926;
- Local<Value> date = v8::Date::New(PI);
+ Local<Value> date = v8::Date::New(env->GetIsolate(), PI);
CHECK_EQ(3.0, date->NumberValue());
- date.As<v8::Date>()->Set(v8_str("property"), v8::Integer::New(42));
+ date.As<v8::Date>()->Set(v8_str("property"),
+ v8::Integer::New(env->GetIsolate(), 42));
CHECK_EQ(42, date.As<v8::Date>()->Get(v8_str("property"))->Int32Value());
}
THREADED_TEST(Boolean) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::Handle<v8::Boolean> t = v8::True(CcTest::isolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::Boolean> t = v8::True(isolate);
CHECK(t->Value());
- v8::Handle<v8::Boolean> f = v8::False(CcTest::isolate());
+ v8::Handle<v8::Boolean> f = v8::False(isolate);
CHECK(!f->Value());
- v8::Handle<v8::Primitive> u = v8::Undefined(CcTest::isolate());
+ v8::Handle<v8::Primitive> u = v8::Undefined(isolate);
CHECK(!u->BooleanValue());
- v8::Handle<v8::Primitive> n = v8::Null(CcTest::isolate());
+ v8::Handle<v8::Primitive> n = v8::Null(isolate);
CHECK(!n->BooleanValue());
v8::Handle<String> str1 = v8_str("");
CHECK(!str1->BooleanValue());
v8::Handle<String> str2 = v8_str("x");
CHECK(str2->BooleanValue());
- CHECK(!v8::Number::New(0)->BooleanValue());
- CHECK(v8::Number::New(-1)->BooleanValue());
- CHECK(v8::Number::New(1)->BooleanValue());
- CHECK(v8::Number::New(42)->BooleanValue());
+ CHECK(!v8::Number::New(isolate, 0)->BooleanValue());
+ CHECK(v8::Number::New(isolate, -1)->BooleanValue());
+ CHECK(v8::Number::New(isolate, 1)->BooleanValue());
+ CHECK(v8::Number::New(isolate, 42)->BooleanValue());
CHECK(!v8_compile("NaN")->Run()->BooleanValue());
}
THREADED_TEST(GlobalPrototype) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> func_templ =
+ v8::FunctionTemplate::New(isolate);
func_templ->PrototypeTemplate()->Set(
- "dummy",
- v8::FunctionTemplate::New(DummyCallHandler));
+ isolate, "dummy", v8::FunctionTemplate::New(isolate, DummyCallHandler));
v8::Handle<ObjectTemplate> templ = func_templ->InstanceTemplate();
- templ->Set("x", v8_num(200));
+ templ->Set(isolate, "x", v8_num(200));
templ->SetAccessor(v8_str("m"), GetM);
LocalContext env(0, templ);
v8::Handle<Script> script(v8_compile("dummy()"));
THREADED_TEST(ObjectTemplate) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ1 = ObjectTemplate::New();
- templ1->Set("x", v8_num(10));
- templ1->Set("y", v8_num(13));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ1 = ObjectTemplate::New(isolate);
+ templ1->Set(isolate, "x", v8_num(10));
+ templ1->Set(isolate, "y", v8_num(13));
LocalContext env;
Local<v8::Object> instance1 = templ1->NewInstance();
env->Global()->Set(v8_str("p"), instance1);
CHECK(v8_compile("(p.x == 10)")->Run()->BooleanValue());
CHECK(v8_compile("(p.y == 13)")->Run()->BooleanValue());
- Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New();
- fun->PrototypeTemplate()->Set("nirk", v8_num(123));
+ Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
+ fun->PrototypeTemplate()->Set(isolate, "nirk", v8_num(123));
Local<ObjectTemplate> templ2 = fun->InstanceTemplate();
- templ2->Set("a", v8_num(12));
- templ2->Set("b", templ1);
+ templ2->Set(isolate, "a", v8_num(12));
+ templ2->Set(isolate, "b", templ1);
Local<v8::Object> instance2 = templ2->NewInstance();
env->Global()->Set(v8_str("q"), instance2);
CHECK(v8_compile("(q.nirk == 123)")->Run()->BooleanValue());
THREADED_TEST(DescriptorInheritance) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> super = v8::FunctionTemplate::New();
- super->PrototypeTemplate()->Set("flabby",
- v8::FunctionTemplate::New(GetFlabby));
- super->PrototypeTemplate()->Set("PI", v8_num(3.14));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> super = v8::FunctionTemplate::New(isolate);
+ super->PrototypeTemplate()->Set(isolate, "flabby",
+ v8::FunctionTemplate::New(isolate,
+ GetFlabby));
+ super->PrototypeTemplate()->Set(isolate, "PI", v8_num(3.14));
super->InstanceTemplate()->SetAccessor(v8_str("knurd"), GetKnurd);
- v8::Handle<v8::FunctionTemplate> base1 = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> base1 = v8::FunctionTemplate::New(isolate);
base1->Inherit(super);
- base1->PrototypeTemplate()->Set("v1", v8_num(20.1));
+ base1->PrototypeTemplate()->Set(isolate, "v1", v8_num(20.1));
- v8::Handle<v8::FunctionTemplate> base2 = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> base2 = v8::FunctionTemplate::New(isolate);
base2->Inherit(super);
- base2->PrototypeTemplate()->Set("v2", v8_num(10.1));
+ base2->PrototypeTemplate()->Set(isolate, "v2", v8_num(10.1));
LocalContext env;
void SimpleAccessorGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- Handle<Object> self = info.This();
+ Handle<Object> self = Handle<Object>::Cast(info.This());
info.GetReturnValue().Set(
self->Get(String::Concat(v8_str("accessor_"), name)));
}
void SimpleAccessorSetter(Local<String> name, Local<Value> value,
const v8::PropertyCallbackInfo<void>& info) {
- Handle<Object> self = info.This();
+ Handle<Object> self = Handle<Object>::Cast(info.This());
self->Set(String::Concat(v8_str("accessor_"), name), value);
}
+void SymbolAccessorGetter(Local<Name> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CHECK(name->IsSymbol());
+ Local<Symbol> sym = Local<Symbol>::Cast(name);
+ if (sym->Name()->IsUndefined())
+ return;
+ SimpleAccessorGetter(Local<String>::Cast(sym->Name()), info);
+}
+
+void SymbolAccessorSetter(Local<Name> name, Local<Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ CHECK(name->IsSymbol());
+ Local<Symbol> sym = Local<Symbol>::Cast(name);
+ if (sym->Name()->IsUndefined())
+ return;
+ SimpleAccessorSetter(Local<String>::Cast(sym->Name()), value, info);
+}
+
+void SymbolAccessorGetterReturnsDefault(
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CHECK(name->IsSymbol());
+ Local<Symbol> sym = Local<Symbol>::Cast(name);
+ if (sym->Name()->IsUndefined()) return;
+ info.GetReturnValue().Set(info.Data());
+}
+
+static void ThrowingSymbolAccessorGetter(
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetReturnValue().Set(info.GetIsolate()->ThrowException(name));
+}
+
void EmptyInterceptorGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
}
for (i = 0; name_str[i] && prefix[i]; ++i) {
if (name_str[i] != prefix[i]) return;
}
- Handle<Object> self = info.This();
+ Handle<Object> self = Handle<Object>::Cast(info.This());
info.GetReturnValue().Set(self->GetHiddenValue(v8_str(name_str + i)));
}
if (!prefix[i]) return;
if (value->IsInt32() && value->Int32Value() < 10000) {
- Handle<Object> self = info.This();
+ Handle<Object> self = Handle<Object>::Cast(info.This());
self->SetHiddenValue(name, value);
info.GetReturnValue().Set(value);
}
}
+void AddAccessor(Handle<FunctionTemplate> templ,
+ Handle<Name> name,
+ v8::AccessorNameGetterCallback getter,
+ v8::AccessorNameSetterCallback setter) {
+ templ->PrototypeTemplate()->SetAccessor(name, getter, setter);
+}
+
+
THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> parent = FunctionTemplate::New();
- Handle<FunctionTemplate> child = FunctionTemplate::New();
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate());
+ Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate());
child->Inherit(parent);
AddAccessor(parent, v8_str("age"),
SimpleAccessorGetter, SimpleAccessorSetter);
}
-THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) {
+THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ v8::Local<v8::Value> res = CompileRun("var a = []; a;");
+ i::Handle<i::JSObject> a(v8::Utils::OpenHandle(v8::Object::Cast(*res)));
+ CHECK(a->map()->instance_descriptors()->IsFixedArray());
+ CHECK_GT(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0);
+ CompileRun("Object.defineProperty(a, 'length', { writable: false });");
+ CHECK_EQ(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0);
+ // But we should still have an ExecutableAccessorInfo.
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::LookupResult lookup(i_isolate);
+ i::Handle<i::String> name(v8::Utils::OpenHandle(*v8_str("length")));
+ i::LookupIterator it(a, name, i::LookupIterator::OWN_SKIP_INTERCEPTOR);
+ CHECK_EQ(i::LookupIterator::ACCESSOR, it.state());
+ CHECK(it.GetAccessors()->IsExecutableAccessorInfo());
+}
+
+
+THREADED_TEST(EmptyInterceptorBreakTransitions) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> parent = FunctionTemplate::New();
- Handle<FunctionTemplate> child = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
+ AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Constructor"), templ->GetFunction());
+ CompileRun("var o1 = new Constructor;"
+ "o1.a = 1;" // Ensure a and x share the descriptor array.
+ "Object.defineProperty(o1, 'x', {value: 10});");
+ CompileRun("var o2 = new Constructor;"
+ "o2.a = 1;"
+ "Object.defineProperty(o2, 'x', {value: 10});");
+}
+
+
+THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate);
+ Handle<FunctionTemplate> child = FunctionTemplate::New(isolate);
child->Inherit(parent);
AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
LocalContext env;
THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) {
- v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> parent = FunctionTemplate::New();
- Handle<FunctionTemplate> child = FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate);
+ Handle<FunctionTemplate> child = FunctionTemplate::New(isolate);
child->Inherit(parent);
AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
LocalContext env;
THREADED_TEST(SwitchFromInterceptorToAccessor) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddAccessor(templ, v8_str("age"),
SimpleAccessorGetter, SimpleAccessorSetter);
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
THREADED_TEST(SwitchFromAccessorToInterceptor) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddAccessor(templ, v8_str("age"),
SimpleAccessorGetter, SimpleAccessorSetter);
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> parent = FunctionTemplate::New();
- Handle<FunctionTemplate> child = FunctionTemplate::New();
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate());
+ Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate());
child->Inherit(parent);
AddAccessor(parent, v8_str("age"),
SimpleAccessorGetter, SimpleAccessorSetter);
THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> parent = FunctionTemplate::New();
- Handle<FunctionTemplate> child = FunctionTemplate::New();
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate());
+ Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate());
child->Inherit(parent);
AddAccessor(parent, v8_str("age"),
SimpleAccessorGetter, SimpleAccessorSetter);
THREADED_TEST(SwitchFromInterceptorToJSAccessor) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
LocalContext env;
env->Global()->Set(v8_str("Obj"), templ->GetFunction());
THREADED_TEST(SwitchFromJSAccessorToInterceptor) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
LocalContext env;
env->Global()->Set(v8_str("Obj"), templ->GetFunction());
THREADED_TEST(SwitchFromInterceptorToProperty) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> parent = FunctionTemplate::New();
- Handle<FunctionTemplate> child = FunctionTemplate::New();
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate());
+ Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate());
child->Inherit(parent);
AddInterceptor(child, InterceptorGetter, InterceptorSetter);
LocalContext env;
THREADED_TEST(SwitchFromPropertyToInterceptor) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> parent = FunctionTemplate::New();
- Handle<FunctionTemplate> child = FunctionTemplate::New();
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate());
+ Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate());
child->Inherit(parent);
AddInterceptor(child, InterceptorGetter, InterceptorSetter);
LocalContext env;
THREADED_TEST(NamedPropertyHandlerGetter) {
echo_named_call_count = 0;
v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> templ =
+ v8::FunctionTemplate::New(CcTest::isolate());
templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty,
0, 0, 0, 0,
v8_str("data"));
THREADED_TEST(IndexedPropertyHandlerGetter) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->InstanceTemplate()->SetIndexedPropertyHandler(EchoIndexedProperty,
0, 0, 0, 0,
v8_num(637));
THREADED_PROFILED_TEST(PropertyHandlerInPrototype) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
// Set up a prototype chain with three interceptors.
- v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->InstanceTemplate()->SetIndexedPropertyHandler(
CheckThisIndexedPropertyHandler,
CheckThisIndexedPropertySetter,
env->Global()->Set(v8_str("obj"), bottom);
// Indexed and named get.
- Script::Compile(v8_str("obj[0]"))->Run();
- Script::Compile(v8_str("obj.x"))->Run();
+ CompileRun("obj[0]");
+ CompileRun("obj.x");
// Indexed and named set.
- Script::Compile(v8_str("obj[1] = 42"))->Run();
- Script::Compile(v8_str("obj.y = 42"))->Run();
+ CompileRun("obj[1] = 42");
+ CompileRun("obj.y = 42");
// Indexed and named query.
- Script::Compile(v8_str("0 in obj"))->Run();
- Script::Compile(v8_str("'x' in obj"))->Run();
+ CompileRun("0 in obj");
+ CompileRun("'x' in obj");
// Indexed and named deleter.
- Script::Compile(v8_str("delete obj[0]"))->Run();
- Script::Compile(v8_str("delete obj.x"))->Run();
+ CompileRun("delete obj[0]");
+ CompileRun("delete obj.x");
// Enumerators.
- Script::Compile(v8_str("for (var p in obj) ;"))->Run();
+ CompileRun("for (var p in obj) ;");
}
THREADED_TEST(PrePropertyHandler) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
desc->InstanceTemplate()->SetNamedPropertyHandler(PrePropertyHandlerGet,
0,
PrePropertyHandlerQuery);
LocalContext env(NULL, desc->InstanceTemplate());
- Script::Compile(v8_str(
- "var pre = 'Object: pre'; var on = 'Object: on';"))->Run();
- v8::Handle<Value> result_pre = Script::Compile(v8_str("pre"))->Run();
+ CompileRun("var pre = 'Object: pre'; var on = 'Object: on';");
+ v8::Handle<Value> result_pre = CompileRun("pre");
CHECK_EQ(v8_str("PrePropertyHandler: pre"), result_pre);
- v8::Handle<Value> result_on = Script::Compile(v8_str("on"))->Run();
+ v8::Handle<Value> result_on = CompileRun("on");
CHECK_EQ(v8_str("Object: on"), result_on);
- v8::Handle<Value> result_post = Script::Compile(v8_str("post"))->Run();
+ v8::Handle<Value> result_post = CompileRun("post");
CHECK(result_post.IsEmpty());
}
THREADED_TEST(UndefinedIsNotEnumerable) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Handle<Value> result = Script::Compile(v8_str(
- "this.propertyIsEnumerable(undefined)"))->Run();
+ v8::Handle<Value> result = CompileRun("this.propertyIsEnumerable(undefined)");
CHECK(result->IsFalse());
}
ApiTestFuzzer::Fuzz();
int depth = args.This()->Get(v8_str("depth"))->Int32Value();
if (depth == kTargetRecursionDepth) return;
- args.This()->Set(v8_str("depth"), v8::Integer::New(depth + 1));
+ args.This()->Set(v8_str("depth"),
+ v8::Integer::New(args.GetIsolate(), depth + 1));
args.GetReturnValue().Set(call_recursively_script->Run());
}
printf("[depth = %d]\n", depth);
return;
}
- args.This()->Set(v8_str("depth"), v8::Integer::New(depth + 1));
+ args.This()->Set(v8_str("depth"),
+ v8::Integer::New(args.GetIsolate(), depth + 1));
v8::Handle<Value> function =
args.This()->Get(v8_str("callFunctionRecursively"));
args.GetReturnValue().Set(
THREADED_TEST(DeepCrossLanguageRecursion) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate);
global->Set(v8_str("callScriptRecursively"),
- v8::FunctionTemplate::New(CallScriptRecursivelyCall));
+ v8::FunctionTemplate::New(isolate, CallScriptRecursivelyCall));
global->Set(v8_str("callFunctionRecursively"),
- v8::FunctionTemplate::New(CallFunctionRecursivelyCall));
+ v8::FunctionTemplate::New(isolate, CallFunctionRecursivelyCall));
LocalContext env(NULL, global);
- env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
+ env->Global()->Set(v8_str("depth"), v8::Integer::New(isolate, 0));
call_recursively_script = v8_compile("callScriptRecursively()");
call_recursively_script->Run();
call_recursively_script = v8::Handle<Script>();
- env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
- Script::Compile(v8_str("callFunctionRecursively()"))->Run();
+ env->Global()->Set(v8_str("depth"), v8::Integer::New(isolate, 0));
+ CompileRun("callFunctionRecursively()");
}
THREADED_TEST(CallbackExceptionRegression) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
obj->SetNamedPropertyHandler(ThrowingPropertyHandlerGet,
ThrowingPropertyHandlerSet);
LocalContext env;
env->Global()->Set(v8_str("obj"), obj->NewInstance());
- v8::Handle<Value> otto = Script::Compile(v8_str(
- "try { with (obj) { otto; } } catch (e) { e; }"))->Run();
+ v8::Handle<Value> otto = CompileRun(
+ "try { with (obj) { otto; } } catch (e) { e; }");
CHECK_EQ(v8_str("otto"), otto);
- v8::Handle<Value> netto = Script::Compile(v8_str(
- "try { with (obj) { netto = 4; } } catch (e) { e; }"))->Run();
+ v8::Handle<Value> netto = CompileRun(
+ "try { with (obj) { netto = 4; } } catch (e) { e; }");
CHECK_EQ(v8_str("netto"), netto);
}
THREADED_TEST(FunctionPrototype) {
- v8::HandleScope scope(CcTest::isolate());
- Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(isolate);
Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321));
LocalContext env;
env->Global()->Set(v8_str("Foo"), Foo->GetFunction());
- Local<Script> script = Script::Compile(v8_str("Foo.prototype.plak"));
+ Local<Script> script = v8_compile("Foo.prototype.plak");
CHECK_EQ(script->Run()->Int32Value(), 321);
}
THREADED_TEST(InternalFields) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
instance_templ->SetInternalFieldCount(1);
Local<v8::Object> obj = templ->GetFunction()->NewInstance();
THREADED_TEST(GlobalObjectInternalFields) {
- v8::HandleScope scope(CcTest::isolate());
- Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate);
global_template->SetInternalFieldCount(1);
LocalContext env(NULL, global_template);
v8::Handle<v8::Object> global_proxy = env->Global();
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Object> global = env->Global();
- global->Set(0, v8::String::New("value"));
+ global->Set(0, v8::String::NewFromUtf8(CcTest::isolate(), "value"));
CHECK(global->HasRealIndexedProperty(0));
}
THREADED_TEST(InternalFieldsAlignedPointers) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
instance_templ->SetInternalFieldCount(1);
Local<v8::Object> obj = templ->GetFunction()->NewInstance();
void* huge = reinterpret_cast<void*>(~static_cast<uintptr_t>(1));
CheckAlignedPointerInInternalField(obj, huge);
+
+ v8::UniquePersistent<v8::Object> persistent(isolate, obj);
+ CHECK_EQ(1, Object::InternalFieldCount(persistent));
+ CHECK_EQ(huge, Object::GetAlignedPointerFromInternalField(persistent, 0));
}
THREADED_TEST(EmbedderData) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ CheckEmbedderData(
+ &env, 3,
+ v8::String::NewFromUtf8(isolate, "The quick brown fox jumps"));
+ CheckEmbedderData(&env, 2, v8::String::NewFromUtf8(isolate,
+ "over the lazy dog."));
+ CheckEmbedderData(&env, 1, v8::Number::New(isolate, 1.2345));
+ CheckEmbedderData(&env, 0, v8::Boolean::New(isolate, true));
+}
- CheckEmbedderData(&env, 3, v8::String::New("The quick brown fox jumps"));
- CheckEmbedderData(&env, 2, v8::String::New("over the lazy dog."));
- CheckEmbedderData(&env, 1, v8::Number::New(1.2345));
- CheckEmbedderData(&env, 0, v8::Boolean::New(true));
+
+THREADED_TEST(GetIsolate) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::Object> obj = v8::Object::New(isolate);
+ CHECK_EQ(isolate, obj->GetIsolate());
+ CHECK_EQ(isolate, CcTest::global()->GetIsolate());
}
THREADED_TEST(IdentityHash) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
// Ensure that the test starts with an fresh heap to test whether the hash
// code is based on the address.
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
- Local<v8::Object> obj = v8::Object::New();
+ Local<v8::Object> obj = v8::Object::New(isolate);
int hash = obj->GetIdentityHash();
int hash1 = obj->GetIdentityHash();
CHECK_EQ(hash, hash1);
- int hash2 = v8::Object::New()->GetIdentityHash();
+ int hash2 = v8::Object::New(isolate)->GetIdentityHash();
// Since the identity hash is essentially a random number two consecutive
// objects should not be assigned the same hash code. If the test below fails
// the random number generator should be evaluated.
CHECK_NE(hash, hash2);
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
- int hash3 = v8::Object::New()->GetIdentityHash();
+ int hash3 = v8::Object::New(isolate)->GetIdentityHash();
// Make sure that the identity hash is not based on the initial address of
// the object alone. If the test below fails the random number generator
// should be evaluated.
// Put a getter for 'v8::IdentityHash' on the Object's prototype:
{
CompileRun("Object.prototype['v8::IdentityHash'] = 42;\n");
- Local<v8::Object> o1 = v8::Object::New();
- Local<v8::Object> o2 = v8::Object::New();
+ Local<v8::Object> o1 = v8::Object::New(isolate);
+ Local<v8::Object> o2 = v8::Object::New(isolate);
CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash());
}
{
CompileRun(
"function cnst() { return 42; };\n"
"Object.prototype.__defineGetter__('v8::IdentityHash', cnst);\n");
- Local<v8::Object> o1 = v8::Object::New();
- Local<v8::Object> o2 = v8::Object::New();
+ Local<v8::Object> o1 = v8::Object::New(isolate);
+ Local<v8::Object> o2 = v8::Object::New(isolate);
CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash());
}
}
-THREADED_TEST(SymbolProperties) {
- i::FLAG_harmony_symbols = true;
+THREADED_TEST(GlobalProxyIdentityHash) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Handle<Object> global_proxy = env->Global();
+ int hash1 = global_proxy->GetIdentityHash();
+ // Hash should be retained after being detached.
+ env->DetachGlobal();
+ int hash2 = global_proxy->GetIdentityHash();
+ CHECK_EQ(hash1, hash2);
+ {
+ // Re-attach global proxy to a new context, hash should stay the same.
+ LocalContext env2(NULL, Handle<ObjectTemplate>(), global_proxy);
+ int hash3 = global_proxy->GetIdentityHash();
+ CHECK_EQ(hash1, hash3);
+ }
+}
+
+THREADED_TEST(SymbolProperties) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Local<v8::Object> obj = v8::Object::New();
+ v8::Local<v8::Object> obj = v8::Object::New(isolate);
v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate);
- v8::Local<v8::Symbol> sym2 = v8::Symbol::New(isolate, "my-symbol");
+ v8::Local<v8::Symbol> sym2 =
+ v8::Symbol::New(isolate, v8_str("my-symbol"));
+ v8::Local<v8::Symbol> sym3 =
+ v8::Symbol::New(isolate, v8_str("sym3"));
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK(!sym1->StrictEquals(sym2));
CHECK(!sym2->StrictEquals(sym1));
- CHECK(sym2->Name()->Equals(v8::String::New("my-symbol")));
+ CHECK(sym2->Name()->Equals(v8_str("my-symbol")));
v8::Local<v8::Value> sym_val = sym2;
CHECK(sym_val->IsSymbol());
CHECK(sym_obj->IsSymbolObject());
CHECK(!sym2->IsSymbolObject());
CHECK(!obj->IsSymbolObject());
- CHECK(sym_obj->Equals(sym2));
+ CHECK(!sym_obj->Equals(sym2));
CHECK(!sym_obj->StrictEquals(sym2));
CHECK(v8::SymbolObject::Cast(*sym_obj)->Equals(sym_obj));
CHECK(v8::SymbolObject::Cast(*sym_obj)->ValueOf()->Equals(sym2));
CHECK(obj->Delete(sym1));
CHECK(!obj->Has(sym1));
- CHECK(obj->Set(sym1, v8::Integer::New(1503)));
+ CHECK(obj->Set(sym1, v8::Integer::New(isolate, 1503)));
CHECK(obj->Has(sym1));
CHECK_EQ(1503, obj->Get(sym1)->Int32Value());
- CHECK(obj->Set(sym1, v8::Integer::New(2002)));
+ CHECK(obj->Set(sym1, v8::Integer::New(isolate, 2002)));
CHECK(obj->Has(sym1));
CHECK_EQ(2002, obj->Get(sym1)->Int32Value());
CHECK_EQ(v8::None, obj->GetPropertyAttributes(sym1));
CHECK_EQ(0, obj->GetOwnPropertyNames()->Length());
int num_props = obj->GetPropertyNames()->Length();
- CHECK(obj->Set(v8::String::New("bla"), v8::Integer::New(20)));
+ CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"),
+ v8::Integer::New(isolate, 20)));
CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length());
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ CHECK(obj->SetAccessor(sym3, SymbolAccessorGetter, SymbolAccessorSetter));
+ CHECK(obj->Get(sym3)->IsUndefined());
+ CHECK(obj->Set(sym3, v8::Integer::New(isolate, 42)));
+ CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42)));
+ CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals(
+ v8::Integer::New(isolate, 42)));
+
// Add another property and delete it afterwards to force the object in
// slow case.
- CHECK(obj->Set(sym2, v8::Integer::New(2008)));
+ CHECK(obj->Set(sym2, v8::Integer::New(isolate, 2008)));
CHECK_EQ(2002, obj->Get(sym1)->Int32Value());
CHECK_EQ(2008, obj->Get(sym2)->Int32Value());
CHECK_EQ(2002, obj->Get(sym1)->Int32Value());
- CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
+ CHECK_EQ(2, obj->GetOwnPropertyNames()->Length());
CHECK(obj->Has(sym1));
CHECK(obj->Has(sym2));
+ CHECK(obj->Has(sym3));
+ CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3")));
CHECK(obj->Delete(sym2));
CHECK(obj->Has(sym1));
CHECK(!obj->Has(sym2));
+ CHECK(obj->Has(sym3));
+ CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3")));
CHECK_EQ(2002, obj->Get(sym1)->Int32Value());
- CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
-}
+ CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42)));
+ CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals(
+ v8::Integer::New(isolate, 42)));
+ CHECK_EQ(2, obj->GetOwnPropertyNames()->Length());
+ // Symbol properties are inherited.
+ v8::Local<v8::Object> child = v8::Object::New(isolate);
+ child->SetPrototype(obj);
+ CHECK(child->Has(sym1));
+ CHECK_EQ(2002, child->Get(sym1)->Int32Value());
+ CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42)));
+ CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals(
+ v8::Integer::New(isolate, 42)));
+ CHECK_EQ(0, child->GetOwnPropertyNames()->Length());
+}
-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_;
-};
-template <typename T>
-static void CheckInternalFieldsAreZero(v8::Handle<T> value) {
- CHECK_EQ(T::kInternalFieldCount, value->InternalFieldCount());
- for (int i = 0; i < value->InternalFieldCount(); i++) {
- CHECK_EQ(0, value->GetInternalField(i)->Int32Value());
- }
+THREADED_TEST(SymbolTemplateProperties) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::FunctionTemplate> foo = v8::FunctionTemplate::New(isolate);
+ v8::Local<v8::Name> name = v8::Symbol::New(isolate);
+ CHECK(!name.IsEmpty());
+ foo->PrototypeTemplate()->Set(name, v8::FunctionTemplate::New(isolate));
+ v8::Local<v8::Object> new_instance = foo->InstanceTemplate()->NewInstance();
+ CHECK(!new_instance.IsEmpty());
+ CHECK(new_instance->Has(name));
}
-THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
+THREADED_TEST(PrivateProperties) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope handle_scope(isolate);
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Object> obj = v8::Object::New(isolate);
+ v8::Local<v8::Private> priv1 = v8::Private::New(isolate);
+ v8::Local<v8::Private> priv2 =
+ v8::Private::New(isolate, v8_str("my-private"));
- Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(1024);
- CheckInternalFieldsAreZero(ab);
- CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
- CHECK(!ab->IsExternal());
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+
+ CHECK(priv2->Name()->Equals(v8::String::NewFromUtf8(isolate, "my-private")));
+
+ // Make sure delete of a non-existent private symbol property works.
+ CHECK(obj->DeletePrivate(priv1));
+ CHECK(!obj->HasPrivate(priv1));
+
+ CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 1503)));
+ CHECK(obj->HasPrivate(priv1));
+ CHECK_EQ(1503, obj->GetPrivate(priv1)->Int32Value());
+ CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 2002)));
+ CHECK(obj->HasPrivate(priv1));
+ CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
+
+ CHECK_EQ(0, obj->GetOwnPropertyNames()->Length());
+ int num_props = obj->GetPropertyNames()->Length();
+ CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"),
+ v8::Integer::New(isolate, 20)));
+ CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
+ CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length());
+
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+
+ // Add another property and delete it afterwards to force the object in
+ // slow case.
+ CHECK(obj->SetPrivate(priv2, v8::Integer::New(isolate, 2008)));
+ CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
+ CHECK_EQ(2008, obj->GetPrivate(priv2)->Int32Value());
+ CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
+ CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
+
+ CHECK(obj->HasPrivate(priv1));
+ CHECK(obj->HasPrivate(priv2));
+ CHECK(obj->DeletePrivate(priv2));
+ CHECK(obj->HasPrivate(priv1));
+ CHECK(!obj->HasPrivate(priv2));
+ CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
+ CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
+
+ // Private properties are inherited (for the time being).
+ v8::Local<v8::Object> child = v8::Object::New(isolate);
+ child->SetPrototype(obj);
+ CHECK(child->HasPrivate(priv1));
+ CHECK_EQ(2002, child->GetPrivate(priv1)->Int32Value());
+ CHECK_EQ(0, child->GetOwnPropertyNames()->Length());
+}
+
+
+THREADED_TEST(GlobalSymbols) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Local<String> name = v8_str("my-symbol");
+ v8::Local<v8::Symbol> glob = v8::Symbol::For(isolate, name);
+ v8::Local<v8::Symbol> glob2 = v8::Symbol::For(isolate, name);
+ CHECK(glob2->SameValue(glob));
+
+ v8::Local<v8::Symbol> glob_api = v8::Symbol::ForApi(isolate, name);
+ v8::Local<v8::Symbol> glob_api2 = v8::Symbol::ForApi(isolate, name);
+ CHECK(glob_api2->SameValue(glob_api));
+ CHECK(!glob_api->SameValue(glob));
+
+ v8::Local<v8::Symbol> sym = v8::Symbol::New(isolate, name);
+ CHECK(!sym->SameValue(glob));
+
+ CompileRun("var sym2 = Symbol.for('my-symbol')");
+ v8::Local<Value> sym2 = env->Global()->Get(v8_str("sym2"));
+ CHECK(sym2->SameValue(glob));
+ CHECK(!sym2->SameValue(glob_api));
+}
+
+
+static void CheckWellKnownSymbol(v8::Local<v8::Symbol>(*getter)(v8::Isolate*),
+ const char* name) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Symbol> symbol = getter(isolate);
+ std::string script = std::string("var sym = ") + name;
+ CompileRun(script.c_str());
+ v8::Local<Value> value = env->Global()->Get(v8_str("sym"));
+
+ CHECK(!value.IsEmpty());
+ CHECK(!symbol.IsEmpty());
+ CHECK(value->SameValue(symbol));
+}
+
+
+THREADED_TEST(WellKnownSymbols) {
+ CheckWellKnownSymbol(v8::Symbol::GetIterator, "Symbol.iterator");
+ CheckWellKnownSymbol(v8::Symbol::GetUnscopables, "Symbol.unscopables");
+}
+
+
+THREADED_TEST(GlobalPrivates) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Local<String> name = v8_str("my-private");
+ v8::Local<v8::Private> glob = v8::Private::ForApi(isolate, name);
+ v8::Local<v8::Object> obj = v8::Object::New(isolate);
+ CHECK(obj->SetPrivate(glob, v8::Integer::New(isolate, 3)));
+
+ v8::Local<v8::Private> glob2 = v8::Private::ForApi(isolate, name);
+ CHECK(obj->HasPrivate(glob2));
+
+ v8::Local<v8::Private> priv = v8::Private::New(isolate, name);
+ CHECK(!obj->HasPrivate(priv));
+
+ CompileRun("var intern = %CreateGlobalPrivateSymbol('my-private')");
+ v8::Local<Value> intern = env->Global()->Get(v8_str("intern"));
+ CHECK(!obj->Has(intern));
+}
+
+
+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_;
+};
+
+template <typename T>
+static void CheckInternalFieldsAreZero(v8::Handle<T> value) {
+ CHECK_EQ(T::kInternalFieldCount, value->InternalFieldCount());
+ for (int i = 0; i < value->InternalFieldCount(); i++) {
+ CHECK_EQ(0, value->GetInternalField(i)->Int32Value());
+ }
+}
+
+
+THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024);
+ CheckInternalFieldsAreZero(ab);
+ CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
+ CHECK(!ab->IsExternal());
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
ScopedArrayBufferContents ab_contents(ab->Externalize());
CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength()));
uint8_t* data = static_cast<uint8_t*>(ab_contents.Data());
- ASSERT(data != NULL);
+ DCHECK(data != NULL);
env->Global()->Set(v8_str("ab"), ab);
v8::Handle<v8::Value> result = CompileRun("ab.byteLength");
i::ScopedVector<uint8_t> my_data(100);
memset(my_data.start(), 0, 100);
- Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(my_data.start(), 100);
+ Local<v8::ArrayBuffer> ab3 =
+ v8::ArrayBuffer::New(isolate, my_data.start(), 100);
CheckInternalFieldsAreZero(ab3);
CHECK_EQ(100, static_cast<int>(ab3->ByteLength()));
CHECK(ab3->IsExternal());
}
+THREADED_TEST(ArrayBuffer_DisableNeuter) {
+ 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> ab =
+ v8::ArrayBuffer::New(isolate, my_data.start(), 100);
+ CHECK(ab->IsNeuterable());
+
+ i::Handle<i::JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab);
+ buf->set_is_neuterable(false);
+
+ CHECK(!ab->IsNeuterable());
+}
+
+
static void CheckDataViewIsNeutered(v8::Handle<v8::DataView> dv) {
CHECK_EQ(0, static_cast<int>(dv->ByteLength()));
CHECK_EQ(0, static_cast<int>(dv->ByteOffset()));
static void CheckIsTypedArrayVarNeutered(const char* name) {
i::ScopedVector<char> source(1024);
- i::OS::SNPrintF(source,
+ i::SNPrintF(source,
"%s.byteLength == 0 && %s.byteOffset == 0 && %s.length == 0",
name, name, name);
CHECK(CompileRun(source.start())->IsTrue());
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
- v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(1024);
+ v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, 1024);
v8::Handle<v8::Uint8Array> u8a =
CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023);
THREADED_TEST(HiddenProperties) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- v8::Local<v8::Object> obj = v8::Object::New();
+ v8::Local<v8::Object> obj = v8::Object::New(env->GetIsolate());
v8::Local<v8::String> key = v8_str("api-test::hidden-key");
v8::Local<v8::String> empty = v8_str("");
v8::Local<v8::String> prop_name = v8_str("prop_name");
// Make sure delete of a non-existent hidden value works
CHECK(obj->DeleteHiddenValue(key));
- CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503)));
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 1503)));
CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value());
- CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002)));
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2002)));
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
CHECK(obj->Get(empty)->IsUndefined());
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
- CHECK(obj->Set(empty, v8::Integer::New(2003)));
+ CHECK(obj->Set(empty, v8::Integer::New(isolate, 2003)));
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
CHECK_EQ(2003, obj->Get(empty)->Int32Value());
// Add another property and delete it afterwards to force the object in
// slow case.
- CHECK(obj->Set(prop_name, v8::Integer::New(2008)));
+ CHECK(obj->Set(prop_name, v8::Integer::New(isolate, 2008)));
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
CHECK_EQ(2008, obj->Get(prop_name)->Int32Value());
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
CHECK(obj->SetHiddenValue(key, Handle<Value>()));
CHECK(obj->GetHiddenValue(key).IsEmpty());
- CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002)));
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2002)));
CHECK(obj->DeleteHiddenValue(key));
CHECK(obj->GetHiddenValue(key).IsEmpty());
}
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Local<v8::Object> obj = v8::Object::New();
+ v8::Local<v8::Object> obj = v8::Object::New(env->GetIsolate());
v8::Local<v8::String> key = v8_str("hidden");
CompileRun(
// Make sure that the getter and setter from Object.prototype is not invoked.
// If it did we would have full access to the hidden properties in
// the accessor.
- CHECK(obj->SetHiddenValue(key, v8::Integer::New(42)));
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(env->GetIsolate(), 42)));
ExpectFalse("set_called");
CHECK_EQ(42, obj->GetHiddenValue(key)->Int32Value());
}
THREADED_TEST(HiddenPropertiesWithInterceptors) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
interceptor_for_hidden_properties_called = false;
v8::Local<v8::String> key = v8_str("api-test::hidden-key");
// Associate an interceptor with an object and start setting hidden values.
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
instance_templ->SetNamedPropertyHandler(InterceptorForHiddenProperties);
Local<v8::Function> function = fun_templ->GetFunction();
Local<v8::Object> obj = function->NewInstance();
- CHECK(obj->SetHiddenValue(key, v8::Integer::New(2302)));
+ CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2302)));
CHECK_EQ(2302, obj->GetHiddenValue(key)->Int32Value());
CHECK(!interceptor_for_hidden_properties_called);
}
THREADED_TEST(External) {
v8::HandleScope scope(CcTest::isolate());
int x = 3;
- Local<v8::External> ext = v8::External::New(&x);
+ Local<v8::External> ext = v8::External::New(CcTest::isolate(), &x);
LocalContext env;
env->Global()->Set(v8_str("ext"), ext);
- Local<Value> reext_obj = Script::Compile(v8_str("this.ext"))->Run();
+ Local<Value> reext_obj = CompileRun("this.ext");
v8::Handle<v8::External> reext = reext_obj.As<v8::External>();
int* ptr = static_cast<int*>(reext->Value());
CHECK_EQ(x, 3);
// Make sure unaligned pointers are wrapped properly.
char* data = i::StrDup("0123456789");
- Local<v8::Value> zero = v8::External::New(&data[0]);
- Local<v8::Value> one = v8::External::New(&data[1]);
- Local<v8::Value> two = v8::External::New(&data[2]);
- Local<v8::Value> three = v8::External::New(&data[3]);
+ Local<v8::Value> zero = v8::External::New(CcTest::isolate(), &data[0]);
+ Local<v8::Value> one = v8::External::New(CcTest::isolate(), &data[1]);
+ Local<v8::Value> two = v8::External::New(CcTest::isolate(), &data[2]);
+ Local<v8::Value> three = v8::External::New(CcTest::isolate(), &data[3]);
char* char_ptr = reinterpret_cast<char*>(v8::External::Cast(*zero)->Value());
CHECK_EQ('0', *char_ptr);
v8::HandleScope scope(isolate);
CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 3);
}
- global.Dispose();
- global.Clear();
+ global.Reset();
{
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();
+ global.Reset();
}
v8::HandleScope scope(isolate);
CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 6);
}
- global.Dispose();
+ global.Reset();
CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1);
}
}
-THREADED_TEST(ClearAndLeakGlobal) {
+template<class T>
+static v8::UniquePersistent<T> PassUnique(v8::UniquePersistent<T> unique) {
+ return unique.Pass();
+}
+
+
+template<class T>
+static v8::UniquePersistent<T> ReturnUnique(v8::Isolate* isolate,
+ const v8::Persistent<T> & global) {
+ v8::UniquePersistent<String> unique(isolate, global);
+ return unique.Pass();
+}
+
+
+THREADED_TEST(UniquePersistent) {
v8::Isolate* isolate = CcTest::isolate();
- 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->global_handles_count();
- global.Reset(isolate, str);
- }
- CHECK_EQ(global_handles->global_handles_count(), initial_handle_count + 1);
- String* str = global.ClearAndLeak();
- CHECK(global.IsEmpty());
- CHECK_EQ(global_handles->global_handles_count(), initial_handle_count + 1);
- global_handles->Destroy(reinterpret_cast<i::Object**>(str));
- CHECK_EQ(global_handles->global_handles_count(), initial_handle_count);
+ 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->global_handles_count();
+ {
+ v8::UniquePersistent<String> unique(isolate, global);
+ CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
+ // Test assignment via Pass
+ {
+ v8::UniquePersistent<String> copy = unique.Pass();
+ CHECK(unique.IsEmpty());
+ CHECK(copy == global);
+ CHECK_EQ(initial_handle_count + 1,
+ global_handles->global_handles_count());
+ unique = copy.Pass();
+ }
+ // Test ctor via Pass
+ {
+ v8::UniquePersistent<String> copy(unique.Pass());
+ CHECK(unique.IsEmpty());
+ CHECK(copy == global);
+ CHECK_EQ(initial_handle_count + 1,
+ global_handles->global_handles_count());
+ unique = copy.Pass();
+ }
+ // Test pass through function call
+ {
+ v8::UniquePersistent<String> copy = PassUnique(unique.Pass());
+ CHECK(unique.IsEmpty());
+ CHECK(copy == global);
+ CHECK_EQ(initial_handle_count + 1,
+ global_handles->global_handles_count());
+ unique = copy.Pass();
+ }
+ CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
+ }
+ // Test pass from function call
+ {
+ v8::UniquePersistent<String> unique = ReturnUnique(isolate, global);
+ CHECK(unique == global);
+ CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
+ }
+ CHECK_EQ(initial_handle_count, global_handles->global_handles_count());
+ global.Reset();
+}
+
+
+template<typename K, typename V>
+class WeakStdMapTraits : public v8::StdMapTraits<K, V> {
+ public:
+ typedef typename v8::PersistentValueMap<K, V, WeakStdMapTraits<K, V> >
+ MapType;
+ static const v8::PersistentContainerCallbackType kCallbackType = v8::kWeak;
+ struct WeakCallbackDataType {
+ MapType* map;
+ K key;
+ };
+ static WeakCallbackDataType* WeakCallbackParameter(
+ MapType* map, const K& key, Local<V> value) {
+ WeakCallbackDataType* data = new WeakCallbackDataType;
+ data->map = map;
+ data->key = key;
+ return data;
+ }
+ static MapType* MapFromWeakCallbackData(
+ const v8::WeakCallbackData<V, WeakCallbackDataType>& data) {
+ return data.GetParameter()->map;
+ }
+ static K KeyFromWeakCallbackData(
+ const v8::WeakCallbackData<V, WeakCallbackDataType>& data) {
+ return data.GetParameter()->key;
+ }
+ static void DisposeCallbackData(WeakCallbackDataType* data) {
+ delete data;
+ }
+ static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value,
+ K key) { }
+};
+
+
+template<typename Map>
+static void TestPersistentValueMap() {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ Map map(isolate);
+ v8::internal::GlobalHandles* global_handles =
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
+ int initial_handle_count = global_handles->global_handles_count();
+ CHECK_EQ(0, static_cast<int>(map.Size()));
+ {
+ HandleScope scope(isolate);
+ Local<v8::Object> obj = map.Get(7);
+ CHECK(obj.IsEmpty());
+ Local<v8::Object> expected = v8::Object::New(isolate);
+ map.Set(7, expected);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ obj = map.Get(7);
+ CHECK_EQ(expected, obj);
+ {
+ typename Map::PersistentValueReference ref = map.GetReference(7);
+ CHECK_EQ(expected, ref.NewLocal(isolate));
+ }
+ v8::UniquePersistent<v8::Object> removed = map.Remove(7);
+ CHECK_EQ(0, static_cast<int>(map.Size()));
+ CHECK(expected == removed);
+ removed = map.Remove(7);
+ CHECK(removed.IsEmpty());
+ map.Set(8, expected);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ map.Set(8, expected);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ {
+ typename Map::PersistentValueReference ref;
+ Local<v8::Object> expected2 = v8::Object::New(isolate);
+ removed = map.Set(8,
+ v8::UniquePersistent<v8::Object>(isolate, expected2), &ref);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ CHECK(expected == removed);
+ CHECK_EQ(expected2, ref.NewLocal(isolate));
+ }
+ }
+ CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
+ if (map.IsWeak()) {
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->heap()->
+ CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+ } else {
+ map.Clear();
+ }
+ CHECK_EQ(0, static_cast<int>(map.Size()));
+ CHECK_EQ(initial_handle_count, global_handles->global_handles_count());
+}
+
+
+TEST(PersistentValueMap) {
+ // Default case, w/o weak callbacks:
+ TestPersistentValueMap<v8::StdPersistentValueMap<int, v8::Object> >();
+
+ // Custom traits with weak callbacks:
+ typedef v8::PersistentValueMap<int, v8::Object,
+ WeakStdMapTraits<int, v8::Object> > WeakPersistentValueMap;
+ TestPersistentValueMap<WeakPersistentValueMap>();
+}
+
+
+TEST(PersistentValueVector) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::internal::GlobalHandles* global_handles =
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
+ int handle_count = global_handles->global_handles_count();
+ HandleScope scope(isolate);
+
+ v8::PersistentValueVector<v8::Object> vector(isolate);
+
+ Local<v8::Object> obj1 = v8::Object::New(isolate);
+ Local<v8::Object> obj2 = v8::Object::New(isolate);
+ v8::UniquePersistent<v8::Object> obj3(isolate, v8::Object::New(isolate));
+
+ CHECK(vector.IsEmpty());
+ CHECK_EQ(0, static_cast<int>(vector.Size()));
+
+ vector.ReserveCapacity(3);
+ CHECK(vector.IsEmpty());
+
+ vector.Append(obj1);
+ vector.Append(obj2);
+ vector.Append(obj1);
+ vector.Append(obj3.Pass());
+ vector.Append(obj1);
+
+ CHECK(!vector.IsEmpty());
+ CHECK_EQ(5, static_cast<int>(vector.Size()));
+ CHECK(obj3.IsEmpty());
+ CHECK_EQ(obj1, vector.Get(0));
+ CHECK_EQ(obj1, vector.Get(2));
+ CHECK_EQ(obj1, vector.Get(4));
+ CHECK_EQ(obj2, vector.Get(1));
+
+ CHECK_EQ(5 + handle_count, global_handles->global_handles_count());
+
+ vector.Clear();
+ CHECK(vector.IsEmpty());
+ CHECK_EQ(0, static_cast<int>(vector.Size()));
+ CHECK_EQ(handle_count, global_handles->global_handles_count());
}
v8::Persistent<Value>::Cast(global_string);
CHECK(v8::Local<v8::Value>::New(isolate, global_value)->IsString());
CHECK(global_string == v8::Persistent<String>::Cast(global_value));
- global_string.Dispose();
+ global_string.Reset();
}
CHECK_EQ(local1 == anotherLocal1, true);
CHECK_EQ(local1 != anotherLocal1, false);
}
- global1.Dispose();
- global2.Dispose();
+ global1.Reset();
+ global2.Reset();
}
template<typename T>
-static void WeakPointerCallback(v8::Isolate* isolate,
- Persistent<T>* handle,
- WeakCallCounter* counter) {
- CHECK_EQ(1234, counter->id());
- counter->increment();
- handle->Dispose();
+struct WeakCallCounterAndPersistent {
+ explicit WeakCallCounterAndPersistent(WeakCallCounter* counter)
+ : counter(counter) {}
+ WeakCallCounter* counter;
+ v8::Persistent<T> handle;
+};
+
+
+template <typename T>
+static void WeakPointerCallback(
+ const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T> >& data) {
+ CHECK_EQ(1234, data.GetParameter()->counter->id());
+ data.GetParameter()->counter->increment();
+ data.GetParameter()->handle.Reset();
}
v8::Isolate* iso = env->GetIsolate();
HandleScope scope(iso);
- Persistent<Value> g1s1;
- Persistent<Value> g1s2;
- Persistent<Value> g1c1;
- Persistent<Value> g2s1;
- Persistent<Value> g2s2;
- Persistent<Value> g2c1;
-
WeakCallCounter counter(1234);
+ WeakCallCounterAndPersistent<Value> g1s1(&counter);
+ WeakCallCounterAndPersistent<Value> g1s2(&counter);
+ WeakCallCounterAndPersistent<Value> g1c1(&counter);
+ WeakCallCounterAndPersistent<Value> g2s1(&counter);
+ WeakCallCounterAndPersistent<Value> g2s2(&counter);
+ WeakCallCounterAndPersistent<Value> g2c1(&counter);
+
{
HandleScope scope(iso);
- g1s1.Reset(iso, Object::New());
- g1s2.Reset(iso, Object::New());
- g1c1.Reset(iso, Object::New());
- g1s1.MakeWeak(&counter, &WeakPointerCallback);
- g1s2.MakeWeak(&counter, &WeakPointerCallback);
- g1c1.MakeWeak(&counter, &WeakPointerCallback);
+ g1s1.handle.Reset(iso, Object::New(iso));
+ g1s2.handle.Reset(iso, Object::New(iso));
+ g1c1.handle.Reset(iso, Object::New(iso));
+ g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
+ g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
+ g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
- g2s1.Reset(iso, Object::New());
- g2s2.Reset(iso, Object::New());
- g2c1.Reset(iso, Object::New());
- g2s1.MakeWeak(&counter, &WeakPointerCallback);
- g2s2.MakeWeak(&counter, &WeakPointerCallback);
- g2c1.MakeWeak(&counter, &WeakPointerCallback);
+ g2s1.handle.Reset(iso, Object::New(iso));
+ g2s2.handle.Reset(iso, Object::New(iso));
+ g2c1.handle.Reset(iso, Object::New(iso));
+ g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
+ g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
+ g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
}
- Persistent<Value> root(iso, g1s1); // make a root.
+ WeakCallCounterAndPersistent<Value> root(&counter);
+ root.handle.Reset(iso, g1s1.handle); // make a root.
// Connect group 1 and 2, make a cycle.
{
HandleScope scope(iso);
- CHECK(Local<Object>::New(iso, g1s2.As<Object>())->
- Set(0, Local<Value>::New(iso, g2s2)));
- CHECK(Local<Object>::New(iso, g2s1.As<Object>())->
- Set(0, Local<Value>::New(iso, g1s1)));
+ CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>())->
+ Set(0, Local<Value>::New(iso, g2s2.handle)));
+ CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>())->
+ Set(0, Local<Value>::New(iso, g1s1.handle)));
}
{
- UniqueId id1 = MakeUniqueId(g1s1);
- UniqueId id2 = MakeUniqueId(g2s2);
- iso->SetObjectGroupId(g1s1, id1);
- iso->SetObjectGroupId(g1s2, id1);
- iso->SetReferenceFromGroup(id1, g1c1);
- iso->SetObjectGroupId(g2s1, id2);
- iso->SetObjectGroupId(g2s2, id2);
- iso->SetReferenceFromGroup(id2, g2c1);
+ UniqueId id1 = MakeUniqueId(g1s1.handle);
+ UniqueId id2 = MakeUniqueId(g2s2.handle);
+ iso->SetObjectGroupId(g1s1.handle, id1);
+ iso->SetObjectGroupId(g1s2.handle, id1);
+ iso->SetReferenceFromGroup(id1, g1c1.handle);
+ iso->SetObjectGroupId(g2s1.handle, id2);
+ iso->SetObjectGroupId(g2s2.handle, id2);
+ iso->SetReferenceFromGroup(id2, g2c1.handle);
}
// Do a single full GC, ensure incremental marking is stopped.
v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
CHECK_EQ(0, counter.NumberOfWeakCalls());
// Weaken the root.
- root.MakeWeak(&counter, &WeakPointerCallback);
+ root.handle.SetWeak(&root, &WeakPointerCallback);
// But make children strong roots---all the objects (except for children)
// should be collectable now.
- g1c1.ClearWeak();
- g2c1.ClearWeak();
+ g1c1.handle.ClearWeak();
+ g2c1.handle.ClearWeak();
// Groups are deleted, rebuild groups.
{
- UniqueId id1 = MakeUniqueId(g1s1);
- UniqueId id2 = MakeUniqueId(g2s2);
- iso->SetObjectGroupId(g1s1, id1);
- iso->SetObjectGroupId(g1s2, id1);
- iso->SetReferenceFromGroup(id1, g1c1);
- iso->SetObjectGroupId(g2s1, id2);
- iso->SetObjectGroupId(g2s2, id2);
- iso->SetReferenceFromGroup(id2, g2c1);
+ UniqueId id1 = MakeUniqueId(g1s1.handle);
+ UniqueId id2 = MakeUniqueId(g2s2.handle);
+ iso->SetObjectGroupId(g1s1.handle, id1);
+ iso->SetObjectGroupId(g1s2.handle, id1);
+ iso->SetReferenceFromGroup(id1, g1c1.handle);
+ iso->SetObjectGroupId(g2s1.handle, id2);
+ iso->SetObjectGroupId(g2s2.handle, id2);
+ iso->SetReferenceFromGroup(id2, g2c1.handle);
}
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(5, counter.NumberOfWeakCalls());
// And now make children weak again and collect them.
- g1c1.MakeWeak(&counter, &WeakPointerCallback);
- g2c1.MakeWeak(&counter, &WeakPointerCallback);
+ g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
+ g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(7, counter.NumberOfWeakCalls());
v8::Isolate* iso = env->GetIsolate();
HandleScope scope(iso);
- Persistent<Object> g1s1;
- Persistent<String> g1s2;
- Persistent<String> g1c1;
- Persistent<Object> g2s1;
- Persistent<String> g2s2;
- Persistent<String> g2c1;
-
WeakCallCounter counter(1234);
+ WeakCallCounterAndPersistent<Object> g1s1(&counter);
+ WeakCallCounterAndPersistent<String> g1s2(&counter);
+ WeakCallCounterAndPersistent<String> g1c1(&counter);
+ WeakCallCounterAndPersistent<Object> g2s1(&counter);
+ WeakCallCounterAndPersistent<String> g2s2(&counter);
+ WeakCallCounterAndPersistent<String> g2c1(&counter);
+
{
HandleScope scope(iso);
- g1s1.Reset(iso, Object::New());
- g1s2.Reset(iso, String::New("foo1"));
- g1c1.Reset(iso, String::New("foo2"));
- g1s1.MakeWeak(&counter, &WeakPointerCallback);
- g1s2.MakeWeak(&counter, &WeakPointerCallback);
- g1c1.MakeWeak(&counter, &WeakPointerCallback);
+ g1s1.handle.Reset(iso, Object::New(iso));
+ g1s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo1"));
+ g1c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo2"));
+ g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
+ g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
+ g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
- g2s1.Reset(iso, Object::New());
- g2s2.Reset(iso, String::New("foo3"));
- g2c1.Reset(iso, String::New("foo4"));
- g2s1.MakeWeak(&counter, &WeakPointerCallback);
- g2s2.MakeWeak(&counter, &WeakPointerCallback);
- g2c1.MakeWeak(&counter, &WeakPointerCallback);
+ g2s1.handle.Reset(iso, Object::New(iso));
+ g2s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo3"));
+ g2c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo4"));
+ g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
+ g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
+ g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
}
- Persistent<Value> root(iso, g1s1); // make a root.
+ WeakCallCounterAndPersistent<Value> root(&counter);
+ root.handle.Reset(iso, g1s1.handle); // make a root.
// Connect group 1 and 2, make a cycle.
{
HandleScope scope(iso);
- CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1)));
- CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1)));
+ CHECK(Local<Object>::New(iso, g1s1.handle)
+ ->Set(0, Local<Object>::New(iso, g2s1.handle)));
+ CHECK(Local<Object>::New(iso, g2s1.handle)
+ ->Set(0, Local<Object>::New(iso, g1s1.handle)));
}
{
- UniqueId id1 = MakeUniqueId(g1s1);
- UniqueId id2 = MakeUniqueId(g2s2);
- iso->SetObjectGroupId(g1s1, id1);
- iso->SetObjectGroupId(g1s2, id1);
- iso->SetReference(g1s1, g1c1);
- iso->SetObjectGroupId(g2s1, id2);
- iso->SetObjectGroupId(g2s2, id2);
- iso->SetReferenceFromGroup(id2, g2c1);
+ UniqueId id1 = MakeUniqueId(g1s1.handle);
+ UniqueId id2 = MakeUniqueId(g2s2.handle);
+ iso->SetObjectGroupId(g1s1.handle, id1);
+ iso->SetObjectGroupId(g1s2.handle, id1);
+ iso->SetReference(g1s1.handle, g1c1.handle);
+ iso->SetObjectGroupId(g2s1.handle, id2);
+ iso->SetObjectGroupId(g2s2.handle, id2);
+ iso->SetReferenceFromGroup(id2, g2c1.handle);
}
// Do a single full GC, ensure incremental marking is stopped.
v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
CHECK_EQ(0, counter.NumberOfWeakCalls());
// Weaken the root.
- root.MakeWeak(&counter, &WeakPointerCallback);
+ root.handle.SetWeak(&root, &WeakPointerCallback);
// But make children strong roots---all the objects (except for children)
// should be collectable now.
- g1c1.ClearWeak();
- g2c1.ClearWeak();
+ g1c1.handle.ClearWeak();
+ g2c1.handle.ClearWeak();
// Groups are deleted, rebuild groups.
{
- UniqueId id1 = MakeUniqueId(g1s1);
- UniqueId id2 = MakeUniqueId(g2s2);
- iso->SetObjectGroupId(g1s1, id1);
- iso->SetObjectGroupId(g1s2, id1);
- iso->SetReference(g1s1, g1c1);
- iso->SetObjectGroupId(g2s1, id2);
- iso->SetObjectGroupId(g2s2, id2);
- iso->SetReferenceFromGroup(id2, g2c1);
+ UniqueId id1 = MakeUniqueId(g1s1.handle);
+ UniqueId id2 = MakeUniqueId(g2s2.handle);
+ iso->SetObjectGroupId(g1s1.handle, id1);
+ iso->SetObjectGroupId(g1s2.handle, id1);
+ iso->SetReference(g1s1.handle, g1c1.handle);
+ iso->SetObjectGroupId(g2s1.handle, id2);
+ iso->SetObjectGroupId(g2s2.handle, id2);
+ iso->SetReferenceFromGroup(id2, g2c1.handle);
}
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(5, counter.NumberOfWeakCalls());
// And now make children weak again and collect them.
- g1c1.MakeWeak(&counter, &WeakPointerCallback);
- g2c1.MakeWeak(&counter, &WeakPointerCallback);
+ g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
+ g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(7, counter.NumberOfWeakCalls());
WeakCallCounter counter(1234);
- Persistent<Value> g1s1;
- Persistent<Value> g1s2;
- Persistent<Value> g2s1;
- Persistent<Value> g2s2;
- Persistent<Value> g3s1;
- Persistent<Value> g3s2;
- Persistent<Value> g4s1;
- Persistent<Value> g4s2;
+ WeakCallCounterAndPersistent<Value> g1s1(&counter);
+ WeakCallCounterAndPersistent<Value> g1s2(&counter);
+ WeakCallCounterAndPersistent<Value> g2s1(&counter);
+ WeakCallCounterAndPersistent<Value> g2s2(&counter);
+ WeakCallCounterAndPersistent<Value> g3s1(&counter);
+ WeakCallCounterAndPersistent<Value> g3s2(&counter);
+ WeakCallCounterAndPersistent<Value> g4s1(&counter);
+ WeakCallCounterAndPersistent<Value> g4s2(&counter);
{
HandleScope scope(iso);
- g1s1.Reset(iso, Object::New());
- g1s2.Reset(iso, Object::New());
- g1s1.MakeWeak(&counter, &WeakPointerCallback);
- g1s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g1s1.IsWeak());
- CHECK(g1s2.IsWeak());
-
- g2s1.Reset(iso, Object::New());
- g2s2.Reset(iso, Object::New());
- g2s1.MakeWeak(&counter, &WeakPointerCallback);
- g2s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g2s1.IsWeak());
- CHECK(g2s2.IsWeak());
-
- g3s1.Reset(iso, Object::New());
- g3s2.Reset(iso, Object::New());
- g3s1.MakeWeak(&counter, &WeakPointerCallback);
- g3s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g3s1.IsWeak());
- CHECK(g3s2.IsWeak());
-
- g4s1.Reset(iso, Object::New());
- g4s2.Reset(iso, Object::New());
- g4s1.MakeWeak(&counter, &WeakPointerCallback);
- g4s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g4s1.IsWeak());
- CHECK(g4s2.IsWeak());
- }
-
- Persistent<Value> root(iso, g1s1); // make a root.
+ g1s1.handle.Reset(iso, Object::New(iso));
+ g1s2.handle.Reset(iso, Object::New(iso));
+ g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
+ g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
+ CHECK(g1s1.handle.IsWeak());
+ CHECK(g1s2.handle.IsWeak());
+
+ g2s1.handle.Reset(iso, Object::New(iso));
+ g2s2.handle.Reset(iso, Object::New(iso));
+ g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
+ g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
+ CHECK(g2s1.handle.IsWeak());
+ CHECK(g2s2.handle.IsWeak());
+
+ g3s1.handle.Reset(iso, Object::New(iso));
+ g3s2.handle.Reset(iso, Object::New(iso));
+ g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback);
+ g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback);
+ CHECK(g3s1.handle.IsWeak());
+ CHECK(g3s2.handle.IsWeak());
+
+ g4s1.handle.Reset(iso, Object::New(iso));
+ g4s2.handle.Reset(iso, Object::New(iso));
+ g4s1.handle.SetWeak(&g4s1, &WeakPointerCallback);
+ g4s2.handle.SetWeak(&g4s2, &WeakPointerCallback);
+ CHECK(g4s1.handle.IsWeak());
+ CHECK(g4s2.handle.IsWeak());
+ }
+
+ WeakCallCounterAndPersistent<Value> root(&counter);
+ root.handle.Reset(iso, g1s1.handle); // make a root.
// Connect groups. We're building the following cycle:
// G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
// groups.
{
- UniqueId id1 = MakeUniqueId(g1s1);
- UniqueId id2 = MakeUniqueId(g2s1);
- UniqueId id3 = MakeUniqueId(g3s1);
- UniqueId id4 = MakeUniqueId(g4s1);
- iso->SetObjectGroupId(g1s1, id1);
- iso->SetObjectGroupId(g1s2, id1);
- iso->SetReferenceFromGroup(id1, g2s1);
- iso->SetObjectGroupId(g2s1, id2);
- iso->SetObjectGroupId(g2s2, id2);
- iso->SetReferenceFromGroup(id2, g3s1);
- iso->SetObjectGroupId(g3s1, id3);
- iso->SetObjectGroupId(g3s2, id3);
- iso->SetReferenceFromGroup(id3, g4s1);
- iso->SetObjectGroupId(g4s1, id4);
- iso->SetObjectGroupId(g4s2, id4);
- iso->SetReferenceFromGroup(id4, g1s1);
+ UniqueId id1 = MakeUniqueId(g1s1.handle);
+ UniqueId id2 = MakeUniqueId(g2s1.handle);
+ UniqueId id3 = MakeUniqueId(g3s1.handle);
+ UniqueId id4 = MakeUniqueId(g4s1.handle);
+ iso->SetObjectGroupId(g1s1.handle, id1);
+ iso->SetObjectGroupId(g1s2.handle, id1);
+ iso->SetReferenceFromGroup(id1, g2s1.handle);
+ iso->SetObjectGroupId(g2s1.handle, id2);
+ iso->SetObjectGroupId(g2s2.handle, id2);
+ iso->SetReferenceFromGroup(id2, g3s1.handle);
+ iso->SetObjectGroupId(g3s1.handle, id3);
+ iso->SetObjectGroupId(g3s2.handle, id3);
+ iso->SetReferenceFromGroup(id3, g4s1.handle);
+ iso->SetObjectGroupId(g4s1.handle, id4);
+ iso->SetObjectGroupId(g4s2.handle, id4);
+ iso->SetReferenceFromGroup(id4, g1s1.handle);
}
// Do a single full GC
v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
CHECK_EQ(0, counter.NumberOfWeakCalls());
// Weaken the root.
- root.MakeWeak(&counter, &WeakPointerCallback);
+ root.handle.SetWeak(&root, &WeakPointerCallback);
// Groups are deleted, rebuild groups.
{
- UniqueId id1 = MakeUniqueId(g1s1);
- UniqueId id2 = MakeUniqueId(g2s1);
- UniqueId id3 = MakeUniqueId(g3s1);
- UniqueId id4 = MakeUniqueId(g4s1);
- iso->SetObjectGroupId(g1s1, id1);
- iso->SetObjectGroupId(g1s2, id1);
- iso->SetReferenceFromGroup(id1, g2s1);
- iso->SetObjectGroupId(g2s1, id2);
- iso->SetObjectGroupId(g2s2, id2);
- iso->SetReferenceFromGroup(id2, g3s1);
- iso->SetObjectGroupId(g3s1, id3);
- iso->SetObjectGroupId(g3s2, id3);
- iso->SetReferenceFromGroup(id3, g4s1);
- iso->SetObjectGroupId(g4s1, id4);
- iso->SetObjectGroupId(g4s2, id4);
- iso->SetReferenceFromGroup(id4, g1s1);
+ UniqueId id1 = MakeUniqueId(g1s1.handle);
+ UniqueId id2 = MakeUniqueId(g2s1.handle);
+ UniqueId id3 = MakeUniqueId(g3s1.handle);
+ UniqueId id4 = MakeUniqueId(g4s1.handle);
+ iso->SetObjectGroupId(g1s1.handle, id1);
+ iso->SetObjectGroupId(g1s2.handle, id1);
+ iso->SetReferenceFromGroup(id1, g2s1.handle);
+ iso->SetObjectGroupId(g2s1.handle, id2);
+ iso->SetObjectGroupId(g2s2.handle, id2);
+ iso->SetReferenceFromGroup(id2, g3s1.handle);
+ iso->SetObjectGroupId(g3s1.handle, id3);
+ iso->SetObjectGroupId(g3s2.handle, id3);
+ iso->SetReferenceFromGroup(id3, g4s1.handle);
+ iso->SetObjectGroupId(g4s1.handle, id4);
+ iso->SetObjectGroupId(g4s2.handle, id4);
+ iso->SetReferenceFromGroup(id4, g1s1.handle);
}
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
WeakCallCounter counter(1234);
- Persistent<Value> g1s1;
- Persistent<Value> g1s2;
- Persistent<Value> g2s1;
- Persistent<Value> g2s2;
- Persistent<Value> g3s1;
- Persistent<Value> g3s2;
+ WeakCallCounterAndPersistent<Value> g1s1(&counter);
+ WeakCallCounterAndPersistent<Value> g1s2(&counter);
+ WeakCallCounterAndPersistent<Value> g2s1(&counter);
+ WeakCallCounterAndPersistent<Value> g2s2(&counter);
+ WeakCallCounterAndPersistent<Value> g3s1(&counter);
+ WeakCallCounterAndPersistent<Value> g3s2(&counter);
{
HandleScope scope(iso);
- g1s1.Reset(iso, Object::New());
- g1s2.Reset(iso, Object::New());
- g1s1.MakeWeak(&counter, &WeakPointerCallback);
- g1s2.MakeWeak(&counter, &WeakPointerCallback);
+ g1s1.handle.Reset(iso, Object::New(iso));
+ g1s2.handle.Reset(iso, Object::New(iso));
+ g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
+ g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
- g2s1.Reset(iso, Object::New());
- g2s2.Reset(iso, Object::New());
- g2s1.MakeWeak(&counter, &WeakPointerCallback);
- g2s2.MakeWeak(&counter, &WeakPointerCallback);
+ g2s1.handle.Reset(iso, Object::New(iso));
+ g2s2.handle.Reset(iso, Object::New(iso));
+ g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
+ g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
- g3s1.Reset(iso, Object::New());
- g3s2.Reset(iso, Object::New());
- g3s1.MakeWeak(&counter, &WeakPointerCallback);
- g3s2.MakeWeak(&counter, &WeakPointerCallback);
+ g3s1.handle.Reset(iso, Object::New(iso));
+ g3s2.handle.Reset(iso, Object::New(iso));
+ g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback);
+ g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback);
}
// Make a root.
- Persistent<Value> root(iso, g1s1);
- root.MarkPartiallyDependent();
+ WeakCallCounterAndPersistent<Value> root(&counter);
+ root.handle.Reset(iso, g1s1.handle);
+ root.handle.MarkPartiallyDependent();
// 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();
- g1s2.MarkPartiallyDependent();
- g2s1.MarkPartiallyDependent();
- g2s2.MarkPartiallyDependent();
- g3s1.MarkPartiallyDependent();
- g3s2.MarkPartiallyDependent();
- iso->SetObjectGroupId(g1s1, UniqueId(1));
- iso->SetObjectGroupId(g1s2, UniqueId(1));
- Local<Object>::New(iso, g1s1.As<Object>())->Set(
- v8_str("x"), Local<Value>::New(iso, g2s1));
- iso->SetObjectGroupId(g2s1, UniqueId(2));
- iso->SetObjectGroupId(g2s2, UniqueId(2));
- Local<Object>::New(iso, g2s1.As<Object>())->Set(
- v8_str("x"), Local<Value>::New(iso, g3s1));
- iso->SetObjectGroupId(g3s1, UniqueId(3));
- iso->SetObjectGroupId(g3s2, UniqueId(3));
- Local<Object>::New(iso, g3s1.As<Object>())->Set(
- v8_str("x"), Local<Value>::New(iso, g1s1));
+ g1s1.handle.MarkPartiallyDependent();
+ g1s2.handle.MarkPartiallyDependent();
+ g2s1.handle.MarkPartiallyDependent();
+ g2s2.handle.MarkPartiallyDependent();
+ g3s1.handle.MarkPartiallyDependent();
+ g3s2.handle.MarkPartiallyDependent();
+ iso->SetObjectGroupId(g1s1.handle, UniqueId(1));
+ iso->SetObjectGroupId(g1s2.handle, UniqueId(1));
+ Local<Object>::New(iso, g1s1.handle.As<Object>())->Set(
+ v8_str("x"), Local<Value>::New(iso, g2s1.handle));
+ iso->SetObjectGroupId(g2s1.handle, UniqueId(2));
+ iso->SetObjectGroupId(g2s2.handle, UniqueId(2));
+ Local<Object>::New(iso, g2s1.handle.As<Object>())->Set(
+ v8_str("x"), Local<Value>::New(iso, g3s1.handle));
+ iso->SetObjectGroupId(g3s1.handle, UniqueId(3));
+ iso->SetObjectGroupId(g3s2.handle, UniqueId(3));
+ Local<Object>::New(iso, g3s1.handle.As<Object>())->Set(
+ v8_str("x"), Local<Value>::New(iso, g1s1.handle));
}
v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
iso)->heap();
- heap->CollectGarbage(i::NEW_SPACE);
+ heap->CollectAllGarbage(i::Heap::kNoGCFlags);
// All objects should be alive.
CHECK_EQ(0, counter.NumberOfWeakCalls());
// Weaken the root.
- root.MakeWeak(&counter, &WeakPointerCallback);
- root.MarkPartiallyDependent();
+ root.handle.SetWeak(&root, &WeakPointerCallback);
+ root.handle.MarkPartiallyDependent();
// Groups are deleted, rebuild groups.
{
HandleScope handle_scope(iso);
- g1s1.MarkPartiallyDependent();
- g1s2.MarkPartiallyDependent();
- g2s1.MarkPartiallyDependent();
- g2s2.MarkPartiallyDependent();
- g3s1.MarkPartiallyDependent();
- g3s2.MarkPartiallyDependent();
- iso->SetObjectGroupId(g1s1, UniqueId(1));
- iso->SetObjectGroupId(g1s2, UniqueId(1));
- Local<Object>::New(iso, g1s1.As<Object>())->Set(
- v8_str("x"), Local<Value>::New(iso, g2s1));
- iso->SetObjectGroupId(g2s1, UniqueId(2));
- iso->SetObjectGroupId(g2s2, UniqueId(2));
- Local<Object>::New(iso, g2s1.As<Object>())->Set(
- v8_str("x"), Local<Value>::New(iso, g3s1));
- iso->SetObjectGroupId(g3s1, UniqueId(3));
- iso->SetObjectGroupId(g3s2, UniqueId(3));
- Local<Object>::New(iso, g3s1.As<Object>())->Set(
- v8_str("x"), Local<Value>::New(iso, g1s1));
- }
-
- heap->CollectGarbage(i::NEW_SPACE);
+ g1s1.handle.MarkPartiallyDependent();
+ g1s2.handle.MarkPartiallyDependent();
+ g2s1.handle.MarkPartiallyDependent();
+ g2s2.handle.MarkPartiallyDependent();
+ g3s1.handle.MarkPartiallyDependent();
+ g3s2.handle.MarkPartiallyDependent();
+ iso->SetObjectGroupId(g1s1.handle, UniqueId(1));
+ iso->SetObjectGroupId(g1s2.handle, UniqueId(1));
+ Local<Object>::New(iso, g1s1.handle.As<Object>())->Set(
+ v8_str("x"), Local<Value>::New(iso, g2s1.handle));
+ iso->SetObjectGroupId(g2s1.handle, UniqueId(2));
+ iso->SetObjectGroupId(g2s2.handle, UniqueId(2));
+ Local<Object>::New(iso, g2s1.handle.As<Object>())->Set(
+ v8_str("x"), Local<Value>::New(iso, g3s1.handle));
+ iso->SetObjectGroupId(g3s1.handle, UniqueId(3));
+ iso->SetObjectGroupId(g3s2.handle, UniqueId(3));
+ Local<Object>::New(iso, g3s1.handle.As<Object>())->Set(
+ v8_str("x"), Local<Value>::New(iso, g1s1.handle));
+ }
+
+ heap->CollectAllGarbage(i::Heap::kNoGCFlags);
// All objects should be gone. 7 global handles in total.
CHECK_EQ(7, counter.NumberOfWeakCalls());
THREADED_TEST(ScriptException) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<Script> script = Script::Compile(v8_str("throw 'panama!';"));
+ Local<Script> script = v8_compile("throw 'panama!';");
v8::TryCatch try_catch;
Local<Value> result = script->Run();
CHECK(result.IsEmpty());
static void check_message_0(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK_EQ(5.76, data->NumberValue());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
- CHECK_EQ(7.56, message->GetScriptData()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
CHECK(!message->IsSharedCrossOrigin());
message_received = true;
}
message_received = false;
v8::HandleScope scope(CcTest::isolate());
CHECK(!message_received);
- v8::V8::AddMessageListener(check_message_0, v8_num(5.76));
LocalContext context;
- v8::ScriptOrigin origin =
- v8::ScriptOrigin(v8_str("6.75"));
- v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
- &origin);
- script->SetData(v8_str("7.56"));
+ v8::V8::AddMessageListener(check_message_0, v8_num(5.76));
+ v8::Handle<v8::Script> script = CompileWithOrigin("throw 'error'", "6.75");
script->Run();
CHECK(message_received);
// clear out the message listener
static void check_message_3(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
LocalContext context;
v8::ScriptOrigin origin =
v8::ScriptOrigin(v8_str("6.75"),
- v8::Integer::New(1, isolate),
- v8::Integer::New(2, isolate),
+ v8::Integer::New(isolate, 1),
+ v8::Integer::New(isolate, 2),
v8::True(isolate));
v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
&origin);
static void check_message_4(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(!message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
LocalContext context;
v8::ScriptOrigin origin =
v8::ScriptOrigin(v8_str("6.75"),
- v8::Integer::New(1, isolate),
- v8::Integer::New(2, isolate),
+ v8::Integer::New(isolate, 1),
+ v8::Integer::New(isolate, 2),
v8::False(isolate));
v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
&origin);
static void check_message_5a(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
static void check_message_5b(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(!message->IsSharedCrossOrigin());
- CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
message_received = true;
}
LocalContext context;
v8::ScriptOrigin origin =
v8::ScriptOrigin(v8_str("6.75"),
- v8::Integer::New(1, isolate),
- v8::Integer::New(2, isolate),
+ v8::Integer::New(isolate, 1),
+ v8::Integer::New(isolate, 2),
v8::True(isolate));
v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
&origin);
v8::V8::AddMessageListener(check_message_5b);
origin =
v8::ScriptOrigin(v8_str("6.75"),
- v8::Integer::New(1, isolate),
- v8::Integer::New(2, isolate),
+ v8::Integer::New(isolate, 1),
+ v8::Integer::New(isolate, 2),
v8::False(isolate));
script = Script::Compile(v8_str("throw 'error'"),
&origin);
THREADED_TEST(GetSetProperty) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
context->Global()->Set(v8_str("foo"), v8_num(14));
context->Global()->Set(v8_str("12"), v8_num(92));
- context->Global()->Set(v8::Integer::New(16), v8_num(32));
+ context->Global()->Set(v8::Integer::New(isolate, 16), v8_num(32));
context->Global()->Set(v8_num(13), v8_num(56));
- Local<Value> foo = Script::Compile(v8_str("this.foo"))->Run();
+ Local<Value> foo = CompileRun("this.foo");
CHECK_EQ(14, foo->Int32Value());
- Local<Value> twelve = Script::Compile(v8_str("this[12]"))->Run();
+ Local<Value> twelve = CompileRun("this[12]");
CHECK_EQ(92, twelve->Int32Value());
- Local<Value> sixteen = Script::Compile(v8_str("this[16]"))->Run();
+ Local<Value> sixteen = CompileRun("this[16]");
CHECK_EQ(32, sixteen->Int32Value());
- Local<Value> thirteen = Script::Compile(v8_str("this[13]"))->Run();
+ Local<Value> thirteen = CompileRun("this[13]");
CHECK_EQ(56, thirteen->Int32Value());
- CHECK_EQ(92, context->Global()->Get(v8::Integer::New(12))->Int32Value());
+ CHECK_EQ(92,
+ context->Global()->Get(v8::Integer::New(isolate, 12))->Int32Value());
CHECK_EQ(92, context->Global()->Get(v8_str("12"))->Int32Value());
CHECK_EQ(92, context->Global()->Get(v8_num(12))->Int32Value());
- CHECK_EQ(32, context->Global()->Get(v8::Integer::New(16))->Int32Value());
+ CHECK_EQ(32,
+ context->Global()->Get(v8::Integer::New(isolate, 16))->Int32Value());
CHECK_EQ(32, context->Global()->Get(v8_str("16"))->Int32Value());
CHECK_EQ(32, context->Global()->Get(v8_num(16))->Int32Value());
- CHECK_EQ(56, context->Global()->Get(v8::Integer::New(13))->Int32Value());
+ CHECK_EQ(56,
+ context->Global()->Get(v8::Integer::New(isolate, 13))->Int32Value());
CHECK_EQ(56, context->Global()->Get(v8_str("13"))->Int32Value());
CHECK_EQ(56, context->Global()->Get(v8_num(13))->Int32Value());
}
CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(prop));
// read-only
prop = v8_str("read_only");
- context->Global()->Set(prop, v8_num(7), v8::ReadOnly);
+ context->Global()->ForceSet(prop, v8_num(7), v8::ReadOnly);
CHECK_EQ(7, context->Global()->Get(prop)->Int32Value());
CHECK_EQ(v8::ReadOnly, context->Global()->GetPropertyAttributes(prop));
- Script::Compile(v8_str("read_only = 9"))->Run();
+ CompileRun("read_only = 9");
CHECK_EQ(7, context->Global()->Get(prop)->Int32Value());
context->Global()->Set(prop, v8_num(10));
CHECK_EQ(7, context->Global()->Get(prop)->Int32Value());
// dont-delete
prop = v8_str("dont_delete");
- context->Global()->Set(prop, v8_num(13), v8::DontDelete);
+ context->Global()->ForceSet(prop, v8_num(13), v8::DontDelete);
CHECK_EQ(13, context->Global()->Get(prop)->Int32Value());
- Script::Compile(v8_str("delete dont_delete"))->Run();
+ CompileRun("delete dont_delete");
CHECK_EQ(13, context->Global()->Get(prop)->Int32Value());
CHECK_EQ(v8::DontDelete, context->Global()->GetPropertyAttributes(prop));
// dont-enum
prop = v8_str("dont_enum");
- context->Global()->Set(prop, v8_num(28), v8::DontEnum);
+ context->Global()->ForceSet(prop, v8_num(28), v8::DontEnum);
CHECK_EQ(v8::DontEnum, context->Global()->GetPropertyAttributes(prop));
// absent
prop = v8_str("absent");
THREADED_TEST(Array) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Local<v8::Array> array = v8::Array::New();
+ Local<v8::Array> array = v8::Array::New(context->GetIsolate());
CHECK_EQ(0, array->Length());
CHECK(array->Get(0)->IsUndefined());
CHECK(!array->Has(0));
CHECK(!array->Has(1));
CHECK(array->Has(2));
CHECK_EQ(7, array->Get(2)->Int32Value());
- Local<Value> obj = Script::Compile(v8_str("[1, 2, 3]"))->Run();
+ Local<Value> obj = CompileRun("[1, 2, 3]");
Local<v8::Array> arr = obj.As<v8::Array>();
CHECK_EQ(3, arr->Length());
CHECK_EQ(1, arr->Get(0)->Int32Value());
CHECK_EQ(2, arr->Get(1)->Int32Value());
CHECK_EQ(3, arr->Get(2)->Int32Value());
- array = v8::Array::New(27);
+ array = v8::Array::New(context->GetIsolate(), 27);
CHECK_EQ(27, array->Length());
- array = v8::Array::New(-27);
+ array = v8::Array::New(context->GetIsolate(), -27);
CHECK_EQ(0, array->Length());
}
void HandleF(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::HandleScope scope(args.GetIsolate());
+ v8::EscapableHandleScope scope(args.GetIsolate());
ApiTestFuzzer::Fuzz();
- Local<v8::Array> result = v8::Array::New(args.Length());
+ Local<v8::Array> result = v8::Array::New(args.GetIsolate(), args.Length());
for (int i = 0; i < args.Length(); i++)
result->Set(i, args[i]);
- args.GetReturnValue().Set(scope.Close(result));
+ args.GetReturnValue().Set(scope.Escape(result));
}
THREADED_TEST(Vector) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> global = ObjectTemplate::New();
- global->Set(v8_str("f"), v8::FunctionTemplate::New(HandleF));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> global = ObjectTemplate::New(isolate);
+ global->Set(v8_str("f"), v8::FunctionTemplate::New(isolate, HandleF));
LocalContext context(0, global);
const char* fun = "f()";
v8::Handle<Value> args1[] = { v8_num(1.1) };
Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->Call(Foo, 1, args1));
CHECK_EQ(1, a1->Length());
- CHECK_EQ(1.1, a1->Get(v8::Integer::New(0))->NumberValue());
+ CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue());
v8::Handle<Value> args2[] = { v8_num(2.2),
v8_num(3.3) };
Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->Call(Foo, 2, args2));
CHECK_EQ(2, a2->Length());
- CHECK_EQ(2.2, a2->Get(v8::Integer::New(0))->NumberValue());
- CHECK_EQ(3.3, a2->Get(v8::Integer::New(1))->NumberValue());
+ CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue());
+ CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue());
v8::Handle<Value> args3[] = { v8_num(4.4),
v8_num(5.5),
v8_num(6.6) };
Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->Call(Foo, 3, args3));
CHECK_EQ(3, a3->Length());
- CHECK_EQ(4.4, a3->Get(v8::Integer::New(0))->NumberValue());
- CHECK_EQ(5.5, a3->Get(v8::Integer::New(1))->NumberValue());
- CHECK_EQ(6.6, a3->Get(v8::Integer::New(2))->NumberValue());
+ CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue());
+ CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue());
+ CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue());
v8::Handle<Value> args4[] = { v8_num(7.7),
v8_num(8.8),
v8_num(10.11) };
Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->Call(Foo, 4, args4));
CHECK_EQ(4, a4->Length());
- CHECK_EQ(7.7, a4->Get(v8::Integer::New(0))->NumberValue());
- CHECK_EQ(8.8, a4->Get(v8::Integer::New(1))->NumberValue());
- CHECK_EQ(9.9, a4->Get(v8::Integer::New(2))->NumberValue());
- CHECK_EQ(10.11, a4->Get(v8::Integer::New(3))->NumberValue());
+ CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue());
+ CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue());
+ CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue());
+ CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue());
Local<v8::Value> r1 = ReturnThisSloppy->Call(v8::Undefined(isolate), 0, NULL);
CHECK(r1->StrictEquals(context->Global()));
}
-static const char* js_code_causing_out_of_memory =
- "var a = new Array(); while(true) a.push(a);";
-
-
-// These tests run for a long time and prevent us from running tests
-// that come after them so they cannot run in parallel.
-TEST(OutOfMemory) {
- // It's not possible to read a snapshot into a heap with different dimensions.
- if (i::Snapshot::IsEnabled()) return;
- // Set heap limits.
- static const int K = 1024;
- v8::ResourceConstraints constraints;
- constraints.set_max_young_space_size(256 * K);
- constraints.set_max_old_space_size(5 * K * K);
- v8::SetResourceConstraints(&constraints);
-
- // Execute a script that causes out of memory.
- LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::V8::IgnoreOutOfMemoryException();
- Local<Script> script =
- Script::Compile(String::New(js_code_causing_out_of_memory));
- Local<Value> result = script->Run();
-
- // Check for out of memory state.
- CHECK(result.IsEmpty());
- CHECK(context->HasOutOfMemoryException());
-}
-
-
-void ProvokeOutOfMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
- ApiTestFuzzer::Fuzz();
-
- LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<Script> script =
- Script::Compile(String::New(js_code_causing_out_of_memory));
- Local<Value> result = script->Run();
-
- // Check for out of memory state.
- CHECK(result.IsEmpty());
- CHECK(context->HasOutOfMemoryException());
-
- args.GetReturnValue().Set(result);
-}
-
-
-TEST(OutOfMemoryNested) {
- // It's not possible to read a snapshot into a heap with different dimensions.
- if (i::Snapshot::IsEnabled()) return;
- // Set heap limits.
- static const int K = 1024;
- v8::ResourceConstraints constraints;
- constraints.set_max_young_space_size(256 * K);
- constraints.set_max_old_space_size(5 * K * K);
- v8::SetResourceConstraints(&constraints);
-
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
- templ->Set(v8_str("ProvokeOutOfMemory"),
- v8::FunctionTemplate::New(ProvokeOutOfMemory));
- LocalContext context(0, templ);
- v8::V8::IgnoreOutOfMemoryException();
- Local<Value> result = CompileRun(
- "var thrown = false;"
- "try {"
- " ProvokeOutOfMemory();"
- "} catch (e) {"
- " thrown = true;"
- "}");
- // Check for out of memory state.
- CHECK(result.IsEmpty());
- CHECK(context->HasOutOfMemoryException());
-}
-
-
-TEST(HugeConsStringOutOfMemory) {
- // It's not possible to read a snapshot into a heap with different dimensions.
- if (i::Snapshot::IsEnabled()) return;
- // Set heap limits.
- static const int K = 1024;
- v8::ResourceConstraints constraints;
- constraints.set_max_young_space_size(256 * K);
- constraints.set_max_old_space_size(4 * K * K);
- v8::SetResourceConstraints(&constraints);
-
- // Execute a script that causes out of memory.
- v8::V8::IgnoreOutOfMemoryException();
-
- LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
-
- // Build huge string. This should fail with out of memory exception.
- Local<Value> result = CompileRun(
- "var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();"
- "for (var i = 0; i < 22; i++) { str = str + str; }");
-
- // Check for out of memory state.
- CHECK(result.IsEmpty());
- CHECK(context->HasOutOfMemoryException());
-}
-
-
THREADED_TEST(ConstructCall) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
CompileRun(
"function Foo() {"
" var result = [];"
v8::Handle<Value> args1[] = { v8_num(1.1) };
Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->NewInstance(1, args1));
CHECK_EQ(1, a1->Length());
- CHECK_EQ(1.1, a1->Get(v8::Integer::New(0))->NumberValue());
+ CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue());
v8::Handle<Value> args2[] = { v8_num(2.2),
v8_num(3.3) };
Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->NewInstance(2, args2));
CHECK_EQ(2, a2->Length());
- CHECK_EQ(2.2, a2->Get(v8::Integer::New(0))->NumberValue());
- CHECK_EQ(3.3, a2->Get(v8::Integer::New(1))->NumberValue());
+ CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue());
+ CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue());
v8::Handle<Value> args3[] = { v8_num(4.4),
v8_num(5.5),
v8_num(6.6) };
Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->NewInstance(3, args3));
CHECK_EQ(3, a3->Length());
- CHECK_EQ(4.4, a3->Get(v8::Integer::New(0))->NumberValue());
- CHECK_EQ(5.5, a3->Get(v8::Integer::New(1))->NumberValue());
- CHECK_EQ(6.6, a3->Get(v8::Integer::New(2))->NumberValue());
+ CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue());
+ CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue());
+ CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue());
v8::Handle<Value> args4[] = { v8_num(7.7),
v8_num(8.8),
v8_num(10.11) };
Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->NewInstance(4, args4));
CHECK_EQ(4, a4->Length());
- CHECK_EQ(7.7, a4->Get(v8::Integer::New(0))->NumberValue());
- CHECK_EQ(8.8, a4->Get(v8::Integer::New(1))->NumberValue());
- CHECK_EQ(9.9, a4->Get(v8::Integer::New(2))->NumberValue());
- CHECK_EQ(10.11, a4->Get(v8::Integer::New(3))->NumberValue());
+ CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue());
+ CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue());
+ CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue());
+ CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue());
}
}
v8::HandleScope scope(args.GetIsolate());
v8::TryCatch try_catch;
- Local<Value> result = v8::Script::Compile(args[0]->ToString())->Run();
+ Local<Value> result = CompileRun(args[0]->ToString());
CHECK(!try_catch.HasCaught() || result.IsEmpty());
args.GetReturnValue().Set(try_catch.HasCaught());
}
THREADED_TEST(APICatch) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("ThrowFromC"),
- v8::FunctionTemplate::New(ThrowFromC));
+ v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
CompileRun(
"var thrown = false;"
THREADED_TEST(APIThrowTryCatch) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("ThrowFromC"),
- v8::FunctionTemplate::New(ThrowFromC));
+ v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
v8::TryCatch try_catch;
CompileRun("ThrowFromC();");
// JS stack. This test therefore fails on the simulator. The test is
// not threaded to allow the threading tests to run on the simulator.
TEST(TryCatchInTryFinally) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("CCatcher"),
- v8::FunctionTemplate::New(CCatcher));
+ v8::FunctionTemplate::New(isolate, CCatcher));
LocalContext context(0, templ);
Local<Value> result = CompileRun("try {"
" try {"
// formatting. However, they are invoked when performing normal error
// string conversions.
TEST(APIThrowMessageOverwrittenToString) {
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
v8::V8::AddMessageListener(check_reference_error_message);
- Local<ObjectTemplate> templ = ObjectTemplate::New();
- templ->Set(v8_str("fail"), v8::FunctionTemplate::New(Fail));
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("fail"), v8::FunctionTemplate::New(isolate, Fail));
LocalContext context(NULL, templ);
CompileRun("asdf;");
CompileRun("var limit = {};"
TEST(APIThrowMessage) {
message_received = false;
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
v8::V8::AddMessageListener(receive_message);
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("ThrowFromC"),
- v8::FunctionTemplate::New(ThrowFromC));
+ v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
CompileRun("ThrowFromC();");
CHECK(message_received);
TEST(APIThrowMessageAndVerboseTryCatch) {
message_received = false;
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
v8::V8::AddMessageListener(receive_message);
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("ThrowFromC"),
- v8::FunctionTemplate::New(ThrowFromC));
+ v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
THREADED_TEST(ExternalScriptException) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("ThrowFromC"),
- v8::FunctionTemplate::New(ThrowFromC));
+ v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
v8::TryCatch try_catch;
- Local<Script> script
- = Script::Compile(v8_str("ThrowFromC(); throw 'panama';"));
- Local<Value> result = script->Run();
+ Local<Value> result = CompileRun("ThrowFromC(); throw 'panama';");
CHECK(result.IsEmpty());
CHECK(try_catch.HasCaught());
String::Utf8Value exception_value(try_catch.Exception());
// JS stack. This test therefore fails on the simulator. The test is
// not threaded to allow the threading tests to run on the simulator.
TEST(ExceptionOrder) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
- templ->Set(v8_str("check"), v8::FunctionTemplate::New(JSCheck));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("check"), v8::FunctionTemplate::New(isolate, JSCheck));
templ->Set(v8_str("CThrowCountDown"),
- v8::FunctionTemplate::New(CThrowCountDown));
+ v8::FunctionTemplate::New(isolate, CThrowCountDown));
LocalContext context(0, templ);
CompileRun(
"function JSThrowCountDown(count, jsInterval, cInterval, expected) {"
THREADED_TEST(ThrowValues) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
- templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(ThrowValue));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(isolate, ThrowValue));
LocalContext context(0, templ);
v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun(
"function Run(obj) {"
"}"
"[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];"));
CHECK_EQ(5, result->Length());
- CHECK(result->Get(v8::Integer::New(0))->IsString());
- CHECK(result->Get(v8::Integer::New(1))->IsNumber());
- CHECK_EQ(1, result->Get(v8::Integer::New(1))->Int32Value());
- CHECK(result->Get(v8::Integer::New(2))->IsNumber());
- CHECK_EQ(0, result->Get(v8::Integer::New(2))->Int32Value());
- CHECK(result->Get(v8::Integer::New(3))->IsNull());
- CHECK(result->Get(v8::Integer::New(4))->IsUndefined());
+ CHECK(result->Get(v8::Integer::New(isolate, 0))->IsString());
+ CHECK(result->Get(v8::Integer::New(isolate, 1))->IsNumber());
+ CHECK_EQ(1, result->Get(v8::Integer::New(isolate, 1))->Int32Value());
+ CHECK(result->Get(v8::Integer::New(isolate, 2))->IsNumber());
+ CHECK_EQ(0, result->Get(v8::Integer::New(isolate, 2))->Int32Value());
+ CHECK(result->Get(v8::Integer::New(isolate, 3))->IsNull());
+ CHECK(result->Get(v8::Integer::New(isolate, 4))->IsUndefined());
}
v8::HandleScope scope(context->GetIsolate());
v8::TryCatch try_catch;
CHECK(!try_catch.HasCaught());
- Script::Compile(v8_str("throw 10"))->Run();
+ CompileRun("throw 10");
CHECK(try_catch.HasCaught());
CHECK_EQ(10, try_catch.Exception()->Int32Value());
try_catch.Reset();
CHECK(!try_catch.HasCaught());
- Script::Compile(v8_str("throw 0"))->Run();
+ CompileRun("throw 0");
CHECK(try_catch.HasCaught());
CHECK_EQ(0, try_catch.Exception()->Int32Value());
}
v8::HandleScope scope(context->GetIsolate());
v8::TryCatch try_catch;
CHECK(!try_catch.HasCaught());
- Script::Compile(v8_str("var o = {}; with (o) { throw 42; }"))->Run();
+ CompileRun("var o = {}; with (o) { throw 42; }");
CHECK(try_catch.HasCaught());
}
THREADED_TEST(TryCatchAndFinally) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
context->Global()->Set(
v8_str("native_with_try_catch"),
- v8::FunctionTemplate::New(WithTryCatch)->GetFunction());
+ v8::FunctionTemplate::New(isolate, WithTryCatch)->GetFunction());
v8::TryCatch try_catch;
CHECK(!try_catch.HasCaught());
CompileRun(
}
-static void TryCatchNestedHelper(int depth) {
+static void TryCatchNested1Helper(int depth) {
+ if (depth > 0) {
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+ TryCatchNested1Helper(depth - 1);
+ CHECK(try_catch.HasCaught());
+ try_catch.ReThrow();
+ } else {
+ CcTest::isolate()->ThrowException(v8_str("E1"));
+ }
+}
+
+
+static void TryCatchNested2Helper(int depth) {
if (depth > 0) {
v8::TryCatch try_catch;
try_catch.SetVerbose(true);
- TryCatchNestedHelper(depth - 1);
+ TryCatchNested2Helper(depth - 1);
CHECK(try_catch.HasCaught());
try_catch.ReThrow();
} else {
- CcTest::isolate()->ThrowException(v8_str("back"));
+ CompileRun("throw 'E2';");
}
}
v8::V8::Initialize();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
- TryCatchNestedHelper(5);
- CHECK(try_catch.HasCaught());
- CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "back"));
+
+ {
+ // Test nested try-catch with a native throw in the end.
+ v8::TryCatch try_catch;
+ TryCatchNested1Helper(5);
+ CHECK(try_catch.HasCaught());
+ CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E1"));
+ }
+
+ {
+ // Test nested try-catch with a JavaScript throw in the end.
+ v8::TryCatch try_catch;
+ TryCatchNested2Helper(5);
+ CHECK(try_catch.HasCaught());
+ CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E2"));
+ }
}
void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) {
CHECK(try_catch->HasCaught());
Handle<Message> message = try_catch->Message();
- Handle<Value> resource = message->GetScriptResourceName();
+ Handle<Value> resource = message->GetScriptOrigin().ResourceName();
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(resource), "inner"));
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(message->Get()),
"Uncaught Error: a"));
// This exercises the ability of TryCatch.ReThrow() to restore the
// inner pending Message before throwing the exception again.
TEST(TryCatchMixedNesting) {
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
v8::V8::Initialize();
v8::TryCatch try_catch;
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("TryCatchMixedNestingHelper"),
- v8::FunctionTemplate::New(TryCatchMixedNestingHelper));
+ v8::FunctionTemplate::New(isolate, TryCatchMixedNestingHelper));
LocalContext context(0, templ);
CompileRunWithOrigin("TryCatchMixedNestingHelper();\n", "outer", 1, 1);
TryCatchMixedNestingCheck(&try_catch);
}
+void TryCatchNativeHelper(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ApiTestFuzzer::Fuzz();
+ v8::TryCatch try_catch;
+ args.GetIsolate()->ThrowException(v8_str("boom"));
+ CHECK(try_catch.HasCaught());
+}
+
+
+TEST(TryCatchNative) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::V8::Initialize();
+ v8::TryCatch try_catch;
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("TryCatchNativeHelper"),
+ v8::FunctionTemplate::New(isolate, TryCatchNativeHelper));
+ LocalContext context(0, templ);
+ CompileRun("TryCatchNativeHelper();");
+ CHECK(!try_catch.HasCaught());
+}
+
+
+void TryCatchNativeResetHelper(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ApiTestFuzzer::Fuzz();
+ v8::TryCatch try_catch;
+ args.GetIsolate()->ThrowException(v8_str("boom"));
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
+ CHECK(!try_catch.HasCaught());
+}
+
+
+TEST(TryCatchNativeReset) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::V8::Initialize();
+ v8::TryCatch try_catch;
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("TryCatchNativeResetHelper"),
+ v8::FunctionTemplate::New(isolate, TryCatchNativeResetHelper));
+ LocalContext context(0, templ);
+ CompileRun("TryCatchNativeResetHelper();");
+ CHECK(!try_catch.HasCaught());
+}
+
+
THREADED_TEST(Equality) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
CHECK(v8_num(1)->StrictEquals(v8_num(1)));
CHECK(!v8_num(1)->StrictEquals(v8_num(2)));
CHECK(v8_num(0.0)->StrictEquals(v8_num(-0.0)));
- Local<Value> not_a_number = v8_num(i::OS::nan_value());
+ Local<Value> not_a_number = v8_num(v8::base::OS::nan_value());
CHECK(!not_a_number->StrictEquals(not_a_number));
CHECK(v8::False(isolate)->StrictEquals(v8::False(isolate)));
CHECK(!v8::False(isolate)->StrictEquals(v8::Undefined(isolate)));
- v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::Handle<v8::Object> obj = v8::Object::New(isolate);
v8::Persistent<v8::Object> alias(isolate, obj);
CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj));
- alias.Dispose();
+ alias.Reset();
CHECK(v8_str("a")->SameValue(v8_str("a")));
CHECK(!v8_str("a")->SameValue(v8_str("b")));
THREADED_TEST(MultiRun) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Local<Script> script = Script::Compile(v8_str("x"));
+ Local<Script> script = v8_compile("x");
for (int i = 0; i < 10; i++)
script->Run();
}
THREADED_TEST(SimplePropertyRead) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"));
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> script = Script::Compile(v8_str("obj.x"));
+ Local<Script> script = v8_compile("obj.x");
for (int i = 0; i < 10; i++) {
Local<Value> result = script->Run();
CHECK_EQ(result, v8_str("x"));
THREADED_TEST(DefinePropertyOnAPIAccessor) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"));
context->Global()->Set(v8_str("obj"), templ->NewInstance());
// Uses getOwnPropertyDescriptor to check the configurable status
- Local<Script> script_desc
- = Script::Compile(v8_str("var prop = Object.getOwnPropertyDescriptor( "
- "obj, 'x');"
- "prop.configurable;"));
+ Local<Script> script_desc = v8_compile(
+ "var prop = Object.getOwnPropertyDescriptor( "
+ "obj, 'x');"
+ "prop.configurable;");
Local<Value> result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), true);
// Redefine get - but still configurable
- Local<Script> script_define
- = Script::Compile(v8_str("var desc = { get: function(){return 42; },"
- " configurable: true };"
- "Object.defineProperty(obj, 'x', desc);"
- "obj.x"));
+ Local<Script> script_define = v8_compile(
+ "var desc = { get: function(){return 42; },"
+ " configurable: true };"
+ "Object.defineProperty(obj, 'x', desc);"
+ "obj.x");
result = script_define->Run();
CHECK_EQ(result, v8_num(42));
CHECK_EQ(result->BooleanValue(), true);
// Redefine to a non-configurable
- script_define
- = Script::Compile(v8_str("var desc = { get: function(){return 43; },"
- " configurable: false };"
- "Object.defineProperty(obj, 'x', desc);"
- "obj.x"));
+ script_define = v8_compile(
+ "var desc = { get: function(){return 43; },"
+ " configurable: false };"
+ "Object.defineProperty(obj, 'x', desc);"
+ "obj.x");
result = script_define->Run();
CHECK_EQ(result, v8_num(43));
result = script_desc->Run();
THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> script_desc = Script::Compile(v8_str("var prop ="
- "Object.getOwnPropertyDescriptor( "
- "obj, 'x');"
- "prop.configurable;"));
+ Local<Script> script_desc = v8_compile(
+ "var prop ="
+ "Object.getOwnPropertyDescriptor( "
+ "obj, 'x');"
+ "prop.configurable;");
Local<Value> result = script_desc->Run();
CHECK_EQ(result->BooleanValue(), true);
- Local<Script> script_define =
- Script::Compile(v8_str("var desc = {get: function(){return 42; },"
- " configurable: true };"
- "Object.defineProperty(obj, 'x', desc);"
- "obj.x"));
+ Local<Script> script_define = v8_compile(
+ "var desc = {get: function(){return 42; },"
+ " configurable: true };"
+ "Object.defineProperty(obj, 'x', desc);"
+ "obj.x");
result = script_define->Run();
CHECK_EQ(result, v8_num(42));
CHECK_EQ(result->BooleanValue(), true);
- script_define =
- Script::Compile(v8_str("var desc = {get: function(){return 43; },"
- " configurable: false };"
- "Object.defineProperty(obj, 'x', desc);"
- "obj.x"));
+ script_define = v8_compile(
+ "var desc = {get: function(){return 43; },"
+ " configurable: false };"
+ "Object.defineProperty(obj, 'x', desc);"
+ "obj.x");
result = script_define->Run();
CHECK_EQ(result, v8_num(43));
result = script_desc->Run();
THREADED_TEST(DefineAPIAccessorOnObject) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
LocalContext context;
context->Global()->Set(v8_str("obj1"), templ->NewInstance());
THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
LocalContext context;
context->Global()->Set(v8_str("obj1"), templ->NewInstance());
THREADED_TEST(ElementAPIAccessor) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
LocalContext context;
context->Global()->Set(v8_str("obj1"), templ->NewInstance());
THREADED_TEST(SimplePropertyWrite) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("x"), GetXValue, SetXValue, v8_str("donut"));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> script = Script::Compile(v8_str("obj.x = 4"));
+ Local<Script> script = v8_compile("obj.x = 4");
for (int i = 0; i < 10; i++) {
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), Local<Value>::New(CcTest::isolate(), xValue));
- xValue.Dispose();
- xValue.Clear();
+ xValue.Reset();
}
}
THREADED_TEST(SetterOnly) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("x"), NULL, SetXValue, v8_str("donut"));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> script = Script::Compile(v8_str("obj.x = 4; obj.x"));
+ Local<Script> script = v8_compile("obj.x = 4; obj.x");
for (int i = 0; i < 10; i++) {
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), Local<Value>::New(CcTest::isolate(), xValue));
- xValue.Dispose();
- xValue.Clear();
+ xValue.Reset();
}
}
THREADED_TEST(NoAccessors) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("x"),
static_cast<v8::AccessorGetterCallback>(NULL),
NULL,
v8_str("donut"));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> script = Script::Compile(v8_str("obj.x = 4; obj.x"));
+ Local<Script> script = v8_compile("obj.x = 4; obj.x");
for (int i = 0; i < 10; i++) {
script->Run();
}
THREADED_TEST(NamedInterceptorPropertyRead) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(XPropertyGetter);
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> script = Script::Compile(v8_str("obj.x"));
+ Local<Script> script = v8_compile("obj.x");
for (int i = 0; i < 10; i++) {
Local<Value> result = script->Run();
CHECK_EQ(result, v8_str("x"));
THREADED_TEST(NamedInterceptorDictionaryIC) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(XPropertyGetter);
LocalContext context;
// Create an object with a named interceptor.
context->Global()->Set(v8_str("interceptor_obj"), templ->NewInstance());
- Local<Script> script = Script::Compile(v8_str("interceptor_obj.x"));
+ Local<Script> script = v8_compile("interceptor_obj.x");
for (int i = 0; i < 10; i++) {
Local<Value> result = script->Run();
CHECK_EQ(result, v8_str("x"));
v8::Local<Context> context1 = Context::New(isolate);
context1->Enter();
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(XPropertyGetter);
// Create an object with a named interceptor.
v8::Local<v8::Object> object = templ->NewInstance();
const v8::PropertyCallbackInfo<v8::Value>& info) {
// Set x on the prototype object and do not handle the get request.
v8::Handle<v8::Value> proto = info.Holder()->GetPrototype();
- proto.As<v8::Object>()->Set(v8_str("x"), v8::Integer::New(23));
+ proto.As<v8::Object>()->Set(v8_str("x"),
+ v8::Integer::New(info.GetIsolate(), 23));
}
// This is a regression test for http://crbug.com/20104. Map
// transitions should not interfere with post interceptor lookup.
THREADED_TEST(NamedInterceptorMapTransitionRead) {
- v8::HandleScope scope(CcTest::isolate());
- Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> function_template =
+ v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_template
= function_template->InstanceTemplate();
instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter);
THREADED_TEST(IndexedInterceptorWithIndexedAccessor) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IndexedPropertyGetter,
IndexedPropertySetter);
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> getter_script = Script::Compile(v8_str(
- "obj.__defineGetter__(\"3\", function(){return 5;});obj[3];"));
- Local<Script> setter_script = Script::Compile(v8_str(
+ Local<Script> getter_script = v8_compile(
+ "obj.__defineGetter__(\"3\", function(){return 5;});obj[3];");
+ Local<Script> setter_script = v8_compile(
"obj.__defineSetter__(\"17\", function(val){this.foo = val;});"
"obj[17] = 23;"
- "obj.foo;"));
- Local<Script> interceptor_setter_script = Script::Compile(v8_str(
+ "obj.foo;");
+ Local<Script> interceptor_setter_script = v8_compile(
"obj.__defineSetter__(\"39\", function(val){this.foo = \"hit\";});"
"obj[39] = 47;"
- "obj.foo;")); // This setter should not run, due to the interceptor.
- Local<Script> interceptor_getter_script = Script::Compile(v8_str(
- "obj[37];"));
+ "obj.foo;"); // This setter should not run, due to the interceptor.
+ Local<Script> interceptor_getter_script = v8_compile(
+ "obj[37];");
Local<Value> result = getter_script->Run();
CHECK_EQ(v8_num(5), result);
result = setter_script->Run();
void UnboxedDoubleIndexedPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
// Force the list of returned keys to be stored in a FastDoubleArray.
- Local<Script> indexed_property_names_script = Script::Compile(v8_str(
+ Local<Script> indexed_property_names_script = v8_compile(
"keys = new Array(); keys[125000] = 1;"
"for(i = 0; i < 80000; i++) { keys[i] = i; };"
- "keys.length = 25; keys;"));
+ "keys.length = 25; keys;");
Local<Value> result = indexed_property_names_script->Run();
info.GetReturnValue().Set(Local<v8::Array>::Cast(result));
}
// Make sure that the the interceptor code in the runtime properly handles
// merging property name lists for double-array-backed arrays.
THREADED_TEST(IndexedInterceptorUnboxedDoubleWithIndexedAccessor) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(UnboxedDoubleIndexedPropertyGetter,
UnboxedDoubleIndexedPropertySetter,
0,
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
// When obj is created, force it to be Stored in a FastDoubleArray.
- Local<Script> create_unboxed_double_script = Script::Compile(v8_str(
+ Local<Script> create_unboxed_double_script = v8_compile(
"obj[125000] = 1; for(i = 0; i < 80000; i+=2) { obj[i] = i; } "
"key_count = 0; "
"for (x in obj) {key_count++;};"
- "obj;"));
+ "obj;");
Local<Value> result = create_unboxed_double_script->Run();
CHECK(result->ToObject()->HasRealIndexedProperty(2000));
- Local<Script> key_count_check = Script::Compile(v8_str(
- "key_count;"));
+ Local<Script> key_count_check = v8_compile("key_count;");
result = key_count_check->Run();
CHECK_EQ(v8_num(40013), result);
}
-void NonStrictArgsIndexedPropertyEnumerator(
+void SloppyArgsIndexedPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
// Force the list of returned keys to be stored in a Arguments object.
- Local<Script> indexed_property_names_script = Script::Compile(v8_str(
+ Local<Script> indexed_property_names_script = v8_compile(
"function f(w,x) {"
" return arguments;"
"}"
"keys = f(0, 1, 2, 3);"
- "keys;"));
+ "keys;");
Local<Object> result =
Local<Object>::Cast(indexed_property_names_script->Run());
// Have to populate the handle manually, as it's not Cast-able.
}
-static void NonStrictIndexedPropertyGetter(
+static void SloppyIndexedPropertyGetter(
uint32_t index,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
// Make sure that the the interceptor code in the runtime properly handles
// merging property name lists for non-string arguments arrays.
-THREADED_TEST(IndexedInterceptorNonStrictArgsWithIndexedAccessor) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
- templ->SetIndexedPropertyHandler(NonStrictIndexedPropertyGetter,
+THREADED_TEST(IndexedInterceptorSloppyArgsWithIndexedAccessor) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->SetIndexedPropertyHandler(SloppyIndexedPropertyGetter,
0,
0,
0,
- NonStrictArgsIndexedPropertyEnumerator);
+ SloppyArgsIndexedPropertyEnumerator);
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
- Local<Script> create_args_script =
- Script::Compile(v8_str(
- "var key_count = 0;"
- "for (x in obj) {key_count++;} key_count;"));
+ Local<Script> create_args_script = v8_compile(
+ "var key_count = 0;"
+ "for (x in obj) {key_count++;} key_count;");
Local<Value> result = create_args_script->Run();
CHECK_EQ(v8_num(4), result);
}
THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(IndexedInterceptorWithNoSetter) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
context->Global()->Set(v8_str("obj"), obj);
const char* code =
- "try {"
- " for (var i = 0; i < 100; i++) {"
+ "var result = 'PASSED';"
+ "for (var i = 0; i < 100; i++) {"
+ " try {"
" var v = obj[0];"
- " if (v != undefined) throw 'Wrong value ' + v + ' at iteration ' + i;"
+ " result = 'Wrong value ' + v + ' at iteration ' + i;"
+ " break;"
+ " } catch (e) {"
+ " /* pass */"
" }"
- " 'PASSED'"
- "} catch(e) {"
- " e"
- "}";
+ "}"
+ "result";
ExpectString(code, "PASSED");
}
THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) {
i::FLAG_allow_natives_syntax = true;
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
context->Global()->Set(v8_str("obj"), obj);
const char* code =
- "try {"
- " for (var i = 0; i < 100; i++) {"
- " var expected = i;"
+ "var result = 'PASSED';"
+ "for (var i = 0; i < 100; i++) {"
+ " var expected = i;"
+ " if (i == 5) {"
+ " %EnableAccessChecks(obj);"
+ " }"
+ " try {"
+ " var v = obj[i];"
" if (i == 5) {"
- " %EnableAccessChecks(obj);"
- " expected = undefined;"
+ " result = 'Should not have reached this!';"
+ " break;"
+ " } else if (v != expected) {"
+ " result = 'Wrong value ' + v + ' at iteration ' + i;"
+ " break;"
+ " }"
+ " } catch (e) {"
+ " if (i != 5) {"
+ " result = e;"
" }"
- " var v = obj[i];"
- " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
- " if (i == 5) %DisableAccessChecks(obj);"
" }"
- " 'PASSED'"
- "} catch(e) {"
- " e"
- "}";
+ " if (i == 5) %DisableAccessChecks(obj);"
+ "}"
+ "result";
ExpectString(code, "PASSED");
}
THREADED_TEST(IndexedInterceptorWithDifferentIndices) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(IndexedInterceptorWithNegativeIndices) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(IndexedInterceptorWithNotSmiLookup) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(IndexedInterceptorGoingMegamorphic) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(IndexedInterceptorReceiverTurningSmi) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(IndexedInterceptorOnProto) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
LocalContext context;
THREADED_TEST(MultiContexts) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<ObjectTemplate> templ = ObjectTemplate::New();
- templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(DummyCallHandler));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(isolate,
+ DummyCallHandler));
Local<String> password = v8_str("Password");
"8901");
LocalContext env0;
- Local<Script> script0 = Script::Compile(source);
+ Local<Script> script0 = v8_compile(source);
CHECK_EQ(8901.0, script0->Run()->NumberValue());
LocalContext env1;
- Local<Script> script1 = Script::Compile(source);
+ Local<Script> script1 = v8_compile(source);
CHECK_EQ(8901.0, script1->Run()->NumberValue());
}
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> desc =
+ v8::FunctionTemplate::New(env->GetIsolate());
desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
Local<v8::Object> obj = desc->GetFunction()->NewInstance();
THREADED_TEST(VoidLiteral) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
Local<v8::Object> obj = desc->GetFunction()->NewInstance();
THREADED_TEST(ExtensibleOnUndetectable) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
- Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
Local<v8::Object> obj = desc->GetFunction()->NewInstance();
Local<String> source = v8_str("undetectable.x = 42;"
"undetectable.x");
- Local<Script> script = Script::Compile(source);
+ Local<Script> script = v8_compile(source);
- CHECK_EQ(v8::Integer::New(42), script->Run());
+ CHECK_EQ(v8::Integer::New(isolate, 42), script->Run());
ExpectBoolean("Object.isExtensible(undetectable)", true);
source = v8_str("Object.preventExtensions(undetectable);");
- script = Script::Compile(source);
+ script = v8_compile(source);
script->Run();
ExpectBoolean("Object.isExtensible(undetectable)", false);
source = v8_str("undetectable.y = 2000;");
- script = Script::Compile(source);
+ script = v8_compile(source);
script->Run();
ExpectBoolean("undetectable.y == undefined", true);
}
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<String> obj = String::NewUndetectable("foo");
+ Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo",
+ String::kUndetectableString);
env->Global()->Set(v8_str("undetectable"), obj);
ExpectString("undetectable", "foo");
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<String> obj = String::NewUndetectable("foo");
+ Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo",
+ String::kUndetectableString);
env->Global()->Set(v8_str("undetectable"), obj);
env->Global()->Set(v8_str("detectable"), v8_str("bar"));
}
-template <typename T> static void USE(T) { }
-
-
-// This test is not intended to be run, just type checked.
-static inline void PersistentHandles(v8::Isolate* isolate) {
- USE(PersistentHandles);
+// The point of this test is type checking. We run it only so compilers
+// don't complain about an unused function.
+TEST(PersistentHandles) {
+ LocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
Local<String> str = v8_str("foo");
v8::Persistent<String> p_str(isolate, str);
- p_str.Dispose();
- Local<Script> scr = Script::Compile(v8_str(""));
+ p_str.Reset();
+ Local<Script> scr = v8_compile("");
v8::Persistent<Script> p_scr(isolate, scr);
- p_scr.Dispose();
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ p_scr.Reset();
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
v8::Persistent<ObjectTemplate> p_templ(isolate, templ);
- p_templ.Dispose();
+ p_templ.Reset();
}
THREADED_TEST(GlobalObjectTemplate) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
- Local<ObjectTemplate> global_template = ObjectTemplate::New();
+ Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
global_template->Set(v8_str("JSNI_Log"),
- v8::FunctionTemplate::New(HandleLogDelegator));
+ v8::FunctionTemplate::New(isolate, HandleLogDelegator));
v8::Local<Context> context = Context::New(isolate, 0, global_template);
Context::Scope context_scope(context);
- Script::Compile(v8_str("JSNI_Log('LOG')"))->Run();
+ CompileRun("JSNI_Log('LOG')");
}
"}";
-THREADED_TEST(SimpleExtensions) {
+TEST(SimpleExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource));
const char* extension_names[] = { "simpletest" };
v8::Handle<Context> context =
Context::New(CcTest::isolate(), &extensions);
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run();
- CHECK_EQ(result, v8::Integer::New(4));
+ v8::Handle<Value> result = CompileRun("Foo()");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4));
+}
+
+
+static const char* kStackTraceFromExtensionSource =
+ "function foo() {"
+ " throw new Error();"
+ "}"
+ "function bar() {"
+ " foo();"
+ "}";
+
+
+TEST(StackTraceInExtension) {
+ v8::HandleScope handle_scope(CcTest::isolate());
+ v8::RegisterExtension(new Extension("stacktracetest",
+ kStackTraceFromExtensionSource));
+ const char* extension_names[] = { "stacktracetest" };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context =
+ Context::New(CcTest::isolate(), &extensions);
+ Context::Scope lock(context);
+ CompileRun("function user() { bar(); }"
+ "var error;"
+ "try{ user(); } catch (e) { error = e; }");
+ CHECK_EQ(-1, CompileRun("error.stack.indexOf('foo')")->Int32Value());
+ CHECK_EQ(-1, CompileRun("error.stack.indexOf('bar')")->Int32Value());
+ CHECK_NE(-1, CompileRun("error.stack.indexOf('user')")->Int32Value());
}
-THREADED_TEST(NullExtensions) {
+TEST(NullExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("nulltest", NULL));
const char* extension_names[] = { "nulltest" };
v8::Handle<Context> context =
Context::New(CcTest::isolate(), &extensions);
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str("1+3"))->Run();
- CHECK_EQ(result, v8::Integer::New(4));
+ v8::Handle<Value> result = CompileRun("1+3");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4));
}
static const int kEmbeddedExtensionSourceValidLen = 34;
-THREADED_TEST(ExtensionMissingSourceLength) {
+TEST(ExtensionMissingSourceLength) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("srclentest_fail",
kEmbeddedExtensionSource));
}
-THREADED_TEST(ExtensionWithSourceLength) {
+TEST(ExtensionWithSourceLength) {
for (int source_len = kEmbeddedExtensionSourceValidLen - 1;
source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) {
v8::HandleScope handle_scope(CcTest::isolate());
i::ScopedVector<char> extension_name(32);
- i::OS::SNPrintF(extension_name, "ext #%d", source_len);
+ i::SNPrintF(extension_name, "ext #%d", source_len);
v8::RegisterExtension(new Extension(extension_name.start(),
kEmbeddedExtensionSource, 0, 0,
source_len));
Context::New(CcTest::isolate(), &extensions);
if (source_len == kEmbeddedExtensionSourceValidLen) {
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str("Ret54321()"))->Run();
- CHECK_EQ(v8::Integer::New(54321), result);
+ v8::Handle<Value> result = CompileRun("Ret54321()");
+ CHECK_EQ(v8::Integer::New(CcTest::isolate(), 54321), result);
} else {
// Anything but exactly the right length should fail to compile.
CHECK_EQ(0, *context);
"})()";
-THREADED_TEST(UseEvalFromExtension) {
+TEST(UseEvalFromExtension) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1));
v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2));
v8::Handle<Context> context =
Context::New(CcTest::isolate(), &extensions);
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str("UseEval1()"))->Run();
- CHECK_EQ(result, v8::Integer::New(42));
- result = Script::Compile(v8_str("UseEval2()"))->Run();
- CHECK_EQ(result, v8::Integer::New(42));
+ v8::Handle<Value> result = CompileRun("UseEval1()");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42));
+ result = CompileRun("UseEval2()");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42));
}
"})()";
-THREADED_TEST(UseWithFromExtension) {
+TEST(UseWithFromExtension) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1));
v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2));
v8::Handle<Context> context =
Context::New(CcTest::isolate(), &extensions);
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str("UseWith1()"))->Run();
- CHECK_EQ(result, v8::Integer::New(87));
- result = Script::Compile(v8_str("UseWith2()"))->Run();
- CHECK_EQ(result, v8::Integer::New(87));
+ v8::Handle<Value> result = CompileRun("UseWith1()");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87));
+ result = CompileRun("UseWith2()");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 87));
}
-THREADED_TEST(AutoExtensions) {
+TEST(AutoExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
Extension* extension = new Extension("autotest", kSimpleExtensionSource);
extension->set_auto_enable(true);
v8::Handle<Context> context =
Context::New(CcTest::isolate());
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run();
- CHECK_EQ(result, v8::Integer::New(4));
+ v8::Handle<Value> result = CompileRun("Foo()");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 4));
}
// Test that a syntax error in an extension does not cause a fatal
// error but results in an empty context.
-THREADED_TEST(SyntaxErrorExtensions) {
+TEST(SyntaxErrorExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("syntaxerror",
kSyntaxErrorInExtensionSource));
// Test that an exception when installing an extension does not cause
// a fatal error but results in an empty context.
-THREADED_TEST(ExceptionExtensions) {
+TEST(ExceptionExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("exception",
kExceptionInExtensionSource));
"call_runtime_last_index_of('bobbobboellebobboellebobbob');";
// Test that a native runtime calls are supported in extensions.
-THREADED_TEST(NativeCallInExtensions) {
+TEST(NativeCallInExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("nativecall",
kNativeCallInExtensionSource));
v8::Handle<Context> context =
Context::New(CcTest::isolate(), &extensions);
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run();
- CHECK_EQ(result, v8::Integer::New(3));
+ v8::Handle<Value> result = CompileRun(kNativeCallTest);
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 3));
}
: Extension(name, source),
function_(fun) { }
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
+ v8::Isolate* isolate,
v8::Handle<v8::String> name) {
- return v8::FunctionTemplate::New(function_);
+ return v8::FunctionTemplate::New(isolate, function_);
}
static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) {
};
-THREADED_TEST(NativeFunctionDeclaration) {
+TEST(NativeFunctionDeclaration) {
v8::HandleScope handle_scope(CcTest::isolate());
const char* name = "nativedecl";
v8::RegisterExtension(new NativeFunctionExtension(name,
v8::Handle<Context> context =
Context::New(CcTest::isolate(), &extensions);
Context::Scope lock(context);
- v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run();
- CHECK_EQ(result, v8::Integer::New(42));
+ v8::Handle<Value> result = CompileRun("foo(42);");
+ CHECK_EQ(result, v8::Integer::New(CcTest::isolate(), 42));
}
-THREADED_TEST(NativeFunctionDeclarationError) {
+TEST(NativeFunctionDeclarationError) {
v8::HandleScope handle_scope(CcTest::isolate());
const char* name = "nativedeclerr";
// Syntax error in extension code.
}
-THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
+TEST(NativeFunctionDeclarationErrorEscape) {
v8::HandleScope handle_scope(CcTest::isolate());
const char* name = "nativedeclerresc";
// Syntax error in extension code - escape code in "native" means that
v8::HandleScope handle_scope(CcTest::isolate());
v8::ExtensionConfiguration config(1, &name);
LocalContext context(&config);
- CHECK_EQ(String::New(expected), context->Global()->Get(v8_str("loaded")));
+ CHECK_EQ(String::NewFromUtf8(CcTest::isolate(), expected),
+ context->Global()->Get(v8_str("loaded")));
}
class FunctionExtension : public Extension {
public:
FunctionExtension() : Extension("functiontest", kExtensionTestScript) { }
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
+ v8::Isolate* isolate,
v8::Handle<String> name);
};
static int lookup_count = 0;
-v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunction(
- v8::Handle<String> name) {
+v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate(
+ v8::Isolate* isolate, v8::Handle<String> name) {
lookup_count++;
if (name->Equals(v8_str("A"))) {
- return v8::FunctionTemplate::New(CallFun, v8::Integer::New(8));
+ return v8::FunctionTemplate::New(
+ isolate, CallFun, v8::Integer::New(isolate, 8));
} else if (name->Equals(v8_str("B"))) {
- return v8::FunctionTemplate::New(CallFun, v8::Integer::New(7));
+ return v8::FunctionTemplate::New(
+ isolate, CallFun, v8::Integer::New(isolate, 7));
} else if (name->Equals(v8_str("C"))) {
- return v8::FunctionTemplate::New(CallFun, v8::Integer::New(6));
+ return v8::FunctionTemplate::New(
+ isolate, CallFun, v8::Integer::New(isolate, 6));
} else {
return v8::Handle<v8::FunctionTemplate>();
}
v8::ExtensionConfiguration config(1, exts);
LocalContext context(&config);
CHECK_EQ(3, lookup_count);
- CHECK_EQ(v8::Integer::New(8), Script::Compile(v8_str("Foo(0)"))->Run());
- CHECK_EQ(v8::Integer::New(7), Script::Compile(v8_str("Foo(1)"))->Run());
- CHECK_EQ(v8::Integer::New(6), Script::Compile(v8_str("Foo(2)"))->Run());
+ CHECK_EQ(v8::Integer::New(CcTest::isolate(), 8),
+ CompileRun("Foo(0)"));
+ CHECK_EQ(v8::Integer::New(CcTest::isolate(), 7),
+ CompileRun("Foo(1)"));
+ CHECK_EQ(v8::Integer::New(CcTest::isolate(), 6),
+ CompileRun("Foo(2)"));
}
for (int i = 0; i < 10; i++) {
// Run a few times to ensure that allocation of objects doesn't
// change behavior of a constructor function.
- CHECK_EQ(v8::Integer::New(8),
- Script::Compile(v8_str("(new A()).data"))->Run());
- CHECK_EQ(v8::Integer::New(7),
- Script::Compile(v8_str("(new B()).data"))->Run());
- CHECK_EQ(v8::Integer::New(6),
- Script::Compile(v8_str("(new C()).data"))->Run());
+ CHECK_EQ(v8::Integer::New(CcTest::isolate(), 8),
+ CompileRun("(new A()).data"));
+ CHECK_EQ(v8::Integer::New(CcTest::isolate(), 7),
+ CompileRun("(new B()).data"));
+ CHECK_EQ(v8::Integer::New(CcTest::isolate(), 6),
+ CompileRun("(new C()).data"));
}
}
}
-static const char* js_code_causing_huge_string_flattening =
- "var str = 'X';"
- "for (var i = 0; i < 30; i++) {"
- " str = str + str;"
- "}"
- "str.match(/X/);";
-
-
-void OOMCallback(const char* location, const char* message) {
- exit(0);
-}
-
-
-TEST(RegexpOutOfMemory) {
- // Execute a script that causes out of memory when flattening a string.
- v8::HandleScope scope(CcTest::isolate());
- v8::V8::SetFatalErrorHandler(OOMCallback);
- LocalContext context;
- Local<Script> script =
- Script::Compile(String::New(js_code_causing_huge_string_flattening));
- last_location = NULL;
- script->Run();
-
- CHECK(false); // Should not return.
-}
-
-
static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
- CHECK(message->GetScriptResourceName()->IsUndefined());
- CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName());
+ CHECK(message->GetScriptOrigin().ResourceName()->IsUndefined());
+ CHECK_EQ(v8::Undefined(CcTest::isolate()),
+ message->GetScriptOrigin().ResourceName());
message->GetLineNumber();
message->GetSourceLine();
}
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
v8::V8::AddMessageListener(MissingScriptInfoMessageListener);
- Script::Compile(v8_str("throw Error()"))->Run();
+ CompileRun("throw Error()");
v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener);
}
-int global_index = 0;
-
-class Snorkel {
- public:
- Snorkel() { index_ = global_index++; }
- int index_;
+struct FlagAndPersistent {
+ bool flag;
+ v8::Persistent<v8::Object> handle;
};
-class Whammy {
- public:
- explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
- ~Whammy() { script_.Dispose(); }
- v8::Handle<Script> getScript() {
- if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
- return Local<Script>::New(isolate_, script_);
- }
-
- public:
- static const int kObjectCount = 256;
- int cursor_;
- v8::Isolate* isolate_;
- v8::Persistent<v8::Object> objects_[kObjectCount];
- v8::Persistent<Script> script_;
-};
-static void HandleWeakReference(v8::Isolate* isolate,
- v8::Persistent<v8::Value>* obj,
- Snorkel* snorkel) {
- delete snorkel;
- obj->ClearWeak();
+static void SetFlag(
+ const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
+ data.GetParameter()->flag = true;
}
-void WhammyPropertyGetter(Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- Whammy* whammy =
- static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
- v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_];
+static void IndependentWeakHandle(bool global_gc, bool interlinked) {
+ v8::Isolate* iso = CcTest::isolate();
+ v8::HandleScope scope(iso);
+ v8::Handle<Context> context = Context::New(iso);
+ Context::Scope context_scope(context);
+
+ FlagAndPersistent object_a, object_b;
- v8::Handle<v8::Object> obj = v8::Object::New();
- if (!prev.IsEmpty()) {
- v8::Local<v8::Object>::New(info.GetIsolate(), prev)
- ->Set(v8_str("next"), obj);
- prev.MakeWeak<Value, Snorkel>(new Snorkel(), &HandleWeakReference);
- whammy->objects_[whammy->cursor_].Clear();
+ intptr_t big_heap_size;
+
+ {
+ v8::HandleScope handle_scope(iso);
+ Local<Object> a(v8::Object::New(iso));
+ Local<Object> b(v8::Object::New(iso));
+ object_a.handle.Reset(iso, a);
+ object_b.handle.Reset(iso, b);
+ if (interlinked) {
+ a->Set(v8_str("x"), b);
+ b->Set(v8_str("x"), a);
+ }
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ }
+ // We are relying on this creating a big flag array and reserving the space
+ // up front.
+ v8::Handle<Value> big_array = CompileRun("new Array(50000)");
+ a->Set(v8_str("y"), big_array);
+ big_heap_size = CcTest::heap()->SizeOfObjects();
+ }
+
+ object_a.flag = false;
+ object_b.flag = false;
+ object_a.handle.SetPhantom(&object_a, &SetFlag);
+ object_b.handle.SetPhantom(&object_b, &SetFlag);
+ CHECK(!object_b.handle.IsIndependent());
+ object_a.handle.MarkIndependent();
+ object_b.handle.MarkIndependent();
+ CHECK(object_b.handle.IsIndependent());
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
}
- whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj);
- whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount;
- info.GetReturnValue().Set(whammy->getScript()->Run());
+ // A single GC should be enough to reclaim the memory, since we are using
+ // phantom handles.
+ CHECK_LT(CcTest::heap()->SizeOfObjects(), big_heap_size - 200000);
+ CHECK(object_a.flag);
+ CHECK(object_b.flag);
}
-THREADED_TEST(WeakReference) {
- v8::HandleScope handle_scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New();
- Whammy* whammy = new Whammy(CcTest::isolate());
- templ->SetNamedPropertyHandler(WhammyPropertyGetter,
- 0, 0, 0, 0,
- v8::External::New(whammy));
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- v8::Handle<Context> context =
- Context::New(CcTest::isolate(), &extensions);
- Context::Scope context_scope(context);
-
- v8::Handle<v8::Object> interceptor = templ->NewInstance();
- context->Global()->Set(v8_str("whammy"), interceptor);
- const char* code =
- "var last;"
- "for (var i = 0; i < 10000; i++) {"
- " var obj = whammy.length;"
- " if (last) last.next = obj;"
- " last = obj;"
- "}"
- "gc();"
- "4";
- v8::Handle<Value> result = CompileRun(code);
- CHECK_EQ(4.0, result->NumberValue());
- delete whammy;
+THREADED_TEST(IndependentWeakHandle) {
+ IndependentWeakHandle(false, false);
+ IndependentWeakHandle(false, true);
+ IndependentWeakHandle(true, false);
+ IndependentWeakHandle(true, true);
}
-static void DisposeAndSetFlag(v8::Isolate* isolate,
- v8::Persistent<v8::Object>* obj,
- bool* data) {
- obj->Dispose();
- *(data) = true;
+static void ResetUseValueAndSetFlag(
+ const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
+ // Blink will reset the handle, and then use the other handle, so they
+ // can't use the same backing slot.
+ data.GetParameter()->handle.Reset();
+ data.GetValue()->IsBoolean(); // Make sure the handle still works.
+ data.GetParameter()->flag = true;
}
-THREADED_TEST(IndependentWeakHandle) {
+static void ResetWeakHandle(bool global_gc) {
v8::Isolate* iso = CcTest::isolate();
v8::HandleScope scope(iso);
v8::Handle<Context> context = Context::New(iso);
Context::Scope context_scope(context);
- v8::Persistent<v8::Object> object_a, object_b;
+ FlagAndPersistent object_a, object_b;
{
v8::HandleScope handle_scope(iso);
- object_a.Reset(iso, v8::Object::New());
- object_b.Reset(iso, v8::Object::New());
+ Local<Object> a(v8::Object::New(iso));
+ Local<Object> b(v8::Object::New(iso));
+ object_a.handle.Reset(iso, a);
+ object_b.handle.Reset(iso, b);
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ }
+ }
+
+ object_a.flag = false;
+ object_b.flag = false;
+ object_a.handle.SetWeak(&object_a, &ResetUseValueAndSetFlag);
+ object_b.handle.SetWeak(&object_b, &ResetUseValueAndSetFlag);
+ if (!global_gc) {
+ object_a.handle.MarkIndependent();
+ object_b.handle.MarkIndependent();
+ CHECK(object_b.handle.IsIndependent());
+ }
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
}
+ CHECK(object_a.flag);
+ CHECK(object_b.flag);
+}
+
- bool object_a_disposed = false;
- bool object_b_disposed = false;
- object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
- object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag);
- CHECK(!object_b.IsIndependent());
- object_a.MarkIndependent();
- object_b.MarkIndependent();
- CHECK(object_b.IsIndependent());
- CcTest::heap()->PerformScavenge();
- CHECK(object_a_disposed);
- CHECK(object_b_disposed);
+THREADED_TEST(ResetWeakHandle) {
+ ResetWeakHandle(false);
+ ResetWeakHandle(true);
}
static void InvokeScavenge() {
- CcTest::heap()->PerformScavenge();
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
}
}
-static void ForceScavenge(v8::Isolate* isolate,
- v8::Persistent<v8::Object>* obj,
- bool* data) {
- obj->Dispose();
- *(data) = true;
+static void ForceScavenge(
+ const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
+ data.GetParameter()->handle.Reset();
+ data.GetParameter()->flag = true;
InvokeScavenge();
}
-static void ForceMarkSweep(v8::Isolate* isolate,
- v8::Persistent<v8::Object>* obj,
- bool* data) {
- obj->Dispose();
- *(data) = true;
+static void ForceMarkSweep(
+ const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
+ data.GetParameter()->handle.Reset();
+ data.GetParameter()->flag = true;
InvokeMarkSweep();
}
Context::Scope context_scope(context);
static const int kNumberOfGCTypes = 2;
- typedef v8::WeakReferenceCallbacks<v8::Object, bool>::Revivable Callback;
+ typedef v8::WeakCallbackData<v8::Object, FlagAndPersistent>::Callback
+ Callback;
Callback gc_forcing_callback[kNumberOfGCTypes] =
{&ForceScavenge, &ForceMarkSweep};
for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) {
for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) {
- v8::Persistent<v8::Object> object;
+ FlagAndPersistent object;
{
v8::HandleScope handle_scope(isolate);
- object.Reset(isolate, v8::Object::New());
+ object.handle.Reset(isolate, v8::Object::New(isolate));
}
- bool disposed = false;
- object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]);
- object.MarkIndependent();
+ object.flag = false;
+ object.handle.SetWeak(&object, gc_forcing_callback[inner_gc]);
+ object.handle.MarkIndependent();
invoke_gc[outer_gc]();
- CHECK(disposed);
+ CHECK(object.flag);
}
}
}
-static void RevivingCallback(v8::Isolate* isolate,
- v8::Persistent<v8::Object>* obj,
- bool* data) {
- obj->ClearWeak();
- *(data) = true;
+static void RevivingCallback(
+ const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
+ data.GetParameter()->handle.ClearWeak();
+ data.GetParameter()->flag = true;
}
v8::Handle<Context> context = Context::New(isolate);
Context::Scope context_scope(context);
- v8::Persistent<v8::Object> object;
+ FlagAndPersistent object;
{
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Object> o = v8::Object::New();
- object.Reset(isolate, o);
- o->Set(v8_str("x"), v8::Integer::New(1));
+ v8::Local<v8::Object> o = v8::Object::New(isolate);
+ object.handle.Reset(isolate, o);
+ o->Set(v8_str("x"), v8::Integer::New(isolate, 1));
v8::Local<String> y_str = v8_str("y");
o->Set(y_str, y_str);
}
- bool revived = false;
- object.MakeWeak(&revived, &RevivingCallback);
- object.MarkIndependent();
- CcTest::heap()->PerformScavenge();
- CHECK(revived);
+ object.flag = false;
+ object.handle.SetWeak(&object, &RevivingCallback);
+ object.handle.MarkIndependent();
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CHECK(object.flag);
CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
{
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object);
+ v8::Local<v8::Object> o =
+ v8::Local<v8::Object>::New(isolate, object.handle);
v8::Local<String> y_str = v8_str("y");
- CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x")));
+ CHECK_EQ(v8::Integer::New(isolate, 1), o->Get(v8_str("x")));
CHECK(o->Get(y_str)->Equals(y_str));
}
}
v8::Isolate* isolate = args.GetIsolate();
CHECK_EQ(args_fun, args.Callee());
CHECK_EQ(3, args.Length());
- CHECK_EQ(v8::Integer::New(1, isolate), args[0]);
- CHECK_EQ(v8::Integer::New(2, isolate), args[1]);
- CHECK_EQ(v8::Integer::New(3, isolate), args[2]);
+ CHECK_EQ(v8::Integer::New(isolate, 1), args[0]);
+ CHECK_EQ(v8::Integer::New(isolate, 2), args[1]);
+ CHECK_EQ(v8::Integer::New(isolate, 3), args[2]);
CHECK_EQ(v8::Undefined(isolate), args[3]);
v8::HandleScope scope(args.GetIsolate());
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
THREADED_TEST(Arguments) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New();
- global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate);
+ global->Set(v8_str("f"),
+ v8::FunctionTemplate::New(isolate, ArgumentsTestCallback));
LocalContext context(NULL, global);
args_fun = context->Global()->Get(v8_str("f")).As<Function>();
v8_compile("f(1, 2, 3)")->Run();
THREADED_TEST(Deleter) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
obj->SetNamedPropertyHandler(NoBlockGetterX, NULL, NULL, PDeleter, NULL);
obj->SetIndexedPropertyHandler(NoBlockGetterI, NULL, NULL, IDeleter, NULL);
LocalContext context;
static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) {
ApiTestFuzzer::Fuzz();
- v8::Handle<v8::Array> result = v8::Array::New(3);
- result->Set(v8::Integer::New(0), v8_str("foo"));
- result->Set(v8::Integer::New(1), v8_str("bar"));
- result->Set(v8::Integer::New(2), v8_str("baz"));
+ v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3);
+ result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("foo"));
+ result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("bar"));
+ result->Set(v8::Integer::New(info.GetIsolate(), 2), v8_str("baz"));
info.GetReturnValue().Set(result);
}
static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) {
ApiTestFuzzer::Fuzz();
- v8::Handle<v8::Array> result = v8::Array::New(2);
- result->Set(v8::Integer::New(0), v8_str("0"));
- result->Set(v8::Integer::New(1), v8_str("1"));
+ v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2);
+ result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("0"));
+ result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("1"));
info.GetReturnValue().Set(result);
}
THREADED_TEST(Enumerators) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
obj->SetNamedPropertyHandler(GetK, NULL, NULL, NULL, NamedEnum);
obj->SetIndexedPropertyHandler(IndexedGetK, NULL, NULL, NULL, IndexedEnum);
LocalContext context;
// documenting our behavior.
CHECK_EQ(17, result->Length());
// Indexed properties in numerical order.
- CHECK_EQ(v8_str("5"), result->Get(v8::Integer::New(0)));
- CHECK_EQ(v8_str("10"), result->Get(v8::Integer::New(1)));
- CHECK_EQ(v8_str("140000"), result->Get(v8::Integer::New(2)));
- CHECK_EQ(v8_str("4294967295"), result->Get(v8::Integer::New(3)));
+ CHECK_EQ(v8_str("5"), result->Get(v8::Integer::New(isolate, 0)));
+ CHECK_EQ(v8_str("10"), result->Get(v8::Integer::New(isolate, 1)));
+ CHECK_EQ(v8_str("140000"), result->Get(v8::Integer::New(isolate, 2)));
+ CHECK_EQ(v8_str("4294967295"), result->Get(v8::Integer::New(isolate, 3)));
// Indexed interceptor properties in the order they are returned
// from the enumerator interceptor.
- CHECK_EQ(v8_str("0"), result->Get(v8::Integer::New(4)));
- CHECK_EQ(v8_str("1"), result->Get(v8::Integer::New(5)));
+ CHECK_EQ(v8_str("0"), result->Get(v8::Integer::New(isolate, 4)));
+ CHECK_EQ(v8_str("1"), result->Get(v8::Integer::New(isolate, 5)));
// Named properties in insertion order.
- CHECK_EQ(v8_str("a"), result->Get(v8::Integer::New(6)));
- CHECK_EQ(v8_str("b"), result->Get(v8::Integer::New(7)));
- CHECK_EQ(v8_str("c"), result->Get(v8::Integer::New(8)));
- CHECK_EQ(v8_str("4294967296"), result->Get(v8::Integer::New(9)));
- CHECK_EQ(v8_str("d"), result->Get(v8::Integer::New(10)));
- CHECK_EQ(v8_str("e"), result->Get(v8::Integer::New(11)));
- CHECK_EQ(v8_str("30000000000"), result->Get(v8::Integer::New(12)));
- CHECK_EQ(v8_str("f"), result->Get(v8::Integer::New(13)));
+ CHECK_EQ(v8_str("a"), result->Get(v8::Integer::New(isolate, 6)));
+ CHECK_EQ(v8_str("b"), result->Get(v8::Integer::New(isolate, 7)));
+ CHECK_EQ(v8_str("c"), result->Get(v8::Integer::New(isolate, 8)));
+ CHECK_EQ(v8_str("4294967296"), result->Get(v8::Integer::New(isolate, 9)));
+ CHECK_EQ(v8_str("d"), result->Get(v8::Integer::New(isolate, 10)));
+ CHECK_EQ(v8_str("e"), result->Get(v8::Integer::New(isolate, 11)));
+ CHECK_EQ(v8_str("30000000000"), result->Get(v8::Integer::New(isolate, 12)));
+ CHECK_EQ(v8_str("f"), result->Get(v8::Integer::New(isolate, 13)));
// Named interceptor properties.
- CHECK_EQ(v8_str("foo"), result->Get(v8::Integer::New(14)));
- CHECK_EQ(v8_str("bar"), result->Get(v8::Integer::New(15)));
- CHECK_EQ(v8_str("baz"), result->Get(v8::Integer::New(16)));
+ CHECK_EQ(v8_str("foo"), result->Get(v8::Integer::New(isolate, 14)));
+ CHECK_EQ(v8_str("bar"), result->Get(v8::Integer::New(isolate, 15)));
+ CHECK_EQ(v8_str("baz"), result->Get(v8::Integer::New(isolate, 16)));
}
THREADED_TEST(GetterHolders) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
obj->SetAccessor(v8_str("p1"), PGetter);
obj->SetAccessor(v8_str("p2"), PGetter);
obj->SetAccessor(v8_str("p3"), PGetter);
THREADED_TEST(PreInterceptorHolders) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
- obj->SetNamedPropertyHandler(PGetter2);
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
+ obj->SetNamedPropertyHandler(PGetter2);
p_getter_count2 = 0;
RunHolderTest(obj);
CHECK_EQ(40, p_getter_count2);
THREADED_TEST(ObjectInstantiation) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("t"), PGetter2);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
CHECK_NE(obj, context->Global()->Get(v8_str("o")));
context->Global()->Set(v8_str("o2"), obj);
v8::Handle<Value> value =
- Script::Compile(v8_str("o.__proto__ === o2.__proto__"))->Run();
+ CompileRun("o.__proto__ === o2.__proto__");
CHECK_EQ(v8::True(isolate), value);
context->Global()->Set(v8_str("o"), obj);
}
int len = str->Utf8Length();
if (len < 0) {
i::Handle<i::String> istr(v8::Utils::OpenHandle(*str));
- i::FlattenString(istr);
+ i::String::Flatten(istr);
len = str->Utf8Length();
}
return len;
v8::Handle<String> str = v8_str("abcde");
// abc<Icelandic eth><Unicode snowman>.
v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203");
- v8::Handle<String> str3 = v8::String::New("abc\0def", 7);
+ v8::Handle<String> str3 = v8::String::NewFromUtf8(
+ context->GetIsolate(), "abc\0def", v8::String::kNormalString, 7);
+ // "ab" + lead surrogate + "cd" + trail surrogate + "ef"
+ uint16_t orphans[8] = { 0x61, 0x62, 0xd800, 0x63, 0x64, 0xdc00, 0x65, 0x66 };
+ v8::Handle<String> orphans_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), orphans, v8::String::kNormalString, 8);
+ // single lead surrogate
+ uint16_t lead[1] = { 0xd800 };
+ v8::Handle<String> lead_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), lead, v8::String::kNormalString, 1);
+ // single trail surrogate
+ uint16_t trail[1] = { 0xdc00 };
+ v8::Handle<String> trail_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), trail, v8::String::kNormalString, 1);
+ // surrogate pair
+ uint16_t pair[2] = { 0xd800, 0xdc00 };
+ v8::Handle<String> pair_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), pair, v8::String::kNormalString, 2);
const int kStride = 4; // Must match stride in for loops in JS below.
CompileRun(
"var left = '';"
CHECK_EQ(2, charlen);
CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3));
+ // allow orphan surrogates by default
+ memset(utf8buf, 0x1, 1000);
+ len = orphans_str->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen);
+ CHECK_EQ(13, len);
+ CHECK_EQ(8, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "ab\355\240\200cd\355\260\200ef"));
+
+ // replace orphan surrogates with unicode replacement character
+ memset(utf8buf, 0x1, 1000);
+ len = orphans_str->WriteUtf8(utf8buf,
+ sizeof(utf8buf),
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(13, len);
+ CHECK_EQ(8, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "ab\357\277\275cd\357\277\275ef"));
+
+ // replace single lead surrogate with unicode replacement character
+ memset(utf8buf, 0x1, 1000);
+ len = lead_str->WriteUtf8(utf8buf,
+ sizeof(utf8buf),
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(4, len);
+ CHECK_EQ(1, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "\357\277\275"));
+
+ // replace single trail surrogate with unicode replacement character
+ memset(utf8buf, 0x1, 1000);
+ len = trail_str->WriteUtf8(utf8buf,
+ sizeof(utf8buf),
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(4, len);
+ CHECK_EQ(1, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "\357\277\275"));
+
+ // do not replace / write anything if surrogate pair does not fit the buffer
+ // space
+ memset(utf8buf, 0x1, 1000);
+ len = pair_str->WriteUtf8(utf8buf,
+ 3,
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(0, len);
+ CHECK_EQ(0, charlen);
+
memset(utf8buf, 0x1, sizeof(utf8buf));
len = GetUtf8Length(left_tree);
int utf8_expected =
static void Utf16Helper(
- LocalContext& context,
+ LocalContext& context, // NOLINT
const char* name,
const char* lengths_name,
int len) {
static void WriteUtf8Helper(
- LocalContext& context,
+ LocalContext& context, // NOLINT
const char* name,
const char* lengths_name,
int len) {
return *is1 == *is2;
}
-
-static void SameSymbolHelper(const char* a, const char* b) {
- Handle<String> symbol1 = v8::String::NewSymbol(a);
- Handle<String> symbol2 = v8::String::NewSymbol(b);
+static void SameSymbolHelper(v8::Isolate* isolate, const char* a,
+ const char* b) {
+ Handle<String> symbol1 =
+ v8::String::NewFromUtf8(isolate, a, v8::String::kInternalizedString);
+ Handle<String> symbol2 =
+ v8::String::NewFromUtf8(isolate, b, v8::String::kInternalizedString);
CHECK(SameSymbol(symbol1, symbol2));
}
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Handle<String> symbol1 = v8::String::NewSymbol("abc");
- Handle<String> symbol2 = v8::String::NewSymbol("abc");
+ Handle<String> symbol1 = v8::String::NewFromUtf8(
+ context->GetIsolate(), "abc", v8::String::kInternalizedString);
+ Handle<String> symbol2 = v8::String::NewFromUtf8(
+ context->GetIsolate(), "abc", v8::String::kInternalizedString);
CHECK(SameSymbol(symbol1, symbol2));
- SameSymbolHelper("\360\220\220\205", // 4 byte encoding.
+ SameSymbolHelper(context->GetIsolate(),
+ "\360\220\220\205", // 4 byte encoding.
"\355\240\201\355\260\205"); // 2 3-byte surrogates.
- SameSymbolHelper("\355\240\201\355\260\206", // 2 3-byte surrogates.
+ SameSymbolHelper(context->GetIsolate(),
+ "\355\240\201\355\260\206", // 2 3-byte surrogates.
"\360\220\220\206"); // 4 byte encoding.
- SameSymbolHelper("x\360\220\220\205", // 4 byte encoding.
+ SameSymbolHelper(context->GetIsolate(),
+ "x\360\220\220\205", // 4 byte encoding.
"x\355\240\201\355\260\205"); // 2 3-byte surrogates.
- SameSymbolHelper("x\355\240\201\355\260\206", // 2 3-byte surrogates.
+ SameSymbolHelper(context->GetIsolate(),
+ "x\355\240\201\355\260\206", // 2 3-byte surrogates.
"x\360\220\220\206"); // 4 byte encoding.
CompileRun(
"var sym0 = 'benedictus';"
"if (sym3.charCodeAt(2) != 0xdc07) throw sym1.charCodeAt(2);"
"if (sym4.length != 3) throw sym4;"
"if (sym4.charCodeAt(2) != 0xdc08) throw sym2.charCodeAt(2);");
- Handle<String> sym0 = v8::String::NewSymbol("benedictus");
- Handle<String> sym0b = v8::String::NewSymbol("S\303\270ren");
- Handle<String> sym1 = v8::String::NewSymbol("\355\240\201\355\260\207");
- Handle<String> sym2 = v8::String::NewSymbol("\360\220\220\210");
- Handle<String> sym3 = v8::String::NewSymbol("x\355\240\201\355\260\207");
- Handle<String> sym4 = v8::String::NewSymbol("x\360\220\220\210");
+ Handle<String> sym0 = v8::String::NewFromUtf8(
+ context->GetIsolate(), "benedictus", v8::String::kInternalizedString);
+ Handle<String> sym0b = v8::String::NewFromUtf8(
+ context->GetIsolate(), "S\303\270ren", v8::String::kInternalizedString);
+ Handle<String> sym1 =
+ v8::String::NewFromUtf8(context->GetIsolate(), "\355\240\201\355\260\207",
+ v8::String::kInternalizedString);
+ Handle<String> sym2 =
+ v8::String::NewFromUtf8(context->GetIsolate(), "\360\220\220\210",
+ v8::String::kInternalizedString);
+ Handle<String> sym3 = v8::String::NewFromUtf8(
+ context->GetIsolate(), "x\355\240\201\355\260\207",
+ v8::String::kInternalizedString);
+ Handle<String> sym4 =
+ v8::String::NewFromUtf8(context->GetIsolate(), "x\360\220\220\210",
+ v8::String::kInternalizedString);
v8::Local<v8::Object> global = context->Global();
Local<Value> s0 = global->Get(v8_str("sym0"));
Local<Value> s0b = global->Get(v8_str("sym0b"));
THREADED_TEST(ToArrayIndex) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::Handle<String> str = v8_str("42");
v8::Handle<v8::Uint32> index = str->ToArrayIndex();
index = str->ToArrayIndex();
CHECK(!index.IsEmpty());
CHECK_EQ(4294967295.0, index->Uint32Value());
- v8::Handle<v8::Number> num = v8::Number::New(1);
+ v8::Handle<v8::Number> num = v8::Number::New(isolate, 1);
index = num->ToArrayIndex();
CHECK(!index.IsEmpty());
CHECK_EQ(1.0, index->Uint32Value());
- num = v8::Number::New(-1);
+ num = v8::Number::New(isolate, -1);
index = num->ToArrayIndex();
CHECK(index.IsEmpty());
- v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::Handle<v8::Object> obj = v8::Object::New(isolate);
index = obj->ToArrayIndex();
CHECK(index.IsEmpty());
}
}
+static void ThrowV8Exception(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ ApiTestFuzzer::Fuzz();
+ v8::Handle<String> foo = v8_str("foo");
+ v8::Handle<String> message = v8_str("message");
+ v8::Handle<Value> error = v8::Exception::Error(foo);
+ CHECK(error->IsObject());
+ CHECK(error.As<v8::Object>()->Get(message)->Equals(foo));
+ info.GetIsolate()->ThrowException(error);
+ info.GetReturnValue().SetUndefined();
+}
+
+
+THREADED_TEST(ExceptionGetMessage) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+ v8::Handle<String> foo_str = v8_str("foo");
+ v8::Handle<String> message_str = v8_str("message");
+
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+
+ Local<v8::FunctionTemplate> fun =
+ v8::FunctionTemplate::New(context->GetIsolate(), ThrowV8Exception);
+ v8::Local<v8::Object> global = context->Global();
+ global->Set(v8_str("throwV8Exception"), fun->GetFunction());
+
+ TryCatch try_catch;
+ CompileRun(
+ "function f1() {\n"
+ " throwV8Exception();\n"
+ "};\n"
+ "f1();");
+ CHECK(try_catch.HasCaught());
+
+ v8::Handle<v8::Value> error = try_catch.Exception();
+ CHECK(error->IsObject());
+ CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str));
+
+ v8::Handle<v8::Message> message = v8::Exception::GetMessage(error);
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(2, message->GetLineNumber());
+ CHECK_EQ(2, message->GetStartColumn());
+
+ v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace();
+ CHECK(!stackTrace.IsEmpty());
+ CHECK_EQ(2, stackTrace->GetFrameCount());
+
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+
+ // Now check message location when SetCaptureStackTraceForUncaughtExceptions
+ // is false.
+ try_catch.Reset();
+
+ CompileRun(
+ "function f2() {\n"
+ " return throwV8Exception();\n"
+ "};\n"
+ "f2();");
+ CHECK(try_catch.HasCaught());
+
+ error = try_catch.Exception();
+ CHECK(error->IsObject());
+ CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str));
+
+ message = v8::Exception::GetMessage(error);
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(2, message->GetLineNumber());
+ CHECK_EQ(9, message->GetStartColumn());
+
+ // Should be empty stack trace.
+ stackTrace = message->GetStackTrace();
+ CHECK(stackTrace.IsEmpty());
+}
+
+
static void YGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
static void YSetter(Local<String> name,
Local<Value> value,
const v8::PropertyCallbackInfo<void>& info) {
- if (info.This()->Has(name)) {
- info.This()->Delete(name);
- }
- info.This()->Set(name, value);
+ Local<Object> this_obj = Local<Object>::Cast(info.This());
+ if (this_obj->Has(name)) this_obj->Delete(name);
+ this_obj->Set(name, value);
}
THREADED_TEST(DeleteAccessor) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
obj->SetAccessor(v8_str("y"), YGetter, YSetter);
LocalContext context;
v8::Handle<v8::Object> holder = obj->NewInstance();
THREADED_TEST(TypeSwitch) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> templ1 = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> templ3 = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> templ1 = v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> templ3 = v8::FunctionTemplate::New(isolate);
v8::Handle<v8::FunctionTemplate> templs[3] = { templ1, templ2, templ3 };
v8::Handle<v8::TypeSwitch> type_switch = v8::TypeSwitch::New(3, templs);
LocalContext context;
- v8::Handle<v8::Object> obj0 = v8::Object::New();
+ v8::Handle<v8::Object> obj0 = v8::Object::New(isolate);
v8::Handle<v8::Object> obj1 = templ1->GetFunction()->NewInstance();
v8::Handle<v8::Object> obj2 = templ2->GetFunction()->NewInstance();
v8::Handle<v8::Object> obj3 = templ3->GetFunction()->NewInstance();
}
-// For use within the TestSecurityHandler() test.
-static bool g_security_callback_result = false;
-static bool NamedSecurityTestCallback(Local<v8::Object> global,
- Local<Value> name,
- v8::AccessType type,
- Local<Value> data) {
- // Always allow read access.
- if (type == v8::ACCESS_GET)
- return true;
-
- // Sometimes allow other access.
- return g_security_callback_result;
-}
-
-
-static bool IndexedSecurityTestCallback(Local<v8::Object> global,
- uint32_t key,
- v8::AccessType type,
- Local<Value> data) {
- // Always allow read access.
- if (type == v8::ACCESS_GET)
- return true;
-
- // Sometimes allow other access.
- return g_security_callback_result;
-}
-
-
static int trouble_nesting = 0;
static void TroubleCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
TEST(ApiUncaughtException) {
report_count = 0;
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::V8::AddMessageListener(ApiUncaughtExceptionTestListener);
- Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(TroubleCallback);
+ Local<v8::FunctionTemplate> fun =
+ v8::FunctionTemplate::New(isolate, TroubleCallback);
v8::Local<v8::Object> global = env->Global();
global->Set(v8_str("trouble"), fun->GetFunction());
- Script::Compile(v8_str("function trouble_callee() {"
- " var x = null;"
- " return x.foo;"
- "};"
- "function trouble_caller() {"
- " trouble();"
- "};"))->Run();
+ CompileRun(
+ "function trouble_callee() {"
+ " var x = null;"
+ " return x.foo;"
+ "};"
+ "function trouble_caller() {"
+ " trouble();"
+ "};");
Local<Value> trouble = global->Get(v8_str("trouble"));
CHECK(trouble->IsFunction());
Local<Value> trouble_callee = global->Get(v8_str("trouble_callee"));
static const char* script_resource_name = "ExceptionInNativeScript.js";
static void ExceptionInNativeScriptTestListener(v8::Handle<v8::Message> message,
v8::Handle<Value>) {
- v8::Handle<v8::Value> name_val = message->GetScriptResourceName();
+ v8::Handle<v8::Value> name_val = message->GetScriptOrigin().ResourceName();
CHECK(!name_val.IsEmpty() && name_val->IsString());
- v8::String::Utf8Value name(message->GetScriptResourceName());
+ v8::String::Utf8Value name(message->GetScriptOrigin().ResourceName());
CHECK_EQ(script_resource_name, *name);
CHECK_EQ(3, message->GetLineNumber());
v8::String::Utf8Value source_line(message->GetSourceLine());
TEST(ExceptionInNativeScript) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::V8::AddMessageListener(ExceptionInNativeScriptTestListener);
- Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(TroubleCallback);
+ Local<v8::FunctionTemplate> fun =
+ v8::FunctionTemplate::New(isolate, TroubleCallback);
v8::Local<v8::Object> global = env->Global();
global->Set(v8_str("trouble"), fun->GetFunction());
- Script::Compile(v8_str("function trouble() {\n"
- " var o = {};\n"
- " new o.foo();\n"
- "};"), v8::String::New(script_resource_name))->Run();
+ CompileRunWithOrigin(
+ "function trouble() {\n"
+ " var o = {};\n"
+ " new o.foo();\n"
+ "};",
+ script_resource_name);
Local<Value> trouble = global->Get(v8_str("trouble"));
CHECK(trouble->IsFunction());
Function::Cast(*trouble)->Call(global, 0, NULL);
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::TryCatch try_catch;
- Script::Compile(v8_str("This doesn't &*&@#$&*^ compile."));
+ v8_compile("This doesn't &*&@#$&*^ compile.");
CHECK_NE(NULL, *try_catch.Exception());
CHECK(try_catch.HasCaught());
}
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::TryCatch try_catch;
- Script::Compile(v8_str("try { throw ''; } catch (e) {}"))->Run();
+ CompileRun("try { throw ''; } catch (e) {}");
CHECK(!try_catch.HasCaught());
- Script::Compile(v8_str("try { throw ''; } finally {}"))->Run();
+ CompileRun("try { throw ''; } finally {}");
CHECK(try_catch.HasCaught());
try_catch.Reset();
- Script::Compile(v8_str("(function() {"
- "try { throw ''; } finally { return; }"
- "})()"))->Run();
+ CompileRun(
+ "(function() {"
+ "try { throw ''; } finally { return; }"
+ "})()");
CHECK(!try_catch.HasCaught());
- Script::Compile(v8_str("(function()"
- " { try { throw ''; } finally { throw 0; }"
- "})()"))->Run();
+ CompileRun(
+ "(function()"
+ " { try { throw ''; } finally { throw 0; }"
+ "})()");
+ CHECK(try_catch.HasCaught());
+}
+
+
+void CEvaluate(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ v8::HandleScope scope(args.GetIsolate());
+ CompileRun(args[0]->ToString());
+}
+
+
+TEST(TryCatchFinallyStoresMessageUsingTryCatchHandler) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->Set(v8_str("CEvaluate"),
+ v8::FunctionTemplate::New(isolate, CEvaluate));
+ LocalContext context(0, templ);
+ v8::TryCatch try_catch;
+ CompileRun("try {"
+ " CEvaluate('throw 1;');"
+ "} finally {"
+ "}");
+ CHECK(try_catch.HasCaught());
+ CHECK(!try_catch.Message().IsEmpty());
+ String::Utf8Value exception_value(try_catch.Exception());
+ CHECK_EQ(*exception_value, "1");
+ try_catch.Reset();
+ CompileRun("try {"
+ " CEvaluate('throw 1;');"
+ "} finally {"
+ " throw 2;"
+ "}");
CHECK(try_catch.HasCaught());
+ CHECK(!try_catch.Message().IsEmpty());
+ String::Utf8Value finally_exception_value(try_catch.Exception());
+ CHECK_EQ(*finally_exception_value, "2");
+}
+
+
+// For use within the TestSecurityHandler() test.
+static bool g_security_callback_result = false;
+static bool NamedSecurityTestCallback(Local<v8::Object> global,
+ Local<Value> name,
+ v8::AccessType type,
+ Local<Value> data) {
+ printf("a\n");
+ // Always allow read access.
+ if (type == v8::ACCESS_GET)
+ return true;
+
+ // Sometimes allow other access.
+ return g_security_callback_result;
+}
+
+
+static bool IndexedSecurityTestCallback(Local<v8::Object> global,
+ uint32_t key,
+ v8::AccessType type,
+ Local<Value> data) {
+ printf("b\n");
+ // Always allow read access.
+ if (type == v8::ACCESS_GET)
+ return true;
+
+ // Sometimes allow other access.
+ return g_security_callback_result;
}
// SecurityHandler can't be run twice
TEST(SecurityHandler) {
- v8::HandleScope scope0(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope0(isolate);
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedSecurityTestCallback,
IndexedSecurityTestCallback);
// Create an environment
- v8::Handle<Context> context0 =
- Context::New(CcTest::isolate(), NULL, global_template);
+ v8::Handle<Context> context0 = Context::New(isolate, NULL, global_template);
context0->Enter();
v8::Handle<v8::Object> global0 = context0->Global();
CHECK_EQ(999, z0->Int32Value());
// Create another environment, should fail security checks.
- v8::HandleScope scope1(CcTest::isolate());
+ v8::HandleScope scope1(isolate);
v8::Handle<Context> context1 =
- Context::New(CcTest::isolate(), NULL, global_template);
+ Context::New(isolate, NULL, global_template);
context1->Enter();
v8::Handle<v8::Object> global1 = context1->Global();
// Create another environment, should pass security checks.
{ g_security_callback_result = true; // allow security handler to pass.
- v8::HandleScope scope2(CcTest::isolate());
+ v8::HandleScope scope2(isolate);
LocalContext context2;
v8::Handle<v8::Object> global2 = context2->Global();
global2->Set(v8_str("othercontext"), global0);
env1->SetSecurityToken(foo);
// Create a function in env1.
- Script::Compile(v8_str("spy=function(){return spy;}"))->Run();
+ CompileRun("spy=function(){return spy;}");
Local<Value> spy = env1->Global()->Get(v8_str("spy"));
CHECK(spy->IsFunction());
// Create another function accessing global objects.
- Script::Compile(v8_str("spy2=function(){return new this.Array();}"))->Run();
+ CompileRun("spy2=function(){return new this.Array();}");
Local<Value> spy2 = env1->Global()->Get(v8_str("spy2"));
CHECK(spy2->IsFunction());
v8::Local<Script> access_other0 = v8_compile("other.Object");
v8::Local<Script> access_other1 = v8_compile("other[42]");
for (int i = 0; i < 5; i++) {
- CHECK(!access_other0->Run()->Equals(other_object));
- CHECK(access_other0->Run()->IsUndefined());
- CHECK(!access_other1->Run()->Equals(v8_num(87)));
- CHECK(access_other1->Run()->IsUndefined());
+ CHECK(access_other0->Run().IsEmpty());
+ CHECK(access_other1->Run().IsEmpty());
}
// Create an object that has 'other' in its prototype chain and make
v8::Local<Script> access_f0 = v8_compile("f.Object");
v8::Local<Script> access_f1 = v8_compile("f[42]");
for (int j = 0; j < 5; j++) {
- CHECK(!access_f0->Run()->Equals(other_object));
- CHECK(access_f0->Run()->IsUndefined());
- CHECK(!access_f1->Run()->Equals(v8_num(87)));
- CHECK(access_f1->Run()->IsUndefined());
+ CHECK(access_f0->Run().IsEmpty());
+ CHECK(access_f1->Run().IsEmpty());
}
// Now it gets hairy: Set the prototype for the other global object
Local<Script> access_f2 = v8_compile("f.foo");
Local<Script> access_f3 = v8_compile("f[99]");
for (int k = 0; k < 5; k++) {
- CHECK(!access_f2->Run()->Equals(v8_num(100)));
- CHECK(access_f2->Run()->IsUndefined());
- CHECK(!access_f3->Run()->Equals(v8_num(101)));
- CHECK(access_f3->Run()->IsUndefined());
+ CHECK(access_f2->Run().IsEmpty());
+ CHECK(access_f3->Run().IsEmpty());
}
}
+static bool named_security_check_with_gc_called;
+
+static bool NamedSecurityCallbackWithGC(Local<v8::Object> global,
+ Local<Value> name,
+ v8::AccessType type,
+ Local<Value> data) {
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ named_security_check_with_gc_called = true;
+ return true;
+}
+
+
+static bool indexed_security_check_with_gc_called;
+
+static bool IndexedSecurityTestCallbackWithGC(Local<v8::Object> global,
+ uint32_t key,
+ v8::AccessType type,
+ Local<Value> data) {
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ indexed_security_check_with_gc_called = true;
+ return true;
+}
+
+
+TEST(SecurityTestGCAllowed) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
+ object_template->SetAccessCheckCallbacks(NamedSecurityCallbackWithGC,
+ IndexedSecurityTestCallbackWithGC);
+
+ v8::Handle<Context> context = Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+
+ context->Global()->Set(v8_str("obj"), object_template->NewInstance());
+
+ named_security_check_with_gc_called = false;
+ CompileRun("obj.foo = new String(1001);");
+ CHECK(named_security_check_with_gc_called);
+
+ indexed_security_check_with_gc_called = false;
+ CompileRun("obj[0] = new String(1002);");
+ CHECK(indexed_security_check_with_gc_called);
+
+ named_security_check_with_gc_called = false;
+ CHECK(CompileRun("obj.foo")->ToString()->Equals(v8_str("1001")));
+ CHECK(named_security_check_with_gc_called);
+
+ indexed_security_check_with_gc_called = false;
+ CHECK(CompileRun("obj[0]")->ToString()->Equals(v8_str("1002")));
+ CHECK(indexed_security_check_with_gc_called);
+}
+
+
THREADED_TEST(CrossDomainDelete) {
LocalContext env1;
v8::HandleScope handle_scope(env1->GetIsolate());
{
Context::Scope scope_env2(env2);
Local<Value> result =
- Script::Compile(v8_str("delete env1.prop"))->Run();
- CHECK(result->IsFalse());
+ CompileRun("delete env1.prop");
+ CHECK(result.IsEmpty());
}
// Check that env1.prop still exists.
Local<String> test = v8_str("propertyIsEnumerable.call(env1, 'prop')");
{
Context::Scope scope_env2(env2);
- Local<Value> result = Script::Compile(test)->Run();
+ Local<Value> result = CompileRun(test);
CHECK(result->IsTrue());
}
env2->SetSecurityToken(bar);
{
Context::Scope scope_env2(env2);
- Local<Value> result = Script::Compile(test)->Run();
- CHECK(result->IsFalse());
+ Local<Value> result = CompileRun(test);
+ CHECK(result.IsEmpty());
}
}
env2->SetSecurityToken(bar);
{
Context::Scope scope_env2(env2);
- Local<Value> result =
- CompileRun("(function(){var obj = {'__proto__':env1};"
- "for (var p in obj)"
- " if (p == 'prop') return false;"
- "return true;})()");
+ Local<Value> result = CompileRun(
+ "(function() {"
+ " var obj = { '__proto__': env1 };"
+ " try {"
+ " for (var p in obj) {"
+ " if (p == 'prop') return false;"
+ " }"
+ " return false;"
+ " } catch (e) {"
+ " return true;"
+ " }"
+ "})()");
CHECK(result->IsTrue());
}
}
// Create a function in env2 and add a reference to it in env1.
Local<v8::Object> global2 = env2->Global();
- global2->Set(v8_str("prop"), v8::Integer::New(1));
+ global2->Set(v8_str("prop"), v8::Integer::New(env2->GetIsolate(), 1));
CompileRun("function getProp() {return prop;}");
env1->Global()->Set(v8_str("getProp"),
// Detach env2's global, and reuse the global object of env2
env2->Exit();
env2->DetachGlobal();
- // env2 has a new global object.
- CHECK(!env2->Global()->Equals(global2));
v8::Handle<Context> env3 = Context::New(env1->GetIsolate(),
0,
CHECK_EQ(global2, global3);
CHECK(global3->Get(v8_str("prop"))->IsUndefined());
CHECK(global3->Get(v8_str("getProp"))->IsUndefined());
- global3->Set(v8_str("prop"), v8::Integer::New(-1));
- global3->Set(v8_str("prop2"), v8::Integer::New(2));
+ global3->Set(v8_str("prop"), v8::Integer::New(env3->GetIsolate(), -1));
+ global3->Set(v8_str("prop2"), v8::Integer::New(env3->GetIsolate(), 2));
env3->Exit();
// Call getProp in env1, and it should return the value 1
// Check that env3 is not accessible from env1
{
Local<Value> r = global3->Get(v8_str("prop2"));
- CHECK(r->IsUndefined());
+ CHECK(r.IsEmpty());
}
}
-TEST(DetachAndReattachGlobal) {
+TEST(DetachGlobal) {
LocalContext env1;
v8::HandleScope scope(env1->GetIsolate());
// Create a property on the global object in env2.
{
v8::Context::Scope scope(env2);
- env2->Global()->Set(v8_str("p"), v8::Integer::New(42));
+ env2->Global()->Set(v8_str("p"), v8::Integer::New(env2->GetIsolate(), 42));
}
// Create a reference to env2 global from env1 global.
// Check that the global has been detached. No other.p property can
// be found.
result = CompileRun("other.p");
- CHECK(result->IsUndefined());
+ CHECK(result.IsEmpty());
// Reuse global2 for env3.
v8::Handle<Context> env3 = Context::New(env1->GetIsolate(),
// Create a property on the global object in env3.
{
v8::Context::Scope scope(env3);
- env3->Global()->Set(v8_str("p"), v8::Integer::New(24));
+ env3->Global()->Set(v8_str("p"), v8::Integer::New(env3->GetIsolate(), 24));
}
// Check that other.p is now the property in env3 and that we have access.
// the global object for env3 which has a different security token,
// so access should be blocked.
result = CompileRun("other.p");
- CHECK(result->IsUndefined());
+ CHECK(result.IsEmpty());
+}
- // Detach the global for env3 and reattach it to env2.
- env3->DetachGlobal();
- env2->ReattachGlobal(global2);
- // Check that we have access to other.p again in env1. |other| is now
- // the global object for env2 which has the same security token as env1.
- result = CompileRun("other.p");
- CHECK(result->IsInt32());
- CHECK_EQ(42, result->Int32Value());
+void GetThisX(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ info.GetReturnValue().Set(
+ info.GetIsolate()->GetCurrentContext()->Global()->Get(v8_str("x")));
+}
+
+
+TEST(DetachedAccesses) {
+ LocalContext env1;
+ v8::HandleScope scope(env1->GetIsolate());
+
+ // Create second environment.
+ Local<ObjectTemplate> inner_global_template =
+ FunctionTemplate::New(env1->GetIsolate())->InstanceTemplate();
+ inner_global_template ->SetAccessorProperty(
+ v8_str("this_x"), FunctionTemplate::New(env1->GetIsolate(), GetThisX));
+ v8::Local<Context> env2 =
+ Context::New(env1->GetIsolate(), NULL, inner_global_template);
+
+ Local<Value> foo = v8_str("foo");
+
+ // Set same security token for env1 and env2.
+ env1->SetSecurityToken(foo);
+ env2->SetSecurityToken(foo);
+
+ env1->Global()->Set(v8_str("x"), v8_str("env1_x"));
+
+ {
+ v8::Context::Scope scope(env2);
+ env2->Global()->Set(v8_str("x"), v8_str("env2_x"));
+ CompileRun(
+ "function bound_x() { return x; }"
+ "function get_x() { return this.x; }"
+ "function get_x_w() { return (function() {return this.x;})(); }");
+ env1->Global()->Set(v8_str("bound_x"), CompileRun("bound_x"));
+ env1->Global()->Set(v8_str("get_x"), CompileRun("get_x"));
+ env1->Global()->Set(v8_str("get_x_w"), CompileRun("get_x_w"));
+ env1->Global()->Set(
+ v8_str("this_x"),
+ CompileRun("Object.getOwnPropertyDescriptor(this, 'this_x').get"));
+ }
+
+ Local<Object> env2_global = env2->Global();
+ env2_global->TurnOnAccessCheck();
+ env2->DetachGlobal();
+
+ Local<Value> result;
+ result = CompileRun("bound_x()");
+ CHECK_EQ(v8_str("env2_x"), result);
+ result = CompileRun("get_x()");
+ CHECK(result.IsEmpty());
+ result = CompileRun("get_x_w()");
+ CHECK(result.IsEmpty());
+ result = CompileRun("this_x()");
+ CHECK_EQ(v8_str("env2_x"), result);
+
+ // Reattach env2's proxy
+ env2 = Context::New(env1->GetIsolate(),
+ 0,
+ v8::Handle<v8::ObjectTemplate>(),
+ env2_global);
+ env2->SetSecurityToken(foo);
+ {
+ v8::Context::Scope scope(env2);
+ env2->Global()->Set(v8_str("x"), v8_str("env3_x"));
+ env2->Global()->Set(v8_str("env1"), env1->Global());
+ result = CompileRun(
+ "results = [];"
+ "for (var i = 0; i < 4; i++ ) {"
+ " results.push(env1.bound_x());"
+ " results.push(env1.get_x());"
+ " results.push(env1.get_x_w());"
+ " results.push(env1.this_x());"
+ "}"
+ "results");
+ Local<v8::Array> results = Local<v8::Array>::Cast(result);
+ CHECK_EQ(16, results->Length());
+ for (int i = 0; i < 16; i += 4) {
+ CHECK_EQ(v8_str("env2_x"), results->Get(i + 0));
+ CHECK_EQ(v8_str("env1_x"), results->Get(i + 1));
+ CHECK_EQ(v8_str("env3_x"), results->Get(i + 2));
+ CHECK_EQ(v8_str("env2_x"), results->Get(i + 3));
+ }
+ }
+
+ result = CompileRun(
+ "results = [];"
+ "for (var i = 0; i < 4; i++ ) {"
+ " results.push(bound_x());"
+ " results.push(get_x());"
+ " results.push(get_x_w());"
+ " results.push(this_x());"
+ "}"
+ "results");
+ Local<v8::Array> results = Local<v8::Array>::Cast(result);
+ CHECK_EQ(16, results->Length());
+ for (int i = 0; i < 16; i += 4) {
+ CHECK_EQ(v8_str("env2_x"), results->Get(i + 0));
+ CHECK_EQ(v8_str("env3_x"), results->Get(i + 1));
+ CHECK_EQ(v8_str("env3_x"), results->Get(i + 2));
+ CHECK_EQ(v8_str("env2_x"), results->Get(i + 3));
+ }
+
+ result = CompileRun(
+ "results = [];"
+ "for (var i = 0; i < 4; i++ ) {"
+ " results.push(this.bound_x());"
+ " results.push(this.get_x());"
+ " results.push(this.get_x_w());"
+ " results.push(this.this_x());"
+ "}"
+ "results");
+ results = Local<v8::Array>::Cast(result);
+ CHECK_EQ(16, results->Length());
+ for (int i = 0; i < 16; i += 4) {
+ CHECK_EQ(v8_str("env2_x"), results->Get(i + 0));
+ CHECK_EQ(v8_str("env1_x"), results->Get(i + 1));
+ CHECK_EQ(v8_str("env3_x"), results->Get(i + 2));
+ CHECK_EQ(v8_str("env2_x"), results->Get(i + 3));
+ }
}
}
-static int g_echo_value_1 = -1;
-static int g_echo_value_2 = -1;
+static int g_echo_value = -1;
static void EchoGetter(
Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(v8_num(g_echo_value_1));
-}
-
-
-static void EchoGetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(v8_num(g_echo_value_2));
+ info.GetReturnValue().Set(v8_num(g_echo_value));
}
Local<Value> value,
const v8::PropertyCallbackInfo<void>&) {
if (value->IsNumber())
- g_echo_value_1 = value->Int32Value();
-}
-
-
-static void EchoSetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Handle<v8::Value> value = info[0];
- if (value->IsNumber())
- g_echo_value_2 = value->Int32Value();
+ g_echo_value = value->Int32Value();
}
TEST(AccessControl) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedAccessBlocker,
IndexedAccessBlocker);
v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE));
- global_template->SetAccessorProperty(
- v8_str("accessible_js_prop"),
- v8::FunctionTemplate::New(EchoGetter),
- v8::FunctionTemplate::New(EchoSetter),
- v8::None,
- v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE));
-
// Add an accessor that is not accessible by cross-domain JS code.
global_template->SetAccessor(v8_str("blocked_prop"),
UnreachableGetter, UnreachableSetter,
global_template->SetAccessorProperty(
v8_str("blocked_js_prop"),
- v8::FunctionTemplate::New(UnreachableFunction),
- v8::FunctionTemplate::New(UnreachableFunction),
+ v8::FunctionTemplate::New(isolate, UnreachableFunction),
+ v8::FunctionTemplate::New(isolate, UnreachableFunction),
v8::None,
v8::DEFAULT);
// Access blocked property.
CompileRun("other.blocked_prop = 1");
- ExpectUndefined("other.blocked_prop");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop')");
- ExpectFalse("propertyIsEnumerable.call(other, 'blocked_prop')");
-
- // Enable ACCESS_HAS
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other.blocked_prop");
- // ... and now we can get the descriptor...
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop').value");
- // ... and enumerate the property.
- ExpectTrue("propertyIsEnumerable.call(other, 'blocked_prop')");
- allowed_access_type[v8::ACCESS_HAS] = false;
+ CHECK(CompileRun("other.blocked_prop").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'blocked_prop')")
+ .IsEmpty());
+ CHECK(
+ CompileRun("propertyIsEnumerable.call(other, 'blocked_prop')").IsEmpty());
// Access blocked element.
- CompileRun("other[239] = 1");
+ CHECK(CompileRun("other[239] = 1").IsEmpty());
- ExpectUndefined("other[239]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239')");
- ExpectFalse("propertyIsEnumerable.call(other, '239')");
+ CHECK(CompileRun("other[239]").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '239')").IsEmpty());
+ CHECK(CompileRun("propertyIsEnumerable.call(other, '239')").IsEmpty());
// Enable ACCESS_HAS
allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other[239]");
+ CHECK(CompileRun("other[239]").IsEmpty());
// ... and now we can get the descriptor...
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239').value");
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '239').value")
+ .IsEmpty());
// ... and enumerate the property.
ExpectTrue("propertyIsEnumerable.call(other, '239')");
allowed_access_type[v8::ACCESS_HAS] = false;
// Access a property with JS accessor.
- CompileRun("other.js_accessor_p = 2");
-
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p')");
+ CHECK(CompileRun("other.js_accessor_p = 2").IsEmpty());
- // Enable ACCESS_HAS.
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
- allowed_access_type[v8::ACCESS_HAS] = false;
+ CHECK(CompileRun("other.js_accessor_p").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'js_accessor_p')")
+ .IsEmpty());
// Enable both ACCESS_HAS and ACCESS_GET.
allowed_access_type[v8::ACCESS_HAS] = true;
ExpectString("other.js_accessor_p", "getter");
ExpectObject(
"Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
-
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
ExpectObject(
"Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
ExpectUndefined(
"Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectString("other.js_accessor_p", "getter");
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
// Access an element with JS accessor.
- CompileRun("other[42] = 2");
+ CHECK(CompileRun("other[42] = 2").IsEmpty());
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42')");
-
- // Enable ACCESS_HAS.
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
- allowed_access_type[v8::ACCESS_HAS] = false;
+ CHECK(CompileRun("other[42]").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '42')").IsEmpty());
// Enable both ACCESS_HAS and ACCESS_GET.
allowed_access_type[v8::ACCESS_HAS] = true;
ExpectString("other[42]", "el_getter");
ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
-
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectString("other[42]", "el_getter");
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
v8::Handle<Value> value;
value = CompileRun("other.accessible_prop = 3");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- CHECK_EQ(3, g_echo_value_1);
-
- // Access accessible js property
- value = CompileRun("other.accessible_js_prop = 3");
- CHECK(value->IsNumber());
- CHECK_EQ(3, value->Int32Value());
- CHECK_EQ(3, g_echo_value_2);
+ CHECK_EQ(3, g_echo_value);
value = CompileRun("other.accessible_prop");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- value = CompileRun("other.accessible_js_prop");
- CHECK(value->IsNumber());
- CHECK_EQ(3, value->Int32Value());
-
value = CompileRun(
"Object.getOwnPropertyDescriptor(other, 'accessible_prop').value");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- value = CompileRun(
- "Object.getOwnPropertyDescriptor(other, 'accessible_js_prop').get()");
- CHECK(value->IsNumber());
- CHECK_EQ(3, value->Int32Value());
-
value = CompileRun("propertyIsEnumerable.call(other, 'accessible_prop')");
CHECK(value->IsTrue());
- value = CompileRun("propertyIsEnumerable.call(other, 'accessible_js_prop')");
- CHECK(value->IsTrue());
-
// Enumeration doesn't enumerate accessors from inaccessible objects in
// the prototype chain even if the accessors are in themselves accessible.
- value =
- CompileRun("(function(){var obj = {'__proto__':other};"
- "for (var p in obj)"
- " if (p == 'accessible_prop' ||"
- " p == 'accessible_js_prop' ||"
- " p == 'blocked_js_prop' ||"
- " p == 'blocked_js_prop') {"
- " return false;"
- " }"
- "return true;})()");
+ value = CompileRun(
+ "(function() {"
+ " var obj = { '__proto__': other };"
+ " try {"
+ " for (var p in obj) {"
+ " if (p == 'accessible_prop' ||"
+ " p == 'blocked_js_prop' ||"
+ " p == 'blocked_js_prop') {"
+ " return false;"
+ " }"
+ " }"
+ " return false;"
+ " } catch (e) {"
+ " return true;"
+ " }"
+ "})()");
CHECK(value->IsTrue());
context1->Exit();
TEST(AccessControlES5) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedAccessBlocker,
IndexedAccessBlocker);
global1->Set(v8_str("other"), global0);
// Regression test for issue 1154.
- ExpectTrue("Object.keys(other).indexOf('blocked_prop') == -1");
-
- ExpectUndefined("other.blocked_prop");
+ CHECK(CompileRun("Object.keys(other)").IsEmpty());
+ CHECK(CompileRun("other.blocked_prop").IsEmpty());
// Regression test for issue 1027.
CompileRun("Object.defineProperty(\n"
" other, 'blocked_prop', {configurable: false})");
- ExpectUndefined("other.blocked_prop");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop')");
+ CHECK(CompileRun("other.blocked_prop").IsEmpty());
+ CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'blocked_prop')")
+ .IsEmpty());
// Regression test for issue 1171.
ExpectTrue("Object.isExtensible(other)");
// Make sure that we can set the accessible accessors value using normal
// assignment.
CompileRun("other.accessible_prop = 42");
- CHECK_EQ(42, g_echo_value_1);
+ CHECK_EQ(42, g_echo_value);
v8::Handle<Value> value;
- // We follow Safari in ignoring assignments to host object accessors.
CompileRun("Object.defineProperty(other, 'accessible_prop', {value: -1})");
value = CompileRun("other.accessible_prop == 42");
CHECK(value->IsTrue());
}
-static bool GetOwnPropertyNamesNamedBlocker(Local<v8::Object> global,
- Local<Value> name,
- v8::AccessType type,
- Local<Value> data) {
+static bool BlockEverythingNamed(Local<v8::Object> object, Local<Value> name,
+ v8::AccessType type, Local<Value> data) {
return false;
}
-static bool GetOwnPropertyNamesIndexedBlocker(Local<v8::Object> global,
- uint32_t key,
- v8::AccessType type,
- Local<Value> data) {
+static bool BlockEverythingIndexed(Local<v8::Object> object, uint32_t key,
+ v8::AccessType type, Local<Value> data) {
return false;
}
THREADED_TEST(AccessControlGetOwnPropertyNames) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
- v8::Handle<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
- obj_template->Set(v8_str("x"), v8::Integer::New(42));
- obj_template->SetAccessCheckCallbacks(GetOwnPropertyNamesNamedBlocker,
- GetOwnPropertyNamesIndexedBlocker);
+ obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
+ obj_template->SetAccessCheckCallbacks(BlockEverythingNamed,
+ BlockEverythingIndexed);
// Create an environment
v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
// proxy object. Accessing the object that requires access checks
// is blocked by the access checks on the object itself.
value = CompileRun("Object.getOwnPropertyNames(other).length == 0");
- CHECK(value->IsTrue());
+ CHECK(value.IsEmpty());
value = CompileRun("Object.getOwnPropertyNames(object).length == 0");
- CHECK(value->IsTrue());
+ CHECK(value.IsEmpty());
context1->Exit();
context0->Exit();
}
+TEST(SuperAccessControl) {
+ i::FLAG_harmony_classes = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
+ obj_template->SetAccessCheckCallbacks(BlockEverythingNamed,
+ BlockEverythingIndexed);
+ LocalContext env;
+ env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "function f() { return super.hasOwnProperty; };"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "function f() { return super[42]; };"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "function f() { super.hasOwnProperty = function () {}; };"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "Object.defineProperty(Object.prototype, 'x', { set : function(){}});"
+ "function f() { "
+ " 'use strict';"
+ " super.x = function () {}; "
+ "};"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
+}
+
+
static void IndexedPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
- v8::Handle<v8::Array> result = v8::Array::New(2);
- result->Set(0, v8::Integer::New(7));
- result->Set(1, v8::Object::New());
+ v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2);
+ result->Set(0, v8::Integer::New(info.GetIsolate(), 7));
+ result->Set(1, v8::Object::New(info.GetIsolate()));
info.GetReturnValue().Set(result);
}
static void NamedPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
- v8::Handle<v8::Array> result = v8::Array::New(2);
+ v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2);
result->Set(0, v8_str("x"));
- result->Set(1, v8::Object::New());
+ result->Set(1, v8::Object::New(info.GetIsolate()));
info.GetReturnValue().Set(result);
}
THREADED_TEST(GetOwnPropertyNamesWithInterceptor) {
- v8::HandleScope handle_scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
- obj_template->Set(v8_str("7"), v8::Integer::New(7));
- obj_template->Set(v8_str("x"), v8::Integer::New(42));
+ obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7));
+ obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42));
obj_template->SetIndexedPropertyHandler(NULL, NULL, NULL, NULL,
IndexedPropertyEnumerator);
obj_template->SetNamedPropertyHandler(NULL, NULL, NULL, NULL,
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
- v8::Handle<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> func_template =
+ v8::FunctionTemplate::New(isolate);
v8::Handle<v8::ObjectTemplate> global_template =
func_template->InstanceTemplate();
CHECK_EQ(10, value->Int32Value());
value = v8_compile("other.unreachable")->Run();
- CHECK(value->IsUndefined());
+ CHECK(value.IsEmpty());
context1->Exit();
context0->Exit();
// Create an object that requires access-check functions to be
// called for cross-domain access.
- v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
object_template->SetAccessCheckCallbacks(NamedAccessCounter,
IndexedAccessCounter);
Local<v8::Object> object = object_template->NewInstance();
// Create an object that requires access-check functions to be
// called for cross-domain access.
- v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
object_template->SetAccessCheckCallbacks(NamedAccessFlatten,
IndexedAccessFlatten);
Local<v8::Object> object = object_template->NewInstance();
// Create an object that requires access-check functions to be
// called for cross-domain access. The object also has interceptors
// interceptor.
- v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
object_template->SetAccessCheckCallbacks(NamedAccessCounter,
IndexedAccessCounter);
object_template->SetNamedPropertyHandler(AccessControlNamedGetter,
THREADED_TEST(InstanceProperties) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> instance = t->InstanceTemplate();
instance->Set(v8_str("x"), v8_num(42));
instance->Set(v8_str("f"),
- v8::FunctionTemplate::New(InstanceFunctionCallback));
+ v8::FunctionTemplate::New(isolate, InstanceFunctionCallback));
Local<Value> o = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("i"), o);
- Local<Value> value = Script::Compile(v8_str("i.x"))->Run();
+ Local<Value> value = CompileRun("i.x");
CHECK_EQ(42, value->Int32Value());
- value = Script::Compile(v8_str("i.f()"))->Run();
+ value = CompileRun("i.f()");
CHECK_EQ(12, value->Int32Value());
}
THREADED_TEST(GlobalObjectInstanceProperties) {
- v8::HandleScope handle_scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
Local<Value> global_object;
- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
t->InstanceTemplate()->SetNamedPropertyHandler(
GlobalObjectInstancePropertiesGet);
Local<ObjectTemplate> instance_template = t->InstanceTemplate();
instance_template->Set(v8_str("x"), v8_num(42));
instance_template->Set(v8_str("f"),
- v8::FunctionTemplate::New(InstanceFunctionCallback));
+ v8::FunctionTemplate::New(isolate,
+ InstanceFunctionCallback));
// The script to check how Crankshaft compiles missing global function
// invocations. function g is not defined and should throw on call.
// environment initialization.
global_object = env->Global();
- Local<Value> value = Script::Compile(v8_str("x"))->Run();
+ Local<Value> value = CompileRun("x");
CHECK_EQ(42, value->Int32Value());
- value = Script::Compile(v8_str("f()"))->Run();
+ value = CompileRun("f()");
CHECK_EQ(12, value->Int32Value());
- value = Script::Compile(v8_str(script))->Run();
+ value = CompileRun(script);
CHECK_EQ(1, value->Int32Value());
}
{
// Create new environment reusing the global object.
LocalContext env(NULL, instance_template, global_object);
- Local<Value> value = Script::Compile(v8_str("x"))->Run();
+ Local<Value> value = CompileRun("x");
CHECK_EQ(42, value->Int32Value());
- value = Script::Compile(v8_str("f()"))->Run();
+ value = CompileRun("f()");
CHECK_EQ(12, value->Int32Value());
- value = Script::Compile(v8_str(script))->Run();
+ value = CompileRun(script);
CHECK_EQ(1, value->Int32Value());
}
}
THREADED_TEST(CallKnownGlobalReceiver) {
- v8::HandleScope handle_scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
Local<Value> global_object;
- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> instance_template = t->InstanceTemplate();
// The script to check that we leave global object not
// Hold on to the global object so it can be used again in another
// environment initialization.
global_object = env->Global();
- foo = Script::Compile(v8_str(script))->Run();
+ foo = CompileRun(script);
}
{
// Create new environment reusing the global object.
LocalContext env(NULL, instance_template, global_object);
env->Global()->Set(v8_str("foo"), foo);
- Script::Compile(v8_str("foo()"))->Run();
+ CompileRun("foo()");
}
}
THREADED_TEST(ShadowObject) {
shadow_y = shadow_y_setter_call_count = shadow_y_getter_call_count = 0;
- v8::HandleScope handle_scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
- Local<ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ Local<ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate);
LocalContext context(NULL, global_template);
- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
t->InstanceTemplate()->SetNamedPropertyHandler(ShadowNamedGet);
t->InstanceTemplate()->SetIndexedPropertyHandler(ShadowIndexedGet);
Local<ObjectTemplate> proto = t->PrototypeTemplate();
Local<ObjectTemplate> instance = t->InstanceTemplate();
proto->Set(v8_str("f"),
- v8::FunctionTemplate::New(ShadowFunctionCallback, Local<Value>()));
+ v8::FunctionTemplate::New(isolate,
+ ShadowFunctionCallback,
+ Local<Value>()));
proto->Set(v8_str("x"), v8_num(12));
instance->SetAccessor(v8_str("y"), ShadowYGetter, ShadowYSetter);
context->Global()->Set(v8_str("__proto__"), o);
Local<Value> value =
- Script::Compile(v8_str("this.propertyIsEnumerable(0)"))->Run();
+ CompileRun("this.propertyIsEnumerable(0)");
CHECK(value->IsBoolean());
CHECK(!value->BooleanValue());
- value = Script::Compile(v8_str("x"))->Run();
+ value = CompileRun("x");
CHECK_EQ(12, value->Int32Value());
- value = Script::Compile(v8_str("f()"))->Run();
+ value = CompileRun("f()");
CHECK_EQ(42, value->Int32Value());
- Script::Compile(v8_str("y = 43"))->Run();
+ CompileRun("y = 43");
CHECK_EQ(1, shadow_y_setter_call_count);
- value = Script::Compile(v8_str("y"))->Run();
+ value = CompileRun("y");
CHECK_EQ(1, shadow_y_getter_call_count);
CHECK_EQ(42, value->Int32Value());
}
THREADED_TEST(HiddenPrototype) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
- Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate);
t0->InstanceTemplate()->Set(v8_str("x"), v8_num(0));
- Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
t1->SetHiddenPrototype(true);
t1->InstanceTemplate()->Set(v8_str("y"), v8_num(1));
- Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate);
t2->SetHiddenPrototype(true);
t2->InstanceTemplate()->Set(v8_str("z"), v8_num(2));
- Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate);
t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3));
Local<v8::Object> o0 = t0->GetFunction()->NewInstance();
THREADED_TEST(HiddenPrototypeSet) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
- Local<v8::FunctionTemplate> ot = v8::FunctionTemplate::New();
- Local<v8::FunctionTemplate> ht = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> ot = v8::FunctionTemplate::New(isolate);
+ Local<v8::FunctionTemplate> ht = v8::FunctionTemplate::New(isolate);
ht->SetHiddenPrototype(true);
- Local<v8::FunctionTemplate> pt = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> pt = v8::FunctionTemplate::New(isolate);
ht->InstanceTemplate()->Set(v8_str("x"), v8_num(0));
Local<v8::Object> o = ot->GetFunction()->NewInstance();
LocalContext context;
v8::HandleScope handle_scope(context->GetIsolate());
- Handle<FunctionTemplate> t = FunctionTemplate::New();
+ Handle<FunctionTemplate> t = FunctionTemplate::New(context->GetIsolate());
t->SetHiddenPrototype(true);
t->InstanceTemplate()->Set(v8_str("foo"), v8_num(75));
Handle<Object> p = t->GetFunction()->NewInstance();
- Handle<Object> o = Object::New();
+ Handle<Object> o = Object::New(context->GetIsolate());
o->SetPrototype(p);
int hash = o->GetIdentityHash();
USE(hash);
o->Set(v8_str("foo"), v8_num(42));
- ASSERT_EQ(hash, o->GetIdentityHash());
+ DCHECK_EQ(hash, o->GetIdentityHash());
}
THREADED_TEST(SetPrototype) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
- Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate);
t0->InstanceTemplate()->Set(v8_str("x"), v8_num(0));
- Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
t1->SetHiddenPrototype(true);
t1->InstanceTemplate()->Set(v8_str("y"), v8_num(1));
- Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate);
t2->SetHiddenPrototype(true);
t2->InstanceTemplate()->Set(v8_str("z"), v8_num(2));
- Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate);
t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3));
Local<v8::Object> o0 = t0->GetFunction()->NewInstance();
// Getting property names of an object with a prototype chain that
-// triggers dictionary elements in GetLocalPropertyNames() shouldn't
+// triggers dictionary elements in GetOwnPropertyNames() shouldn't
// crash the runtime.
THREADED_TEST(Regress91517) {
i::FLAG_allow_natives_syntax = true;
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
- Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
t1->SetHiddenPrototype(true);
t1->InstanceTemplate()->Set(v8_str("foo"), v8_num(1));
- Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate);
t2->SetHiddenPrototype(true);
t2->InstanceTemplate()->Set(v8_str("fuz1"), v8_num(2));
- t2->InstanceTemplate()->Set(v8_str("objects"), v8::Object::New());
+ t2->InstanceTemplate()->Set(v8_str("objects"), v8::Object::New(isolate));
t2->InstanceTemplate()->Set(v8_str("fuz2"), v8_num(2));
- Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate);
t3->SetHiddenPrototype(true);
t3->InstanceTemplate()->Set(v8_str("boo"), v8_num(3));
- Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New(isolate);
t4->InstanceTemplate()->Set(v8_str("baz"), v8_num(4));
// Force dictionary-based properties.
i::ScopedVector<char> name_buf(1024);
for (int i = 1; i <= 1000; i++) {
- i::OS::SNPrintF(name_buf, "sdf%d", i);
+ i::SNPrintF(name_buf, "sdf%d", i);
t2->InstanceTemplate()->Set(v8_str(name_buf.start()), v8_num(2));
}
CHECK(o3->SetPrototype(o2));
CHECK(o2->SetPrototype(o1));
- // Call the runtime version of GetLocalPropertyNames() on the natively
+ // Call the runtime version of GetOwnPropertyNames() on the natively
// created object through JavaScript.
context->Global()->Set(v8_str("obj"), o4);
- CompileRun("var names = %GetLocalPropertyNames(obj, true);");
+ // PROPERTY_ATTRIBUTES_NONE = 0
+ CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
ExpectInt32("names.length", 1006);
ExpectTrue("names.indexOf(\"baz\") >= 0");
}
-THREADED_TEST(FunctionReadOnlyPrototype) {
+// Getting property names of an object with a hidden and inherited
+// prototype should not duplicate the accessor properties inherited.
+THREADED_TEST(Regress269562) {
+ i::FLAG_allow_natives_syntax = true;
LocalContext context;
v8::HandleScope handle_scope(context->GetIsolate());
- Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
- t1->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(42));
+ Local<v8::FunctionTemplate> t1 =
+ v8::FunctionTemplate::New(context->GetIsolate());
+ t1->SetHiddenPrototype(true);
+
+ Local<v8::ObjectTemplate> i1 = t1->InstanceTemplate();
+ i1->SetAccessor(v8_str("foo"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ i1->SetAccessor(v8_str("bar"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ i1->SetAccessor(v8_str("baz"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ i1->Set(v8_str("n1"), v8_num(1));
+ i1->Set(v8_str("n2"), v8_num(2));
+
+ Local<v8::Object> o1 = t1->GetFunction()->NewInstance();
+ Local<v8::FunctionTemplate> t2 =
+ v8::FunctionTemplate::New(context->GetIsolate());
+ t2->SetHiddenPrototype(true);
+
+ // Inherit from t1 and mark prototype as hidden.
+ t2->Inherit(t1);
+ t2->InstanceTemplate()->Set(v8_str("mine"), v8_num(4));
+
+ Local<v8::Object> o2 = t2->GetFunction()->NewInstance();
+ CHECK(o2->SetPrototype(o1));
+
+ v8::Local<v8::Symbol> sym =
+ v8::Symbol::New(context->GetIsolate(), v8_str("s1"));
+ o1->Set(sym, v8_num(3));
+ o1->SetHiddenValue(
+ v8_str("h1"), v8::Integer::New(context->GetIsolate(), 2013));
+
+ // Call the runtime version of GetOwnPropertyNames() on
+ // the natively created object through JavaScript.
+ context->Global()->Set(v8_str("obj"), o2);
+ context->Global()->Set(v8_str("sym"), sym);
+ // PROPERTY_ATTRIBUTES_NONE = 0
+ CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
+
+ ExpectInt32("names.length", 7);
+ ExpectTrue("names.indexOf(\"foo\") >= 0");
+ ExpectTrue("names.indexOf(\"bar\") >= 0");
+ ExpectTrue("names.indexOf(\"baz\") >= 0");
+ ExpectTrue("names.indexOf(\"n1\") >= 0");
+ ExpectTrue("names.indexOf(\"n2\") >= 0");
+ ExpectTrue("names.indexOf(sym) >= 0");
+ ExpectTrue("names.indexOf(\"mine\") >= 0");
+}
+
+
+THREADED_TEST(FunctionReadOnlyPrototype) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
+ t1->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(isolate, 42));
t1->ReadOnlyPrototype();
context->Global()->Set(v8_str("func1"), t1->GetFunction());
// Configured value of ReadOnly flag.
CHECK_EQ(42,
CompileRun("func1.prototype = {}; func1.prototype.x")->Int32Value());
- Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
- t2->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(42));
+ Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate);
+ t2->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(isolate, 42));
context->Global()->Set(v8_str("func2"), t2->GetFunction());
// Default value of ReadOnly flag.
CHECK(CompileRun(
THREADED_TEST(SetPrototypeThrows) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
Local<v8::Object> o0 = t->GetFunction()->NewInstance();
Local<v8::Object> o1 = t->GetFunction()->NewInstance();
v8::TryCatch try_catch;
CHECK(!o1->SetPrototype(o0));
CHECK(!try_catch.HasCaught());
- ASSERT(!CcTest::i_isolate()->has_pending_exception());
+ DCHECK(!CcTest::i_isolate()->has_pending_exception());
CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value());
}
THREADED_TEST(FunctionRemovePrototype) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
- Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
t1->RemovePrototype();
Local<v8::Function> fun = t1->GetFunction();
context->Global()->Set(v8_str("fun"), fun);
THREADED_TEST(GetterSetterExceptions) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
CompileRun(
"function Foo() { };"
"function Throw() { throw 5; };"
Local<v8::Object> x =
Local<v8::Object>::Cast(context->Global()->Get(v8_str("x")));
v8::TryCatch try_catch;
- x->Set(v8_str("set"), v8::Integer::New(8));
+ x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
x->Get(v8_str("get"));
- x->Set(v8_str("set"), v8::Integer::New(8));
+ x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
x->Get(v8_str("get"));
- x->Set(v8_str("set"), v8::Integer::New(8));
+ x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
x->Get(v8_str("get"));
- x->Set(v8_str("set"), v8::Integer::New(8));
+ x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
x->Get(v8_str("get"));
}
THREADED_TEST(Constructor) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
- Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->SetClassName(v8_str("Fun"));
Local<Function> cons = templ->GetFunction();
context->Global()->Set(v8_str("Fun"), cons);
if (args.IsConstructCall()) {
Local<Object> Holder = args.Holder();
- This = Object::New();
+ This = Object::New(args.GetIsolate());
Local<Value> proto = Holder->GetPrototype();
if (proto->IsObject()) {
This->SetPrototype(proto);
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope handle_scope(isolate);
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
instance_template->SetCallAsFunctionHandler(ConstructorCallback);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj"), instance);
}
// Check exception handling when there is no constructor set for the Object.
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj2"), instance);
v8::TryCatch try_catch;
}
// Check the case when constructor throws exception.
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
instance_template->SetCallAsFunctionHandler(ThrowValue);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj3"), instance);
// Check whether constructor returns with an object or non-object.
{ Local<FunctionTemplate> function_template =
- FunctionTemplate::New(FakeConstructorCallback);
+ FunctionTemplate::New(isolate, FakeConstructorCallback);
Local<Function> function = function_template->GetFunction();
Local<Object> instance1 = function;
context->Global()->Set(v8_str("obj4"), instance1);
CHECK(!try_catch.HasCaught());
CHECK(value->IsObject());
- Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
instance_template->SetCallAsFunctionHandler(FakeConstructorCallback);
Local<Object> instance2 = instance_template->NewInstance();
context->Global()->Set(v8_str("obj5"), instance2);
THREADED_TEST(FunctionDescriptorException) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
- Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->SetClassName(v8_str("Fun"));
Local<Function> cons = templ->GetFunction();
context->Global()->Set(v8_str("Fun"), cons);
" (new Fun()).blah()"
" } catch (e) {"
" var str = String(e);"
- " if (str.indexOf('TypeError') == -1) return 1;"
- " if (str.indexOf('[object Fun]') != -1) return 2;"
- " if (str.indexOf('#<Fun>') == -1) return 3;"
+ // " if (str.indexOf('TypeError') == -1) return 1;"
+ // " if (str.indexOf('[object Fun]') != -1) return 2;"
+ // " if (str.indexOf('#<Fun>') == -1) return 3;"
" return 0;"
" }"
" return 4;"
v8::HandleScope scope(current->GetIsolate());
// Tests where aliased eval can only be resolved dynamically.
- Local<Script> script =
- Script::Compile(v8_str("function f(x) { "
- " var foo = 2;"
- " with (x) { return eval('foo'); }"
- "}"
- "foo = 0;"
- "result1 = f(new Object());"
- "result2 = f(this);"
- "var x = new Object();"
- "x.eval = function(x) { return 1; };"
- "result3 = f(x);"));
+ Local<Script> script = v8_compile(
+ "function f(x) { "
+ " var foo = 2;"
+ " with (x) { return eval('foo'); }"
+ "}"
+ "foo = 0;"
+ "result1 = f(new Object());"
+ "result2 = f(this);"
+ "var x = new Object();"
+ "x.eval = function(x) { return 1; };"
+ "result3 = f(x);");
script->Run();
CHECK_EQ(2, current->Global()->Get(v8_str("result1"))->Int32Value());
CHECK_EQ(0, current->Global()->Get(v8_str("result2"))->Int32Value());
CHECK_EQ(1, current->Global()->Get(v8_str("result3"))->Int32Value());
v8::TryCatch try_catch;
- script =
- Script::Compile(v8_str("function f(x) { "
- " var bar = 2;"
- " with (x) { return eval('bar'); }"
- "}"
- "result4 = f(this)"));
+ script = v8_compile(
+ "function f(x) { "
+ " var bar = 2;"
+ " with (x) { return eval('bar'); }"
+ "}"
+ "result4 = f(this)");
script->Run();
CHECK(!try_catch.HasCaught());
CHECK_EQ(2, current->Global()->Get(v8_str("result4"))->Int32Value());
current->Global()->Set(v8_str("other"), other->Global());
// Check that new variables are introduced in other context.
- Local<Script> script =
- Script::Compile(v8_str("other.eval('var foo = 1234')"));
+ Local<Script> script = v8_compile("other.eval('var foo = 1234')");
script->Run();
Local<Value> foo = other->Global()->Get(v8_str("foo"));
CHECK_EQ(1234, foo->Int32Value());
// Check that writing to non-existing properties introduces them in
// the other context.
- script =
- Script::Compile(v8_str("other.eval('na = 1234')"));
+ script = v8_compile("other.eval('na = 1234')");
script->Run();
CHECK_EQ(1234, other->Global()->Get(v8_str("na"))->Int32Value());
CHECK(!current->Global()->Has(v8_str("na")));
// Check that global variables in current context are not visible in other
// context.
v8::TryCatch try_catch;
- script =
- Script::Compile(v8_str("var bar = 42; other.eval('bar');"));
+ script = v8_compile("var bar = 42; other.eval('bar');");
Local<Value> result = script->Run();
CHECK(try_catch.HasCaught());
try_catch.Reset();
// Check that local variables in current context are not visible in other
// context.
- script =
- Script::Compile(v8_str("(function() { "
- " var baz = 87;"
- " return other.eval('baz');"
- "})();"));
+ script = v8_compile(
+ "(function() { "
+ " var baz = 87;"
+ " return other.eval('baz');"
+ "})();");
result = script->Run();
CHECK(try_catch.HasCaught());
try_catch.Reset();
// Check that global variables in the other environment are visible
// when evaluting code.
other->Global()->Set(v8_str("bis"), v8_num(1234));
- script = Script::Compile(v8_str("other.eval('bis')"));
+ script = v8_compile("other.eval('bis')");
CHECK_EQ(1234, script->Run()->Int32Value());
CHECK(!try_catch.HasCaught());
// Check that the 'this' pointer points to the global object evaluating
// code.
other->Global()->Set(v8_str("t"), other->Global());
- script = Script::Compile(v8_str("other.eval('this == t')"));
+ script = v8_compile("other.eval('this == t')");
result = script->Run();
CHECK(result->IsTrue());
CHECK(!try_catch.HasCaught());
// Check that variables introduced in with-statement are not visible in
// other context.
- script =
- Script::Compile(v8_str("with({x:2}){other.eval('x')}"));
+ script = v8_compile("with({x:2}){other.eval('x')}");
result = script->Run();
CHECK(try_catch.HasCaught());
try_catch.Reset();
// Check that you cannot use 'eval.call' with another object than the
// current global object.
- script =
- Script::Compile(v8_str("other.y = 1; eval.call(other, 'y')"));
+ script = v8_compile("other.y = 1; eval.call(other, 'y')");
result = script->Run();
CHECK(try_catch.HasCaught());
}
current->Global()->Set(v8_str("other"), other->Global());
// Trigger lazy loading in other context.
- Local<Script> script =
- Script::Compile(v8_str("other.eval('new Date(42)')"));
+ Local<Script> script = v8_compile("other.eval('new Date(42)')");
Local<Value> value = script->Run();
CHECK_EQ(42.0, value->NumberValue());
}
// functions.
THREADED_TEST(CallAsFunction) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
- { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> instance_template = t->InstanceTemplate();
instance_template->SetCallAsFunctionHandler(call_as_function);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
CHECK_EQ(28, value->Int32Value());
}
- { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> instance_template(t->InstanceTemplate());
USE(instance_template);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
String::Utf8Value exception_value1(try_catch.Exception());
- CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function",
+ // TODO(verwaest): Better message
+ CHECK_EQ("TypeError: object is not a function",
*exception_value1);
try_catch.Reset();
try_catch.Reset();
}
- { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> instance_template = t->InstanceTemplate();
instance_template->SetCallAsFunctionHandler(ThrowValue);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
try_catch.Reset();
}
- { v8::Isolate* isolate = context->GetIsolate();
- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> instance_template = t->InstanceTemplate();
instance_template->SetCallAsFunctionHandler(ReturnThis);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
CHECK(a5->StrictEquals(instance));
}
- { v8::Isolate* isolate = context->GetIsolate();
- CompileRun(
+ { CompileRun(
"function ReturnThisSloppy() {"
" return this;"
"}"
// Check whether a non-function object is callable.
THREADED_TEST(CallableObject) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
instance_template->SetCallAsFunctionHandler(call_as_function);
Local<Object> instance = instance_template->NewInstance();
v8::TryCatch try_catch;
CHECK(!try_catch.HasCaught());
}
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
Local<Object> instance = instance_template->NewInstance();
v8::TryCatch try_catch;
}
{ Local<FunctionTemplate> function_template =
- FunctionTemplate::New(call_as_function);
+ FunctionTemplate::New(isolate, call_as_function);
Local<Function> function = function_template->GetFunction();
Local<Object> instance = function;
v8::TryCatch try_catch;
CHECK(!try_catch.HasCaught());
}
- { Local<FunctionTemplate> function_template = FunctionTemplate::New();
+ { Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate);
Local<Function> function = function_template->GetFunction();
Local<Object> instance = function;
v8::TryCatch try_catch;
}
-static int CountHandles() {
- return v8::HandleScope::NumberOfHandles();
-}
-
-
-static int Recurse(int depth, int iterations) {
- v8::HandleScope scope(CcTest::isolate());
- if (depth == 0) return CountHandles();
+static int Recurse(v8::Isolate* isolate, int depth, int iterations) {
+ v8::HandleScope scope(isolate);
+ if (depth == 0) return v8::HandleScope::NumberOfHandles(isolate);
for (int i = 0; i < iterations; i++) {
- Local<v8::Number> n(v8::Integer::New(42));
+ Local<v8::Number> n(v8::Integer::New(isolate, 42));
}
- return Recurse(depth - 1, iterations);
+ return Recurse(isolate, depth - 1, iterations);
}
THREADED_TEST(HandleIteration) {
static const int kIterations = 500;
static const int kNesting = 200;
- CHECK_EQ(0, CountHandles());
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope0(isolate);
+ CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate));
{
- v8::HandleScope scope1(CcTest::isolate());
- CHECK_EQ(0, CountHandles());
+ v8::HandleScope scope1(isolate);
+ CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate));
for (int i = 0; i < kIterations; i++) {
- Local<v8::Number> n(v8::Integer::New(42));
- CHECK_EQ(i + 1, CountHandles());
+ Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42));
+ CHECK_EQ(i + 1, v8::HandleScope::NumberOfHandles(isolate));
}
- CHECK_EQ(kIterations, CountHandles());
+ CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate));
{
v8::HandleScope scope2(CcTest::isolate());
for (int j = 0; j < kIterations; j++) {
- Local<v8::Number> n(v8::Integer::New(42));
- CHECK_EQ(j + 1 + kIterations, CountHandles());
+ Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42));
+ CHECK_EQ(j + 1 + kIterations,
+ v8::HandleScope::NumberOfHandles(isolate));
}
}
- CHECK_EQ(kIterations, CountHandles());
+ CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate));
}
- CHECK_EQ(0, CountHandles());
- CHECK_EQ(kNesting * kIterations, Recurse(kNesting, kIterations));
+ CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate));
+ CHECK_EQ(kNesting * kIterations, Recurse(isolate, kNesting, kIterations));
}
THREADED_TEST(InterceptorHasOwnProperty) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetter);
Local<Function> function = fun_templ->GetFunction();
THREADED_TEST(InterceptorHasOwnPropertyCausingGC) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC);
Local<Function> function = fun_templ->GetFunction();
static void CheckInterceptorLoadIC(NamedPropertyGetter getter,
const char* source,
int expected) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(getter, 0, 0, 0, 0, v8_str("data"));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
CHECK_EQ(isolate, info.GetIsolate());
CHECK_EQ(v8_str("data"), info.Data());
CHECK_EQ(v8_str("x"), name);
- info.GetReturnValue().Set(v8::Integer::New(42));
+ info.GetReturnValue().Set(v8::Integer::New(isolate, 42));
}
ApiTestFuzzer::Fuzz();
info.GetReturnValue().Set(
v8_str("x")->Equals(name) ?
- v8::Handle<v8::Value>(v8::Integer::New(42)) :
+ v8::Handle<v8::Value>(v8::Integer::New(info.GetIsolate(), 42)) :
v8::Handle<v8::Value>());
}
static void SetOnThis(Local<String> name,
Local<Value> value,
const v8::PropertyCallbackInfo<void>& info) {
- info.This()->ForceSet(name, value);
+ Local<Object>::Cast(info.This())->ForceSet(name, value);
}
THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
templ->SetAccessor(v8_str("y"), Return239Callback);
LocalContext context;
THREADED_TEST(InterceptorLoadICWithCallbackOnProto) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback);
LocalContext context;
THREADED_TEST(InterceptorLoadICForCallbackWithOverride) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
templ->SetAccessor(v8_str("y"), Return239Callback);
// Test the case when we stored callback into
// a stub, but interceptor produced value on its own.
THREADED_TEST(InterceptorLoadICCallbackNotNeeded) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback);
LocalContext context;
// Test the case when we stored callback into
// a stub, but it got invalidated later on.
THREADED_TEST(InterceptorLoadICInvalidatedCallback) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis);
LocalContext context;
// a stub, but it got invalidated later on due to override on
// global object which is between interceptor and callbacks' holders.
THREADED_TEST(InterceptorLoadICInvalidatedCallbackViaGlobal) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis);
LocalContext context;
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK(v8_str("x")->Equals(name));
- info.GetReturnValue().Set(v8::Integer::New(0));
+ info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 0));
}
// This test should hit the store IC for the interceptor case.
THREADED_TEST(InterceptorStoreIC) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorLoadICGetter,
InterceptorStoreICSetter,
0, 0, 0, v8_str("data"));
THREADED_TEST(InterceptorStoreICWithNoSetter) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// This test should hit the call IC for the interceptor case.
THREADED_TEST(InterceptorCallIC) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorCallICGetter);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// This test checks that if interceptor doesn't provide
// a value, we can fetch regular value.
THREADED_TEST(InterceptorCallICSeesOthers) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// even if we cached shadowed variant, interceptor's function
// is invoked
THREADED_TEST(InterceptorCallICCacheableNotNeeded) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorCallICGetter4);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// Test the case when we stored cacheable lookup into
// a stub, but it got invalidated later on
THREADED_TEST(InterceptorCallICInvalidatedCacheable) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// This test checks that if interceptor doesn't provide a function,
// cached constant function is used
THREADED_TEST(InterceptorCallICConstantFunctionUsed) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// even if we cached constant function, interceptor's function
// is invoked
THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorCallICGetter5);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// to test the optimized compiler.
THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) {
i::FLAG_allow_natives_syntax = true;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorCallICGetter6);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// Test the case when we stored constant function into
// a stub, but it got invalidated later on
THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// a stub, but it got invalidated later on due to override on
// global object which is between interceptor and constant function' holders.
THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// Test the case when actual function to call sits on global object.
THREADED_TEST(InterceptorCallICCachedFromGlobal) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New();
- nativeobject_templ->Set("callback",
- v8::FunctionTemplate::New(DirectApiCallback));
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> nativeobject_templ =
+ v8::ObjectTemplate::New(isolate);
+ nativeobject_templ->Set(isolate, "callback",
+ v8::FunctionTemplate::New(isolate,
+ DirectApiCallback));
v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance();
context->Global()->Set(v8_str("nativeobject"), nativeobject_obj);
// call the api function multiple times to ensure direct call stub creation.
THREADED_TEST(CallICFastApi_DirectCall_Throw) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New();
- nativeobject_templ->Set("callback",
- v8::FunctionTemplate::New(ThrowingDirectApiCallback));
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> nativeobject_templ =
+ v8::ObjectTemplate::New(isolate);
+ nativeobject_templ->Set(isolate, "callback",
+ v8::FunctionTemplate::New(isolate,
+ ThrowingDirectApiCallback));
v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance();
context->Global()->Set(v8_str("nativeobject"), nativeobject_obj);
// call the api function multiple times to ensure direct call stub creation.
template<typename Accessor>
static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate);
obj->SetAccessor(v8_str("p1"), accessor);
context->Global()->Set(v8_str("o1"), obj->NewInstance());
p_getter_count = 0;
THREADED_TEST(LoadICFastApi_DirectCall_Throw) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate);
obj->SetAccessor(v8_str("p1"), ThrowingDirectGetterCallback);
context->Global()->Set(v8_str("o1"), obj->NewInstance());
v8::Handle<Value> result = CompileRun(
THREADED_PROFILED_TEST(InterceptorCallICFastApi_TrivialSignature) {
int interceptor_call_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
+ v8::FunctionTemplate::New(isolate,
+ FastApiCallback_TrivialSignature,
v8_str("method_data"),
v8::Handle<v8::Signature>());
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
- NULL, NULL, NULL, NULL,
- v8::External::New(&interceptor_call_count));
+ templ->SetNamedPropertyHandler(
+ InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
+ v8::External::New(isolate, &interceptor_call_count));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) {
int interceptor_call_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
- NULL, NULL, NULL, NULL,
- v8::External::New(&interceptor_call_count));
+ templ->SetNamedPropertyHandler(
+ InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
+ v8::External::New(isolate, &interceptor_call_count));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) {
int interceptor_call_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
- NULL, NULL, NULL, NULL,
- v8::External::New(&interceptor_call_count));
+ templ->SetNamedPropertyHandler(
+ InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
+ v8::External::New(isolate, &interceptor_call_count));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
int interceptor_call_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
- NULL, NULL, NULL, NULL,
- v8::External::New(&interceptor_call_count));
+ templ->SetNamedPropertyHandler(
+ InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
+ v8::External::New(isolate, &interceptor_call_count));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
int interceptor_call_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
- NULL, NULL, NULL, NULL,
- v8::External::New(&interceptor_call_count));
+ templ->SetNamedPropertyHandler(
+ InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
+ v8::External::New(isolate, &interceptor_call_count));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
" }"
"}");
CHECK(try_catch.HasCaught());
- CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
+ // TODO(verwaest): Adjust message.
+ CHECK_EQ(v8_str("TypeError: undefined is not a function"),
try_catch.Exception()->ToString());
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
CHECK_GE(interceptor_call_count, 50);
THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
int interceptor_call_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
- NULL, NULL, NULL, NULL,
- v8::External::New(&interceptor_call_count));
+ templ->SetNamedPropertyHandler(
+ InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
+ v8::External::New(isolate, &interceptor_call_count));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_TrivialSignature,
+ v8::FunctionTemplate::New(isolate,
+ FastApiCallback_TrivialSignature,
v8_str("method_data"),
v8::Handle<v8::Signature>());
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
" }"
"}");
CHECK(try_catch.HasCaught());
- CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
+ // TODO(verwaest): Adjust message.
+ CHECK_EQ(v8_str("TypeError: undefined is not a function"),
try_catch.Exception()->ToString());
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
}
THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::FunctionTemplate> method_templ =
- v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
- v8_str("method_data"),
- v8::Signature::New(fun_templ));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New(
+ isolate, FastApiCallback_SimpleSignature, v8_str("method_data"),
+ v8::Signature::New(isolate, fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
// Test the case when we stored cacheable lookup into
// a stub, but the function name changed (to another cacheable function).
THREADED_TEST(InterceptorKeyedCallICKeyChange1) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// a stub, but the function name changed (and the new function is present
// both before and after the interceptor in the prototype chain).
THREADED_TEST(InterceptorKeyedCallICKeyChange2) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorKeyedCallICGetter);
LocalContext context;
context->Global()->Set(v8_str("proto1"), templ->NewInstance());
// Same as InterceptorKeyedCallICKeyChange1 only the cacheable function sit
// on the global object.
THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
// Test the case when actual function to call sits on global object.
THREADED_TEST(InterceptorKeyedCallICFromGlobal) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ_o->NewInstance());
// Test the map transition before the interceptor.
THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("proto"), templ_o->NewInstance());
// Test the map transition after the interceptor.
THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
templ_o->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ_o->NewInstance());
// Once in a while, the interceptor will reply that a property was not
// found in which case we should get a reference error.
THREADED_TEST(InterceptorICReferenceErrors) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorICRefErrorGetter);
LocalContext context(0, templ, v8::Handle<Value>());
call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run();
// exception once in a while.
THREADED_TEST(InterceptorICGetterExceptions) {
interceptor_ic_exception_get_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(InterceptorICExceptionGetter);
LocalContext context(0, templ, v8::Handle<Value>());
call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run();
// once in a while.
THREADED_TEST(InterceptorICSetterExceptions) {
interceptor_ic_exception_set_count = 0;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(0, InterceptorICExceptionSetter);
LocalContext context(0, templ, v8::Handle<Value>());
v8::Handle<Value> value = CompileRun(
// Test that we ignore null interceptors.
THREADED_TEST(NullNamedInterceptor) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(
static_cast<v8::NamedPropertyGetterCallback>(0));
LocalContext context;
- templ->Set("x", v8_num(42));
+ templ->Set(CcTest::isolate(), "x", v8_num(42));
v8::Handle<v8::Object> obj = templ->NewInstance();
context->Global()->Set(v8_str("obj"), obj);
v8::Handle<Value> value = CompileRun("obj.x");
// Test that we ignore null interceptors.
THREADED_TEST(NullIndexedInterceptor) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(
static_cast<v8::IndexedPropertyGetterCallback>(0));
LocalContext context;
- templ->Set("42", v8_num(42));
+ templ->Set(CcTest::isolate(), "42", v8_num(42));
v8::Handle<v8::Object> obj = templ->NewInstance();
context->Global()->Set(v8_str("obj"), obj);
v8::Handle<Value> value = CompileRun("obj[42]");
THREADED_TEST(NamedPropertyHandlerGetterAttributes) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->InstanceTemplate()->SetNamedPropertyHandler(InterceptorLoadXICGetter);
LocalContext env;
env->Global()->Set(v8_str("obj"),
LocalContext context;
HandleScope scope(context->GetIsolate());
- Local<FunctionTemplate> templ = FunctionTemplate::New();
+ Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate());
Local<ObjectTemplate> instance_templ = templ->InstanceTemplate();
instance_templ->SetAccessor(v8_str("f"), ThrowingGetter);
Local<Object> instance = templ->GetFunction()->NewInstance();
- Local<Object> another = Object::New();
+ Local<Object> another = Object::New(context->GetIsolate());
another->SetPrototype(instance);
Local<Object> with_js_getter = CompileRun(
Handle<String> errorMessageString = message->Get();
CHECK(!errorMessageString.IsEmpty());
message->GetStackTrace();
- message->GetScriptResourceName();
+ message->GetScriptOrigin().ResourceName();
}
THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) {
LocalContext context;
- HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ HandleScope scope(isolate);
Local<Function> func =
- FunctionTemplate::New(ThrowingCallbackWithTryCatch)->GetFunction();
+ FunctionTemplate::New(isolate,
+ ThrowingCallbackWithTryCatch)->GetFunction();
context->Global()->Set(v8_str("func"), func);
MessageCallback callbacks[] =
THREADED_TEST(Overriding) {
- i::FLAG_es5_readonly = true;
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
// Parent template.
- Local<v8::FunctionTemplate> parent_templ = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> parent_templ = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> parent_instance_templ =
parent_templ->InstanceTemplate();
parent_instance_templ->SetAccessor(v8_str("f"), ParentGetter);
// Template that inherits from the parent template.
- Local<v8::FunctionTemplate> child_templ = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> child_templ = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> child_instance_templ =
child_templ->InstanceTemplate();
child_templ->Inherit(parent_templ);
THREADED_TEST(IsConstructCall) {
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
// Function template with call handler.
- Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->SetCallHandler(IsConstructHandler);
LocalContext context;
THREADED_TEST(ObjectProtoToString) {
- v8::HandleScope scope(CcTest::isolate());
- Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
templ->SetClassName(v8_str("MyClass"));
LocalContext context;
}
+TEST(ObjectProtoToStringES6) {
+ // TODO(dslomov, caitp): merge into ObjectProtoToString test once shipped.
+ i::FLAG_harmony_tostring = true;
+ LocalContext context;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
+ templ->SetClassName(v8_str("MyClass"));
+
+ Local<String> customized_tostring = v8_str("customized toString");
+
+ // Replace Object.prototype.toString
+ CompileRun(
+ "Object.prototype.toString = function() {"
+ " return 'customized toString';"
+ "}");
+
+ // Normal ToString call should call replaced Object.prototype.toString
+ Local<v8::Object> instance = templ->GetFunction()->NewInstance();
+ Local<String> value = instance->ToString();
+ CHECK(value->IsString() && value->Equals(customized_tostring));
+
+ // ObjectProtoToString should not call replace toString function.
+ value = instance->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object MyClass]")));
+
+ // Check global
+ value = context->Global()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object global]")));
+
+ // Check ordinary object
+ Local<Value> object = CompileRun("new Object()");
+ value = object.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Object]")));
+
+ // Check that ES6 semantics using @@toStringTag work
+ Local<v8::Symbol> toStringTag = v8::Symbol::GetToStringTag(isolate);
+
+#define TEST_TOSTRINGTAG(type, tag, expected) \
+ do { \
+ object = CompileRun("new " #type "()"); \
+ object.As<v8::Object>()->Set(toStringTag, v8_str(#tag)); \
+ value = object.As<v8::Object>()->ObjectProtoToString(); \
+ CHECK(value->IsString() && \
+ value->Equals(v8_str("[object " #expected "]"))); \
+ } while (0)
+
+ TEST_TOSTRINGTAG(Array, Object, Object);
+ TEST_TOSTRINGTAG(Object, Arguments, ~Arguments);
+ TEST_TOSTRINGTAG(Object, Array, ~Array);
+ TEST_TOSTRINGTAG(Object, Boolean, ~Boolean);
+ TEST_TOSTRINGTAG(Object, Date, ~Date);
+ TEST_TOSTRINGTAG(Object, Error, ~Error);
+ TEST_TOSTRINGTAG(Object, Function, ~Function);
+ TEST_TOSTRINGTAG(Object, Number, ~Number);
+ TEST_TOSTRINGTAG(Object, RegExp, ~RegExp);
+ TEST_TOSTRINGTAG(Object, String, ~String);
+ TEST_TOSTRINGTAG(Object, Foo, Foo);
+
+#undef TEST_TOSTRINGTAG
+
+ // @@toStringTag getter throws
+ Local<Value> obj = v8::Object::New(isolate);
+ obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter);
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ }
+
+ // @@toStringTag getter does not throw
+ obj = v8::Object::New(isolate);
+ obj.As<v8::Object>()->SetAccessor(
+ toStringTag, SymbolAccessorGetterReturnsDefault, 0, v8_str("Test"));
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+ CHECK(!try_catch.HasCaught());
+ }
+
+ // JS @@toStringTag value
+ obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj");
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+ CHECK(!try_catch.HasCaught());
+ }
+
+ // JS @@toStringTag getter throws
+ obj = CompileRun(
+ "obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {"
+ " get: function() { throw 'Test'; }"
+ "}); obj");
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ }
+
+ // JS @@toStringTag getter does not throw
+ obj = CompileRun(
+ "obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {"
+ " get: function() { return 'Test'; }"
+ "}); obj");
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+ CHECK(!try_catch.HasCaught());
+ }
+}
+
+
THREADED_TEST(ObjectGetConstructorName) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
bool ApiTestFuzzer::fuzzing_ = false;
-i::Semaphore ApiTestFuzzer::all_tests_done_(0);
+v8::base::Semaphore ApiTestFuzzer::all_tests_done_(0);
int ApiTestFuzzer::active_tests_;
int ApiTestFuzzer::tests_being_run_;
int ApiTestFuzzer::current_;
// These are locking tests that don't need to be run again
// as part of the locking aggregation tests.
TEST(NestedLockers) {
- v8::Locker locker(CcTest::isolate());
- CHECK(v8::Locker::IsLocked(CcTest::isolate()));
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::Locker locker(isolate);
+ CHECK(v8::Locker::IsLocked(isolate));
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(ThrowInJS);
+ Local<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(isolate, ThrowInJS);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("throw_in_js"), fun);
Local<Script> script = v8_compile("(function () {"
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(ThrowInJSNoCatch);
+ v8::FunctionTemplate::New(env->GetIsolate(), ThrowInJSNoCatch);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("throw_in_js"), fun);
Local<Script> script = v8_compile("(function () {"
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(UnlockForAMoment);
+ v8::FunctionTemplate::New(CcTest::isolate(), UnlockForAMoment);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("unlock_for_a_moment"), fun);
Local<Script> script = v8_compile("(function () {"
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(UnlockForAMoment);
+ v8::FunctionTemplate::New(CcTest::isolate(), UnlockForAMoment);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("unlock_for_a_moment"), fun);
Local<Script> script = v8_compile("(function () {"
static int GetGlobalObjectsCount() {
- CcTest::heap()->EnsureHeapIsIterable();
int count = 0;
i::HeapIterator it(CcTest::heap());
for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
TEST(DontLeakGlobalObjects) {
// Regression test for issues 1139850 and 1174891.
+ i::FLAG_expose_gc = true;
v8::V8::Initialize();
for (int i = 0; i < 5; i++) {
{ v8::HandleScope scope(CcTest::isolate());
LocalContext context;
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope(CcTest::isolate());
LocalContext context;
v8_compile("Date")->Run();
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope(CcTest::isolate());
LocalContext context;
v8_compile("/aaa/")->Run();
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope(CcTest::isolate());
LocalContext context(&extensions);
v8_compile("gc();")->Run();
}
- v8::V8::ContextDisposedNotification();
+ CcTest::isolate()->ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
}
}
CopyableObject handle1;
{
v8::HandleScope scope(isolate);
- handle1.Reset(isolate, v8::Object::New());
+ handle1.Reset(isolate, v8::Object::New(isolate));
}
CHECK_EQ(initial_handles + 1, globals->global_handles_count());
CopyableObject handle2;
int initial_handles = globals->global_handles_count();
{
v8::HandleScope scope(isolate);
- v8::Local<v8::Object> obj = v8::Object::New();
- obj->Set(v8_str("key"), v8::Integer::New(231, isolate));
+ v8::Local<v8::Object> obj = v8::Object::New(isolate);
+ obj->Set(v8_str("key"), v8::Integer::New(isolate, 231));
v8::Persistent<v8::Object>* handle =
new v8::Persistent<v8::Object>(isolate, obj);
handle->SetWeak<v8::Object, v8::Persistent<v8::Object> >(handle,
v8::Persistent<v8::Object> some_object;
v8::Persistent<v8::Object> bad_handle;
-void NewPersistentHandleCallback(v8::Isolate* isolate,
- v8::Persistent<v8::Value>* handle,
- void*) {
- v8::HandleScope scope(isolate);
- bad_handle.Reset(isolate, some_object);
- handle->Dispose();
+void NewPersistentHandleCallback(
+ const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
+ v8::HandleScope scope(data.GetIsolate());
+ bad_handle.Reset(data.GetIsolate(), some_object);
+ data.GetParameter()->Reset();
}
v8::Persistent<v8::Object> handle1, handle2;
{
v8::HandleScope scope(isolate);
- some_object.Reset(isolate, v8::Object::New());
- handle1.Reset(isolate, v8::Object::New());
- handle2.Reset(isolate, v8::Object::New());
+ some_object.Reset(isolate, v8::Object::New(isolate));
+ handle1.Reset(isolate, v8::Object::New(isolate));
+ handle2.Reset(isolate, v8::Object::New(isolate));
}
// Note: order is implementation dependent alas: currently
// global handle nodes are processed by PostGarbageCollectionProcessing
// in reverse allocation order, so if second allocated handle is deleted,
// weak callback of the first handle would be able to 'reallocate' it.
- handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback);
- handle2.Dispose();
- CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ handle1.SetWeak(&handle1, NewPersistentHandleCallback);
+ handle2.Reset();
+ CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
}
v8::Persistent<v8::Object> to_be_disposed;
-void DisposeAndForceGcCallback(v8::Isolate* isolate,
- v8::Persistent<v8::Value>* handle,
- void*) {
- to_be_disposed.Dispose();
+void DisposeAndForceGcCallback(
+ const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
+ to_be_disposed.Reset();
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
- handle->Dispose();
+ data.GetParameter()->Reset();
}
v8::Persistent<v8::Object> handle1, handle2;
{
v8::HandleScope scope(isolate);
- handle1.Reset(isolate, v8::Object::New());
- handle2.Reset(isolate, v8::Object::New());
+ handle1.Reset(isolate, v8::Object::New(isolate));
+ handle2.Reset(isolate, v8::Object::New(isolate));
}
- handle1.MakeWeak<v8::Value, void>(NULL, DisposeAndForceGcCallback);
+ handle1.SetWeak(&handle1, DisposeAndForceGcCallback);
to_be_disposed.Reset(isolate, handle2);
- CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
}
-void DisposingCallback(v8::Isolate* isolate,
- v8::Persistent<v8::Value>* handle,
- void*) {
- handle->Dispose();
+void DisposingCallback(
+ const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
+ data.GetParameter()->Reset();
}
-void HandleCreatingCallback(v8::Isolate* isolate,
- v8::Persistent<v8::Value>* handle,
- void*) {
- v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object>(isolate, v8::Object::New());
- handle->Dispose();
+void HandleCreatingCallback(
+ const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
+ v8::HandleScope scope(data.GetIsolate());
+ v8::Persistent<v8::Object>(data.GetIsolate(),
+ v8::Object::New(data.GetIsolate()));
+ data.GetParameter()->Reset();
}
v8::Persistent<v8::Object> handle1, handle2, handle3;
{
v8::HandleScope scope(isolate);
- handle3.Reset(isolate, v8::Object::New());
- handle2.Reset(isolate, v8::Object::New());
- handle1.Reset(isolate, v8::Object::New());
+ handle3.Reset(isolate, v8::Object::New(isolate));
+ handle2.Reset(isolate, v8::Object::New(isolate));
+ handle1.Reset(isolate, v8::Object::New(isolate));
}
- handle2.MakeWeak<v8::Value, void>(NULL, DisposingCallback);
- handle3.MakeWeak<v8::Value, void>(NULL, HandleCreatingCallback);
- CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ handle2.SetWeak(&handle2, DisposingCallback);
+ handle3.SetWeak(&handle3, HandleCreatingCallback);
+ CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
}
static v8::Handle<Value> NestedScope(v8::Local<Context> env) {
- v8::HandleScope inner(env->GetIsolate());
+ v8::EscapableHandleScope inner(env->GetIsolate());
env->Enter();
- v8::Handle<Value> three = v8_num(3);
- v8::Handle<Value> value = inner.Close(three);
+ v8::Local<Value> three = v8_num(3);
+ v8::Local<Value> value = inner.Escape(three);
env->Exit();
return value;
}
v8::Local<Context> env = Context::New(isolate);
env->Enter();
- Local<ObjectTemplate> t = ObjectTemplate::New();
- t->Set(v8_str("asdf"), v8::FunctionTemplate::New(RuntimeCallback));
+ Local<ObjectTemplate> t = ObjectTemplate::New(isolate);
+ t->Set(v8_str("asdf"), v8::FunctionTemplate::New(isolate, RuntimeCallback));
env->Global()->Set(v8_str("obj"), t->NewInstance());
const char* script =
CompileRun(script);
bar_func_ = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar"))));
- ASSERT(!bar_func_.is_null());
+ DCHECK(!bar_func_.is_null());
foo_func_ =
i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo"))));
- ASSERT(!foo_func_.is_null());
+ DCHECK(!foo_func_.is_null());
v8::Handle<v8::Value> value = CompileRun("bar();");
CHECK(value->IsNumber());
void SetFunctionEntryHookTest::RunTest() {
// Work in a new isolate throughout.
- v8::Isolate* isolate = v8::Isolate::New();
-
- // Test setting the entry hook on the new isolate.
- CHECK(v8::V8::SetFunctionEntryHook(isolate, EntryHook));
-
- // Replacing the hook, once set should fail.
- CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook));
+ v8::Isolate::CreateParams create_params;
+ create_params.entry_hook = EntryHook;
+ create_params.code_event_handler = JitEvent;
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope scope(isolate);
- v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, JitEvent);
-
RunLoopInNewEnv(isolate);
// Check the exepected invocation counts.
// We should record no invocations in this isolate.
CHECK_EQ(0, static_cast<int>(invocations_.size()));
}
- // Since the isolate has been used, we shouldn't be able to set an entry
- // hook anymore.
- CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook));
isolate->Dispose();
}
UNINITIALIZED_TEST(SetJitCodeEventHandler) {
i::FLAG_stress_compaction = true;
i::FLAG_incremental_marking = false;
+ if (i::FLAG_never_compact) return;
const char* script =
"function bar() {"
" var sum = 0;"
// have remnants of state from other code.
v8::Isolate* isolate = v8::Isolate::New();
isolate->Enter();
- i::Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::Heap* heap = i_isolate->heap();
{
v8::HandleScope scope(isolate);
saw_bar = 0;
move_events = 0;
- V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, event_handler);
+ isolate->SetJitCodeEventHandler(v8::kJitCodeEventDefault, event_handler);
// Generate new code objects sparsely distributed across several
// different fragmented code-space pages.
const int kIterations = 10;
for (int i = 0; i < kIterations; ++i) {
LocalContext env(isolate);
- i::AlwaysAllocateScope always_allocate;
+ i::AlwaysAllocateScope always_allocate(i_isolate);
SimulateFullSpace(heap->code_space());
CompileRun(script);
// Force code movement.
heap->CollectAllAvailableGarbage("TestSetJitCodeEventHandler");
- V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+ isolate->SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
CHECK_LE(kIterations, saw_bar);
CHECK_LT(0, move_events);
i::HashMap lineinfo(MatchPointers);
jitcode_line_info = &lineinfo;
- V8::SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting, event_handler);
- V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+ isolate->SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting,
+ event_handler);
+ isolate->SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
jitcode_line_info = NULL;
// We expect that we got some events. Note that if we could get code removal
}
-static int64_t cast(intptr_t x) { return static_cast<int64_t>(x); }
-
-
THREADED_TEST(ExternalAllocatedMemory) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope outer(isolate);
v8::Local<Context> env(Context::New(isolate));
CHECK(!env.IsEmpty());
- const intptr_t kSize = 1024*1024;
- int64_t baseline = cast(isolate->AdjustAmountOfExternalAllocatedMemory(0));
- CHECK_EQ(baseline + cast(kSize),
- cast(isolate->AdjustAmountOfExternalAllocatedMemory(kSize)));
+ const int64_t kSize = 1024*1024;
+ int64_t baseline = isolate->AdjustAmountOfExternalAllocatedMemory(0);
+ CHECK_EQ(baseline + kSize,
+ isolate->AdjustAmountOfExternalAllocatedMemory(kSize));
CHECK_EQ(baseline,
- cast(isolate->AdjustAmountOfExternalAllocatedMemory(-kSize)));
+ isolate->AdjustAmountOfExternalAllocatedMemory(-kSize));
}
v8::HandleScope outer(isolate);
static v8::Persistent<v8::ObjectTemplate> templ;
if (templ.IsEmpty()) {
- v8::HandleScope inner(isolate);
- v8::Handle<v8::ObjectTemplate> local = v8::ObjectTemplate::New();
+ v8::EscapableHandleScope inner(isolate);
+ v8::Local<v8::ObjectTemplate> local = v8::ObjectTemplate::New(isolate);
local->SetInternalFieldCount(1);
- templ.Reset(isolate, inner.Close(local));
+ templ.Reset(isolate, inner.Escape(local));
}
v8::Handle<v8::Object> result =
v8::Local<v8::ObjectTemplate>::New(isolate, templ)->NewInstance();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
v8::TryCatch try_catch;
- v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New(
+ v8::Handle<v8::Value> result = CompileRun(
"function f() {"
" return f();"
"}"
""
- "f();"));
- v8::Handle<v8::Value> result = script->Run();
+ "f();");
CHECK(result.IsEmpty());
}
CHECK_EQ(3, message->GetEndColumn());
v8::String::Utf8Value line(message->GetSourceLine());
CHECK_EQ(" throw 'nirk';", *line);
- v8::String::Utf8Value name(message->GetScriptResourceName());
+ v8::String::Utf8Value name(message->GetScriptOrigin().ResourceName());
CHECK_EQ(resource_name, *name);
}
THREADED_TEST(TryCatchSourceInfo) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::String> source = v8::String::New(
+ v8::Local<v8::String> source = v8_str(
"function Foo() {\n"
" return Bar();\n"
"}\n"
const char* resource_name;
v8::Handle<v8::Script> script;
resource_name = "test.js";
- script = v8::Script::Compile(source, v8::String::New(resource_name));
+ script = CompileWithOrigin(source, resource_name);
CheckTryCatchSourceInfo(script, resource_name, 0);
resource_name = "test1.js";
- v8::ScriptOrigin origin1(v8::String::New(resource_name));
+ v8::ScriptOrigin origin1(
+ v8::String::NewFromUtf8(context->GetIsolate(), resource_name));
script = v8::Script::Compile(source, &origin1);
CheckTryCatchSourceInfo(script, resource_name, 0);
resource_name = "test2.js";
- v8::ScriptOrigin origin2(v8::String::New(resource_name), v8::Integer::New(7));
+ v8::ScriptOrigin origin2(
+ v8::String::NewFromUtf8(context->GetIsolate(), resource_name),
+ v8::Integer::New(context->GetIsolate(), 7));
script = v8::Script::Compile(source, &origin2);
CheckTryCatchSourceInfo(script, resource_name, 7);
}
THREADED_TEST(CompilationCache) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::String> source0 = v8::String::New("1234");
- v8::Handle<v8::String> source1 = v8::String::New("1234");
- v8::Handle<v8::Script> script0 =
- v8::Script::Compile(source0, v8::String::New("test.js"));
- v8::Handle<v8::Script> script1 =
- v8::Script::Compile(source1, v8::String::New("test.js"));
+ v8::Handle<v8::String> source0 =
+ v8::String::NewFromUtf8(context->GetIsolate(), "1234");
+ v8::Handle<v8::String> source1 =
+ v8::String::NewFromUtf8(context->GetIsolate(), "1234");
+ v8::Handle<v8::Script> script0 = CompileWithOrigin(source0, "test.js");
+ v8::Handle<v8::Script> script1 = CompileWithOrigin(source1, "test.js");
v8::Handle<v8::Script> script2 =
v8::Script::Compile(source0); // different origin
CHECK_EQ(1234, script0->Run()->Int32Value());
THREADED_TEST(CallbackFunctionName) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<ObjectTemplate> t = ObjectTemplate::New();
- t->Set(v8_str("asdf"), v8::FunctionTemplate::New(FunctionNameCallback));
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> t = ObjectTemplate::New(isolate);
+ t->Set(v8_str("asdf"),
+ v8::FunctionTemplate::New(isolate, FunctionNameCallback));
context->Global()->Set(v8_str("obj"), t->NewInstance());
v8::Handle<v8::Value> value = CompileRun("obj.asdf.name");
CHECK(value->IsString());
THREADED_TEST(DateAccess) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::Value> date = v8::Date::New(1224744689038.0);
+ v8::Handle<v8::Value> date =
+ v8::Date::New(context->GetIsolate(), 1224744689038.0);
CHECK(date->IsDate());
CHECK_EQ(1224744689038.0, date.As<v8::Date>()->ValueOf());
}
-void CheckProperties(v8::Handle<v8::Value> val, int elmc, const char* elmv[]) {
+void CheckProperties(v8::Isolate* isolate,
+ v8::Handle<v8::Value> val,
+ int elmc,
+ const char* elmv[]) {
v8::Handle<v8::Object> obj = val.As<v8::Object>();
v8::Handle<v8::Array> props = obj->GetPropertyNames();
CHECK_EQ(elmc, props->Length());
for (int i = 0; i < elmc; i++) {
- v8::String::Utf8Value elm(props->Get(v8::Integer::New(i)));
+ v8::String::Utf8Value elm(props->Get(v8::Integer::New(isolate, i)));
CHECK_EQ(elmv[i], *elm);
}
}
-void CheckOwnProperties(v8::Handle<v8::Value> val,
+void CheckOwnProperties(v8::Isolate* isolate,
+ v8::Handle<v8::Value> val,
int elmc,
const char* elmv[]) {
v8::Handle<v8::Object> obj = val.As<v8::Object>();
v8::Handle<v8::Array> props = obj->GetOwnPropertyNames();
CHECK_EQ(elmc, props->Length());
for (int i = 0; i < elmc; i++) {
- v8::String::Utf8Value elm(props->Get(v8::Integer::New(i)));
+ v8::String::Utf8Value elm(props->Get(v8::Integer::New(isolate, i)));
CHECK_EQ(elmv[i], *elm);
}
}
THREADED_TEST(PropertyEnumeration) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New(
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::Value> obj = CompileRun(
"var result = [];"
"result[0] = {};"
"result[1] = {a: 1, b: 2};"
"var proto = {x: 1, y: 2, z: 3};"
"var x = { __proto__: proto, w: 0, z: 1 };"
"result[3] = x;"
- "result;"))->Run();
+ "result;");
v8::Handle<v8::Array> elms = obj.As<v8::Array>();
CHECK_EQ(4, elms->Length());
int elmc0 = 0;
const char** elmv0 = NULL;
- CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
- CheckOwnProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
+ CheckProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0);
+ CheckOwnProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0);
int elmc1 = 2;
const char* elmv1[] = {"a", "b"};
- CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
- CheckOwnProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
+ CheckProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 1)), elmc1, elmv1);
+ CheckOwnProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 1)), elmc1, elmv1);
int elmc2 = 3;
const char* elmv2[] = {"0", "1", "2"};
- CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
- CheckOwnProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
+ CheckProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 2)), elmc2, elmv2);
+ CheckOwnProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 2)), elmc2, elmv2);
int elmc3 = 4;
const char* elmv3[] = {"w", "z", "x", "y"};
- CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3);
+ CheckProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 3)), elmc3, elmv3);
int elmc4 = 2;
const char* elmv4[] = {"w", "z"};
- CheckOwnProperties(elms->Get(v8::Integer::New(3)), elmc4, elmv4);
+ CheckOwnProperties(
+ isolate, elms->Get(v8::Integer::New(isolate, 3)), elmc4, elmv4);
}
THREADED_TEST(PropertyEnumeration2) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New(
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::Value> obj = CompileRun(
"var result = [];"
"result[0] = {};"
"result[1] = {a: 1, b: 2};"
"var proto = {x: 1, y: 2, z: 3};"
"var x = { __proto__: proto, w: 0, z: 1 };"
"result[3] = x;"
- "result;"))->Run();
+ "result;");
v8::Handle<v8::Array> elms = obj.As<v8::Array>();
CHECK_EQ(4, elms->Length());
int elmc0 = 0;
const char** elmv0 = NULL;
- CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
+ CheckProperties(isolate,
+ elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0);
- v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(0));
+ v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(isolate, 0));
v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames();
CHECK_EQ(0, props->Length());
for (uint32_t i = 0; i < props->Length(); i++) {
- printf("p[%d]\n", i);
+ printf("p[%u]\n", i);
}
}
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessCheckCallbacks(NamedSetAccessBlocker,
IndexedSetAccessBlocker);
templ->Set(v8_str("x"), v8::True(isolate));
THREADED_TEST(AccessChecksReenabledCorrectly) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessCheckCallbacks(NamedGetAccessBlocker,
IndexedGetAccessBlocker);
templ->Set(v8_str("a"), v8_str("a"));
for (char k = '0'; k <= '9'; k++) {
buf[2] = k;
buf[3] = 0;
- templ->Set(v8_str(buf), v8::Number::New(k));
+ templ->Set(v8_str(buf), v8::Number::New(isolate, k));
}
}
}
context->Global()->Set(v8_str("obj_1"), instance_1);
Local<Value> value_1 = CompileRun("obj_1.a");
- CHECK(value_1->IsUndefined());
+ CHECK(value_1.IsEmpty());
Local<v8::Object> instance_2 = templ->NewInstance();
context->Global()->Set(v8_str("obj_2"), instance_2);
Local<Value> value_2 = CompileRun("obj_2.a");
- CHECK(value_2->IsUndefined());
+ CHECK(value_2.IsEmpty());
}
THREADED_TEST(AccessControlRepeatedContextCreation) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedSetAccessBlocker,
IndexedSetAccessBlocker);
i::Handle<i::ObjectTemplateInfo> internal_template =
// Create an environment with access check to the global object disabled by
// default.
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedGetAccessBlocker,
IndexedGetAccessBlocker,
v8::Handle<v8::Value>(),
}
// Detach the global and turn on access check.
+ Local<Object> hidden_global = Local<Object>::Cast(
+ context->Global()->GetPrototype());
context->DetachGlobal();
- context->Global()->TurnOnAccessCheck();
+ hidden_global->TurnOnAccessCheck();
- // Failing access check to property get results in undefined.
- CHECK(f1->Call(global, 0, NULL)->IsUndefined());
- CHECK(f2->Call(global, 0, NULL)->IsUndefined());
-
- // Failing access check to function call results in exception.
+ // Failing access check results in exception.
+ CHECK(f1->Call(global, 0, NULL).IsEmpty());
+ CHECK(f2->Call(global, 0, NULL).IsEmpty());
CHECK(g1->Call(global, 0, NULL).IsEmpty());
CHECK(g2->Call(global, 0, NULL).IsEmpty());
// Create an environment with access check to the global object disabled by
// default. When the registered access checker will block access to properties
// a and h.
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedGetAccessBlockAandH,
IndexedGetAccessBlocker,
v8::Handle<v8::Value>(),
// Detach the global and turn on access check now blocking access to property
// a and function h.
+ Local<Object> hidden_global = Local<Object>::Cast(
+ context->Global()->GetPrototype());
context->DetachGlobal();
- context->Global()->TurnOnAccessCheck();
+ hidden_global->TurnOnAccessCheck();
- // Failing access check to property get results in undefined.
- CHECK(f1->Call(global, 0, NULL)->IsUndefined());
- CHECK(f2->Call(global, 0, NULL)->IsUndefined());
-
- // Failing access check to function call results in exception.
+ // Failing access check results in exception.
+ CHECK(f1->Call(global, 0, NULL).IsEmpty());
+ CHECK(f2->Call(global, 0, NULL).IsEmpty());
CHECK(g1->Call(global, 0, NULL).IsEmpty());
CHECK(g2->Call(global, 0, NULL).IsEmpty());
// Now compile the source again. And get the newly compiled functions, except
// for h for which access is blocked.
CompileRun(source);
- f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1")));
- f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2")));
- g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1")));
- g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2")));
- CHECK(context->Global()->Get(v8_str("h"))->IsUndefined());
-
- // Failing access check to property get results in undefined.
- CHECK(f1->Call(global, 0, NULL)->IsUndefined());
- CHECK(f2->Call(global, 0, NULL)->IsUndefined());
-
- // Failing access check to function call results in exception.
+ f1 = Local<Function>::Cast(hidden_global->Get(v8_str("f1")));
+ f2 = Local<Function>::Cast(hidden_global->Get(v8_str("f2")));
+ g1 = Local<Function>::Cast(hidden_global->Get(v8_str("g1")));
+ g2 = Local<Function>::Cast(hidden_global->Get(v8_str("g2")));
+ CHECK(hidden_global->Get(v8_str("h")).IsEmpty());
+
+ // Failing access check results in exception.
+ v8::Local<v8::Value> result = f1->Call(global, 0, NULL);
+ CHECK(result.IsEmpty());
+ CHECK(f1->Call(global, 0, NULL).IsEmpty());
+ CHECK(f2->Call(global, 0, NULL).IsEmpty());
CHECK(g1->Call(global, 0, NULL).IsEmpty());
CHECK(g2->Call(global, 0, NULL).IsEmpty());
}
-// This test verifies that pre-compilation (aka preparsing) can be called
-// without initializing the whole VM. Thus we cannot run this test in a
-// multi-threaded setup.
-TEST(PreCompile) {
- // TODO(155): This test would break without the initialization of V8. This is
- // a workaround for now to make this test not fail.
- v8::V8::Initialize();
- v8::Isolate* isolate = CcTest::isolate();
- const char* script = "function foo(a) { return a+1; }";
- v8::ScriptData* sd =
- v8::ScriptData::PreCompile(isolate, script, i::StrLength(script));
- CHECK_NE(sd->Length(), 0);
- CHECK_NE(sd->Data(), NULL);
- CHECK(!sd->HasError());
- delete sd;
-}
-
-
-TEST(PreCompileWithError) {
- v8::V8::Initialize();
- v8::Isolate* isolate = CcTest::isolate();
- const char* script = "function foo(a) { return 1 * * 2; }";
- v8::ScriptData* sd =
- v8::ScriptData::PreCompile(isolate, script, i::StrLength(script));
- CHECK(sd->HasError());
- delete sd;
-}
-
-
-TEST(Regress31661) {
- v8::V8::Initialize();
- v8::Isolate* isolate = CcTest::isolate();
- const char* script = " The Definintive Guide";
- v8::ScriptData* sd =
- v8::ScriptData::PreCompile(isolate, script, i::StrLength(script));
- CHECK(sd->HasError());
- delete sd;
-}
-
-
// Tests that ScriptData can be serialized and deserialized.
TEST(PreCompileSerialization) {
v8::V8::Initialize();
- v8::Isolate* isolate = CcTest::isolate();
- const char* script = "function foo(a) { return a+1; }";
- v8::ScriptData* sd =
- v8::ScriptData::PreCompile(isolate, script, i::StrLength(script));
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ HandleScope handle_scope(isolate);
+ i::FLAG_min_preparse_length = 0;
+ const char* script = "function foo(a) { return a+1; }";
+ v8::ScriptCompiler::Source source(v8_str(script));
+ v8::ScriptCompiler::Compile(isolate, &source,
+ v8::ScriptCompiler::kProduceParserCache);
// Serialize.
- int serialized_data_length = sd->Length();
- char* serialized_data = i::NewArray<char>(serialized_data_length);
- i::OS::MemCopy(serialized_data, sd->Data(), serialized_data_length);
+ const v8::ScriptCompiler::CachedData* cd = source.GetCachedData();
+ i::byte* serialized_data = i::NewArray<i::byte>(cd->length);
+ i::MemCopy(serialized_data, cd->data, cd->length);
// Deserialize.
- v8::ScriptData* deserialized_sd =
- v8::ScriptData::New(serialized_data, serialized_data_length);
+ i::ScriptData* deserialized = new i::ScriptData(serialized_data, cd->length);
// Verify that the original is the same as the deserialized.
- CHECK_EQ(sd->Length(), deserialized_sd->Length());
- CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length()));
- CHECK_EQ(sd->HasError(), deserialized_sd->HasError());
-
- delete sd;
- delete deserialized_sd;
-}
-
+ CHECK_EQ(cd->length, deserialized->length());
+ CHECK_EQ(0, memcmp(cd->data, deserialized->data(), cd->length));
-// Attempts to deserialize bad data.
-TEST(PreCompileDeserializationError) {
- v8::V8::Initialize();
- const char* data = "DONT CARE";
- int invalid_size = 3;
- v8::ScriptData* sd = v8::ScriptData::New(data, invalid_size);
-
- CHECK_EQ(0, sd->Length());
-
- delete sd;
-}
-
-
-// Attempts to deserialize bad data.
-TEST(PreCompileInvalidPreparseDataError) {
- v8::V8::Initialize();
- v8::Isolate* isolate = CcTest::isolate();
- LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
-
- const char* script = "function foo(){ return 5;}\n"
- "function bar(){ return 6 + 7;} foo();";
- v8::ScriptData* sd =
- v8::ScriptData::PreCompile(isolate, script, i::StrLength(script));
- CHECK(!sd->HasError());
- // ScriptDataImpl private implementation details
- const int kHeaderSize = i::PreparseDataConstants::kHeaderSize;
- const int kFunctionEntrySize = i::FunctionEntry::kSize;
- const int kFunctionEntryStartOffset = 0;
- const int kFunctionEntryEndOffset = 1;
- unsigned* sd_data =
- reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
-
- // Overwrite function bar's end position with 0.
- sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryEndOffset] = 0;
- v8::TryCatch try_catch;
-
- Local<String> source = String::New(script);
- Local<Script> compiled_script = Script::New(source, NULL, sd);
- CHECK(try_catch.HasCaught());
- String::Utf8Value exception_value(try_catch.Message()->Get());
- CHECK_EQ("Uncaught SyntaxError: Invalid preparser data for function bar",
- *exception_value);
-
- try_catch.Reset();
-
- // Overwrite function bar's start position with 200. The function entry
- // will not be found when searching for it by position and we should fall
- // back on eager compilation.
- sd = v8::ScriptData::PreCompile(isolate, script, i::StrLength(script));
- sd_data = reinterpret_cast<unsigned*>(const_cast<char*>(sd->Data()));
- sd_data[kHeaderSize + 1 * kFunctionEntrySize + kFunctionEntryStartOffset] =
- 200;
- compiled_script = Script::New(source, NULL, sd);
- CHECK(!try_catch.HasCaught());
-
- delete sd;
-}
-
-
-// Verifies that the Handle<String> and const char* versions of the API produce
-// the same results (at least for one trivial case).
-TEST(PreCompileAPIVariationsAreSame) {
- v8::V8::Initialize();
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope scope(isolate);
-
- const char* cstring = "function foo(a) { return a+1; }";
-
- v8::ScriptData* sd_from_cstring =
- v8::ScriptData::PreCompile(isolate, cstring, i::StrLength(cstring));
-
- TestAsciiResource* resource = new TestAsciiResource(cstring);
- v8::ScriptData* sd_from_external_string = v8::ScriptData::PreCompile(
- v8::String::NewExternal(resource));
-
- v8::ScriptData* sd_from_string = v8::ScriptData::PreCompile(
- v8::String::New(cstring));
-
- CHECK_EQ(sd_from_cstring->Length(), sd_from_external_string->Length());
- CHECK_EQ(0, memcmp(sd_from_cstring->Data(),
- sd_from_external_string->Data(),
- sd_from_cstring->Length()));
-
- CHECK_EQ(sd_from_cstring->Length(), sd_from_string->Length());
- CHECK_EQ(0, memcmp(sd_from_cstring->Data(),
- sd_from_string->Data(),
- sd_from_cstring->Length()));
-
-
- delete sd_from_cstring;
- delete sd_from_external_string;
- delete sd_from_string;
+ delete deserialized;
+ i::DeleteArray(serialized_data);
}
}
-class ApplyInterruptTest {
- public:
- ApplyInterruptTest() : block_(0) {}
- ~ApplyInterruptTest() {}
- void RunTest() {
- gc_count_ = 0;
- gc_during_apply_ = 0;
- apply_success_ = false;
- gc_success_ = false;
- GCThread gc_thread(this);
- gc_thread.Start();
- v8::Isolate* isolate = CcTest::isolate();
- v8::Locker::StartPreemption(isolate, 1);
-
- LongRunningApply();
- {
- v8::Unlocker unlock(isolate);
- gc_thread.Join();
- }
- v8::Locker::StopPreemption(isolate);
- CHECK(apply_success_);
- CHECK(gc_success_);
- }
-
- private:
- // Number of garbage collections required.
- static const int kRequiredGCs = 2;
-
- class GCThread : public i::Thread {
- public:
- explicit GCThread(ApplyInterruptTest* test)
- : Thread("GCThread"), test_(test) {}
- virtual void Run() {
- test_->CollectGarbage();
- }
- private:
- ApplyInterruptTest* test_;
- };
-
- void CollectGarbage() {
- block_.Wait();
- while (gc_during_apply_ < kRequiredGCs) {
- {
- v8::Locker lock(CcTest::isolate());
- v8::Isolate::Scope isolate_scope(CcTest::isolate());
- CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
- gc_count_++;
- }
- i::OS::Sleep(1);
- }
- gc_success_ = true;
- }
-
- void LongRunningApply() {
- block_.Signal();
- int rounds = 0;
- while (gc_during_apply_ < kRequiredGCs) {
- int gc_before = gc_count_;
- {
- const char* c_source =
- "function do_very_little(bar) {"
- " this.foo = bar;"
- "}"
- "for (var i = 0; i < 100000; i++) {"
- " do_very_little.apply(this, ['bar']);"
- "}";
- Local<String> source = String::New(c_source);
- Local<Script> script = Script::Compile(source);
- Local<Value> result = script->Run();
- // Check that no exception was thrown.
- CHECK(!result.IsEmpty());
- }
- int gc_after = gc_count_;
- gc_during_apply_ += gc_after - gc_before;
- rounds++;
- }
- apply_success_ = true;
- }
-
- i::Semaphore block_;
- int gc_count_;
- int gc_during_apply_;
- bool apply_success_;
- bool gc_success_;
-};
-
-
-// Test that nothing bad happens if we get a preemption just when we were
-// about to do an apply().
-TEST(ApplyInterruption) {
- v8::Locker lock(CcTest::isolate());
- v8::V8::Initialize();
- v8::HandleScope scope(CcTest::isolate());
- Local<Context> local_env;
- {
- LocalContext env;
- local_env = env.local();
- }
-
- // Local context should still be live.
- CHECK(!local_env.IsEmpty());
- local_env->Enter();
-
- // Should complete without problems.
- ApplyInterruptTest().RunTest();
-
- local_env->Exit();
-}
-
-
// Verify that we can clone an object
TEST(ObjectClone) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
const char* sample =
"var rv = {};" \
obj->Set(v8_str("gamma"), v8_str("cloneme"));
CHECK_EQ(v8_str("hello"), obj->Get(v8_str("alpha")));
- CHECK_EQ(v8::Integer::New(123), obj->Get(v8_str("beta")));
+ CHECK_EQ(v8::Integer::New(isolate, 123), obj->Get(v8_str("beta")));
CHECK_EQ(v8_str("cloneme"), obj->Get(v8_str("gamma")));
// Clone it.
Local<v8::Object> clone = obj->Clone();
CHECK_EQ(v8_str("hello"), clone->Get(v8_str("alpha")));
- CHECK_EQ(v8::Integer::New(123), clone->Get(v8_str("beta")));
+ CHECK_EQ(v8::Integer::New(isolate, 123), clone->Get(v8_str("beta")));
CHECK_EQ(v8_str("cloneme"), clone->Get(v8_str("gamma")));
// Set a property on the clone, verify each object.
- clone->Set(v8_str("beta"), v8::Integer::New(456));
- CHECK_EQ(v8::Integer::New(123), obj->Get(v8_str("beta")));
- CHECK_EQ(v8::Integer::New(456), clone->Get(v8_str("beta")));
+ clone->Set(v8_str("beta"), v8::Integer::New(isolate, 456));
+ CHECK_EQ(v8::Integer::New(isolate, 123), obj->Get(v8_str("beta")));
+ CHECK_EQ(v8::Integer::New(isolate, 456), clone->Get(v8_str("beta")));
}
-class AsciiVectorResource : public v8::String::ExternalAsciiStringResource {
+class OneByteVectorResource : public v8::String::ExternalOneByteStringResource {
public:
- explicit AsciiVectorResource(i::Vector<const char> vector)
+ explicit OneByteVectorResource(i::Vector<const char> vector)
: data_(vector) {}
- virtual ~AsciiVectorResource() {}
+ virtual ~OneByteVectorResource() {}
virtual size_t length() const { return data_.length(); }
virtual const char* data() const { return data_.start(); }
private:
static void MorphAString(i::String* string,
- AsciiVectorResource* ascii_resource,
+ OneByteVectorResource* one_byte_resource,
UC16VectorResource* uc16_resource) {
CHECK(i::StringShape(string).IsExternal());
if (string->IsOneByteRepresentation()) {
// Check old map is not internalized or long.
- CHECK(string->map() == CcTest::heap()->external_ascii_string_map());
+ CHECK(string->map() == CcTest::heap()->external_one_byte_string_map());
// Morph external string to be TwoByte string.
string->set_map(CcTest::heap()->external_string_map());
i::ExternalTwoByteString* morphed =
} else {
// Check old map is not internalized or long.
CHECK(string->map() == CcTest::heap()->external_string_map());
- // Morph external string to be ASCII string.
- string->set_map(CcTest::heap()->external_ascii_string_map());
- i::ExternalAsciiString* morphed =
- i::ExternalAsciiString::cast(string);
- morphed->set_resource(ascii_resource);
+ // Morph external string to be one-byte string.
+ string->set_map(CcTest::heap()->external_one_byte_string_map());
+ i::ExternalOneByteString* morphed = i::ExternalOneByteString::cast(string);
+ morphed->set_resource(one_byte_resource);
}
}
LocalContext env;
i::Factory* factory = CcTest::i_isolate()->factory();
v8::HandleScope scope(env->GetIsolate());
- AsciiVectorResource ascii_resource(
+ OneByteVectorResource one_byte_resource(
i::Vector<const char>(c_string, i::StrLength(c_string)));
UC16VectorResource uc16_resource(
i::Vector<const uint16_t>(two_byte_string,
i::StrLength(c_string)));
- Local<String> lhs(v8::Utils::ToLocal(
- factory->NewExternalStringFromAscii(&ascii_resource)));
- Local<String> rhs(v8::Utils::ToLocal(
- factory->NewExternalStringFromAscii(&ascii_resource)));
+ Local<String> lhs(
+ v8::Utils::ToLocal(factory->NewExternalStringFromOneByte(
+ &one_byte_resource).ToHandleChecked()));
+ Local<String> rhs(
+ v8::Utils::ToLocal(factory->NewExternalStringFromOneByte(
+ &one_byte_resource).ToHandleChecked()));
env->Global()->Set(v8_str("lhs"), lhs);
env->Global()->Set(v8_str("rhs"), rhs);
CHECK(lhs->IsOneByte());
CHECK(rhs->IsOneByte());
- MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource);
- MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource);
+ MorphAString(*v8::Utils::OpenHandle(*lhs), &one_byte_resource,
+ &uc16_resource);
+ MorphAString(*v8::Utils::OpenHandle(*rhs), &one_byte_resource,
+ &uc16_resource);
// This should UTF-8 without flattening, since everything is ASCII.
Handle<String> cons = v8_compile("cons")->Run().As<String>();
const char* expected_slice_on_cons =
"ow is the time for all good men to come to the aid of the party"
"Now is the time for all good men to come to the aid of the part";
- CHECK_EQ(String::New(expected_cons),
+ CHECK_EQ(String::NewFromUtf8(env->GetIsolate(), expected_cons),
env->Global()->Get(v8_str("cons")));
- CHECK_EQ(String::New(expected_slice),
+ CHECK_EQ(String::NewFromUtf8(env->GetIsolate(), expected_slice),
env->Global()->Get(v8_str("slice")));
- CHECK_EQ(String::New(expected_slice_on_cons),
+ CHECK_EQ(String::NewFromUtf8(env->GetIsolate(), expected_slice_on_cons),
env->Global()->Get(v8_str("slice_on_cons")));
}
i::DeleteArray(two_byte_string);
// This is a very short list of sources, which currently is to check for a
// regression caused by r2703.
- const char* ascii_sources[] = {
- "0.5",
- "-0.5", // This mainly testes PushBack in the Scanner.
- "--0.5", // This mainly testes PushBack in the Scanner.
- NULL
- };
+ const char* one_byte_sources[] = {
+ "0.5",
+ "-0.5", // This mainly testes PushBack in the Scanner.
+ "--0.5", // This mainly testes PushBack in the Scanner.
+ NULL};
// Compile the sources as external two byte strings.
- for (int i = 0; ascii_sources[i] != NULL; i++) {
- uint16_t* two_byte_string = AsciiToTwoByteString(ascii_sources[i]);
- UC16VectorResource uc16_resource(
- i::Vector<const uint16_t>(two_byte_string,
- i::StrLength(ascii_sources[i])));
- v8::Local<v8::String> source = v8::String::NewExternal(&uc16_resource);
+ for (int i = 0; one_byte_sources[i] != NULL; i++) {
+ uint16_t* two_byte_string = AsciiToTwoByteString(one_byte_sources[i]);
+ TestResource* uc16_resource = new TestResource(two_byte_string);
+ v8::Local<v8::String> source =
+ v8::String::NewExternal(context->GetIsolate(), uc16_resource);
v8::Script::Compile(source);
- i::DeleteArray(two_byte_string);
}
}
#ifndef V8_INTERPRETED_REGEXP
struct RegExpInterruptionData {
- int loop_count;
+ v8::base::Atomic32 loop_count;
UC16VectorResource* string_resource;
v8::Persistent<v8::String> string;
} regexp_interruption_data;
-class RegExpInterruptionThread : public i::Thread {
+class RegExpInterruptionThread : public v8::base::Thread {
public:
explicit RegExpInterruptionThread(v8::Isolate* isolate)
- : Thread("TimeoutThread"), isolate_(isolate) {}
+ : Thread(Options("TimeoutThread")), isolate_(isolate) {}
virtual void Run() {
- for (regexp_interruption_data.loop_count = 0;
- regexp_interruption_data.loop_count < 7;
- regexp_interruption_data.loop_count++) {
- i::OS::Sleep(50); // Wait a bit before requesting GC.
+ for (v8::base::NoBarrier_Store(®exp_interruption_data.loop_count, 0);
+ v8::base::NoBarrier_Load(®exp_interruption_data.loop_count) < 7;
+ v8::base::NoBarrier_AtomicIncrement(
+ ®exp_interruption_data.loop_count, 1)) {
+ v8::base::OS::Sleep(50); // Wait a bit before requesting GC.
reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC();
}
- i::OS::Sleep(50); // Wait a bit before terminating.
+ v8::base::OS::Sleep(50); // Wait a bit before terminating.
v8::V8::TerminateExecution(isolate_);
}
void RunBeforeGC(v8::GCType type, v8::GCCallbackFlags flags) {
- if (regexp_interruption_data.loop_count != 2) return;
+ if (v8::base::NoBarrier_Load(®exp_interruption_data.loop_count) != 2) {
+ return;
+ }
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::String> string = v8::Local<v8::String>::New(
CcTest::isolate(), regexp_interruption_data.string);
RegExpInterruptionThread timeout_thread(CcTest::isolate());
v8::V8::AddGCPrologueCallback(RunBeforeGC);
- static const char* ascii_content = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- i::uc16* uc16_content = AsciiToTwoByteString(ascii_content);
- v8::Local<v8::String> string = v8_str(ascii_content);
+ static const char* one_byte_content = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ i::uc16* uc16_content = AsciiToTwoByteString(one_byte_content);
+ v8::Local<v8::String> string = v8_str(one_byte_content);
CcTest::global()->Set(v8_str("a"), string);
regexp_interruption_data.string.Reset(CcTest::isolate(), string);
regexp_interruption_data.string_resource = new UC16VectorResource(
- i::Vector<const i::uc16>(uc16_content, i::StrLength(ascii_content)));
+ i::Vector<const i::uc16>(uc16_content, i::StrLength(one_byte_content)));
v8::TryCatch try_catch;
timeout_thread.Start();
timeout_thread.Join();
- delete regexp_interruption_data.string_resource;
- regexp_interruption_data.string.Dispose();
+ regexp_interruption_data.string.Reset();
+ i::DeleteArray(uc16_content);
}
#endif // V8_INTERPRETED_REGEXP
// Test that we cannot set a property on the global object if there
// is a read-only property in the prototype chain.
TEST(ReadOnlyPropertyInGlobalProto) {
- i::FLAG_es5_readonly = true;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
LocalContext context(0, templ);
v8::Handle<v8::Object> global = context->Global();
v8::Handle<v8::Object> global_proto =
v8::Handle<v8::Object>::Cast(global->Get(v8_str("__proto__")));
- global_proto->Set(v8_str("x"), v8::Integer::New(0), v8::ReadOnly);
- global_proto->Set(v8_str("y"), v8::Integer::New(0), v8::ReadOnly);
+ global_proto->ForceSet(v8_str("x"), v8::Integer::New(isolate, 0),
+ v8::ReadOnly);
+ global_proto->ForceSet(v8_str("y"), v8::Integer::New(isolate, 0),
+ v8::ReadOnly);
// Check without 'eval' or 'with'.
v8::Handle<v8::Value> res =
CompileRun("function f() { x = 42; return x; }; f()");
- CHECK_EQ(v8::Integer::New(0), res);
+ CHECK_EQ(v8::Integer::New(isolate, 0), res);
// Check with 'eval'.
res = CompileRun("function f() { eval('1'); y = 43; return y; }; f()");
- CHECK_EQ(v8::Integer::New(0), res);
+ CHECK_EQ(v8::Integer::New(isolate, 0), res);
// Check with 'with'.
res = CompileRun("function f() { with (this) { y = 44 }; return y; }; f()");
- CHECK_EQ(v8::Integer::New(0), res);
+ CHECK_EQ(v8::Integer::New(isolate, 0), res);
}
static int force_set_set_count = 0;
force_set_set_count = 0;
pass_on_get = false;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
- v8::Handle<v8::String> access_property = v8::String::New("a");
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ v8::Handle<v8::String> access_property =
+ v8::String::NewFromUtf8(isolate, "a");
templ->SetAccessor(access_property, ForceSetGetter, ForceSetSetter);
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
// Ordinary properties
- v8::Handle<v8::String> simple_property = v8::String::New("p");
- global->Set(simple_property, v8::Int32::New(4), v8::ReadOnly);
+ v8::Handle<v8::String> simple_property =
+ v8::String::NewFromUtf8(isolate, "p");
+ global->ForceSet(simple_property, v8::Int32::New(isolate, 4), v8::ReadOnly);
CHECK_EQ(4, global->Get(simple_property)->Int32Value());
// This should fail because the property is read-only
- global->Set(simple_property, v8::Int32::New(5));
+ global->Set(simple_property, v8::Int32::New(isolate, 5));
CHECK_EQ(4, global->Get(simple_property)->Int32Value());
// This should succeed even though the property is read-only
- global->ForceSet(simple_property, v8::Int32::New(6));
+ global->ForceSet(simple_property, v8::Int32::New(isolate, 6));
CHECK_EQ(6, global->Get(simple_property)->Int32Value());
// Accessors
CHECK_EQ(3, global->Get(access_property)->Int32Value());
// CHECK_EQ the property shouldn't override it, just call the setter
// which in this case does nothing.
- global->Set(access_property, v8::Int32::New(7));
+ global->Set(access_property, v8::Int32::New(isolate, 7));
CHECK_EQ(3, global->Get(access_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(2, force_set_get_count);
// Forcing the property to be set should override the accessor without
// calling it
- global->ForceSet(access_property, v8::Int32::New(8));
+ global->ForceSet(access_property, v8::Int32::New(isolate, 8));
CHECK_EQ(8, global->Get(access_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(2, force_set_get_count);
force_set_set_count = 0;
pass_on_get = false;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter);
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
- v8::Handle<v8::String> some_property = v8::String::New("a");
+ v8::Handle<v8::String> some_property =
+ v8::String::NewFromUtf8(isolate, "a");
CHECK_EQ(0, force_set_set_count);
CHECK_EQ(0, force_set_get_count);
CHECK_EQ(3, global->Get(some_property)->Int32Value());
// Setting the property shouldn't override it, just call the setter
// which in this case does nothing.
- global->Set(some_property, v8::Int32::New(7));
+ global->Set(some_property, v8::Int32::New(isolate, 7));
CHECK_EQ(3, global->Get(some_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(2, force_set_get_count);
CHECK_EQ(3, force_set_get_count);
// Forcing the property to be set should cause the value to be
// set locally without calling the interceptor.
- global->ForceSet(some_property, v8::Int32::New(8));
+ global->ForceSet(some_property, v8::Int32::New(isolate, 8));
CHECK_EQ(8, global->Get(some_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(4, force_set_get_count);
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(5, force_set_get_count);
// The interceptor should also work for other properties
- CHECK_EQ(3, global->Get(v8::String::New("b"))->Int32Value());
+ CHECK_EQ(3, global->Get(v8::String::NewFromUtf8(isolate, "b"))
+ ->Int32Value());
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(6, force_set_get_count);
}
THREADED_TEST(ForceDelete) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
// Ordinary properties
- v8::Handle<v8::String> simple_property = v8::String::New("p");
- global->Set(simple_property, v8::Int32::New(4), v8::DontDelete);
+ v8::Handle<v8::String> simple_property =
+ v8::String::NewFromUtf8(isolate, "p");
+ global->ForceSet(simple_property, v8::Int32::New(isolate, 4), v8::DontDelete);
CHECK_EQ(4, global->Get(simple_property)->Int32Value());
// This should fail because the property is dont-delete.
CHECK(!global->Delete(simple_property));
force_delete_interceptor_count = 0;
pass_on_delete = false;
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(0, 0, 0, ForceDeleteDeleter);
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
- v8::Handle<v8::String> some_property = v8::String::New("a");
- global->Set(some_property, v8::Integer::New(42), v8::DontDelete);
+ v8::Handle<v8::String> some_property =
+ v8::String::NewFromUtf8(isolate, "a");
+ global->ForceSet(some_property, v8::Integer::New(isolate, 42),
+ v8::DontDelete);
// Deleting a property should get intercepted and nothing should
// happen.
"f();");
CHECK_EQ(42, res->Int32Value());
ctx2->Exit();
- v8::Handle<v8::String> G_property = v8::String::New("G");
+ v8::Handle<v8::String> G_property =
+ v8::String::NewFromUtf8(CcTest::isolate(), "G");
CHECK(ctx1->Global()->ForceDelete(G_property));
ctx2->Enter();
ExpectString(
// Create an object with a C++ callback in context0.
calling_context0->Enter();
Local<v8::FunctionTemplate> callback_templ =
- v8::FunctionTemplate::New(GetCallingContextCallback);
+ v8::FunctionTemplate::New(isolate, GetCallingContextCallback);
calling_context0->Global()->Set(v8_str("callback"),
callback_templ->GetFunction());
calling_context0->Exit();
// Check that a variable declaration with no explicit initialization
// value does shadow an existing property in the prototype chain.
THREADED_TEST(InitGlobalVarInProtoChain) {
- i::FLAG_es52_globals = true;
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
// Introduce a variable in the prototype chain.
// See http://code.google.com/p/v8/issues/detail?id=398
THREADED_TEST(ReplaceConstantFunction) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- v8::Handle<v8::Object> obj = v8::Object::New();
- v8::Handle<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New();
- v8::Handle<v8::String> foo_string = v8::String::New("foo");
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::Object> obj = v8::Object::New(isolate);
+ v8::Handle<v8::FunctionTemplate> func_templ =
+ v8::FunctionTemplate::New(isolate);
+ v8::Handle<v8::String> foo_string =
+ v8::String::NewFromUtf8(isolate, "foo");
obj->Set(foo_string, func_templ->GetFunction());
v8::Handle<v8::Object> obj_clone = obj->Clone();
- obj_clone->Set(foo_string, v8::String::New("Hello"));
+ obj_clone->Set(foo_string,
+ v8::String::NewFromUtf8(isolate, "Hello"));
CHECK(!obj->Get(foo_string)->IsUndefined());
}
-// Regression test for http://crbug.com/16276.
-THREADED_TEST(Regress16276) {
- LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- // Force the IC in f to be a dictionary load IC.
- CompileRun("function f(obj) { return obj.x; }\n"
- "var obj = { x: { foo: 42 }, y: 87 };\n"
- "var x = obj.x;\n"
- "delete obj.y;\n"
- "for (var i = 0; i < 5; i++) f(obj);");
- // Detach the global object to make 'this' refer directly to the
- // global object (not the proxy), and make sure that the dictionary
- // load IC doesn't mess up loading directly from the global object.
- context->DetachGlobal();
- CHECK_EQ(42, CompileRun("f(this).foo")->Int32Value());
-}
-
static void CheckElementValue(i::Isolate* isolate,
int expected,
i::Handle<i::Object> obj,
int offset) {
- i::Object* element = obj->GetElement(isolate, offset)->ToObjectChecked();
+ i::Object* element =
+ *i::Object::GetElement(isolate, obj, offset).ToHandleChecked();
CHECK_EQ(expected, i::Smi::cast(element)->value());
}
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(
+ i::Handle<i::ExternalUint8ClampedArray> pixels =
+ i::Handle<i::ExternalUint8ClampedArray>::cast(
factory->NewExternalArray(kElementCount,
- v8::kExternalPixelArray,
+ v8::kExternalUint8ClampedArray,
pixel_data));
// Force GC to trigger verification.
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(i % 256, pixel_data[i]);
}
- v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate());
i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
// Set the elements to be the pixels.
// jsobj->set_elements(*pixels);
obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount);
CheckElementValue(isolate, 1, jsobj, 1);
- obj->Set(v8_str("field"), v8::Int32::New(1503));
+ obj->Set(v8_str("field"), v8::Int32::New(CcTest::isolate(), 1503));
context->Global()->Set(v8_str("pixels"), obj);
v8::Handle<v8::Value> result = CompileRun("pixels.field");
CHECK_EQ(1503, result->Int32Value());
i::Handle<i::Smi> value(i::Smi::FromInt(2),
reinterpret_cast<i::Isolate*>(context->GetIsolate()));
i::Handle<i::Object> no_failure;
- no_failure =
- i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
- ASSERT(!no_failure.is_null());
- i::USE(no_failure);
+ no_failure = i::JSObject::SetElement(
+ jsobj, 1, value, NONE, i::SLOPPY).ToHandleChecked();
+ DCHECK(!no_failure.is_null());
+ USE(no_failure);
CheckElementValue(isolate, 2, jsobj, 1);
*value.location() = i::Smi::FromInt(256);
- no_failure =
- i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
- ASSERT(!no_failure.is_null());
- i::USE(no_failure);
+ no_failure = i::JSObject::SetElement(
+ jsobj, 1, value, NONE, i::SLOPPY).ToHandleChecked();
+ DCHECK(!no_failure.is_null());
+ USE(no_failure);
CheckElementValue(isolate, 255, jsobj, 1);
*value.location() = i::Smi::FromInt(-1);
- no_failure =
- i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
- ASSERT(!no_failure.is_null());
- i::USE(no_failure);
+ no_failure = i::JSObject::SetElement(
+ jsobj, 1, value, NONE, i::SLOPPY).ToHandleChecked();
+ DCHECK(!no_failure.is_null());
+ USE(no_failure);
CheckElementValue(isolate, 0, jsobj, 1);
result = CompileRun("for (var i = 0; i < 8; i++) {"
v8::HandleScope scope(context->GetIsolate());
for (int size = 0; size < 100; size += 10) {
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(size));
- v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate());
obj->SetIndexedPropertiesToPixelData(pixel_data, size);
CHECK(obj->HasIndexedPropertiesInPixelData());
CHECK_EQ(pixel_data, obj->GetIndexedPropertiesPixelData());
THREADED_TEST(PixelArrayWithInterceptor) {
LocalContext context;
i::Factory* factory = CcTest::i_isolate()->factory();
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
- i::Handle<i::ExternalPixelArray> pixels =
- i::Handle<i::ExternalPixelArray>::cast(
+ i::Handle<i::ExternalUint8ClampedArray> pixels =
+ i::Handle<i::ExternalUint8ClampedArray>::cast(
factory->NewExternalArray(kElementCount,
- v8::kExternalPixelArray,
+ v8::kExternalUint8ClampedArray,
pixel_data));
for (int i = 0; i < kElementCount; i++) {
pixels->set(i, i % 256);
}
- v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> templ =
+ v8::ObjectTemplate::New(context->GetIsolate());
templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter,
NotHandledIndexedPropertySetter);
v8::Handle<v8::Object> obj = templ->NewInstance();
static int ExternalArrayElementSize(v8::ExternalArrayType array_type) {
switch (array_type) {
- case v8::kExternalByteArray:
- case v8::kExternalUnsignedByteArray:
- case v8::kExternalPixelArray:
+ case v8::kExternalInt8Array:
+ case v8::kExternalUint8Array:
+ case v8::kExternalUint8ClampedArray:
return 1;
break;
- case v8::kExternalShortArray:
- case v8::kExternalUnsignedShortArray:
+ case v8::kExternalInt16Array:
+ case v8::kExternalUint16Array:
return 2;
break;
- case v8::kExternalIntArray:
- case v8::kExternalUnsignedIntArray:
- case v8::kExternalFloatArray:
+ case v8::kExternalInt32Array:
+ case v8::kExternalUint32Array:
+ case v8::kExternalFloat32Array:
return 4;
break;
- case v8::kExternalDoubleArray:
+ case v8::kExternalFloat64Array:
return 8;
break;
default:
int64_t low, int64_t high) {
i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
i::Isolate* isolate = jsobj->GetIsolate();
- obj->Set(v8_str("field"), v8::Int32::New(1503));
+ obj->Set(v8_str("field"),
+ v8::Int32::New(reinterpret_cast<v8::Isolate*>(isolate), 1503));
context->Global()->Set(v8_str("ext_array"), obj);
v8::Handle<v8::Value> result = CompileRun("ext_array.field");
CHECK_EQ(1503, result->Int32Value());
result = CompileRun("ext_array[1]");
CHECK_EQ(1, result->Int32Value());
- // Check pass through of assigned smis
- result = CompileRun("var sum = 0;"
- "for (var i = 0; i < 8; i++) {"
- " sum += ext_array[i] = ext_array[i] = -i;"
- "}"
- "sum;");
- CHECK_EQ(-28, result->Int32Value());
-
// Check assigned smis
result = CompileRun("for (var i = 0; i < 8; i++) {"
" ext_array[i] = i;"
" sum += ext_array[i];"
"}"
"sum;");
+
CHECK_EQ(28, result->Int32Value());
+ // Check pass through of assigned smis
+ result = CompileRun("var sum = 0;"
+ "for (var i = 0; i < 8; i++) {"
+ " sum += ext_array[i] = ext_array[i] = -i;"
+ "}"
+ "sum;");
+ CHECK_EQ(-28, result->Int32Value());
+
// Check assigned smis in reverse order
result = CompileRun("for (var i = 8; --i >= 0; ) {"
" }"
"}"
"res;";
- i::OS::SNPrintF(test_buf,
- boundary_program,
- low);
+ i::SNPrintF(test_buf,
+ boundary_program,
+ low);
result = CompileRun(test_buf.start());
CHECK_EQ(low, result->IntegerValue());
- i::OS::SNPrintF(test_buf,
- boundary_program,
- high);
+ i::SNPrintF(test_buf,
+ boundary_program,
+ high);
result = CompileRun(test_buf.start());
CHECK_EQ(high, result->IntegerValue());
CHECK_EQ(28, result->Int32Value());
// Make sure out-of-range loads do not throw.
- i::OS::SNPrintF(test_buf,
- "var caught_exception = false;"
- "try {"
- " ext_array[%d];"
- "} catch (e) {"
- " caught_exception = true;"
- "}"
- "caught_exception;",
- element_count);
+ i::SNPrintF(test_buf,
+ "var caught_exception = false;"
+ "try {"
+ " ext_array[%d];"
+ "} catch (e) {"
+ " caught_exception = true;"
+ "}"
+ "caught_exception;",
+ element_count);
result = CompileRun(test_buf.start());
CHECK_EQ(false, result->BooleanValue());
// Make sure out-of-range stores do not throw.
- i::OS::SNPrintF(test_buf,
- "var caught_exception = false;"
- "try {"
- " ext_array[%d] = 1;"
- "} catch (e) {"
- " caught_exception = true;"
- "}"
- "caught_exception;",
- element_count);
+ i::SNPrintF(test_buf,
+ "var caught_exception = false;"
+ "try {"
+ " ext_array[%d] = 1;"
+ "} catch (e) {"
+ " caught_exception = true;"
+ "}"
+ "caught_exception;",
+ element_count);
result = CompileRun(test_buf.start());
CHECK_EQ(false, result->BooleanValue());
"}"
"ext_array[7];");
CHECK_EQ(0, result->Int32Value());
- if (array_type == v8::kExternalDoubleArray ||
- array_type == v8::kExternalFloatArray) {
- CHECK_EQ(static_cast<int>(i::OS::nan_value()),
+ if (array_type == v8::kExternalFloat64Array ||
+ array_type == v8::kExternalFloat32Array) {
+ CHECK_EQ(static_cast<int>(v8::base::OS::nan_value()),
static_cast<int>(
- jsobj->GetElement(isolate, 7)->ToObjectChecked()->Number()));
+ i::Object::GetElement(
+ isolate, jsobj, 7).ToHandleChecked()->Number()));
} else {
CheckElementValue(isolate, 0, jsobj, 7);
}
CHECK_EQ(2, result->Int32Value());
CHECK_EQ(2,
static_cast<int>(
- jsobj->GetElement(isolate, 6)->ToObjectChecked()->Number()));
+ i::Object::GetElement(
+ isolate, jsobj, 6).ToHandleChecked()->Number()));
- if (array_type != v8::kExternalFloatArray &&
- array_type != v8::kExternalDoubleArray) {
+ if (array_type != v8::kExternalFloat32Array &&
+ array_type != v8::kExternalFloat64Array) {
// Though the specification doesn't state it, be explicit about
// converting NaNs and +/-Infinity to zero.
result = CompileRun("for (var i = 0; i < 8; i++) {"
"}"
"ext_array[5];");
int expected_value =
- (array_type == v8::kExternalPixelArray) ? 255 : 0;
+ (array_type == v8::kExternalUint8ClampedArray) ? 255 : 0;
CHECK_EQ(expected_value, result->Int32Value());
CheckElementValue(isolate, expected_value, jsobj, 5);
"var source_data = [0.6, 10.6];"
"var expected_results = [1, 11];";
bool is_unsigned =
- (array_type == v8::kExternalUnsignedByteArray ||
- array_type == v8::kExternalUnsignedShortArray ||
- array_type == v8::kExternalUnsignedIntArray);
- bool is_pixel_data = array_type == v8::kExternalPixelArray;
-
- i::OS::SNPrintF(test_buf,
- "%s"
- "var all_passed = true;"
- "for (var i = 0; i < source_data.length; i++) {"
- " for (var j = 0; j < 8; j++) {"
- " ext_array[j] = source_data[i];"
- " }"
- " all_passed = all_passed &&"
- " (ext_array[5] == expected_results[i]);"
- "}"
- "all_passed;",
- (is_unsigned ?
- unsigned_data :
- (is_pixel_data ? pixel_data : signed_data)));
+ (array_type == v8::kExternalUint8Array ||
+ array_type == v8::kExternalUint16Array ||
+ array_type == v8::kExternalUint32Array);
+ bool is_pixel_data = array_type == v8::kExternalUint8ClampedArray;
+
+ i::SNPrintF(test_buf,
+ "%s"
+ "var all_passed = true;"
+ "for (var i = 0; i < source_data.length; i++) {"
+ " for (var j = 0; j < 8; j++) {"
+ " ext_array[j] = source_data[i];"
+ " }"
+ " all_passed = all_passed &&"
+ " (ext_array[5] == expected_results[i]);"
+ "}"
+ "all_passed;",
+ (is_unsigned ?
+ unsigned_data :
+ (is_pixel_data ? pixel_data : signed_data)));
result = CompileRun(test_buf.start());
CHECK_EQ(true, result->BooleanValue());
}
}
+template <class FixedTypedArrayClass,
+ i::ElementsKind elements_kind,
+ class ElementType>
+static void FixedTypedArrayTestHelper(
+ v8::ExternalArrayType array_type,
+ ElementType low,
+ ElementType high) {
+ i::FLAG_allow_natives_syntax = true;
+ LocalContext context;
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ v8::HandleScope scope(context->GetIsolate());
+ const int kElementCount = 260;
+ i::Handle<FixedTypedArrayClass> fixed_array =
+ i::Handle<FixedTypedArrayClass>::cast(
+ factory->NewFixedTypedArray(kElementCount, array_type));
+ CHECK_EQ(FixedTypedArrayClass::kInstanceType,
+ fixed_array->map()->instance_type());
+ CHECK_EQ(kElementCount, fixed_array->length());
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ for (int i = 0; i < kElementCount; i++) {
+ fixed_array->set(i, static_cast<ElementType>(i));
+ }
+ // Force GC to trigger verification.
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ for (int i = 0; i < kElementCount; i++) {
+ CHECK_EQ(static_cast<int64_t>(static_cast<ElementType>(i)),
+ static_cast<int64_t>(fixed_array->get_scalar(i)));
+ }
+ v8::Handle<v8::Object> obj = v8::Object::New(CcTest::isolate());
+ i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
+ i::Handle<i::Map> fixed_array_map =
+ i::JSObject::GetElementsTransitionMap(jsobj, elements_kind);
+ jsobj->set_map(*fixed_array_map);
+ jsobj->set_elements(*fixed_array);
+
+ ObjectWithExternalArrayTestHelper<FixedTypedArrayClass, ElementType>(
+ context.local(), obj, kElementCount, array_type,
+ static_cast<int64_t>(low),
+ static_cast<int64_t>(high));
+}
+
+
+THREADED_TEST(FixedUint8Array) {
+ FixedTypedArrayTestHelper<i::FixedUint8Array, i::UINT8_ELEMENTS, uint8_t>(
+ v8::kExternalUint8Array,
+ 0x0, 0xFF);
+}
+
+
+THREADED_TEST(FixedUint8ClampedArray) {
+ FixedTypedArrayTestHelper<i::FixedUint8ClampedArray,
+ i::UINT8_CLAMPED_ELEMENTS, uint8_t>(
+ v8::kExternalUint8ClampedArray,
+ 0x0, 0xFF);
+}
+
+
+THREADED_TEST(FixedInt8Array) {
+ FixedTypedArrayTestHelper<i::FixedInt8Array, i::INT8_ELEMENTS, int8_t>(
+ v8::kExternalInt8Array,
+ -0x80, 0x7F);
+}
+
+
+THREADED_TEST(FixedUint16Array) {
+ FixedTypedArrayTestHelper<i::FixedUint16Array, i::UINT16_ELEMENTS, uint16_t>(
+ v8::kExternalUint16Array,
+ 0x0, 0xFFFF);
+}
+
+
+THREADED_TEST(FixedInt16Array) {
+ FixedTypedArrayTestHelper<i::FixedInt16Array, i::INT16_ELEMENTS, int16_t>(
+ v8::kExternalInt16Array,
+ -0x8000, 0x7FFF);
+}
+
+
+THREADED_TEST(FixedUint32Array) {
+ FixedTypedArrayTestHelper<i::FixedUint32Array, i::UINT32_ELEMENTS, uint32_t>(
+ v8::kExternalUint32Array,
+ 0x0, UINT_MAX);
+}
+
+
+THREADED_TEST(FixedInt32Array) {
+ FixedTypedArrayTestHelper<i::FixedInt32Array, i::INT32_ELEMENTS, int32_t>(
+ v8::kExternalInt32Array,
+ INT_MIN, INT_MAX);
+}
+
+
+THREADED_TEST(FixedFloat32Array) {
+ FixedTypedArrayTestHelper<i::FixedFloat32Array, i::FLOAT32_ELEMENTS, float>(
+ v8::kExternalFloat32Array,
+ -500, 500);
+}
+
+
+THREADED_TEST(FixedFloat64Array) {
+ FixedTypedArrayTestHelper<i::FixedFloat64Array, i::FLOAT64_ELEMENTS, float>(
+ v8::kExternalFloat64Array,
+ -500, 500);
+}
+
+
template <class ExternalArrayClass, class ElementType>
static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
int64_t low,
CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i]));
}
- v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate());
i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj);
// Set the elements to be the external array.
obj->SetIndexedPropertiesToExternalArrayData(array_data,
kElementCount);
CHECK_EQ(1,
static_cast<int>(
- jsobj->GetElement(isolate, 1)->ToObjectChecked()->Number()));
+ i::Object::GetElement(
+ isolate, jsobj, 1).ToHandleChecked()->Number()));
ObjectWithExternalArrayTestHelper<ExternalArrayClass, ElementType>(
context.local(), obj, kElementCount, array_type, low, high);
const int kLargeElementCount = kXSize * kYSize * 4;
ElementType* large_array_data =
static_cast<ElementType*>(malloc(kLargeElementCount * element_size));
- v8::Handle<v8::Object> large_obj = v8::Object::New();
+ v8::Handle<v8::Object> large_obj = v8::Object::New(context->GetIsolate());
// Set the elements to be the external array.
large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data,
array_type,
// Property "" set after the external array is associated with the object.
{
- v8::Handle<v8::Object> obj2 = v8::Object::New();
- obj2->Set(v8_str("ee_test_field"), v8::Int32::New(256));
- obj2->Set(v8_str(""), v8::Int32::New(1503));
+ v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate());
+ obj2->Set(v8_str("ee_test_field"),
+ v8::Int32::New(context->GetIsolate(), 256));
+ obj2->Set(v8_str(""), v8::Int32::New(context->GetIsolate(), 1503));
// Set the elements to be the external array.
obj2->SetIndexedPropertiesToExternalArrayData(array_data,
array_type,
// Property "" set after the external array is associated with the object.
{
- v8::Handle<v8::Object> obj2 = v8::Object::New();
- obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256));
+ v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate());
+ obj2->Set(v8_str("ee_test_field_2"),
+ v8::Int32::New(context->GetIsolate(), 256));
// Set the elements to be the external array.
obj2->SetIndexedPropertiesToExternalArrayData(array_data,
array_type,
kElementCount);
- obj2->Set(v8_str(""), v8::Int32::New(1503));
+ obj2->Set(v8_str(""), v8::Int32::New(context->GetIsolate(), 1503));
context->Global()->Set(v8_str("ext_array"), obj2);
result = CompileRun("ext_array['']");
CHECK_EQ(1503, result->Int32Value());
// Should reuse the map from previous test.
{
- v8::Handle<v8::Object> obj2 = v8::Object::New();
- obj2->Set(v8_str("ee_test_field_2"), v8::Int32::New(256));
+ v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate());
+ obj2->Set(v8_str("ee_test_field_2"),
+ v8::Int32::New(context->GetIsolate(), 256));
// Set the elements to be the external array. Should re-use the map
// from previous test.
obj2->SetIndexedPropertiesToExternalArrayData(array_data,
// Property "" is a constant function that shouldn't not be interfered with
// when an external array is set.
{
- v8::Handle<v8::Object> obj2 = v8::Object::New();
+ v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate());
// Start
- obj2->Set(v8_str("ee_test_field3"), v8::Int32::New(256));
+ obj2->Set(v8_str("ee_test_field3"),
+ v8::Int32::New(context->GetIsolate(), 256));
// Add a constant function to an object.
context->Global()->Set(v8_str("ext_array"), obj2);
// Add an external array transition to the same map that
// has the constant transition.
- v8::Handle<v8::Object> obj3 = v8::Object::New();
- obj3->Set(v8_str("ee_test_field3"), v8::Int32::New(256));
+ v8::Handle<v8::Object> obj3 = v8::Object::New(context->GetIsolate());
+ obj3->Set(v8_str("ee_test_field3"),
+ v8::Int32::New(context->GetIsolate(), 256));
obj3->SetIndexedPropertiesToExternalArrayData(array_data,
array_type,
kElementCount);
// by a constant function.
{
// Add an external array transition.
- v8::Handle<v8::Object> obj3 = v8::Object::New();
- obj3->Set(v8_str("ee_test_field4"), v8::Int32::New(256));
+ v8::Handle<v8::Object> obj3 = v8::Object::New(context->GetIsolate());
+ obj3->Set(v8_str("ee_test_field4"),
+ v8::Int32::New(context->GetIsolate(), 256));
obj3->SetIndexedPropertiesToExternalArrayData(array_data,
array_type,
kElementCount);
// Add a constant function to the same map that just got an external array
// transition.
- v8::Handle<v8::Object> obj2 = v8::Object::New();
- obj2->Set(v8_str("ee_test_field4"), v8::Int32::New(256));
+ v8::Handle<v8::Object> obj2 = v8::Object::New(context->GetIsolate());
+ obj2->Set(v8_str("ee_test_field4"),
+ v8::Int32::New(context->GetIsolate(), 256));
context->Global()->Set(v8_str("ext_array"), obj2);
result = CompileRun("ext_array[''] = function() {return 1503;};"
"ext_array['']();");
}
-THREADED_TEST(ExternalByteArray) {
- ExternalArrayTestHelper<i::ExternalByteArray, int8_t>(
- v8::kExternalByteArray,
+THREADED_TEST(ExternalInt8Array) {
+ ExternalArrayTestHelper<i::ExternalInt8Array, int8_t>(
+ v8::kExternalInt8Array,
-128,
127);
}
-THREADED_TEST(ExternalUnsignedByteArray) {
- ExternalArrayTestHelper<i::ExternalUnsignedByteArray, uint8_t>(
- v8::kExternalUnsignedByteArray,
+THREADED_TEST(ExternalUint8Array) {
+ ExternalArrayTestHelper<i::ExternalUint8Array, uint8_t>(
+ v8::kExternalUint8Array,
0,
255);
}
-THREADED_TEST(ExternalPixelArray) {
- ExternalArrayTestHelper<i::ExternalPixelArray, uint8_t>(
- v8::kExternalPixelArray,
+THREADED_TEST(ExternalUint8ClampedArray) {
+ ExternalArrayTestHelper<i::ExternalUint8ClampedArray, uint8_t>(
+ v8::kExternalUint8ClampedArray,
0,
255);
}
-THREADED_TEST(ExternalShortArray) {
- ExternalArrayTestHelper<i::ExternalShortArray, int16_t>(
- v8::kExternalShortArray,
+THREADED_TEST(ExternalInt16Array) {
+ ExternalArrayTestHelper<i::ExternalInt16Array, int16_t>(
+ v8::kExternalInt16Array,
-32768,
32767);
}
-THREADED_TEST(ExternalUnsignedShortArray) {
- ExternalArrayTestHelper<i::ExternalUnsignedShortArray, uint16_t>(
- v8::kExternalUnsignedShortArray,
+THREADED_TEST(ExternalUint16Array) {
+ ExternalArrayTestHelper<i::ExternalUint16Array, uint16_t>(
+ v8::kExternalUint16Array,
0,
65535);
}
-THREADED_TEST(ExternalIntArray) {
- ExternalArrayTestHelper<i::ExternalIntArray, int32_t>(
- v8::kExternalIntArray,
+THREADED_TEST(ExternalInt32Array) {
+ ExternalArrayTestHelper<i::ExternalInt32Array, int32_t>(
+ v8::kExternalInt32Array,
INT_MIN, // -2147483648
INT_MAX); // 2147483647
}
-THREADED_TEST(ExternalUnsignedIntArray) {
- ExternalArrayTestHelper<i::ExternalUnsignedIntArray, uint32_t>(
- v8::kExternalUnsignedIntArray,
+THREADED_TEST(ExternalUint32Array) {
+ ExternalArrayTestHelper<i::ExternalUint32Array, uint32_t>(
+ v8::kExternalUint32Array,
0,
UINT_MAX); // 4294967295
}
-THREADED_TEST(ExternalFloatArray) {
- ExternalArrayTestHelper<i::ExternalFloatArray, float>(
- v8::kExternalFloatArray,
+THREADED_TEST(ExternalFloat32Array) {
+ ExternalArrayTestHelper<i::ExternalFloat32Array, float>(
+ v8::kExternalFloat32Array,
-500,
500);
}
-THREADED_TEST(ExternalDoubleArray) {
- ExternalArrayTestHelper<i::ExternalDoubleArray, double>(
- v8::kExternalDoubleArray,
+THREADED_TEST(ExternalFloat64Array) {
+ ExternalArrayTestHelper<i::ExternalFloat64Array, double>(
+ v8::kExternalFloat64Array,
-500,
500);
}
THREADED_TEST(ExternalArrays) {
- TestExternalByteArray();
- TestExternalUnsignedByteArray();
- TestExternalShortArray();
- TestExternalUnsignedShortArray();
- TestExternalIntArray();
- TestExternalUnsignedIntArray();
- TestExternalFloatArray();
+ TestExternalInt8Array();
+ TestExternalUint8Array();
+ TestExternalInt16Array();
+ TestExternalUint16Array();
+ TestExternalInt32Array();
+ TestExternalUint32Array();
+ TestExternalFloat32Array();
}
for (int size = 0; size < 100; size += 10) {
int element_size = ExternalArrayElementSize(array_type);
void* external_data = malloc(size * element_size);
- v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::Handle<v8::Object> obj = v8::Object::New(context->GetIsolate());
obj->SetIndexedPropertiesToExternalArrayData(
external_data, array_type, size);
CHECK(obj->HasIndexedPropertiesInExternalArrayData());
THREADED_TEST(ExternalArrayInfo) {
- ExternalArrayInfoTestHelper(v8::kExternalByteArray);
- ExternalArrayInfoTestHelper(v8::kExternalUnsignedByteArray);
- ExternalArrayInfoTestHelper(v8::kExternalShortArray);
- ExternalArrayInfoTestHelper(v8::kExternalUnsignedShortArray);
- ExternalArrayInfoTestHelper(v8::kExternalIntArray);
- ExternalArrayInfoTestHelper(v8::kExternalUnsignedIntArray);
- ExternalArrayInfoTestHelper(v8::kExternalFloatArray);
- ExternalArrayInfoTestHelper(v8::kExternalDoubleArray);
- ExternalArrayInfoTestHelper(v8::kExternalPixelArray);
-}
-
-
-void ExternalArrayLimitTestHelper(v8::ExternalArrayType array_type, int size) {
- v8::Handle<v8::Object> obj = v8::Object::New();
+ ExternalArrayInfoTestHelper(v8::kExternalInt8Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint8Array);
+ ExternalArrayInfoTestHelper(v8::kExternalInt16Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint16Array);
+ ExternalArrayInfoTestHelper(v8::kExternalInt32Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint32Array);
+ ExternalArrayInfoTestHelper(v8::kExternalFloat32Array);
+ ExternalArrayInfoTestHelper(v8::kExternalFloat64Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint8ClampedArray);
+}
+
+
+void ExtArrayLimitsHelper(v8::Isolate* isolate,
+ v8::ExternalArrayType array_type,
+ int size) {
+ v8::Handle<v8::Object> obj = v8::Object::New(isolate);
v8::V8::SetFatalErrorHandler(StoringErrorCallback);
last_location = last_message = NULL;
obj->SetIndexedPropertiesToExternalArrayData(NULL, array_type, size);
TEST(ExternalArrayLimits) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0xffffffff);
- ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0x40000000);
- ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0xffffffff);
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0xffffffff);
}
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
- Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(
- backing_store.start(), (kElementCount+2)*sizeof(ElementType));
+ Local<v8::ArrayBuffer> ab =
+ v8::ArrayBuffer::New(isolate, backing_store.start(),
+ (kElementCount + 2) * sizeof(ElementType));
Local<TypedArray> ta =
TypedArray::New(ab, 2*sizeof(ElementType), kElementCount);
CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta);
THREADED_TEST(Uint8Array) {
- TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUnsignedByteArray>(
- v8::kExternalUnsignedByteArray, 0, 0xFF);
+ TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array>(
+ v8::kExternalUint8Array, 0, 0xFF);
}
THREADED_TEST(Int8Array) {
- TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalByteArray>(
- v8::kExternalByteArray, -0x80, 0x7F);
+ TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array>(
+ v8::kExternalInt8Array, -0x80, 0x7F);
}
THREADED_TEST(Uint16Array) {
TypedArrayTestHelper<uint16_t,
v8::Uint16Array,
- i::ExternalUnsignedShortArray>(
- v8::kExternalUnsignedShortArray, 0, 0xFFFF);
+ i::ExternalUint16Array>(
+ v8::kExternalUint16Array, 0, 0xFFFF);
}
THREADED_TEST(Int16Array) {
- TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalShortArray>(
- v8::kExternalShortArray, -0x8000, 0x7FFF);
+ TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array>(
+ v8::kExternalInt16Array, -0x8000, 0x7FFF);
}
THREADED_TEST(Uint32Array) {
- TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUnsignedIntArray>(
- v8::kExternalUnsignedIntArray, 0, UINT_MAX);
+ TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array>(
+ v8::kExternalUint32Array, 0, UINT_MAX);
}
THREADED_TEST(Int32Array) {
- TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalIntArray>(
- v8::kExternalIntArray, INT_MIN, INT_MAX);
+ TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array>(
+ v8::kExternalInt32Array, INT_MIN, INT_MAX);
}
THREADED_TEST(Float32Array) {
- TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloatArray>(
- v8::kExternalFloatArray, -500, 500);
+ TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array>(
+ v8::kExternalFloat32Array, -500, 500);
}
THREADED_TEST(Float64Array) {
- TypedArrayTestHelper<double, v8::Float64Array, i::ExternalDoubleArray>(
- v8::kExternalDoubleArray, -500, 500);
+ TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array>(
+ v8::kExternalFloat64Array, -500, 500);
}
THREADED_TEST(Uint8ClampedArray) {
- TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray, i::ExternalPixelArray>(
- v8::kExternalPixelArray, 0, 0xFF);
+ TypedArrayTestHelper<uint8_t,
+ v8::Uint8ClampedArray, i::ExternalUint8ClampedArray>(
+ v8::kExternalUint8ClampedArray, 0, 0xFF);
}
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
- Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(
- backing_store.start(), 2 + kSize);
+ Local<v8::ArrayBuffer> ab =
+ v8::ArrayBuffer::New(isolate, backing_store.start(), 2 + kSize);
Local<v8::DataView> dv =
v8::DataView::New(ab, 2, kSize);
CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv);
LocalContext c1;
v8::HandleScope scope(c1->GetIsolate());
const char *source = "foo";
- v8::Handle<v8::Script> dep = v8::Script::Compile(v8::String::New(source));
- v8::Handle<v8::Script> indep = v8::Script::New(v8::String::New(source));
- c1->Global()->Set(v8::String::New("foo"), v8::Integer::New(100));
+ v8::Handle<v8::Script> dep = v8_compile(source);
+ v8::ScriptCompiler::Source script_source(v8::String::NewFromUtf8(
+ c1->GetIsolate(), source));
+ v8::Handle<v8::UnboundScript> indep =
+ v8::ScriptCompiler::CompileUnbound(c1->GetIsolate(), &script_source);
+ c1->Global()->Set(v8::String::NewFromUtf8(c1->GetIsolate(), "foo"),
+ v8::Integer::New(c1->GetIsolate(), 100));
CHECK_EQ(dep->Run()->Int32Value(), 100);
- CHECK_EQ(indep->Run()->Int32Value(), 100);
+ CHECK_EQ(indep->BindToCurrentContext()->Run()->Int32Value(), 100);
LocalContext c2;
- c2->Global()->Set(v8::String::New("foo"), v8::Integer::New(101));
+ c2->Global()->Set(v8::String::NewFromUtf8(c2->GetIsolate(), "foo"),
+ v8::Integer::New(c2->GetIsolate(), 101));
CHECK_EQ(dep->Run()->Int32Value(), 100);
- CHECK_EQ(indep->Run()->Int32Value(), 101);
+ CHECK_EQ(indep->BindToCurrentContext()->Run()->Int32Value(), 101);
}
v8::HandleScope scope(context->GetIsolate());
v8::TryCatch try_catch;
const char *source = "function foo() { FAIL.FAIL; }; foo();";
- v8::Handle<v8::String> src = v8::String::New(source);
- v8::Handle<v8::String> origin = v8::String::New("stack-trace-test");
- v8::Script::New(src, origin)->Run();
+ v8::Handle<v8::String> src =
+ v8::String::NewFromUtf8(context->GetIsolate(), source);
+ v8::Handle<v8::String> origin =
+ v8::String::NewFromUtf8(context->GetIsolate(), "stack-trace-test");
+ v8::ScriptCompiler::Source script_source(src, v8::ScriptOrigin(origin));
+ v8::ScriptCompiler::CompileUnbound(context->GetIsolate(), &script_source)
+ ->BindToCurrentContext()
+ ->Run();
CHECK(try_catch.HasCaught());
v8::String::Utf8Value stack(try_catch.StackTrace());
CHECK(strstr(*stack, "at foo (stack-trace-test") != NULL);
const int kOverviewTest = 1;
const int kDetailedTest = 2;
- ASSERT(args.Length() == 1);
+ DCHECK(args.Length() == 1);
int testGroup = args[0]->Int32Value();
if (testGroup == kOverviewTest) {
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview);
+ v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
+ args.GetIsolate(), 10, v8::StackTrace::kOverview);
CHECK_EQ(4, stackTrace->GetFrameCount());
checkStackFrame(origin, "bar", 2, 10, false, false,
stackTrace->GetFrame(0));
CHECK(stackTrace->AsArray()->IsArray());
} else if (testGroup == kDetailedTest) {
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
+ args.GetIsolate(), 10, v8::StackTrace::kDetailed);
CHECK_EQ(4, stackTrace->GetFrameCount());
checkStackFrame(origin, "bat", 4, 22, false, false,
stackTrace->GetFrame(0));
checkStackFrame(origin, "baz", 8, 3, false, true,
stackTrace->GetFrame(1));
-#ifdef ENABLE_DEBUGGER_SUPPORT
bool is_eval = true;
-#else // ENABLE_DEBUGGER_SUPPORT
- bool is_eval = false;
-#endif // ENABLE_DEBUGGER_SUPPORT
-
// This is the source string inside the eval which has the call to baz.
checkStackFrame(NULL, "", 1, 5, is_eval, false,
stackTrace->GetFrame(2));
// TODO(3074796): Reenable this as a THREADED_TEST once it passes.
// THREADED_TEST(CaptureStackTrace) {
TEST(CaptureStackTrace) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Handle<v8::String> origin = v8::String::New("capture-stack-trace-test");
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::String> origin =
+ v8::String::NewFromUtf8(isolate, "capture-stack-trace-test");
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("AnalyzeStackInNativeCode"),
- v8::FunctionTemplate::New(AnalyzeStackInNativeCode));
+ v8::FunctionTemplate::New(isolate, AnalyzeStackInNativeCode));
LocalContext context(0, templ);
// Test getting OVERVIEW information. Should ignore information that is not
" bar();\n"
"}\n"
"var x;eval('new foo();');";
- v8::Handle<v8::String> overview_src = v8::String::New(overview_source);
+ v8::Handle<v8::String> overview_src =
+ v8::String::NewFromUtf8(isolate, overview_source);
+ v8::ScriptCompiler::Source script_source(overview_src,
+ v8::ScriptOrigin(origin));
v8::Handle<Value> overview_result(
- v8::Script::New(overview_src, origin)->Run());
+ v8::ScriptCompiler::CompileUnbound(isolate, &script_source)
+ ->BindToCurrentContext()
+ ->Run());
CHECK(!overview_result.IsEmpty());
CHECK(overview_result->IsObject());
" bat();\n"
"}\n"
"eval('new baz();');";
- v8::Handle<v8::String> detailed_src = v8::String::New(detailed_source);
+ v8::Handle<v8::String> detailed_src =
+ v8::String::NewFromUtf8(isolate, detailed_source);
// Make the script using a non-zero line and column offset.
- v8::Handle<v8::Integer> line_offset = v8::Integer::New(3);
- v8::Handle<v8::Integer> column_offset = v8::Integer::New(5);
+ v8::Handle<v8::Integer> line_offset = v8::Integer::New(isolate, 3);
+ v8::Handle<v8::Integer> column_offset = v8::Integer::New(isolate, 5);
v8::ScriptOrigin detailed_origin(origin, line_offset, column_offset);
- v8::Handle<v8::Script> detailed_script(
- v8::Script::New(detailed_src, &detailed_origin));
- v8::Handle<Value> detailed_result(detailed_script->Run());
+ v8::ScriptCompiler::Source script_source2(detailed_src, detailed_origin);
+ v8::Handle<v8::UnboundScript> detailed_script(
+ v8::ScriptCompiler::CompileUnbound(isolate, &script_source2));
+ v8::Handle<Value> detailed_result(
+ detailed_script->BindToCurrentContext()->Run());
CHECK(!detailed_result.IsEmpty());
CHECK(detailed_result->IsObject());
}
static void StackTraceForUncaughtExceptionListener(
v8::Handle<v8::Message> message,
v8::Handle<Value>) {
+ report_count++;
v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
CHECK_EQ(2, stack_trace->GetFrameCount());
checkStackFrame("origin", "foo", 2, 3, false, false,
v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener);
v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
- Script::Compile(v8_str("function foo() {\n"
- " throw 1;\n"
- "};\n"
- "function bar() {\n"
- " foo();\n"
- "};"),
- v8_str("origin"))->Run();
+ CompileRunWithOrigin(
+ "function foo() {\n"
+ " throw 1;\n"
+ "};\n"
+ "function bar() {\n"
+ " foo();\n"
+ "};",
+ "origin");
+ v8::Local<v8::Object> global = env->Global();
+ Local<Value> trouble = global->Get(v8_str("bar"));
+ CHECK(trouble->IsFunction());
+ Function::Cast(*trouble)->Call(global, 0, NULL);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+ v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener);
+ CHECK_EQ(1, report_count);
+}
+
+
+TEST(GetStackTraceForUncaughtExceptionFromSimpleStackTrace) {
+ report_count = 0;
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ // Create an Error object first.
+ CompileRunWithOrigin(
+ "function foo() {\n"
+ "e=new Error('err');\n"
+ "};\n"
+ "function bar() {\n"
+ " foo();\n"
+ "};\n"
+ "var e;",
+ "origin");
v8::Local<v8::Object> global = env->Global();
Local<Value> trouble = global->Get(v8_str("bar"));
CHECK(trouble->IsFunction());
Function::Cast(*trouble)->Call(global, 0, NULL);
+
+ // Enable capturing detailed stack trace late, and throw the exception.
+ // The detailed stack trace should be extracted from the simple stack.
+ v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+ CompileRunWithOrigin("throw e", "origin");
v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener);
+ CHECK_EQ(1, report_count);
}
}
+v8::PromiseRejectEvent reject_event = v8::kPromiseRejectWithNoHandler;
+int promise_reject_counter = 0;
+int promise_revoke_counter = 0;
+int promise_reject_line_number = -1;
+int promise_reject_frame_count = -1;
+
+void PromiseRejectCallback(v8::PromiseRejectMessage message) {
+ if (message.GetEvent() == v8::kPromiseRejectWithNoHandler) {
+ promise_reject_counter++;
+ CcTest::global()->Set(v8_str("rejected"), message.GetPromise());
+ CcTest::global()->Set(v8_str("value"), message.GetValue());
+ v8::Handle<v8::StackTrace> stack_trace =
+ v8::Exception::GetMessage(message.GetValue())->GetStackTrace();
+ if (!stack_trace.IsEmpty()) {
+ promise_reject_frame_count = stack_trace->GetFrameCount();
+ if (promise_reject_frame_count > 0) {
+ CHECK(stack_trace->GetFrame(0)->GetScriptName()->Equals(v8_str("pro")));
+ promise_reject_line_number = stack_trace->GetFrame(0)->GetLineNumber();
+ } else {
+ promise_reject_line_number = -1;
+ }
+ }
+ } else {
+ promise_revoke_counter++;
+ CcTest::global()->Set(v8_str("revoked"), message.GetPromise());
+ CHECK(message.GetValue().IsEmpty());
+ }
+}
+
+
+v8::Handle<v8::Promise> GetPromise(const char* name) {
+ return v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str(name)));
+}
+
+
+v8::Handle<v8::Value> RejectValue() {
+ return CcTest::global()->Get(v8_str("value"));
+}
+
+
+void ResetPromiseStates() {
+ promise_reject_counter = 0;
+ promise_revoke_counter = 0;
+ promise_reject_line_number = -1;
+ promise_reject_frame_count = -1;
+ CcTest::global()->Set(v8_str("rejected"), v8_str(""));
+ CcTest::global()->Set(v8_str("value"), v8_str(""));
+ CcTest::global()->Set(v8_str("revoked"), v8_str(""));
+}
+
+
+TEST(PromiseRejectCallback) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ isolate->SetPromiseRejectCallback(PromiseRejectCallback);
+
+ ResetPromiseStates();
+
+ // Create promise p0.
+ CompileRun(
+ "var reject; \n"
+ "var p0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n");
+ CHECK(!GetPromise("p0")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add resolve handler (and default reject handler) to p0.
+ CompileRun("var p1 = p0.then(function(){});");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(!GetPromise("p1")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject p0.
+ CompileRun("reject('ppp');");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(!GetPromise("p1")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK_EQ(v8::kPromiseRejectWithNoHandler, reject_event);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("p1")));
+ CHECK(RejectValue()->Equals(v8_str("ppp")));
+
+ // Reject p0 again. Callback is not triggered again.
+ CompileRun("reject();");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(!GetPromise("p1")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add resolve handler to p1.
+ CompileRun("var p2 = p1.then(function(){});");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(GetPromise("p1")->HasHandler());
+ CHECK(!GetPromise("p2")->HasHandler());
+ CHECK_EQ(2, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("p2")));
+ CHECK(RejectValue()->Equals(v8_str("ppp")));
+ CHECK(GetPromise("revoked")->Equals(GetPromise("p1")));
+
+ ResetPromiseStates();
+
+ // Create promise q0.
+ CompileRun(
+ "var q0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n");
+ CHECK(!GetPromise("q0")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add reject handler to q0.
+ CompileRun("var q1 = q0.catch(function() {});");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(!GetPromise("q1")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject q0.
+ CompileRun("reject('qq')");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(!GetPromise("q1")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add a new reject handler, which rejects by returning Promise.reject().
+ // The returned promise q_ triggers a reject callback at first, only to
+ // revoke it when returning it causes q2 to be rejected.
+ CompileRun(
+ "var q_;"
+ "var q2 = q0.catch( \n"
+ " function() { \n"
+ " q_ = Promise.reject('qqq'); \n"
+ " return q_; \n"
+ " } \n"
+ "); \n");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(!GetPromise("q1")->HasHandler());
+ CHECK(!GetPromise("q2")->HasHandler());
+ CHECK(GetPromise("q_")->HasHandler());
+ CHECK_EQ(2, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("q2")));
+ CHECK(GetPromise("revoked")->Equals(GetPromise("q_")));
+ CHECK(RejectValue()->Equals(v8_str("qqq")));
+
+ // Add a reject handler to the resolved q1, which rejects by throwing.
+ CompileRun(
+ "var q3 = q1.then( \n"
+ " function() { \n"
+ " throw 'qqqq'; \n"
+ " } \n"
+ "); \n");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(GetPromise("q1")->HasHandler());
+ CHECK(!GetPromise("q2")->HasHandler());
+ CHECK(!GetPromise("q3")->HasHandler());
+ CHECK_EQ(3, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("q3")));
+ CHECK(RejectValue()->Equals(v8_str("qqqq")));
+
+ ResetPromiseStates();
+
+ // Create promise r0, which has three handlers, two of which handle rejects.
+ CompileRun(
+ "var r0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n"
+ "var r1 = r0.catch(function() {}); \n"
+ "var r2 = r0.then(function() {}); \n"
+ "var r3 = r0.then(function() {}, \n"
+ " function() {}); \n");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(!GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject r0.
+ CompileRun("reject('rrr')");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(!GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("r2")));
+ CHECK(RejectValue()->Equals(v8_str("rrr")));
+
+ // Add reject handler to r2.
+ CompileRun("var r4 = r2.catch(function() {});");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK(!GetPromise("r4")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("revoked")->Equals(GetPromise("r2")));
+ CHECK(RejectValue()->Equals(v8_str("rrr")));
+
+ // Add reject handlers to r4.
+ CompileRun("var r5 = r4.then(function() {}, function() {});");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK(GetPromise("r4")->HasHandler());
+ CHECK(!GetPromise("r5")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+
+ ResetPromiseStates();
+
+ // Create promise s0, which has three handlers, none of which handle rejects.
+ CompileRun(
+ "var s0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n"
+ "var s1 = s0.then(function() {}); \n"
+ "var s2 = s0.then(function() {}); \n"
+ "var s3 = s0.then(function() {}); \n");
+ CHECK(GetPromise("s0")->HasHandler());
+ CHECK(!GetPromise("s1")->HasHandler());
+ CHECK(!GetPromise("s2")->HasHandler());
+ CHECK(!GetPromise("s3")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject s0.
+ CompileRun("reject('sss')");
+ CHECK(GetPromise("s0")->HasHandler());
+ CHECK(!GetPromise("s1")->HasHandler());
+ CHECK(!GetPromise("s2")->HasHandler());
+ CHECK(!GetPromise("s3")->HasHandler());
+ CHECK_EQ(3, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK(RejectValue()->Equals(v8_str("sss")));
+
+ // Test stack frames.
+ V8::SetCaptureStackTraceForUncaughtExceptions(true);
+
+ ResetPromiseStates();
+
+ // Create promise t0, which is rejected in the constructor with an error.
+ CompileRunWithOrigin(
+ "var t0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reference_error; \n"
+ " } \n"
+ "); \n",
+ "pro", 0, 0);
+ CHECK(!GetPromise("t0")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK_EQ(2, promise_reject_frame_count);
+ CHECK_EQ(3, promise_reject_line_number);
+
+ ResetPromiseStates();
+
+ // Create promise u0 and chain u1 to it, which is rejected via throw.
+ CompileRunWithOrigin(
+ "var u0 = Promise.resolve(); \n"
+ "var u1 = u0.then( \n"
+ " function() { \n"
+ " (function() { \n"
+ " throw new Error(); \n"
+ " })(); \n"
+ " } \n"
+ " ); \n",
+ "pro", 0, 0);
+ CHECK(GetPromise("u0")->HasHandler());
+ CHECK(!GetPromise("u1")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK_EQ(2, promise_reject_frame_count);
+ CHECK_EQ(5, promise_reject_line_number);
+
+ // Throw in u3, which handles u1's rejection.
+ CompileRunWithOrigin(
+ "function f() { \n"
+ " return (function() { \n"
+ " return new Error(); \n"
+ " })(); \n"
+ "} \n"
+ "var u2 = Promise.reject(f()); \n"
+ "var u3 = u1.catch( \n"
+ " function() { \n"
+ " return u2; \n"
+ " } \n"
+ " ); \n",
+ "pro", 0, 0);
+ CHECK(GetPromise("u0")->HasHandler());
+ CHECK(GetPromise("u1")->HasHandler());
+ CHECK(GetPromise("u2")->HasHandler());
+ CHECK(!GetPromise("u3")->HasHandler());
+ CHECK_EQ(3, promise_reject_counter);
+ CHECK_EQ(2, promise_revoke_counter);
+ CHECK_EQ(3, promise_reject_frame_count);
+ CHECK_EQ(3, promise_reject_line_number);
+
+ ResetPromiseStates();
+
+ // Create promise rejected promise v0, which is incorrectly handled by v1
+ // via chaining cycle.
+ CompileRunWithOrigin(
+ "var v0 = Promise.reject(); \n"
+ "var v1 = v0.catch( \n"
+ " function() { \n"
+ " return v1; \n"
+ " } \n"
+ " ); \n",
+ "pro", 0, 0);
+ CHECK(GetPromise("v0")->HasHandler());
+ CHECK(!GetPromise("v1")->HasHandler());
+ CHECK_EQ(2, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK_EQ(0, promise_reject_frame_count);
+ CHECK_EQ(-1, promise_reject_line_number);
+}
+
+
void AnalyzeStackOfEvalWithSourceURL(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
+ args.GetIsolate(), 10, v8::StackTrace::kDetailed);
CHECK_EQ(5, stackTrace->GetFrameCount());
v8::Handle<v8::String> url = v8_str("eval_url");
for (int i = 0; i < 3; i++) {
TEST(SourceURLInStackTrace) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("AnalyzeStackOfEvalWithSourceURL"),
- v8::FunctionTemplate::New(AnalyzeStackOfEvalWithSourceURL));
+ v8::FunctionTemplate::New(isolate,
+ AnalyzeStackOfEvalWithSourceURL));
LocalContext context(0, templ);
const char *source =
"eval('(' + outer +')()%s');";
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, source, "//# sourceURL=eval_url");
+ i::SNPrintF(code, source, "//# sourceURL=eval_url");
CHECK(CompileRun(code.start())->IsUndefined());
- i::OS::SNPrintF(code, source, "//@ sourceURL=eval_url");
+ i::SNPrintF(code, source, "//@ sourceURL=eval_url");
CHECK(CompileRun(code.start())->IsUndefined());
}
void AnalyzeScriptIdInStack(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kScriptId);
+ v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
+ args.GetIsolate(), 10, v8::StackTrace::kScriptId);
CHECK_EQ(2, stackTrace->GetFrameCount());
for (int i = 0; i < 2; i++) {
scriptIdInStack[i] = stackTrace->GetFrame(i)->GetScriptId();
TEST(ScriptIdInStackTrace) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("AnalyzeScriptIdInStack"),
- v8::FunctionTemplate::New(AnalyzeScriptIdInStack));
+ v8::FunctionTemplate::New(isolate, AnalyzeScriptIdInStack));
LocalContext context(0, templ);
- v8::Handle<v8::String> scriptSource = v8::String::New(
+ v8::Handle<v8::String> scriptSource = v8::String::NewFromUtf8(
+ isolate,
"function foo() {\n"
" AnalyzeScriptIdInStack();"
"}\n"
"foo();\n");
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
- v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin));
+ v8::Local<v8::Script> script = CompileWithOrigin(scriptSource, "test");
script->Run();
for (int i = 0; i < 2; i++) {
CHECK(scriptIdInStack[i] != v8::Message::kNoScriptIdInfo);
- CHECK_EQ(scriptIdInStack[i], script->GetId());
+ CHECK_EQ(scriptIdInStack[i], script->GetUnboundScript()->GetId());
}
}
void AnalyzeStackOfInlineScriptWithSourceURL(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
+ args.GetIsolate(), 10, v8::StackTrace::kDetailed);
CHECK_EQ(4, stackTrace->GetFrameCount());
v8::Handle<v8::String> url = v8_str("url");
for (int i = 0; i < 3; i++) {
TEST(InlineScriptWithSourceURLInStackTrace) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("AnalyzeStackOfInlineScriptWithSourceURL"),
v8::FunctionTemplate::New(
- AnalyzeStackOfInlineScriptWithSourceURL));
+ CcTest::isolate(), AnalyzeStackOfInlineScriptWithSourceURL));
LocalContext context(0, templ);
const char *source =
"outer()\n%s";
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ i::SNPrintF(code, source, "//# sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
- i::OS::SNPrintF(code, source, "//@ sourceURL=source_url");
+ i::SNPrintF(code, source, "//@ sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
}
void AnalyzeStackOfDynamicScriptWithSourceURL(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
+ args.GetIsolate(), 10, v8::StackTrace::kDetailed);
CHECK_EQ(4, stackTrace->GetFrameCount());
v8::Handle<v8::String> url = v8_str("source_url");
for (int i = 0; i < 3; i++) {
TEST(DynamicWithSourceURLInStackTrace) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("AnalyzeStackOfDynamicScriptWithSourceURL"),
v8::FunctionTemplate::New(
- AnalyzeStackOfDynamicScriptWithSourceURL));
+ CcTest::isolate(), AnalyzeStackOfDynamicScriptWithSourceURL));
LocalContext context(0, templ);
const char *source =
"outer()\n%s";
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ i::SNPrintF(code, source, "//# sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined());
- i::OS::SNPrintF(code, source, "//@ sourceURL=source_url");
+ i::SNPrintF(code, source, "//@ sourceURL=source_url");
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined());
}
-static void CreateGarbageInOldSpace() {
- i::Factory* factory = CcTest::i_isolate()->factory();
- v8::HandleScope scope(CcTest::isolate());
- i::AlwaysAllocateScope always_allocate;
- for (int i = 0; i < 1000; i++) {
- factory->NewFixedArray(1000, i::TENURED);
- }
+TEST(DynamicWithSourceURLInStackTraceString) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ const char *source =
+ "function outer() {\n"
+ " function foo() {\n"
+ " FAIL.FAIL;\n"
+ " }\n"
+ " foo();\n"
+ "}\n"
+ "outer()\n%s";
+
+ i::ScopedVector<char> code(1024);
+ i::SNPrintF(code, source, "//# sourceURL=source_url");
+ v8::TryCatch try_catch;
+ CompileRunWithOrigin(code.start(), "", 0, 0);
+ CHECK(try_catch.HasCaught());
+ v8::String::Utf8Value stack(try_catch.StackTrace());
+ CHECK(strstr(*stack, "at foo (source_url:3:5)") != NULL);
+}
+
+
+TEST(EvalWithSourceURLInMessageScriptResourceNameOrSourceURL) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ const char *source =
+ "function outer() {\n"
+ " var scriptContents = \"function foo() { FAIL.FAIL; }\\\n"
+ " //# sourceURL=source_url\";\n"
+ " eval(scriptContents);\n"
+ " foo(); }\n"
+ "outer();\n"
+ "//# sourceURL=outer_url";
+
+ v8::TryCatch try_catch;
+ CompileRun(source);
+ CHECK(try_catch.HasCaught());
+
+ Local<v8::Message> message = try_catch.Message();
+ Handle<Value> sourceURL =
+ message->GetScriptOrigin().ResourceName();
+ CHECK_EQ(*v8::String::Utf8Value(sourceURL), "source_url");
+}
+
+
+TEST(RecursionWithSourceURLInMessageScriptResourceNameOrSourceURL) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ const char *source =
+ "function outer() {\n"
+ " var scriptContents = \"function boo(){ boo(); }\\\n"
+ " //# sourceURL=source_url\";\n"
+ " eval(scriptContents);\n"
+ " boo(); }\n"
+ "outer();\n"
+ "//# sourceURL=outer_url";
+
+ v8::TryCatch try_catch;
+ CompileRun(source);
+ CHECK(try_catch.HasCaught());
+
+ Local<v8::Message> message = try_catch.Message();
+ Handle<Value> sourceURL =
+ message->GetScriptOrigin().ResourceName();
+ CHECK_EQ(*v8::String::Utf8Value(sourceURL), "source_url");
+}
+
+
+static void CreateGarbageInOldSpace() {
+ i::Factory* factory = CcTest::i_isolate()->factory();
+ v8::HandleScope scope(CcTest::isolate());
+ i::AlwaysAllocateScope always_allocate(CcTest::i_isolate());
+ for (int i = 0; i < 1000; i++) {
+ factory->NewFixedArray(1000, i::TENURED);
+ }
}
// Test that idle notification can be handled and eventually returns true.
TEST(IdleNotification) {
const intptr_t MB = 1024 * 1024;
+ const int IdlePauseInMs = 1000;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
intptr_t initial_size = CcTest::heap()->SizeOfObjects();
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification();
+ finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK(finished);
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification(IdlePauseInMs);
+ finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK(finished);
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification(IdlePauseInMs);
+ finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
}
intptr_t final_size = CcTest::heap()->SizeOfObjects();
CHECK(finished);
}
-TEST(Regress2107) {
- const intptr_t MB = 1024 * 1024;
- const int kShortIdlePauseInMs = 100;
- const int kLongIdlePauseInMs = 1000;
+TEST(Regress2333) {
LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(env->GetIsolate());
- intptr_t initial_size = CcTest::heap()->SizeOfObjects();
- // Send idle notification to start a round of incremental GCs.
- v8::V8::IdleNotification(kShortIdlePauseInMs);
- // Emulate 7 page reloads.
- for (int i = 0; i < 7; i++) {
- {
- v8::HandleScope inner_scope(env->GetIsolate());
- v8::Local<v8::Context> ctx = v8::Context::New(isolate);
- ctx->Enter();
- CreateGarbageInOldSpace();
- ctx->Exit();
- }
- v8::V8::ContextDisposedNotification();
- v8::V8::IdleNotification(kLongIdlePauseInMs);
- }
- // Create garbage and check that idle notification still collects it.
- CreateGarbageInOldSpace();
- intptr_t size_with_garbage = CcTest::heap()->SizeOfObjects();
- CHECK_GT(size_with_garbage, initial_size + MB);
- bool finished = false;
- for (int i = 0; i < 200 && !finished; i++) {
- finished = v8::V8::IdleNotification(kShortIdlePauseInMs);
+ for (int i = 0; i < 3; i++) {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
}
- intptr_t final_size = CcTest::heap()->SizeOfObjects();
- CHECK_LT(final_size, initial_size + 1);
}
static uint32_t* stack_limit;
static const int stack_breathing_room = 256 * i::KB;
-TEST(SetResourceConstraints) {
+TEST(SetStackLimit) {
uint32_t* set_limit = ComputeStackLimit(stack_breathing_room);
// Set stack limit.
- v8::ResourceConstraints constraints;
- constraints.set_stack_limit(set_limit);
- CHECK(v8::SetResourceConstraints(&constraints));
+ CcTest::isolate()->SetStackLimit(reinterpret_cast<uintptr_t>(set_limit));
// Execute a script.
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(GetStackLimitCallback);
+ v8::FunctionTemplate::New(env->GetIsolate(), GetStackLimitCallback);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("get_stack_limit"), fun);
CompileRun("get_stack_limit();");
}
-TEST(SetResourceConstraintsInThread) {
+TEST(SetStackLimitInThread) {
uint32_t* set_limit;
{
v8::Locker locker(CcTest::isolate());
set_limit = ComputeStackLimit(stack_breathing_room);
// Set stack limit.
- v8::ResourceConstraints constraints;
- constraints.set_stack_limit(set_limit);
- CHECK(v8::SetResourceConstraints(&constraints));
+ CcTest::isolate()->SetStackLimit(reinterpret_cast<uintptr_t>(set_limit));
// Execute a script.
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(GetStackLimitCallback);
+ v8::FunctionTemplate::New(CcTest::isolate(), GetStackLimitCallback);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("get_stack_limit"), fun);
CompileRun("get_stack_limit();");
virtual ~VisitorImpl() {}
virtual void VisitExternalString(v8::Handle<v8::String> string) {
if (!string->IsExternal()) {
- CHECK(string->IsExternalAscii());
+ CHECK(string->IsExternalOneByte());
return;
}
v8::String::ExternalStringResource* resource =
};
+TEST(ExternalizeOldSpaceTwoByteCons) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::Local<v8::String> cons =
+ CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+ CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
+ CcTest::heap()->CollectAllAvailableGarbage();
+ CHECK(CcTest::heap()->old_pointer_space()->Contains(
+ *v8::Utils::OpenHandle(*cons)));
+
+ TestResource* resource = new TestResource(
+ AsciiToTwoByteString("Romeo Montague Juliet Capulet"));
+ cons->MakeExternal(resource);
+
+ CHECK(cons->IsExternal());
+ CHECK_EQ(resource, cons->GetExternalStringResource());
+ String::Encoding encoding;
+ CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::TWO_BYTE_ENCODING, encoding);
+}
+
+
+TEST(ExternalizeOldSpaceOneByteCons) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::Local<v8::String> cons =
+ CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+ CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
+ CcTest::heap()->CollectAllAvailableGarbage();
+ CHECK(CcTest::heap()->old_pointer_space()->Contains(
+ *v8::Utils::OpenHandle(*cons)));
+
+ TestOneByteResource* resource =
+ new TestOneByteResource(i::StrDup("Romeo Montague Juliet Capulet"));
+ cons->MakeExternal(resource);
+
+ CHECK(cons->IsExternalOneByte());
+ CHECK_EQ(resource, cons->GetExternalOneByteStringResource());
+ String::Encoding encoding;
+ CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ONE_BYTE_ENCODING, encoding);
+}
+
+
TEST(VisitExternalStrings) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
uint16_t* two_byte_string = AsciiToTwoByteString(string);
TestResource* resource[4];
resource[0] = new TestResource(two_byte_string);
- v8::Local<v8::String> string0 = v8::String::NewExternal(resource[0]);
- resource[1] = new TestResource(two_byte_string);
- v8::Local<v8::String> string1 = v8::String::NewExternal(resource[1]);
+ v8::Local<v8::String> string0 =
+ v8::String::NewExternal(env->GetIsolate(), resource[0]);
+ resource[1] = new TestResource(two_byte_string, NULL, false);
+ v8::Local<v8::String> string1 =
+ v8::String::NewExternal(env->GetIsolate(), resource[1]);
// Externalized symbol.
- resource[2] = new TestResource(two_byte_string);
- v8::Local<v8::String> string2 = v8::String::NewSymbol(string);
+ resource[2] = new TestResource(two_byte_string, NULL, false);
+ v8::Local<v8::String> string2 = v8::String::NewFromUtf8(
+ env->GetIsolate(), string, v8::String::kInternalizedString);
CHECK(string2->MakeExternal(resource[2]));
// Symbolized External.
resource[3] = new TestResource(AsciiToTwoByteString("Some other string"));
- v8::Local<v8::String> string3 = v8::String::NewExternal(resource[3]);
+ v8::Local<v8::String> string3 =
+ v8::String::NewExternal(env->GetIsolate(), resource[3]);
CcTest::heap()->CollectAllAvailableGarbage(); // Tenure string.
// Turn into a symbol.
i::Handle<i::String> string3_i = v8::Utils::OpenHandle(*string3);
- CHECK(!CcTest::heap()->InternalizeString(*string3_i)->IsFailure());
+ CHECK(!CcTest::i_isolate()->factory()->InternalizeString(
+ string3_i).is_null());
CHECK(string3_i->IsInternalizedString());
// We need to add usages for string* to avoid warnings in GCC 4.7
}
+TEST(ExternalStringCollectedAtTearDown) {
+ int destroyed = 0;
+ v8::Isolate* isolate = v8::Isolate::New();
+ { v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope handle_scope(isolate);
+ const char* s = "One string to test them all, one string to find them.";
+ TestOneByteResource* inscription =
+ new TestOneByteResource(i::StrDup(s), &destroyed);
+ v8::Local<v8::String> ring = v8::String::NewExternal(isolate, inscription);
+ // Ring is still alive. Orcs are roaming freely across our lands.
+ CHECK_EQ(0, destroyed);
+ USE(ring);
+ }
+
+ isolate->Dispose();
+ // Ring has been destroyed. Free Peoples of Middle-earth Rejoice.
+ CHECK_EQ(1, destroyed);
+}
+
+
+TEST(ExternalInternalizedStringCollectedAtTearDown) {
+ int destroyed = 0;
+ v8::Isolate* isolate = v8::Isolate::New();
+ { v8::Isolate::Scope isolate_scope(isolate);
+ LocalContext env(isolate);
+ v8::HandleScope handle_scope(isolate);
+ CompileRun("var ring = 'One string to test them all';");
+ const char* s = "One string to test them all";
+ TestOneByteResource* inscription =
+ new TestOneByteResource(i::StrDup(s), &destroyed);
+ v8::Local<v8::String> ring = CompileRun("ring")->ToString();
+ CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString());
+ ring->MakeExternal(inscription);
+ // Ring is still alive. Orcs are roaming freely across our lands.
+ CHECK_EQ(0, destroyed);
+ USE(ring);
+ }
+
+ isolate->Dispose();
+ // Ring has been destroyed. Free Peoples of Middle-earth Rejoice.
+ CHECK_EQ(1, destroyed);
+}
+
+
+TEST(ExternalInternalizedStringCollectedAtGC) {
+ int destroyed = 0;
+ { LocalContext env;
+ v8::HandleScope handle_scope(env->GetIsolate());
+ CompileRun("var ring = 'One string to test them all';");
+ const char* s = "One string to test them all";
+ TestOneByteResource* inscription =
+ new TestOneByteResource(i::StrDup(s), &destroyed);
+ v8::Local<v8::String> ring = CompileRun("ring")->ToString();
+ CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString());
+ ring->MakeExternal(inscription);
+ // Ring is still alive. Orcs are roaming freely across our lands.
+ CHECK_EQ(0, destroyed);
+ USE(ring);
+ }
+
+ // Garbage collector deals swift blows to evil.
+ CcTest::i_isolate()->compilation_cache()->Clear();
+ CcTest::heap()->CollectAllAvailableGarbage();
+
+ // Ring has been destroyed. Free Peoples of Middle-earth Rejoice.
+ CHECK_EQ(1, destroyed);
+}
+
+
static double DoubleFromBits(uint64_t value) {
double target;
- i::OS::MemCopy(&target, &value, sizeof(target));
+ i::MemCopy(&target, &value, sizeof(target));
return target;
}
static uint64_t DoubleToBits(double value) {
uint64_t target;
- i::OS::MemCopy(&target, &value, sizeof(target));
+ i::MemCopy(&target, &value, sizeof(target));
return target;
}
static double DoubleToDateTime(double input) {
double date_limit = 864e13;
if (std::isnan(input) || input < -date_limit || input > date_limit) {
- return i::OS::nan_value();
+ return v8::base::OS::nan_value();
}
- return (input < 0) ? -(floor(-input)) : floor(input);
+ return (input < 0) ? -(std::floor(-input)) : std::floor(input);
}
THREADED_TEST(QuietSignalingNaNs) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::TryCatch try_catch;
// Special double values.
double test_value = test_values[i];
// Check that Number::New preserves non-NaNs and quiets SNaNs.
- v8::Handle<v8::Value> number = v8::Number::New(test_value);
+ v8::Handle<v8::Value> number = v8::Number::New(isolate, test_value);
double stored_number = number->NumberValue();
if (!std::isnan(test_value)) {
CHECK_EQ(test_value, stored_number);
} else {
uint64_t stored_bits = DoubleToBits(stored_number);
// Check if quiet nan (bits 51..62 all set).
-#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
+#if (defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64)) && \
+ !defined(_MIPS_ARCH_MIPS64R6) && !defined(USE_SIMULATOR)
// Most significant fraction bit for quiet nan is set to 0
// on MIPS architecture. Allowed by IEEE-754.
CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
// Check that Date::New preserves non-NaNs in the date range and
// quiets SNaNs.
- v8::Handle<v8::Value> date = v8::Date::New(test_value);
+ v8::Handle<v8::Value> date =
+ v8::Date::New(isolate, test_value);
double expected_stored_date = DoubleToDateTime(test_value);
double stored_date = date->NumberValue();
if (!std::isnan(expected_stored_date)) {
} else {
uint64_t stored_bits = DoubleToBits(stored_date);
// Check if quiet nan (bits 51..62 all set).
-#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
+#if (defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64)) && \
+ !defined(_MIPS_ARCH_MIPS64R6) && !defined(USE_SIMULATOR)
// Most significant fraction bit for quiet nan is set to 0
// on MIPS architecture. Allowed by IEEE-754.
CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
// Test that an exception can be propagated down through a spaghetti
// stack using ReThrow.
THREADED_TEST(SpaghettiStackReThrow) {
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
LocalContext context;
context->Global()->Set(
- v8::String::New("s"),
- v8::FunctionTemplate::New(SpaghettiIncident)->GetFunction());
+ v8::String::NewFromUtf8(isolate, "s"),
+ v8::FunctionTemplate::New(isolate, SpaghettiIncident)->GetFunction());
v8::TryCatch try_catch;
CompileRun(
"var i = 0;"
v8::Local<Context> context = Context::New(isolate);
context->Enter();
- Local<v8::String> obj = v8::String::New("");
+ Local<v8::String> obj = v8::String::NewFromUtf8(isolate, "");
context->SetEmbedderData(0, obj);
CompileRun(source_simple);
context->Exit();
}
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_simple);
CompileRun(source_eval);
context->Exit();
}
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_eval);
CHECK_EQ(1, message->GetLineNumber());
context->Exit();
}
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_exception);
CHECK_GE(2, gc_count);
CHECK_EQ(1, GetGlobalObjectsCount());
- v8::V8::ContextDisposedNotification();
+ isolate->ContextDisposedNotification();
}
THREADED_TEST(ScriptOrigin) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
- v8::Handle<v8::String> script = v8::String::New(
- "function f() {}\n\nfunction g() {}");
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
+ v8::Handle<v8::String> script = v8::String::NewFromUtf8(
+ env->GetIsolate(), "function f() {}\n\nfunction g() {}");
v8::Script::Compile(script, &origin)->Run();
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("f")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("g")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
v8::ScriptOrigin script_origin_f = f->GetScriptOrigin();
CHECK_EQ("test", *v8::String::Utf8Value(script_origin_f.ResourceName()));
THREADED_TEST(FunctionGetInferredName) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
- v8::Handle<v8::String> script = v8::String::New(
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
+ v8::Handle<v8::String> script = v8::String::NewFromUtf8(
+ env->GetIsolate(),
"var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;");
v8::Script::Compile(script, &origin)->Run();
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("f")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
CHECK_EQ("foo.bar.baz", *v8::String::Utf8Value(f->GetInferredName()));
}
" arguments.callee.displayName = 'set_in_runtime';"
"}; g();"
;
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
- v8::Script::Compile(v8::String::New(code), &origin)->Run();
- v8::Local<v8::Value> error = env->Global()->Get(v8::String::New("error"));
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
+ v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), code), &origin)
+ ->Run();
+ v8::Local<v8::Value> error =
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "error"));
v8::Local<v8::Function> a = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("a")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "a")));
v8::Local<v8::Function> b = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("b")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "b")));
v8::Local<v8::Function> c = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("c")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c")));
v8::Local<v8::Function> d = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("d")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "d")));
v8::Local<v8::Function> e = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("e")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "e")));
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("f")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("g")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
CHECK_EQ(false, error->BooleanValue());
CHECK_EQ("display_a", *v8::String::Utf8Value(a->GetDisplayName()));
CHECK_EQ("display_b", *v8::String::Utf8Value(b->GetDisplayName()));
THREADED_TEST(ScriptLineNumber) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
- v8::Handle<v8::String> script = v8::String::New(
- "function f() {}\n\nfunction g() {}");
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
+ v8::Handle<v8::String> script = v8::String::NewFromUtf8(
+ env->GetIsolate(), "function f() {}\n\nfunction g() {}");
v8::Script::Compile(script, &origin)->Run();
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("f")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("g")));
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
CHECK_EQ(0, f->GetScriptLineNumber());
CHECK_EQ(2, g->GetScriptLineNumber());
}
THREADED_TEST(ScriptColumnNumber) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"),
- v8::Integer::New(3), v8::Integer::New(2));
- v8::Handle<v8::String> script = v8::String::New(
- "function foo() {}\n\n function bar() {}");
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8::String::NewFromUtf8(isolate, "test"),
+ v8::Integer::New(isolate, 3),
+ v8::Integer::New(isolate, 2));
+ v8::Handle<v8::String> script = v8::String::NewFromUtf8(
+ isolate, "function foo() {}\n\n function bar() {}");
v8::Script::Compile(script, &origin)->Run();
v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("foo")));
+ env->Global()->Get(v8::String::NewFromUtf8(isolate, "foo")));
v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("bar")));
+ env->Global()->Get(v8::String::NewFromUtf8(isolate, "bar")));
CHECK_EQ(14, foo->GetScriptColumnNumber());
CHECK_EQ(17, bar->GetScriptColumnNumber());
}
THREADED_TEST(FunctionIsBuiltin) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::Local<v8::Function> f;
f = v8::Local<v8::Function>::Cast(CompileRun("Math.floor"));
CHECK(f->IsBuiltin());
THREADED_TEST(FunctionGetScriptId) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"),
- v8::Integer::New(3), v8::Integer::New(2));
- v8::Handle<v8::String> scriptSource = v8::String::New(
- "function foo() {}\n\n function bar() {}");
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8::String::NewFromUtf8(isolate, "test"),
+ v8::Integer::New(isolate, 3),
+ v8::Integer::New(isolate, 2));
+ v8::Handle<v8::String> scriptSource = v8::String::NewFromUtf8(
+ isolate, "function foo() {}\n\n function bar() {}");
v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin));
script->Run();
v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("foo")));
+ env->Global()->Get(v8::String::NewFromUtf8(isolate, "foo")));
v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
- env->Global()->Get(v8::String::New("bar")));
- CHECK_EQ(script->Id(), foo->GetScriptId());
- CHECK_EQ(script->Id(), bar->GetScriptId());
+ env->Global()->Get(v8::String::NewFromUtf8(isolate, "bar")));
+ CHECK_EQ(script->GetUnboundScript()->GetId(), foo->ScriptId());
+ CHECK_EQ(script->GetUnboundScript()->GetId(), bar->ScriptId());
+}
+
+
+THREADED_TEST(FunctionGetBoundFunction) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::NewFromUtf8(
+ env->GetIsolate(), "test"));
+ v8::Handle<v8::String> script = v8::String::NewFromUtf8(
+ env->GetIsolate(),
+ "var a = new Object();\n"
+ "a.x = 1;\n"
+ "function f () { return this.x };\n"
+ "var g = f.bind(a);\n"
+ "var b = g();");
+ v8::Script::Compile(script, &origin)->Run();
+ v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
+ v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
+ CHECK(g->GetBoundFunction()->IsFunction());
+ Local<v8::Function> original_function = Local<v8::Function>::Cast(
+ g->GetBoundFunction());
+ CHECK_EQ(f->GetName(), original_function->GetName());
+ CHECK_EQ(f->GetScriptLineNumber(), original_function->GetScriptLineNumber());
+ CHECK_EQ(f->GetScriptColumnNumber(),
+ original_function->GetScriptColumnNumber());
}
const v8::PropertyCallbackInfo<void>& info) {
CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject());
CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject());
- info.This()->Set(v8_str("y"), v8_num(23));
+ Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23));
}
CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject());
CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject());
if (!name->Equals(v8_str("foo"))) return;
- info.This()->Set(v8_str("y"), v8_num(23));
+ Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23));
info.GetReturnValue().Set(v8_num(23));
}
TEST(SetterOnConstructorPrototype) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
- templ->SetAccessor(v8_str("x"),
- GetterWhichReturns42,
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->SetAccessor(v8_str("x"), GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
LocalContext context;
context->Global()->Set(v8_str("P"), templ->NewInstance());
"C2.prototype.__proto__ = P;");
v8::Local<v8::Script> script;
- script = v8::Script::Compile(v8_str("new C1();"));
+ script = v8_compile("new C1();");
for (int i = 0; i < 10; i++) {
v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
CHECK_EQ(42, c1->Get(v8_str("x"))->Int32Value());
CHECK_EQ(23, c1->Get(v8_str("y"))->Int32Value());
}
- script = v8::Script::Compile(v8_str("new C2();"));
+script = v8_compile("new C2();");
for (int i = 0; i < 10; i++) {
v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
CHECK_EQ(42, c2->Get(v8_str("x"))->Int32Value());
Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
if (name->Equals(v8_str("x"))) {
- info.This()->Set(v8_str("y"), v8_num(23));
+ Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23));
}
}
THREADED_TEST(InterceptorOnConstructorPrototype) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42,
NamedPropertySetterWhichSetsYOnThisTo23);
LocalContext context;
"C2.prototype.__proto__ = P;");
v8::Local<v8::Script> script;
- script = v8::Script::Compile(v8_str("new C1();"));
+ script = v8_compile("new C1();");
for (int i = 0; i < 10; i++) {
v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
CHECK_EQ(23, c1->Get(v8_str("x"))->Int32Value());
CHECK_EQ(42, c1->Get(v8_str("y"))->Int32Value());
}
- script = v8::Script::Compile(v8_str("new C2();"));
+ script = v8_compile("new C2();");
for (int i = 0; i < 10; i++) {
v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run());
CHECK_EQ(23, c2->Get(v8_str("x"))->Int32Value());
"C1.prototype = P;";
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::Local<v8::Script> script;
// Use a simple object as prototype.
- v8::Local<v8::Object> prototype = v8::Object::New();
+ v8::Local<v8::Object> prototype = v8::Object::New(isolate);
prototype->Set(v8_str("y"), v8_num(42));
context->Global()->Set(v8_str("P"), prototype);
// This compile will add the code to the compilation cache.
CompileRun(source);
- script = v8::Script::Compile(v8_str("new C1();"));
+ script = v8_compile("new C1();");
// Allow enough iterations for the inobject slack tracking logic
// to finalize instance size and install the fast construct stub.
for (int i = 0; i < 256; i++) {
}
// Use an API object with accessors as prototype.
- Local<ObjectTemplate> templ = ObjectTemplate::New();
- templ->SetAccessor(v8_str("x"),
- GetterWhichReturns42,
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->SetAccessor(v8_str("x"), GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
context->Global()->Set(v8_str("P"), templ->NewInstance());
// This compile will get the code from the compilation cache.
CompileRun(source);
- script = v8::Script::Compile(v8_str("new C1();"));
+ script = v8_compile("new C1();");
for (int i = 0; i < 10; i++) {
v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run());
CHECK_EQ(42, c1->Get(v8_str("x"))->Int32Value());
int epilogue_call_count = 0;
int prologue_call_count_second = 0;
int epilogue_call_count_second = 0;
+int prologue_call_count_alloc = 0;
+int epilogue_call_count_alloc = 0;
void PrologueCallback(v8::GCType, v8::GCCallbackFlags flags) {
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
}
+void PrologueCallbackAlloc(v8::Isolate* isolate,
+ v8::GCType,
+ v8::GCCallbackFlags flags) {
+ v8::HandleScope scope(isolate);
+
+ CHECK_EQ(flags, v8::kNoGCCallbackFlags);
+ CHECK_EQ(gc_callbacks_isolate, isolate);
+ ++prologue_call_count_alloc;
+
+ // Simulate full heap to see if we will reenter this callback
+ SimulateFullSpace(CcTest::heap()->new_space());
+
+ Local<Object> obj = Object::New(isolate);
+ CHECK(!obj.IsEmpty());
+
+ CcTest::heap()->CollectAllGarbage(
+ i::Heap::kAbortIncrementalMarkingMask);
+}
+
+
+void EpilogueCallbackAlloc(v8::Isolate* isolate,
+ v8::GCType,
+ v8::GCCallbackFlags flags) {
+ v8::HandleScope scope(isolate);
+
+ CHECK_EQ(flags, v8::kNoGCCallbackFlags);
+ CHECK_EQ(gc_callbacks_isolate, isolate);
+ ++epilogue_call_count_alloc;
+
+ // Simulate full heap to see if we will reenter this callback
+ SimulateFullSpace(CcTest::heap()->new_space());
+
+ Local<Object> obj = Object::New(isolate);
+ CHECK(!obj.IsEmpty());
+
+ CcTest::heap()->CollectAllGarbage(
+ i::Heap::kAbortIncrementalMarkingMask);
+}
+
+
TEST(GCCallbacksOld) {
LocalContext context;
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
CHECK_EQ(2, epilogue_call_count_second);
+
+ CHECK_EQ(0, prologue_call_count_alloc);
+ CHECK_EQ(0, epilogue_call_count_alloc);
+ isolate->AddGCPrologueCallback(PrologueCallbackAlloc);
+ isolate->AddGCEpilogueCallback(EpilogueCallbackAlloc);
+ CcTest::heap()->CollectAllGarbage(
+ i::Heap::kAbortIncrementalMarkingMask);
+ CHECK_EQ(1, prologue_call_count_alloc);
+ CHECK_EQ(1, epilogue_call_count_alloc);
+ isolate->RemoveGCPrologueCallback(PrologueCallbackAlloc);
+ isolate->RemoveGCEpilogueCallback(EpilogueCallbackAlloc);
}
}
-static const int k0CacheSize = 16;
-
THREADED_TEST(FillJSFunctionResultCache) {
i::FLAG_allow_natives_syntax = true;
LocalContext context;
}
-THREADED_TEST(TwoByteStringInAsciiCons) {
+THREADED_TEST(TwoByteStringInOneByteCons) {
// See Chromium issue 47824.
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
int length = string->length();
CHECK(string->IsOneByteRepresentation());
- FlattenString(string);
- i::Handle<i::String> flat_string = FlattenGetString(string);
+ i::Handle<i::String> flat_string = i::String::Flatten(string);
CHECK(string->IsOneByteRepresentation());
CHECK(flat_string->IsOneByteRepresentation());
// If the cons string has been short-circuited, skip the following checks.
if (!string.is_identical_to(flat_string)) {
- // At this point, we should have a Cons string which is flat and ASCII,
+ // At this point, we should have a Cons string which is flat and one-byte,
// with a first half that is a two-byte string (although it only contains
- // ASCII characters). This is a valid sequence of steps, and it can happen
- // in real pages.
+ // one-byte characters). This is a valid sequence of steps, and it can
+ // happen in real pages.
CHECK(string->IsOneByteRepresentation());
i::ConsString* cons = i::ConsString::cast(*string);
CHECK_EQ(0, cons->second()->length());
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);
+ uint16_t* string_contents =
+ reinterpret_cast<uint16_t*>(aligned_contents.get());
// 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));
+ Handle<String> string =
+ String::NewExternal(isolate,
+ new TestResource(string_contents, NULL, false));
CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
// Counter example.
string = String::NewFromTwoByte(isolate, string_contents);
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++) {
+ String::NewExternal(isolate,
+ new TestResource(string_contents, NULL, false));
+ USE(two_byte); USE(cons_strings);
+ for (size_t i = 0; i < arraysize(cons_strings); i++) {
// Base assumptions.
string = cons_strings[i];
CHECK(string->IsOneByte() && string->ContainsOnlyOneByte());
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));
+ string = String::NewExternal(
+ isolate,
+ new TestResource(string_contents + alignment, NULL, false));
CHECK_EQ(size, string->Length());
CHECK(!string->ContainsOnlyOneByte());
string_contents[alignment + i] = 0x41;
v8::V8::Initialize();
v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC);
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
// Create an ObjectTemplate for global objects and install access
// check callbacks that will block access.
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedGetAccessBlocker,
IndexedGetAccessBlocker,
v8::Handle<v8::Value>(),
ExpectUndefined("Object.prototype.__lookupGetter__.call("
" other, \'x\')");
- // HasLocalElement.
+ // HasOwnElement.
ExpectFalse("Object.prototype.hasOwnProperty.call(other, \'0\')");
CHECK_EQ(false, global0->HasRealIndexedProperty(0));
v8::Isolate* current_isolate = CcTest::isolate();
v8::Isolate* isolate = v8::Isolate::New();
CHECK(isolate != NULL);
- CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate());
CHECK(current_isolate != isolate);
CHECK(current_isolate == CcTest::isolate());
UNINITIALIZED_TEST(DisposeIsolateWhenInUse) {
v8::Isolate* isolate = v8::Isolate::New();
- CHECK(isolate);
- isolate->Enter();
- v8::HandleScope scope(isolate);
- LocalContext context(isolate);
- // Run something in this isolate.
- ExpectTrue("true");
- v8::V8::SetFatalErrorHandler(StoringErrorCallback);
- last_location = last_message = NULL;
- // Still entered, should fail.
+ {
+ v8::Isolate::Scope i_scope(isolate);
+ v8::HandleScope scope(isolate);
+ LocalContext context(isolate);
+ // Run something in this isolate.
+ ExpectTrue("true");
+ v8::V8::SetFatalErrorHandler(StoringErrorCallback);
+ last_location = last_message = NULL;
+ // Still entered, should fail.
+ isolate->Dispose();
+ CHECK_NE(last_location, NULL);
+ CHECK_NE(last_message, NULL);
+ }
isolate->Dispose();
- CHECK_NE(last_location, NULL);
- CHECK_NE(last_message, NULL);
}
{
v8::Isolate::Scope iscope(isolate2);
- context2.Dispose();
+ context2.Reset();
}
- context1.Dispose();
+ context1.Reset();
isolate1->Exit();
v8::V8::SetFatalErrorHandler(StoringErrorCallback);
v8::HandleScope scope(isolate);
LocalContext context(isolate);
i::ScopedVector<char> code(1024);
- i::OS::SNPrintF(code, "function fib(n) {"
- " if (n <= 2) return 1;"
- " return fib(n-1) + fib(n-2);"
- "}"
- "fib(%d)", limit);
+ i::SNPrintF(code, "function fib(n) {"
+ " if (n <= 2) return 1;"
+ " return fib(n-1) + fib(n-2);"
+ "}"
+ "fib(%d)", limit);
Local<Value> value = CompileRun(code.start());
CHECK(value->IsNumber());
return static_cast<int>(value->NumberValue());
}
-class IsolateThread : public v8::internal::Thread {
+class IsolateThread : public v8::base::Thread {
public:
- IsolateThread(v8::Isolate* isolate, int fib_limit)
- : Thread("IsolateThread"),
- isolate_(isolate),
- fib_limit_(fib_limit),
- result_(0) { }
+ explicit IsolateThread(int fib_limit)
+ : Thread(Options("IsolateThread")), fib_limit_(fib_limit), result_(0) {}
void Run() {
- result_ = CalcFibonacci(isolate_, fib_limit_);
+ v8::Isolate* isolate = v8::Isolate::New();
+ result_ = CalcFibonacci(isolate, fib_limit_);
+ isolate->Dispose();
}
int result() { return result_; }
private:
- v8::Isolate* isolate_;
int fib_limit_;
int result_;
};
TEST(MultipleIsolatesOnIndividualThreads) {
- v8::Isolate* isolate1 = v8::Isolate::New();
- v8::Isolate* isolate2 = v8::Isolate::New();
-
- IsolateThread thread1(isolate1, 21);
- IsolateThread thread2(isolate2, 12);
+ IsolateThread thread1(21);
+ IsolateThread thread2(12);
// Compute some fibonacci numbers on 3 threads in 3 isolates.
thread1.Start();
CHECK_EQ(result2, 144);
CHECK_EQ(result1, thread1.result());
CHECK_EQ(result2, thread2.result());
-
- isolate1->Dispose();
- isolate2->Dispose();
}
CHECK(v->IsNumber());
CHECK_EQ(22, static_cast<int>(v->NumberValue()));
}
+ isolate->Dispose();
}
-class InitDefaultIsolateThread : public v8::internal::Thread {
+class InitDefaultIsolateThread : public v8::base::Thread {
public:
enum TestCase {
- IgnoreOOM,
SetResourceConstraints,
SetFatalHandler,
SetCounterFunction,
};
explicit InitDefaultIsolateThread(TestCase testCase)
- : Thread("InitDefaultIsolateThread"),
+ : Thread(Options("InitDefaultIsolateThread")),
testCase_(testCase),
- result_(false) { }
+ result_(false) {}
void Run() {
- v8::Isolate* isolate = v8::Isolate::New();
- isolate->Enter();
+ v8::Isolate::CreateParams create_params;
switch (testCase_) {
- case IgnoreOOM:
- v8::V8::IgnoreOutOfMemoryException();
- break;
-
- case SetResourceConstraints: {
- static const int K = 1024;
- v8::ResourceConstraints constraints;
- constraints.set_max_young_space_size(256 * K);
- constraints.set_max_old_space_size(4 * K * K);
- v8::SetResourceConstraints(&constraints);
- break;
+ case SetResourceConstraints: {
+ create_params.constraints.set_max_semi_space_size(1);
+ create_params.constraints.set_max_old_space_size(4);
+ break;
+ }
+ default:
+ break;
}
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ isolate->Enter();
+ switch (testCase_) {
+ case SetResourceConstraints:
+ // Already handled in pre-Isolate-creation block.
+ break;
- case SetFatalHandler:
- v8::V8::SetFatalErrorHandler(NULL);
- break;
+ case SetFatalHandler:
+ v8::V8::SetFatalErrorHandler(NULL);
+ break;
- case SetCounterFunction:
- v8::V8::SetCounterFunction(NULL);
- break;
+ case SetCounterFunction:
+ CcTest::isolate()->SetCounterFunction(NULL);
+ break;
- case SetCreateHistogramFunction:
- v8::V8::SetCreateHistogramFunction(NULL);
- break;
+ case SetCreateHistogramFunction:
+ CcTest::isolate()->SetCreateHistogramFunction(NULL);
+ break;
- case SetAddHistogramSampleFunction:
- v8::V8::SetAddHistogramSampleFunction(NULL);
- break;
+ case SetAddHistogramSampleFunction:
+ CcTest::isolate()->SetAddHistogramSampleFunction(NULL);
+ break;
}
isolate->Exit();
isolate->Dispose();
TEST(InitializeDefaultIsolateOnSecondaryThread1) {
- InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM);
-}
-
-
-TEST(InitializeDefaultIsolateOnSecondaryThread2) {
InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints);
}
-TEST(InitializeDefaultIsolateOnSecondaryThread3) {
+TEST(InitializeDefaultIsolateOnSecondaryThread2) {
InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler);
}
-TEST(InitializeDefaultIsolateOnSecondaryThread4) {
+TEST(InitializeDefaultIsolateOnSecondaryThread3) {
InitializeTestHelper(InitDefaultIsolateThread::SetCounterFunction);
}
-TEST(InitializeDefaultIsolateOnSecondaryThread5) {
+TEST(InitializeDefaultIsolateOnSecondaryThread4) {
InitializeTestHelper(InitDefaultIsolateThread::SetCreateHistogramFunction);
}
-TEST(InitializeDefaultIsolateOnSecondaryThread6) {
+TEST(InitializeDefaultIsolateOnSecondaryThread5) {
InitializeTestHelper(InitDefaultIsolateThread::SetAddHistogramSampleFunction);
}
// cell created using the API.
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- context->Global()->Set(v8_str("cell"), v8_str("value"), v8::DontDelete);
+ context->Global()->ForceSet(v8_str("cell"), v8_str("value"), v8::DontDelete);
ExpectBoolean("delete cell", false);
CompileRun(function_code);
ExpectString("readCell()", "value");
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object> object(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object(isolate, v8::Object::New(isolate));
CHECK_EQ(0, object.WrapperClassId());
object.SetWrapperClassId(42);
CHECK_EQ(42, object.WrapperClassId());
Visitor42 visitor(&object);
- v8::V8::VisitHandlesWithClassIds(&visitor);
+ v8::V8::VisitHandlesWithClassIds(isolate, &visitor);
CHECK_EQ(1, visitor.counter_);
- object.Dispose();
+ object.Reset();
}
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object> object(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object(isolate, v8::Object::New(isolate));
CHECK_EQ(0, object.WrapperClassId());
object.SetWrapperClassId(65535);
CHECK_EQ(65535, object.WrapperClassId());
- object.Dispose();
+ object.Reset();
}
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object> object1(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object1(isolate, v8::Object::New(isolate));
CHECK_EQ(0, object1.WrapperClassId());
object1.SetWrapperClassId(42);
CHECK_EQ(42, object1.WrapperClassId());
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
- v8::Persistent<v8::Object> object2(isolate, v8::Object::New());
+ v8::Persistent<v8::Object> object2(isolate, v8::Object::New(isolate));
CHECK_EQ(0, object2.WrapperClassId());
object2.SetWrapperClassId(42);
CHECK_EQ(42, object2.WrapperClassId());
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
CHECK_EQ(1, visitor.counter_);
- object1.Dispose();
- object2.Dispose();
+ object1.Reset();
+ object2.Reset();
}
ExpectTrue("re.test('FoobarbaZ')");
// RegExps are objects on which you can set properties.
- re->Set(v8_str("property"), v8::Integer::New(32));
+ re->Set(v8_str("property"), v8::Integer::New(context->GetIsolate(), 32));
v8::Handle<v8::Value> value(CompileRun("re.property"));
CHECK_EQ(32, value->Int32Value());
static void Enumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
- v8::Handle<v8::Array> result = v8::Array::New();
+ v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate());
result->Set(0, v8_str("universalAnswer"));
info.GetReturnValue().Set(result);
}
TEST(NamedEnumeratorAndForIn) {
LocalContext context;
- v8::HandleScope handle_scope(context->GetIsolate());
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context.local());
- v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate);
tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator);
context->Global()->Set(v8_str("o"), tmpl->NewInstance());
v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun(
static void InstallContextId(v8::Handle<Context> context, int id) {
Context::Scope scope(context);
CompileRun("Object.prototype").As<Object>()->
- Set(v8_str("context_id"), v8::Integer::New(id));
+ Set(v8_str("context_id"), v8::Integer::New(context->GetIsolate(), id));
}
THREADED_TEST(CreationContext) {
- HandleScope handle_scope(CcTest::isolate());
- Handle<Context> context1 = Context::New(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ HandleScope handle_scope(isolate);
+ Handle<Context> context1 = Context::New(isolate);
InstallContextId(context1, 1);
- Handle<Context> context2 = Context::New(CcTest::isolate());
+ Handle<Context> context2 = Context::New(isolate);
InstallContextId(context2, 2);
- Handle<Context> context3 = Context::New(CcTest::isolate());
+ Handle<Context> context3 = Context::New(isolate);
InstallContextId(context3, 3);
- Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New();
+ Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New(isolate);
Local<Object> object1;
Local<Function> func1;
{
Context::Scope scope(context1);
- object1 = Object::New();
+ object1 = Object::New(isolate);
func1 = tmpl->GetFunction();
}
Local<Function> func2;
{
Context::Scope scope(context2);
- object2 = Object::New();
+ object2 = Object::New(isolate);
func2 = tmpl->GetFunction();
}
TEST(HasOwnProperty) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
{ // Check normal properties and defined getters.
Handle<Value> value = CompileRun(
"function Foo() {"
CHECK(object->HasOwnProperty(v8_str("bla")));
}
{ // Check named getter interceptors.
- Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter);
Handle<Object> instance = templ->NewInstance();
CHECK(!instance->HasOwnProperty(v8_str("42")));
CHECK(!instance->HasOwnProperty(v8_str("bar")));
}
{ // Check indexed getter interceptors.
- Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(HasOwnPropertyIndexedPropertyGetter);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("42")));
CHECK(!instance->HasOwnProperty(v8_str("foo")));
}
{ // Check named query interceptors.
- Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(0, 0, HasOwnPropertyNamedPropertyQuery);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("foo")));
CHECK(!instance->HasOwnProperty(v8_str("bar")));
}
{ // Check indexed query interceptors.
- Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(0, 0, HasOwnPropertyIndexedPropertyQuery);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("42")));
CHECK(!instance->HasOwnProperty(v8_str("41")));
}
{ // Check callbacks.
- Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("foo"), HasOwnPropertyAccessorGetter);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("foo")));
CHECK(!instance->HasOwnProperty(v8_str("bar")));
}
{ // Check that query wins on disagreement.
- Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter,
0,
HasOwnPropertyNamedPropertyQuery2);
TEST(IndexedInterceptorWithStringProto) {
- v8::HandleScope scope(CcTest::isolate());
- Handle<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetIndexedPropertyHandler(NULL,
NULL,
HasOwnPropertyIndexedPropertyQuery);
THREADED_TEST(CallAPIFunctionOnNonObject) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Handle<FunctionTemplate> templ = v8::FunctionTemplate::New(NonObjectThis);
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Handle<FunctionTemplate> templ =
+ v8::FunctionTemplate::New(isolate, NonObjectThis);
Handle<Function> function = templ->GetFunction();
context->Global()->Set(v8_str("f"), function);
TryCatch try_catch;
// Regression test for issue 1470.
THREADED_TEST(ReadOnlyIndexedProperties) {
- v8::HandleScope scope(CcTest::isolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
context->Global()->Set(v8_str("obj"), obj);
- obj->Set(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->ForceSet(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly);
obj->Set(v8_str("1"), v8_str("foobar"));
CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("1")));
- obj->Set(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->ForceSet(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly);
obj->Set(v8_num(2), v8_str("foobar"));
CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_num(2)));
// Test non-smi case.
- obj->Set(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly);
+ obj->ForceSet(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly);
obj->Set(v8_str("2000000000"), v8_str("foobar"));
CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("2000000000")));
}
HandleScope scope(isolate);
// Template for object with security check.
- Local<ObjectTemplate> no_proto_template = v8::ObjectTemplate::New();
+ Local<ObjectTemplate> no_proto_template = v8::ObjectTemplate::New(isolate);
// We don't do indexing, so any callback can be used for that.
no_proto_template->SetAccessCheckCallbacks(
BlockProtoNamedSecurityTestCallback,
IndexedSecurityTestCallback);
// Templates for objects with hidden prototypes and possibly security check.
- Local<FunctionTemplate> hidden_proto_template = v8::FunctionTemplate::New();
+ Local<FunctionTemplate> hidden_proto_template =
+ v8::FunctionTemplate::New(isolate);
hidden_proto_template->SetHiddenPrototype(true);
Local<FunctionTemplate> protected_hidden_proto_template =
- v8::FunctionTemplate::New();
+ v8::FunctionTemplate::New(isolate);
protected_hidden_proto_template->InstanceTemplate()->SetAccessCheckCallbacks(
BlockProtoNamedSecurityTestCallback,
IndexedSecurityTestCallback);
context->Enter();
// Plain object, no security check.
- Local<Object> simple_object = Object::New();
+ Local<Object> simple_object = Object::New(isolate);
// Object with explicit security check.
Local<Object> protected_object =
Local<Object> hidden_prototype =
hidden_proto_template->GetFunction()->NewInstance();
Local<Object> object_with_hidden =
- Object::New();
+ Object::New(isolate);
object_with_hidden->SetPrototype(hidden_prototype);
// Hidden prototype with security check on the hidden prototype.
Local<Object> protected_hidden_prototype =
protected_hidden_proto_template->GetFunction()->NewInstance();
Local<Object> object_with_protected_hidden =
- Object::New();
+ Object::New(isolate);
object_with_protected_hidden->SetPrototype(protected_hidden_prototype);
context->Exit();
// Template for object for second context. Values to test are put on it as
// properties.
- Local<ObjectTemplate> global_template = ObjectTemplate::New();
+ Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
global_template->Set(v8_str("simple"), simple_object);
global_template->Set(v8_str("protected"), protected_object);
global_template->Set(v8_str("global"), global_object);
CHECK(result1->Equals(simple_object->GetPrototype()));
Local<Value> result2 = CompileRun("Object.getPrototypeOf(protected)");
- CHECK(result2->Equals(Undefined(isolate)));
+ CHECK(result2.IsEmpty());
Local<Value> result3 = CompileRun("Object.getPrototypeOf(global)");
CHECK(result3->Equals(global_object->GetPrototype()));
Local<Value> result4 = CompileRun("Object.getPrototypeOf(proxy)");
- CHECK(result4->Equals(Undefined(isolate)));
+ CHECK(result4.IsEmpty());
Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)");
CHECK(result5->Equals(
object_with_hidden->GetPrototype()->ToObject()->GetPrototype()));
Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
- CHECK(result6->Equals(Undefined(isolate)));
+ CHECK(result6.IsEmpty());
}
THREADED_TEST(Regress125988) {
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> intercept = FunctionTemplate::New();
+ Handle<FunctionTemplate> intercept = FunctionTemplate::New(CcTest::isolate());
AddInterceptor(intercept, EmptyInterceptorGetter, EmptyInterceptorSetter);
LocalContext env;
env->Global()->Set(v8_str("Intercept"), intercept->GetFunction());
CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[1]")));
CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]")));
- // TODO(1547): Make the following also return "i".
// Calling with environment record as base.
- TestReceiver(o, context->Global(), "func()");
+ TestReceiver(i, foreign_context->Global(), "func()");
// Calling with no base.
- TestReceiver(o, context->Global(), "(1,func)()");
+ TestReceiver(i, foreign_context->Global(), "(1,func)()");
}
void CallCompletedCallback1() {
- i::OS::Print("Firing callback 1.\n");
+ v8::base::OS::Print("Firing callback 1.\n");
callback_fired ^= 1; // Toggle first bit.
}
void CallCompletedCallback2() {
- i::OS::Print("Firing callback 2.\n");
+ v8::base::OS::Print("Firing callback 2.\n");
callback_fired ^= 2; // Toggle second bit.
}
int32_t level = args[0]->Int32Value();
if (level < 3) {
level++;
- i::OS::Print("Entering recursion level %d.\n", level);
+ v8::base::OS::Print("Entering recursion level %d.\n", level);
char script[64];
i::Vector<char> script_vector(script, sizeof(script));
- i::OS::SNPrintF(script_vector, "recursion(%d)", level);
+ i::SNPrintF(script_vector, "recursion(%d)", level);
CompileRun(script_vector.start());
- i::OS::Print("Leaving recursion level %d.\n", level);
+ v8::base::OS::Print("Leaving recursion level %d.\n", level);
CHECK_EQ(0, callback_fired);
} else {
- i::OS::Print("Recursion ends.\n");
+ v8::base::OS::Print("Recursion ends.\n");
CHECK_EQ(0, callback_fired);
}
}
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::Handle<v8::FunctionTemplate> recursive_runtime =
- v8::FunctionTemplate::New(RecursiveCall);
+ v8::FunctionTemplate::New(env->GetIsolate(), RecursiveCall);
env->Global()->Set(v8_str("recursion"),
recursive_runtime->GetFunction());
// Adding the same callback a second time has no effect.
- v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
- v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
- v8::V8::AddCallCompletedCallback(CallCompletedCallback2);
- i::OS::Print("--- Script (1) ---\n");
- Local<Script> script =
- v8::Script::Compile(v8::String::New("recursion(0)"));
+ env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback1);
+ env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback1);
+ env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback2);
+ v8::base::OS::Print("--- Script (1) ---\n");
+ Local<Script> script = v8::Script::Compile(
+ v8::String::NewFromUtf8(env->GetIsolate(), "recursion(0)"));
script->Run();
CHECK_EQ(3, callback_fired);
- i::OS::Print("\n--- Script (2) ---\n");
+ v8::base::OS::Print("\n--- Script (2) ---\n");
callback_fired = 0;
- v8::V8::RemoveCallCompletedCallback(CallCompletedCallback1);
+ env->GetIsolate()->RemoveCallCompletedCallback(CallCompletedCallback1);
script->Run();
CHECK_EQ(2, callback_fired);
- i::OS::Print("\n--- Function ---\n");
+ v8::base::OS::Print("\n--- Function ---\n");
callback_fired = 0;
Local<Function> recursive_function =
Local<Function>::Cast(env->Global()->Get(v8_str("recursion")));
TEST(CallCompletedCallbackOneException) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::V8::AddCallCompletedCallback(CallCompletedCallbackNoException);
+ env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallbackNoException);
CompileRun("throw 'exception';");
}
TEST(CallCompletedCallbackTwoExceptions) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::V8::AddCallCompletedCallback(CallCompletedCallbackException);
+ env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallbackException);
CompileRun("throw 'first exception';");
}
-static int probes_counter = 0;
-static int misses_counter = 0;
-static int updates_counter = 0;
+static void MicrotaskOne(const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("ext1Calls++;");
+}
-static int* LookupCounter(const char* name) {
- if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) {
- return &probes_counter;
- } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) {
- return &misses_counter;
- } else if (strcmp(name, "c:V8.MegamorphicStubCacheUpdates") == 0) {
- return &updates_counter;
- }
- return NULL;
+static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("ext2Calls++;");
}
-static const char* kMegamorphicTestProgram =
- "function ClassA() { };"
- "function ClassB() { };"
- "ClassA.prototype.foo = function() { };"
- "ClassB.prototype.foo = function() { };"
- "function fooify(obj) { obj.foo(); };"
- "var a = new ClassA();"
+void* g_passed_to_three = NULL;
+
+
+static void MicrotaskThree(void* data) {
+ g_passed_to_three = data;
+}
+
+
+TEST(EnqueueMicrotask) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ CompileRun(
+ "var ext1Calls = 0;"
+ "var ext2Calls = 0;");
+ CompileRun("1+1;");
+ CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ CompileRun("1+1;");
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ g_passed_to_three = NULL;
+ env->GetIsolate()->EnqueueMicrotask(MicrotaskThree);
+ CompileRun("1+1;");
+ CHECK_EQ(NULL, g_passed_to_three);
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ int dummy;
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ env->GetIsolate()->EnqueueMicrotask(MicrotaskThree, &dummy);
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(&dummy, g_passed_to_three);
+ CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value());
+ g_passed_to_three = NULL;
+}
+
+
+static void MicrotaskExceptionOne(
+ const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("exception1Calls++;");
+ info.GetIsolate()->ThrowException(
+ v8::Exception::Error(v8_str("first")));
+}
+
+
+static void MicrotaskExceptionTwo(
+ const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("exception2Calls++;");
+ info.GetIsolate()->ThrowException(
+ v8::Exception::Error(v8_str("second")));
+}
+
+
+TEST(RunMicrotasksIgnoresThrownExceptions) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ CompileRun(
+ "var exception1Calls = 0;"
+ "var exception2Calls = 0;");
+ isolate->EnqueueMicrotask(
+ Function::New(isolate, MicrotaskExceptionOne));
+ isolate->EnqueueMicrotask(
+ Function::New(isolate, MicrotaskExceptionTwo));
+ TryCatch try_catch;
+ CompileRun("1+1;");
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(1, CompileRun("exception1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("exception2Calls")->Int32Value());
+}
+
+
+TEST(SetAutorunMicrotasks) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ CompileRun(
+ "var ext1Calls = 0;"
+ "var ext2Calls = 0;");
+ CompileRun("1+1;");
+ CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ CompileRun("1+1;");
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->SetAutorunMicrotasks(false);
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->RunMicrotasks();
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->RunMicrotasks();
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->SetAutorunMicrotasks(true);
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value());
+
+ env->GetIsolate()->EnqueueMicrotask(
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ {
+ v8::Isolate::SuppressMicrotaskExecutionScope scope(env->GetIsolate());
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value());
+ }
+
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value());
+}
+
+
+TEST(RunMicrotasksWithoutEnteringContext) {
+ v8::Isolate* isolate = CcTest::isolate();
+ HandleScope handle_scope(isolate);
+ isolate->SetAutorunMicrotasks(false);
+ Handle<Context> context = Context::New(isolate);
+ {
+ Context::Scope context_scope(context);
+ CompileRun("var ext1Calls = 0;");
+ isolate->EnqueueMicrotask(Function::New(isolate, MicrotaskOne));
+ }
+ isolate->RunMicrotasks();
+ {
+ Context::Scope context_scope(context);
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ }
+ isolate->SetAutorunMicrotasks(true);
+}
+
+
+static void DebugEventInObserver(const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ if (event != v8::Break) return;
+ Handle<Object> exec_state = event_details.GetExecutionState();
+ Handle<Value> break_id = exec_state->Get(v8_str("break_id"));
+ CompileRun("function f(id) { new FrameDetails(id, 0); }");
+ Handle<Function> fun = Handle<Function>::Cast(
+ CcTest::global()->Get(v8_str("f"))->ToObject());
+ fun->Call(CcTest::global(), 1, &break_id);
+}
+
+
+TEST(Regress385349) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ HandleScope handle_scope(isolate);
+ isolate->SetAutorunMicrotasks(false);
+ Handle<Context> context = Context::New(isolate);
+ v8::Debug::SetDebugEventListener(DebugEventInObserver);
+ {
+ Context::Scope context_scope(context);
+ CompileRun("var obj = {};"
+ "Object.observe(obj, function(changes) { debugger; });"
+ "obj.a = 0;");
+ }
+ isolate->RunMicrotasks();
+ isolate->SetAutorunMicrotasks(true);
+ v8::Debug::SetDebugEventListener(NULL);
+}
+
+
+#ifdef DEBUG
+static int probes_counter = 0;
+static int misses_counter = 0;
+static int updates_counter = 0;
+
+
+static int* LookupCounter(const char* name) {
+ if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) {
+ return &probes_counter;
+ } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) {
+ return &misses_counter;
+ } else if (strcmp(name, "c:V8.MegamorphicStubCacheUpdates") == 0) {
+ return &updates_counter;
+ }
+ return NULL;
+}
+
+
+static const char* kMegamorphicTestProgram =
+ "function ClassA() { };"
+ "function ClassB() { };"
+ "ClassA.prototype.foo = function() { };"
+ "ClassB.prototype.foo = function() { };"
+ "function fooify(obj) { obj.foo(); };"
+ "var a = new ClassA();"
"var b = new ClassB();"
"for (var i = 0; i < 10000; i++) {"
" fooify(a);"
" fooify(b);"
"}";
+#endif
static void StubCacheHelper(bool primary) {
- V8::SetCounterFunction(LookupCounter);
- USE(kMegamorphicTestProgram);
#ifdef DEBUG
i::FLAG_native_code_counters = true;
if (primary) {
}
i::FLAG_crankshaft = false;
LocalContext env;
+ env->GetIsolate()->SetCounterFunction(LookupCounter);
v8::HandleScope scope(env->GetIsolate());
int initial_probes = probes_counter;
int initial_misses = misses_counter;
int updates = updates_counter - initial_updates;
CHECK_LT(updates, 10);
CHECK_LT(misses, 10);
- CHECK_GE(probes, 10000);
+ // TODO(verwaest): Update this test to overflow the degree of polymorphism
+ // before megamorphism. The number of probes will only work once we teach the
+ // serializer to embed references to counters in the stubs, given that the
+ // megamorphic_stub_cache_probes is updated in a snapshot-generated stub.
+ CHECK_GE(probes, 0);
#endif
}
}
+#ifdef DEBUG
+static int cow_arrays_created_runtime = 0;
+
+
+static int* LookupCounterCOWArrays(const char* name) {
+ if (strcmp(name, "c:V8.COWArraysCreatedRuntime") == 0) {
+ return &cow_arrays_created_runtime;
+ }
+ return NULL;
+}
+#endif
+
+
+TEST(CheckCOWArraysCreatedRuntimeCounter) {
+#ifdef DEBUG
+ i::FLAG_native_code_counters = true;
+ LocalContext env;
+ env->GetIsolate()->SetCounterFunction(LookupCounterCOWArrays);
+ v8::HandleScope scope(env->GetIsolate());
+ int initial_cow_arrays = cow_arrays_created_runtime;
+ CompileRun("var o = [1, 2, 3];");
+ CHECK_EQ(1, cow_arrays_created_runtime - initial_cow_arrays);
+ CompileRun("var o = {foo: [4, 5, 6], bar: [3, 0]};");
+ CHECK_EQ(3, cow_arrays_created_runtime - initial_cow_arrays);
+ CompileRun("var o = {foo: [1, 2, 3, [4, 5, 6]], bar: 'hi'};");
+ CHECK_EQ(4, cow_arrays_created_runtime - initial_cow_arrays);
+#endif
+}
+
+
TEST(StaticGetters) {
LocalContext context;
i::Factory* factory = CcTest::i_isolate()->factory();
v8::Isolate* isolate = v8::Isolate::New();
isolate->Enter();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- CHECK_EQ(NULL, isolate->GetData());
- CHECK_EQ(NULL, i_isolate->GetData());
- static void* data1 = reinterpret_cast<void*>(0xacce55ed);
- isolate->SetData(data1);
- CHECK_EQ(data1, isolate->GetData());
- CHECK_EQ(data1, i_isolate->GetData());
- static void* data2 = reinterpret_cast<void*>(0xdecea5ed);
- i_isolate->SetData(data2);
- CHECK_EQ(data2, isolate->GetData());
- CHECK_EQ(data2, i_isolate->GetData());
+ for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) {
+ CHECK_EQ(NULL, isolate->GetData(slot));
+ CHECK_EQ(NULL, i_isolate->GetData(slot));
+ }
+ for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) {
+ void* data = reinterpret_cast<void*>(0xacce55ed + slot);
+ isolate->SetData(slot, data);
+ }
+ for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) {
+ void* data = reinterpret_cast<void*>(0xacce55ed + slot);
+ CHECK_EQ(data, isolate->GetData(slot));
+ CHECK_EQ(data, i_isolate->GetData(slot));
+ }
+ for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) {
+ void* data = reinterpret_cast<void*>(0xdecea5ed + slot);
+ isolate->SetData(slot, data);
+ }
+ for (uint32_t slot = 0; slot < v8::Isolate::GetNumberOfDataSlots(); ++slot) {
+ void* data = reinterpret_cast<void*>(0xdecea5ed + slot);
+ CHECK_EQ(data, isolate->GetData(slot));
+ CHECK_EQ(data, i_isolate->GetData(slot));
+ }
isolate->Exit();
isolate->Dispose();
}
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
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);
}
}
-static void CheckInstanceCheckedResult(int getters,
- int setters,
+static void CheckInstanceCheckedResult(int getters, int setters,
bool expects_callbacks,
TryCatch* try_catch) {
if (expects_callbacks) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Local<FunctionTemplate> templ = FunctionTemplate::New();
+ Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate());
Local<ObjectTemplate> inst = templ->InstanceTemplate();
inst->SetAccessor(v8_str("foo"),
InstanceCheckedGetter, InstanceCheckedSetter,
Handle<Value>(),
v8::DEFAULT,
v8::None,
- v8::AccessorSignature::New(templ));
+ v8::AccessorSignature::New(context->GetIsolate(), templ));
context->Global()->Set(v8_str("f"), templ->GetFunction());
printf("Testing positive ...\n");
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Local<FunctionTemplate> templ = FunctionTemplate::New();
+ Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate());
Local<ObjectTemplate> inst = templ->InstanceTemplate();
AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
inst->SetAccessor(v8_str("foo"),
Handle<Value>(),
v8::DEFAULT,
v8::None,
- v8::AccessorSignature::New(templ));
+ v8::AccessorSignature::New(context->GetIsolate(), templ));
context->Global()->Set(v8_str("f"), templ->GetFunction());
printf("Testing positive ...\n");
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Local<FunctionTemplate> templ = FunctionTemplate::New();
+ Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate());
Local<ObjectTemplate> proto = templ->PrototypeTemplate();
- proto->SetAccessor(v8_str("foo"),
- InstanceCheckedGetter, InstanceCheckedSetter,
- Handle<Value>(),
- v8::DEFAULT,
+ proto->SetAccessor(v8_str("foo"), InstanceCheckedGetter,
+ InstanceCheckedSetter, Handle<Value>(), v8::DEFAULT,
v8::None,
- v8::AccessorSignature::New(templ));
+ v8::AccessorSignature::New(context->GetIsolate(), templ));
context->Global()->Set(v8_str("f"), templ->GetFunction());
printf("Testing positive ...\n");
bool remove_accessor,
bool interceptor) {
LocalContext context;
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<ObjectTemplate> templ = ObjectTemplate::New(context->GetIsolate());
if (interceptor) {
templ->SetNamedPropertyHandler(FooGetInterceptor, FooSetInterceptor);
} else {
THREADED_TEST(Regress137002b) {
i::FLAG_allow_natives_syntax = true;
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("foo"),
GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
THREADED_TEST(Regress142088) {
i::FLAG_allow_natives_syntax = true;
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetAccessor(v8_str("foo"),
GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
}
+THREADED_TEST(Regress3337) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::Object> o1 = Object::New(isolate);
+ Local<v8::Object> o2 = Object::New(isolate);
+ i::Handle<i::JSObject> io1 = v8::Utils::OpenHandle(*o1);
+ i::Handle<i::JSObject> io2 = v8::Utils::OpenHandle(*o2);
+ CHECK(io1->map() == io2->map());
+ o1->SetIndexedPropertiesToExternalArrayData(
+ NULL, v8::kExternalUint32Array, 0);
+ o2->SetIndexedPropertiesToExternalArrayData(
+ NULL, v8::kExternalUint32Array, 0);
+ CHECK(io1->map() == io2->map());
+}
+
+
THREADED_TEST(Regress137496) {
i::FLAG_expose_gc = true;
LocalContext context;
THREADED_TEST(Regress149912) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate());
AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
context->Global()->Set(v8_str("Bug"), templ->GetFunction());
CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();");
THREADED_TEST(Regress157124) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<ObjectTemplate> templ = ObjectTemplate::New();
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
Local<Object> obj = templ->NewInstance();
obj->GetIdentityHash();
obj->DeleteHiddenValue(v8_str("Bug"));
THREADED_TEST(Regress2535) {
- i::FLAG_harmony_collections = true;
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
Local<Value> set_value = CompileRun("new Set();");
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- Local<Object> obj = Object::New();
- Local<String> key = String::New("key");
+ Local<Object> obj = Object::New(isolate);
+ Local<String> key = String::NewFromUtf8(context->GetIsolate(), "key");
obj->SetHiddenValue(key, v8::Undefined(isolate));
Local<Value> value = obj->GetHiddenValue(key);
CHECK(!value.IsEmpty());
THREADED_TEST(Regress260106) {
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
- Local<FunctionTemplate> templ = FunctionTemplate::New(DummyCallHandler);
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<FunctionTemplate> templ = FunctionTemplate::New(isolate,
+ DummyCallHandler);
CompileRun("for (var i = 0; i < 128; i++) Object.prototype[i] = 0;");
Local<Function> function = templ->GetFunction();
CHECK(!function.IsEmpty());
}
-#if V8_OS_POSIX
+#if V8_OS_POSIX && !V8_OS_NACL
class ThreadInterruptTest {
public:
ThreadInterruptTest() : sem_(0), sem_value_(0) { }
private:
static const int kExpectedValue = 1;
- class InterruptThread : public i::Thread {
+ class InterruptThread : public v8::base::Thread {
public:
explicit InterruptThread(ThreadInterruptTest* test)
- : Thread("InterruptThread"), test_(test) {}
+ : Thread(Options("InterruptThread")), test_(test) {}
virtual void Run() {
struct sigaction action;
// Ensure that we'll enter waiting condition
- i::OS::Sleep(100);
+ v8::base::OS::Sleep(100);
// Setup signal handler
memset(&action, 0, sizeof(action));
kill(getpid(), SIGCHLD);
// Ensure that if wait has returned because of error
- i::OS::Sleep(100);
+ v8::base::OS::Sleep(100);
// Set value and signal semaphore
test_->sem_value_ = 1;
ThreadInterruptTest* test_;
};
- i::Semaphore sem_;
+ v8::base::Semaphore sem_;
volatile int sem_value_;
};
}
+#endif // V8_OS_POSIX
+
+
static bool NamedAccessAlwaysBlocked(Local<v8::Object> global,
Local<Value> name,
v8::AccessType type,
TEST(JSONStringifyAccessCheck) {
v8::V8::Initialize();
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
// Create an ObjectTemplate for global objects and install access
// check callbacks that will block access.
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked,
IndexAccessAlwaysBlocked);
if (i == 1) {
// Install a toJSON function on the second run.
v8::Handle<v8::FunctionTemplate> toJSON =
- v8::FunctionTemplate::New(UnreachableCallback);
+ v8::FunctionTemplate::New(isolate, UnreachableCallback);
global0->Set(v8_str("toJSON"), toJSON->GetFunction());
}
LocalContext context1(NULL, global_template);
context1->Global()->Set(v8_str("other"), global0);
- ExpectString("JSON.stringify(other)", "{}");
- ExpectString("JSON.stringify({ 'a' : other, 'b' : ['c'] })",
- "{\"a\":{},\"b\":[\"c\"]}");
- ExpectString("JSON.stringify([other, 'b', 'c'])",
- "[{},\"b\",\"c\"]");
+ CHECK(CompileRun("JSON.stringify(other)").IsEmpty());
+ CHECK(CompileRun("JSON.stringify({ 'a' : other, 'b' : ['c'] })").IsEmpty());
+ CHECK(CompileRun("JSON.stringify([other, 'b', 'c'])").IsEmpty());
- v8::Handle<v8::Array> array = v8::Array::New(2);
+ v8::Handle<v8::Array> array = v8::Array::New(isolate, 2);
array->Set(0, v8_str("a"));
array->Set(1, v8_str("b"));
context1->Global()->Set(v8_str("array"), array);
ExpectString("JSON.stringify(array)", "[\"a\",\"b\"]");
array->TurnOnAccessCheck();
- ExpectString("JSON.stringify(array)", "[]");
- ExpectString("JSON.stringify([array])", "[[]]");
- ExpectString("JSON.stringify({'a' : array})", "{\"a\":[]}");
+ CHECK(CompileRun("JSON.stringify(array)").IsEmpty());
+ CHECK(CompileRun("JSON.stringify([array])").IsEmpty());
+ CHECK(CompileRun("JSON.stringify({'a' : array})").IsEmpty());
}
}
access_check_fail_thrown = false;
catch_callback_called = false;
i::ScopedVector<char> source(1024);
- i::OS::SNPrintF(source, "try { %s; } catch (e) { catcher(e); }", script);
+ i::SNPrintF(source, "try { %s; } catch (e) { catcher(e); }", script);
CompileRun(source.start());
CHECK(access_check_fail_thrown);
CHECK(catch_callback_called);
i::FLAG_allow_natives_syntax = true;
v8::V8::Initialize();
v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows);
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
// Create an ObjectTemplate for global objects and install access
// check callbacks that will block access.
- v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked,
IndexAccessAlwaysBlocked);
// Create a context and set an x property on it's global object.
LocalContext context0(NULL, global_template);
- context0->Global()->Set(v8_str("x"), v8_num(42));
v8::Handle<v8::Object> global0 = context0->Global();
// Create a context with a different security token so that the
context1->Global()->Set(v8_str("other"), global0);
v8::Handle<v8::FunctionTemplate> catcher_fun =
- v8::FunctionTemplate::New(CatcherCallback);
+ v8::FunctionTemplate::New(isolate, CatcherCallback);
context1->Global()->Set(v8_str("catcher"), catcher_fun->GetFunction());
v8::Handle<v8::FunctionTemplate> has_own_property_fun =
- v8::FunctionTemplate::New(HasOwnPropertyCallback);
+ v8::FunctionTemplate::New(isolate, HasOwnPropertyCallback);
context1->Global()->Set(v8_str("has_own_property"),
has_own_property_fun->GetFunction());
CheckCorrectThrow("JSON.stringify(other)");
CheckCorrectThrow("has_own_property(other, 'x')");
CheckCorrectThrow("%GetProperty(other, 'x')");
- CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 1, 0)");
- CheckCorrectThrow("%IgnoreAttributesAndSetProperty(other, 'x', 'foo')");
+ CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 0)");
+ CheckCorrectThrow("%AddNamedProperty(other, 'x', 'foo', 1)");
CheckCorrectThrow("%DeleteProperty(other, 'x', 0)");
CheckCorrectThrow("%DeleteProperty(other, '1', 0)");
- CheckCorrectThrow("%HasLocalProperty(other, 'x')");
+ CheckCorrectThrow("%HasOwnProperty(other, 'x')");
CheckCorrectThrow("%HasProperty(other, 'x')");
CheckCorrectThrow("%HasElement(other, 1)");
CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')");
CheckCorrectThrow("%GetPropertyNames(other)");
- CheckCorrectThrow("%GetLocalPropertyNames(other, true)");
- CheckCorrectThrow("%DefineOrRedefineAccessorProperty("
+ // PROPERTY_ATTRIBUTES_NONE = 0
+ CheckCorrectThrow("%GetOwnPropertyNames(other, 0)");
+ CheckCorrectThrow("%DefineAccessorPropertyUnchecked("
"other, 'x', null, null, 1)");
// Reset the failed access check callback so it does not influence
i::FLAG_allow_natives_syntax = true;
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate());
AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
context->Global()->Set(v8_str("Bug"), templ->GetFunction());
CompileRun("\"use strict\"; var o = new Bug;"
THREADED_TEST(CrankshaftInterceptorSetter) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
LocalContext env;
env->Global()->Set(v8_str("Obj"), templ->GetFunction());
THREADED_TEST(CrankshaftInterceptorGetter) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
LocalContext env;
env->Global()->Set(v8_str("Obj"), templ->GetFunction());
THREADED_TEST(CrankshaftInterceptorFieldRead) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
LocalContext env;
env->Global()->Set(v8_str("Obj"), templ->GetFunction());
THREADED_TEST(CrankshaftInterceptorFieldWrite) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
LocalContext env;
env->Global()->Set(v8_str("Obj"), templ->GetFunction());
}
-#endif // V8_OS_POSIX
+class RequestInterruptTestBase {
+ public:
+ RequestInterruptTestBase()
+ : env_(),
+ isolate_(env_->GetIsolate()),
+ sem_(0),
+ warmup_(20000),
+ should_continue_(true) {
+ }
+ virtual ~RequestInterruptTestBase() { }
-static Local<Value> function_new_expected_env;
-static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
- CHECK_EQ(function_new_expected_env, info.Data());
- info.GetReturnValue().Set(17);
-}
+ virtual void StartInterruptThread() = 0;
+ virtual void TestBody() = 0;
-THREADED_TEST(FunctionNew) {
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- Local<Object> data = v8::Object::New();
- function_new_expected_env = data;
- Local<Function> func = Function::New(isolate, FunctionNewCallback, data);
- env->Global()->Set(v8_str("func"), func);
- Local<Value> result = CompileRun("func();");
- CHECK_EQ(v8::Integer::New(17, isolate), result);
- // Verify function not cached
- int serial_number =
- i::Smi::cast(v8::Utils::OpenHandle(*func)
- ->shared()->get_api_func_data()->serial_number())->value();
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::Object* elm = i_isolate->native_context()->function_cache()
- ->GetElementNoExceptionThrown(i_isolate, serial_number);
- CHECK(elm->IsUndefined());
- // Verify that each Function::New creates a new function instance
- Local<Object> data2 = v8::Object::New();
- function_new_expected_env = data2;
- Local<Function> func2 = Function::New(isolate, FunctionNewCallback, data2);
- CHECK(!func2->IsNull());
- CHECK_NE(func, func2);
- env->Global()->Set(v8_str("func2"), func2);
- Local<Value> result2 = CompileRun("func2();");
- CHECK_EQ(v8::Integer::New(17, isolate), result2);
-}
+ void RunTest() {
+ StartInterruptThread();
+ v8::HandleScope handle_scope(isolate_);
-TEST(EscapeableHandleScope) {
- HandleScope outer_scope(CcTest::isolate());
- LocalContext context;
- const int runs = 10;
- Local<String> values[runs];
- for (int i = 0; i < runs; i++) {
- v8::EscapableHandleScope inner_scope(CcTest::isolate());
- Local<String> value;
- if (i != 0) value = v8_str("escape value");
- values[i] = inner_scope.Escape(value);
+ TestBody();
+
+ isolate_->ClearInterrupt();
+
+ // Verify we arrived here because interruptor was called
+ // not due to a bug causing us to exit the loop too early.
+ CHECK(!should_continue());
}
- for (int i = 0; i < runs; i++) {
- Local<String> expected;
- if (i != 0) {
- CHECK_EQ(v8_str("escape value"), values[i]);
- } else {
- CHECK(values[i].IsEmpty());
+
+ void WakeUpInterruptor() {
+ sem_.Signal();
+ }
+
+ bool should_continue() const { return should_continue_; }
+
+ bool ShouldContinue() {
+ if (warmup_ > 0) {
+ if (--warmup_ == 0) {
+ WakeUpInterruptor();
+ }
+ }
+
+ return should_continue_;
+ }
+
+ static void ShouldContinueCallback(
+ const v8::FunctionCallbackInfo<Value>& info) {
+ RequestInterruptTestBase* test =
+ reinterpret_cast<RequestInterruptTestBase*>(
+ info.Data().As<v8::External>()->Value());
+ info.GetReturnValue().Set(test->ShouldContinue());
+ }
+
+ LocalContext env_;
+ v8::Isolate* isolate_;
+ v8::base::Semaphore sem_;
+ int warmup_;
+ bool should_continue_;
+};
+
+
+class RequestInterruptTestBaseWithSimpleInterrupt
+ : public RequestInterruptTestBase {
+ public:
+ RequestInterruptTestBaseWithSimpleInterrupt() : i_thread(this) { }
+
+ virtual void StartInterruptThread() {
+ i_thread.Start();
+ }
+
+ private:
+ class InterruptThread : public v8::base::Thread {
+ public:
+ explicit InterruptThread(RequestInterruptTestBase* test)
+ : Thread(Options("RequestInterruptTest")), test_(test) {}
+
+ virtual void Run() {
+ test_->sem_.Wait();
+ test_->isolate_->RequestInterrupt(&OnInterrupt, test_);
}
+
+ static void OnInterrupt(v8::Isolate* isolate, void* data) {
+ reinterpret_cast<RequestInterruptTestBase*>(data)->
+ should_continue_ = false;
+ }
+
+ private:
+ RequestInterruptTestBase* test_;
+ };
+
+ InterruptThread i_thread;
+};
+
+
+class RequestInterruptTestWithFunctionCall
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
+ public:
+ virtual void TestBody() {
+ Local<Function> func = Function::New(
+ isolate_, ShouldContinueCallback, v8::External::New(isolate_, this));
+ env_->Global()->Set(v8_str("ShouldContinue"), func);
+
+ CompileRun("while (ShouldContinue()) { }");
+ }
+};
+
+
+class RequestInterruptTestWithMethodCall
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
+ public:
+ virtual void TestBody() {
+ v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
+ v8::Local<v8::Template> proto = t->PrototypeTemplate();
+ proto->Set(v8_str("shouldContinue"), Function::New(
+ isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)));
+ env_->Global()->Set(v8_str("Klass"), t->GetFunction());
+
+ CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }");
+ }
+};
+
+
+class RequestInterruptTestWithAccessor
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
+ public:
+ virtual void TestBody() {
+ v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
+ v8::Local<v8::Template> proto = t->PrototypeTemplate();
+ proto->SetAccessorProperty(v8_str("shouldContinue"), FunctionTemplate::New(
+ isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)));
+ env_->Global()->Set(v8_str("Klass"), t->GetFunction());
+
+ CompileRun("var obj = new Klass; while (obj.shouldContinue) { }");
}
+};
+
+
+class RequestInterruptTestWithNativeAccessor
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
+ public:
+ virtual void TestBody() {
+ v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
+ t->InstanceTemplate()->SetNativeDataProperty(
+ v8_str("shouldContinue"),
+ &ShouldContinueNativeGetter,
+ NULL,
+ v8::External::New(isolate_, this));
+ env_->Global()->Set(v8_str("Klass"), t->GetFunction());
+
+ CompileRun("var obj = new Klass; while (obj.shouldContinue) { }");
+ }
+
+ private:
+ static void ShouldContinueNativeGetter(
+ Local<String> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ RequestInterruptTestBase* test =
+ reinterpret_cast<RequestInterruptTestBase*>(
+ info.Data().As<v8::External>()->Value());
+ info.GetReturnValue().Set(test->ShouldContinue());
+ }
+};
+
+
+class RequestInterruptTestWithMethodCallAndInterceptor
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
+ public:
+ virtual void TestBody() {
+ v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_);
+ v8::Local<v8::Template> proto = t->PrototypeTemplate();
+ proto->Set(v8_str("shouldContinue"), Function::New(
+ isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)));
+ v8::Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate();
+ instance_template->SetNamedPropertyHandler(EmptyInterceptor);
+
+ env_->Global()->Set(v8_str("Klass"), t->GetFunction());
+
+ CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }");
+ }
+
+ private:
+ static void EmptyInterceptor(
+ Local<String> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ }
+};
+
+
+class RequestInterruptTestWithMathAbs
+ : public RequestInterruptTestBaseWithSimpleInterrupt {
+ public:
+ virtual void TestBody() {
+ env_->Global()->Set(v8_str("WakeUpInterruptor"), Function::New(
+ isolate_,
+ WakeUpInterruptorCallback,
+ v8::External::New(isolate_, this)));
+
+ env_->Global()->Set(v8_str("ShouldContinue"), Function::New(
+ isolate_,
+ ShouldContinueCallback,
+ v8::External::New(isolate_, this)));
+
+ i::FLAG_allow_natives_syntax = true;
+ CompileRun("function loopish(o) {"
+ " var pre = 10;"
+ " while (o.abs(1) > 0) {"
+ " if (o.abs(1) >= 0 && !ShouldContinue()) break;"
+ " if (pre > 0) {"
+ " if (--pre === 0) WakeUpInterruptor(o === Math);"
+ " }"
+ " }"
+ "}"
+ "var i = 50;"
+ "var obj = {abs: function () { return i-- }, x: null};"
+ "delete obj.x;"
+ "loopish(obj);"
+ "%OptimizeFunctionOnNextCall(loopish);"
+ "loopish(Math);");
+
+ i::FLAG_allow_natives_syntax = false;
+ }
+
+ private:
+ static void WakeUpInterruptorCallback(
+ const v8::FunctionCallbackInfo<Value>& info) {
+ if (!info[0]->BooleanValue()) return;
+
+ RequestInterruptTestBase* test =
+ reinterpret_cast<RequestInterruptTestBase*>(
+ info.Data().As<v8::External>()->Value());
+ test->WakeUpInterruptor();
+ }
+
+ static void ShouldContinueCallback(
+ const v8::FunctionCallbackInfo<Value>& info) {
+ RequestInterruptTestBase* test =
+ reinterpret_cast<RequestInterruptTestBase*>(
+ info.Data().As<v8::External>()->Value());
+ info.GetReturnValue().Set(test->should_continue());
+ }
+};
+
+
+TEST(RequestInterruptTestWithFunctionCall) {
+ RequestInterruptTestWithFunctionCall().RunTest();
+}
+
+
+TEST(RequestInterruptTestWithMethodCall) {
+ RequestInterruptTestWithMethodCall().RunTest();
+}
+
+
+TEST(RequestInterruptTestWithAccessor) {
+ RequestInterruptTestWithAccessor().RunTest();
+}
+
+
+TEST(RequestInterruptTestWithNativeAccessor) {
+ RequestInterruptTestWithNativeAccessor().RunTest();
+}
+
+
+TEST(RequestInterruptTestWithMethodCallAndInterceptor) {
+ RequestInterruptTestWithMethodCallAndInterceptor().RunTest();
+}
+
+
+TEST(RequestInterruptTestWithMathAbs) {
+ RequestInterruptTestWithMathAbs().RunTest();
+}
+
+
+class ClearInterruptFromAnotherThread
+ : public RequestInterruptTestBase {
+ public:
+ ClearInterruptFromAnotherThread() : i_thread(this), sem2_(0) { }
+
+ virtual void StartInterruptThread() {
+ i_thread.Start();
+ }
+
+ virtual void TestBody() {
+ Local<Function> func = Function::New(
+ isolate_, ShouldContinueCallback, v8::External::New(isolate_, this));
+ env_->Global()->Set(v8_str("ShouldContinue"), func);
+
+ CompileRun("while (ShouldContinue()) { }");
+ }
+
+ private:
+ class InterruptThread : public v8::base::Thread {
+ public:
+ explicit InterruptThread(ClearInterruptFromAnotherThread* test)
+ : Thread(Options("RequestInterruptTest")), test_(test) {}
+
+ virtual void Run() {
+ test_->sem_.Wait();
+ test_->isolate_->RequestInterrupt(&OnInterrupt, test_);
+ test_->sem_.Wait();
+ test_->isolate_->ClearInterrupt();
+ test_->sem2_.Signal();
+ }
+
+ static void OnInterrupt(v8::Isolate* isolate, void* data) {
+ ClearInterruptFromAnotherThread* test =
+ reinterpret_cast<ClearInterruptFromAnotherThread*>(data);
+ test->sem_.Signal();
+ bool success = test->sem2_.WaitFor(v8::base::TimeDelta::FromSeconds(2));
+ // Crash instead of timeout to make this failure more prominent.
+ CHECK(success);
+ test->should_continue_ = false;
+ }
+
+ private:
+ ClearInterruptFromAnotherThread* test_;
+ };
+
+ InterruptThread i_thread;
+ v8::base::Semaphore sem2_;
+};
+
+
+TEST(ClearInterruptFromAnotherThread) {
+ ClearInterruptFromAnotherThread().RunTest();
+}
+
+
+static Local<Value> function_new_expected_env;
+static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
+ CHECK_EQ(function_new_expected_env, info.Data());
+ info.GetReturnValue().Set(17);
+}
+
+
+THREADED_TEST(FunctionNew) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Object> data = v8::Object::New(isolate);
+ function_new_expected_env = data;
+ Local<Function> func = Function::New(isolate, FunctionNewCallback, data);
+ env->Global()->Set(v8_str("func"), func);
+ Local<Value> result = CompileRun("func();");
+ CHECK_EQ(v8::Integer::New(isolate, 17), result);
+ // Verify function not cached
+ int serial_number =
+ i::Smi::cast(v8::Utils::OpenHandle(*func)
+ ->shared()->get_api_func_data()->serial_number())->value();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::Handle<i::JSObject> cache(i_isolate->native_context()->function_cache());
+ i::Handle<i::Object> elm =
+ i::Object::GetElement(i_isolate, cache, serial_number).ToHandleChecked();
+ CHECK(elm->IsUndefined());
+ // Verify that each Function::New creates a new function instance
+ Local<Object> data2 = v8::Object::New(isolate);
+ function_new_expected_env = data2;
+ Local<Function> func2 = Function::New(isolate, FunctionNewCallback, data2);
+ CHECK(!func2->IsNull());
+ CHECK_NE(func, func2);
+ env->Global()->Set(v8_str("func2"), func2);
+ Local<Value> result2 = CompileRun("func2();");
+ CHECK_EQ(v8::Integer::New(isolate, 17), result2);
+}
+
+
+TEST(EscapeableHandleScope) {
+ HandleScope outer_scope(CcTest::isolate());
+ LocalContext context;
+ const int runs = 10;
+ Local<String> values[runs];
+ for (int i = 0; i < runs; i++) {
+ v8::EscapableHandleScope inner_scope(CcTest::isolate());
+ Local<String> value;
+ if (i != 0) value = v8_str("escape value");
+ values[i] = inner_scope.Escape(value);
+ }
+ for (int i = 0; i < runs; i++) {
+ Local<String> expected;
+ if (i != 0) {
+ CHECK_EQ(v8_str("escape value"), values[i]);
+ } else {
+ CHECK(values[i].IsEmpty());
+ }
+ }
+}
+
+
+static void SetterWhichExpectsThisAndHolderToDiffer(
+ Local<String>, Local<Value>, const v8::PropertyCallbackInfo<void>& info) {
+ CHECK(info.Holder() != info.This());
+}
+
+
+TEST(Regress239669) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
+ templ->SetAccessor(v8_str("x"), 0, SetterWhichExpectsThisAndHolderToDiffer);
+ context->Global()->Set(v8_str("P"), templ->NewInstance());
+ CompileRun(
+ "function C1() {"
+ " this.x = 23;"
+ "};"
+ "C1.prototype = P;"
+ "for (var i = 0; i < 4; i++ ) {"
+ " new C1();"
+ "}");
+}
+
+
+class ApiCallOptimizationChecker {
+ private:
+ static Local<Object> data;
+ static Local<Object> receiver;
+ static Local<Object> holder;
+ static Local<Object> callee;
+ static int count;
+
+ static void OptimizationCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(callee == info.Callee());
+ CHECK(data == info.Data());
+ CHECK(receiver == info.This());
+ if (info.Length() == 1) {
+ CHECK_EQ(v8_num(1), info[0]);
+ }
+ CHECK(holder == info.Holder());
+ count++;
+ info.GetReturnValue().Set(v8_str("returned"));
+ }
+
+ public:
+ enum SignatureType {
+ kNoSignature,
+ kSignatureOnReceiver,
+ kSignatureOnPrototype
+ };
+
+ void RunAll() {
+ SignatureType signature_types[] =
+ {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype};
+ for (unsigned i = 0; i < arraysize(signature_types); i++) {
+ SignatureType signature_type = signature_types[i];
+ for (int j = 0; j < 2; j++) {
+ bool global = j == 0;
+ int key = signature_type +
+ arraysize(signature_types) * (global ? 1 : 0);
+ Run(signature_type, global, key);
+ }
+ }
+ }
+
+ void Run(SignatureType signature_type, bool global, int key) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ // Build a template for signature checks.
+ Local<v8::ObjectTemplate> signature_template;
+ Local<v8::Signature> signature;
+ {
+ Local<v8::FunctionTemplate> parent_template =
+ FunctionTemplate::New(isolate);
+ parent_template->SetHiddenPrototype(true);
+ Local<v8::FunctionTemplate> function_template
+ = FunctionTemplate::New(isolate);
+ function_template->Inherit(parent_template);
+ switch (signature_type) {
+ case kNoSignature:
+ break;
+ case kSignatureOnReceiver:
+ signature = v8::Signature::New(isolate, function_template);
+ break;
+ case kSignatureOnPrototype:
+ signature = v8::Signature::New(isolate, parent_template);
+ break;
+ }
+ signature_template = function_template->InstanceTemplate();
+ }
+ // Global object must pass checks.
+ Local<v8::Context> context =
+ v8::Context::New(isolate, NULL, signature_template);
+ v8::Context::Scope context_scope(context);
+ // Install regular object that can pass signature checks.
+ Local<Object> function_receiver = signature_template->NewInstance();
+ context->Global()->Set(v8_str("function_receiver"), function_receiver);
+ // Get the holder objects.
+ Local<Object> inner_global =
+ Local<Object>::Cast(context->Global()->GetPrototype());
+ // Install functions on hidden prototype object if there is one.
+ data = Object::New(isolate);
+ Local<FunctionTemplate> function_template = FunctionTemplate::New(
+ isolate, OptimizationCallback, data, signature);
+ Local<Function> function = function_template->GetFunction();
+ Local<Object> global_holder = inner_global;
+ Local<Object> function_holder = function_receiver;
+ if (signature_type == kSignatureOnPrototype) {
+ function_holder = Local<Object>::Cast(function_holder->GetPrototype());
+ global_holder = Local<Object>::Cast(global_holder->GetPrototype());
+ }
+ global_holder->Set(v8_str("g_f"), function);
+ global_holder->SetAccessorProperty(v8_str("g_acc"), function, function);
+ function_holder->Set(v8_str("f"), function);
+ function_holder->SetAccessorProperty(v8_str("acc"), function, function);
+ // Initialize expected values.
+ callee = function;
+ count = 0;
+ if (global) {
+ receiver = context->Global();
+ holder = inner_global;
+ } else {
+ holder = function_receiver;
+ // If not using a signature, add something else to the prototype chain
+ // to test the case that holder != receiver
+ if (signature_type == kNoSignature) {
+ receiver = Local<Object>::Cast(CompileRun(
+ "var receiver_subclass = {};\n"
+ "receiver_subclass.__proto__ = function_receiver;\n"
+ "receiver_subclass"));
+ } else {
+ receiver = Local<Object>::Cast(CompileRun(
+ "var receiver_subclass = function_receiver;\n"
+ "receiver_subclass"));
+ }
+ }
+ // With no signature, the holder is not set.
+ if (signature_type == kNoSignature) holder = receiver;
+ // build wrap_function
+ i::ScopedVector<char> wrap_function(200);
+ if (global) {
+ i::SNPrintF(
+ wrap_function,
+ "function wrap_f_%d() { var f = g_f; return f(); }\n"
+ "function wrap_get_%d() { return this.g_acc; }\n"
+ "function wrap_set_%d() { return this.g_acc = 1; }\n",
+ key, key, key);
+ } else {
+ i::SNPrintF(
+ wrap_function,
+ "function wrap_f_%d() { return receiver_subclass.f(); }\n"
+ "function wrap_get_%d() { return receiver_subclass.acc; }\n"
+ "function wrap_set_%d() { return receiver_subclass.acc = 1; }\n",
+ key, key, key);
+ }
+ // build source string
+ i::ScopedVector<char> source(1000);
+ i::SNPrintF(
+ source,
+ "%s\n" // wrap functions
+ "function wrap_f() { return wrap_f_%d(); }\n"
+ "function wrap_get() { return wrap_get_%d(); }\n"
+ "function wrap_set() { return wrap_set_%d(); }\n"
+ "check = function(returned) {\n"
+ " if (returned !== 'returned') { throw returned; }\n"
+ "}\n"
+ "\n"
+ "check(wrap_f());\n"
+ "check(wrap_f());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_f_%d);\n"
+ "check(wrap_f());\n"
+ "\n"
+ "check(wrap_get());\n"
+ "check(wrap_get());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_get_%d);\n"
+ "check(wrap_get());\n"
+ "\n"
+ "check = function(returned) {\n"
+ " if (returned !== 1) { throw returned; }\n"
+ "}\n"
+ "check(wrap_set());\n"
+ "check(wrap_set());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_set_%d);\n"
+ "check(wrap_set());\n",
+ wrap_function.start(), key, key, key, key, key, key);
+ v8::TryCatch try_catch;
+ CompileRun(source.start());
+ DCHECK(!try_catch.HasCaught());
+ CHECK_EQ(9, count);
+ }
+};
+
+
+Local<Object> ApiCallOptimizationChecker::data;
+Local<Object> ApiCallOptimizationChecker::receiver;
+Local<Object> ApiCallOptimizationChecker::holder;
+Local<Object> ApiCallOptimizationChecker::callee;
+int ApiCallOptimizationChecker::count = 0;
+
+
+TEST(TestFunctionCallOptimization) {
+ i::FLAG_allow_natives_syntax = true;
+ ApiCallOptimizationChecker checker;
+ checker.RunAll();
+}
+
+
+static const char* last_event_message;
+static int last_event_status;
+void StoringEventLoggerCallback(const char* message, int status) {
+ last_event_message = message;
+ last_event_status = status;
+}
+
+
+TEST(EventLogging) {
+ v8::Isolate* isolate = CcTest::isolate();
+ isolate->SetEventLogger(StoringEventLoggerCallback);
+ v8::internal::HistogramTimer histogramTimer(
+ "V8.Test", 0, 10000, 50,
+ reinterpret_cast<v8::internal::Isolate*>(isolate));
+ histogramTimer.Start();
+ CHECK_EQ("V8.Test", last_event_message);
+ CHECK_EQ(0, last_event_status);
+ histogramTimer.Stop();
+ CHECK_EQ("V8.Test", last_event_message);
+ CHECK_EQ(1, last_event_status);
+}
+
+
+TEST(Promises) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Handle<Object> global = context->Global();
+
+ // Creation.
+ Handle<v8::Promise::Resolver> pr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise::Resolver> rr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise> p = pr->GetPromise();
+ Handle<v8::Promise> r = rr->GetPromise();
+ CHECK_EQ(isolate, p->GetIsolate());
+
+ // IsPromise predicate.
+ CHECK(p->IsPromise());
+ CHECK(r->IsPromise());
+ Handle<Value> o = v8::Object::New(isolate);
+ CHECK(!o->IsPromise());
+
+ // Resolution and rejection.
+ pr->Resolve(v8::Integer::New(isolate, 1));
+ CHECK(p->IsPromise());
+ rr->Reject(v8::Integer::New(isolate, 2));
+ CHECK(r->IsPromise());
+
+ // Chaining non-pending promises.
+ CompileRun(
+ "var x1 = 0;\n"
+ "var x2 = 0;\n"
+ "function f1(x) { x1 = x; return x+1 };\n"
+ "function f2(x) { x2 = x; return x+1 };\n");
+ Handle<Function> f1 = Handle<Function>::Cast(global->Get(v8_str("f1")));
+ Handle<Function> f2 = Handle<Function>::Cast(global->Get(v8_str("f2")));
+
+ p->Chain(f1);
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());
+
+ p->Catch(f2);
+ isolate->RunMicrotasks();
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+
+ r->Catch(f2);
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(2, global->Get(v8_str("x2"))->Int32Value());
+
+ r->Chain(f1);
+ isolate->RunMicrotasks();
+ CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());
+
+ // Chaining pending promises.
+ CompileRun("x1 = x2 = 0;");
+ pr = v8::Promise::Resolver::New(isolate);
+ rr = v8::Promise::Resolver::New(isolate);
+
+ pr->GetPromise()->Chain(f1);
+ rr->GetPromise()->Catch(f2);
+ isolate->RunMicrotasks();
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+
+ pr->Resolve(v8::Integer::New(isolate, 1));
+ rr->Reject(v8::Integer::New(isolate, 2));
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+
+ isolate->RunMicrotasks();
+ CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(2, global->Get(v8_str("x2"))->Int32Value());
+
+ // Multi-chaining.
+ CompileRun("x1 = x2 = 0;");
+ pr = v8::Promise::Resolver::New(isolate);
+ pr->GetPromise()->Chain(f1)->Chain(f2);
+ pr->Resolve(v8::Integer::New(isolate, 3));
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());
+
+ CompileRun("x1 = x2 = 0;");
+ rr = v8::Promise::Resolver::New(isolate);
+ rr->GetPromise()->Catch(f1)->Chain(f2);
+ rr->Reject(v8::Integer::New(isolate, 3));
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());
+}
+
+
+TEST(PromiseThen) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Handle<Object> global = context->Global();
+
+ // Creation.
+ Handle<v8::Promise::Resolver> pr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise::Resolver> qr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise> p = pr->GetPromise();
+ Handle<v8::Promise> q = qr->GetPromise();
+
+ CHECK(p->IsPromise());
+ CHECK(q->IsPromise());
+
+ pr->Resolve(v8::Integer::New(isolate, 1));
+ qr->Resolve(p);
+
+ // Chaining non-pending promises.
+ CompileRun(
+ "var x1 = 0;\n"
+ "var x2 = 0;\n"
+ "function f1(x) { x1 = x; return x+1 };\n"
+ "function f2(x) { x2 = x; return x+1 };\n");
+ Handle<Function> f1 = Handle<Function>::Cast(global->Get(v8_str("f1")));
+ Handle<Function> f2 = Handle<Function>::Cast(global->Get(v8_str("f2")));
+
+ // Chain
+ q->Chain(f1);
+ CHECK(global->Get(v8_str("x1"))->IsNumber());
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK(!global->Get(v8_str("x1"))->IsNumber());
+ CHECK_EQ(p, global->Get(v8_str("x1")));
+
+ // Then
+ CompileRun("x1 = x2 = 0;");
+ q->Then(f1);
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());
+
+ // Then
+ CompileRun("x1 = x2 = 0;");
+ pr = v8::Promise::Resolver::New(isolate);
+ qr = v8::Promise::Resolver::New(isolate);
+
+ qr->Resolve(pr);
+ qr->GetPromise()->Then(f1)->Then(f2);
+
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+
+ pr->Resolve(v8::Integer::New(isolate, 3));
+
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());
+}
+
+
+TEST(DisallowJavascriptExecutionScope) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ CompileRun("2+2");
+}
+
+
+TEST(AllowJavascriptExecutionScope) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ v8::Isolate::DisallowJavascriptExecutionScope throw_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
+ { v8::Isolate::AllowJavascriptExecutionScope yes_js(isolate);
+ CompileRun("1+1");
+ }
+}
+
+
+TEST(ThrowOnJavascriptExecution) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::TryCatch try_catch;
+ v8::Isolate::DisallowJavascriptExecutionScope throw_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
+ CompileRun("1+1");
+ CHECK(try_catch.HasCaught());
+}
+
+
+TEST(Regress354123) {
+ LocalContext current;
+ v8::Isolate* isolate = current->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ templ->SetAccessCheckCallbacks(NamedAccessCounter, IndexedAccessCounter);
+ current->Global()->Set(v8_str("friend"), templ->NewInstance());
+
+ // Test access using __proto__ from the prototype chain.
+ named_access_count = 0;
+ CompileRun("friend.__proto__ = {};");
+ CHECK_EQ(2, named_access_count);
+ CompileRun("friend.__proto__;");
+ CHECK_EQ(4, named_access_count);
+
+ // Test access using __proto__ as a hijacked function (A).
+ named_access_count = 0;
+ CompileRun("var p = Object.prototype;"
+ "var f = Object.getOwnPropertyDescriptor(p, '__proto__').set;"
+ "f.call(friend, {});");
+ CHECK_EQ(1, named_access_count);
+ CompileRun("var p = Object.prototype;"
+ "var f = Object.getOwnPropertyDescriptor(p, '__proto__').get;"
+ "f.call(friend);");
+ CHECK_EQ(2, named_access_count);
+
+ // Test access using __proto__ as a hijacked function (B).
+ named_access_count = 0;
+ CompileRun("var f = Object.prototype.__lookupSetter__('__proto__');"
+ "f.call(friend, {});");
+ CHECK_EQ(1, named_access_count);
+ CompileRun("var f = Object.prototype.__lookupGetter__('__proto__');"
+ "f.call(friend);");
+ CHECK_EQ(2, named_access_count);
+
+ // Test access using Object.setPrototypeOf reflective method.
+ named_access_count = 0;
+ CompileRun("Object.setPrototypeOf(friend, {});");
+ CHECK_EQ(1, named_access_count);
+ CompileRun("Object.getPrototypeOf(friend);");
+ CHECK_EQ(2, named_access_count);
+}
+
+
+TEST(CaptureStackTraceForStackOverflow) {
+ v8::internal::FLAG_stack_size = 150;
+ LocalContext current;
+ v8::Isolate* isolate = current->GetIsolate();
+ v8::HandleScope scope(isolate);
+ V8::SetCaptureStackTraceForUncaughtExceptions(
+ true, 10, v8::StackTrace::kDetailed);
+ v8::TryCatch try_catch;
+ CompileRun("(function f(x) { f(x+1); })(0)");
+ CHECK(try_catch.HasCaught());
+}
+
+
+TEST(ScriptNameAndLineNumber) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ const char* url = "http://www.foo.com/foo.js";
+ v8::ScriptOrigin origin(v8_str(url), v8::Integer::New(isolate, 13));
+ v8::ScriptCompiler::Source script_source(v8_str("var foo;"), origin);
+ Local<Script> script = v8::ScriptCompiler::Compile(
+ isolate, &script_source);
+ Local<Value> script_name = script->GetUnboundScript()->GetScriptName();
+ CHECK(!script_name.IsEmpty());
+ CHECK(script_name->IsString());
+ String::Utf8Value utf8_name(script_name);
+ CHECK_EQ(url, *utf8_name);
+ int line_number = script->GetUnboundScript()->GetLineNumber(0);
+ CHECK_EQ(13, line_number);
+}
+
+
+void SourceURLHelper(const char* source, const char* expected_source_url,
+ const char* expected_source_mapping_url) {
+ Local<Script> script = v8_compile(source);
+ if (expected_source_url != NULL) {
+ v8::String::Utf8Value url(script->GetUnboundScript()->GetSourceURL());
+ CHECK_EQ(expected_source_url, *url);
+ } else {
+ CHECK(script->GetUnboundScript()->GetSourceURL()->IsUndefined());
+ }
+ if (expected_source_mapping_url != NULL) {
+ v8::String::Utf8Value url(
+ script->GetUnboundScript()->GetSourceMappingURL());
+ CHECK_EQ(expected_source_mapping_url, *url);
+ } else {
+ CHECK(script->GetUnboundScript()->GetSourceMappingURL()->IsUndefined());
+ }
+}
+
+
+TEST(ScriptSourceURLAndSourceMappingURL) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar1.js\n", "bar1.js", NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceMappingURL=bar2.js\n", NULL, "bar2.js");
+
+ // Both sourceURL and sourceMappingURL.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar3.js\n"
+ "//# sourceMappingURL=bar4.js\n", "bar3.js", "bar4.js");
+
+ // Two source URLs; the first one is ignored.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=ignoreme.js\n"
+ "//# sourceURL=bar5.js\n", "bar5.js", NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceMappingURL=ignoreme.js\n"
+ "//# sourceMappingURL=bar6.js\n", NULL, "bar6.js");
+
+ // SourceURL or sourceMappingURL in the middle of the script.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar7.js\n"
+ "function baz() {}\n", "bar7.js", NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceMappingURL=bar8.js\n"
+ "function baz() {}\n", NULL, "bar8.js");
+
+ // Too much whitespace.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar9.js\n"
+ "//# sourceMappingURL=bar10.js\n", NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL =bar11.js\n"
+ "//# sourceMappingURL =bar12.js\n", NULL, NULL);
+
+ // Disallowed characters in value.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar13 .js \n"
+ "//# sourceMappingURL=bar14 .js \n",
+ NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar15\t.js \n"
+ "//# sourceMappingURL=bar16\t.js \n",
+ NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar17'.js \n"
+ "//# sourceMappingURL=bar18'.js \n",
+ NULL, NULL);
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL=bar19\".js \n"
+ "//# sourceMappingURL=bar20\".js \n",
+ NULL, NULL);
+
+ // Not too much whitespace.
+ SourceURLHelper("function foo() {}\n"
+ "//# sourceURL= bar21.js \n"
+ "//# sourceMappingURL= bar22.js \n", "bar21.js", "bar22.js");
+}
+
+
+TEST(GetOwnPropertyDescriptor) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ CompileRun(
+ "var x = { value : 13};"
+ "Object.defineProperty(x, 'p0', {value : 12});"
+ "Object.defineProperty(x, 'p1', {"
+ " set : function(value) { this.value = value; },"
+ " get : function() { return this.value; },"
+ "});");
+ Local<Object> x = Local<Object>::Cast(env->Global()->Get(v8_str("x")));
+ Local<Value> desc = x->GetOwnPropertyDescriptor(v8_str("no_prop"));
+ CHECK(desc->IsUndefined());
+ desc = x->GetOwnPropertyDescriptor(v8_str("p0"));
+ CHECK_EQ(v8_num(12), Local<Object>::Cast(desc)->Get(v8_str("value")));
+ desc = x->GetOwnPropertyDescriptor(v8_str("p1"));
+ Local<Function> set =
+ Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("set")));
+ Local<Function> get =
+ Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("get")));
+ CHECK_EQ(v8_num(13), get->Call(x, 0, NULL));
+ Handle<Value> args[] = { v8_num(14) };
+ set->Call(x, 1, args);
+ CHECK_EQ(v8_num(14), get->Call(x, 0, NULL));
+}
+
+
+TEST(Regress411877) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
+ object_template->SetAccessCheckCallbacks(NamedAccessCounter,
+ IndexedAccessCounter);
+
+ v8::Handle<Context> context = Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+
+ context->Global()->Set(v8_str("o"), object_template->NewInstance());
+ CompileRun("Object.getOwnPropertyNames(o)");
+}
+
+
+TEST(GetHiddenPropertyTableAfterAccessCheck) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
+ object_template->SetAccessCheckCallbacks(NamedAccessCounter,
+ IndexedAccessCounter);
+
+ v8::Handle<Context> context = Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+
+ v8::Handle<v8::Object> obj = object_template->NewInstance();
+ obj->Set(v8_str("key"), v8_str("value"));
+ obj->Delete(v8_str("key"));
+
+ obj->SetHiddenValue(v8_str("hidden key 2"), v8_str("hidden value 2"));
+}
+
+
+TEST(Regress411793) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
+ object_template->SetAccessCheckCallbacks(NamedAccessCounter,
+ IndexedAccessCounter);
+
+ v8::Handle<Context> context = Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+
+ context->Global()->Set(v8_str("o"), object_template->NewInstance());
+ CompileRun(
+ "Object.defineProperty(o, 'key', "
+ " { get: function() {}, set: function() {} });");
+}
+
+class TestSourceStream : public v8::ScriptCompiler::ExternalSourceStream {
+ public:
+ explicit TestSourceStream(const char** chunks) : chunks_(chunks), index_(0) {}
+
+ virtual size_t GetMoreData(const uint8_t** src) {
+ // Unlike in real use cases, this function will never block.
+ if (chunks_[index_] == NULL) {
+ return 0;
+ }
+ // Copy the data, since the caller takes ownership of it.
+ size_t len = strlen(chunks_[index_]);
+ // We don't need to zero-terminate since we return the length.
+ uint8_t* copy = new uint8_t[len];
+ memcpy(copy, chunks_[index_], len);
+ *src = copy;
+ ++index_;
+ return len;
+ }
+
+ // Helper for constructing a string from chunks (the compilation needs it
+ // too).
+ static char* FullSourceString(const char** chunks) {
+ size_t total_len = 0;
+ for (size_t i = 0; chunks[i] != NULL; ++i) {
+ total_len += strlen(chunks[i]);
+ }
+ char* full_string = new char[total_len + 1];
+ size_t offset = 0;
+ for (size_t i = 0; chunks[i] != NULL; ++i) {
+ size_t len = strlen(chunks[i]);
+ memcpy(full_string + offset, chunks[i], len);
+ offset += len;
+ }
+ full_string[total_len] = 0;
+ return full_string;
+ }
+
+ private:
+ const char** chunks_;
+ unsigned index_;
+};
+
+
+// Helper function for running streaming tests.
+void RunStreamingTest(const char** chunks,
+ v8::ScriptCompiler::StreamedSource::Encoding encoding =
+ v8::ScriptCompiler::StreamedSource::ONE_BYTE,
+ bool expected_success = true) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::TryCatch try_catch;
+
+ v8::ScriptCompiler::StreamedSource source(new TestSourceStream(chunks),
+ encoding);
+ v8::ScriptCompiler::ScriptStreamingTask* task =
+ v8::ScriptCompiler::StartStreamingScript(isolate, &source);
+
+ // TestSourceStream::GetMoreData won't block, so it's OK to just run the
+ // task here in the main thread.
+ task->Run();
+ delete task;
+
+ v8::ScriptOrigin origin(v8_str("http://foo.com"));
+ char* full_source = TestSourceStream::FullSourceString(chunks);
+
+ // The possible errors are only produced while compiling.
+ CHECK_EQ(false, try_catch.HasCaught());
+
+ v8::Handle<Script> script = v8::ScriptCompiler::Compile(
+ isolate, &source, v8_str(full_source), origin);
+ if (expected_success) {
+ CHECK(!script.IsEmpty());
+ v8::Handle<Value> result(script->Run());
+ // All scripts are supposed to return the fixed value 13 when ran.
+ CHECK_EQ(13, result->Int32Value());
+ } else {
+ CHECK(script.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ }
+ delete[] full_source;
+}
+
+
+TEST(StreamingSimpleScript) {
+ // This script is unrealistically small, since no one chunk is enough to fill
+ // the backing buffer of Scanner, let alone overflow it.
+ const char* chunks[] = {"function foo() { ret", "urn 13; } f", "oo(); ",
+ NULL};
+ RunStreamingTest(chunks);
+}
+
+
+TEST(StreamingBiggerScript) {
+ const char* chunk1 =
+ "function foo() {\n"
+ " // Make this chunk sufficiently long so that it will overflow the\n"
+ " // backing buffer of the Scanner.\n"
+ " var i = 0;\n"
+ " var result = 0;\n"
+ " for (i = 0; i < 13; ++i) { result = result + 1; }\n"
+ " result = 0;\n"
+ " for (i = 0; i < 13; ++i) { result = result + 1; }\n"
+ " result = 0;\n"
+ " for (i = 0; i < 13; ++i) { result = result + 1; }\n"
+ " result = 0;\n"
+ " for (i = 0; i < 13; ++i) { result = result + 1; }\n"
+ " return result;\n"
+ "}\n";
+ const char* chunks[] = {chunk1, "foo(); ", NULL};
+ RunStreamingTest(chunks);
+}
+
+
+TEST(StreamingScriptWithParseError) {
+ // Test that parse errors from streamed scripts are propagated correctly.
+ {
+ char chunk1[] =
+ " // This will result in a parse error.\n"
+ " var if else then foo";
+ char chunk2[] = " 13\n";
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::ONE_BYTE,
+ false);
+ }
+ // Test that the next script succeeds normally.
+ {
+ char chunk1[] =
+ " // This will be parsed successfully.\n"
+ " function foo() { return ";
+ char chunk2[] = " 13; }\n";
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+
+ RunStreamingTest(chunks);
+ }
+}
+
+
+TEST(StreamingUtf8Script) {
+ // We'd want to write \uc481 instead of \xec\x92\x81, but Windows compilers
+ // don't like it.
+ const char* chunk1 =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foob\xec\x92\x81r = 13;\n"
+ " return foob\xec\x92\x81r;\n"
+ "}\n";
+ const char* chunks[] = {chunk1, "foo(); ", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+TEST(StreamingUtf8ScriptWithSplitCharactersSanityCheck) {
+ // A sanity check to prove that the approach of splitting UTF-8
+ // characters is correct. Here is an UTF-8 character which will take three
+ // bytes.
+ const char* reference = "\xec\x92\x81";
+ CHECK(3u == strlen(reference)); // NOLINT - no CHECK_EQ for unsigned.
+
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foob";
+ char chunk2[] =
+ "XXXr = 13;\n"
+ " return foob\xec\x92\x81r;\n"
+ "}\n";
+ for (int i = 0; i < 3; ++i) {
+ chunk2[i] = reference[i];
+ }
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+TEST(StreamingUtf8ScriptWithSplitCharacters) {
+ // Stream data where a multi-byte UTF-8 character is split between two data
+ // chunks.
+ const char* reference = "\xec\x92\x81";
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foobX";
+ char chunk2[] =
+ "XXr = 13;\n"
+ " return foob\xec\x92\x81r;\n"
+ "}\n";
+ chunk1[strlen(chunk1) - 1] = reference[0];
+ chunk2[0] = reference[1];
+ chunk2[1] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+TEST(StreamingUtf8ScriptWithSplitCharactersValidEdgeCases) {
+ // Tests edge cases which should still be decoded correctly.
+
+ // Case 1: a chunk contains only bytes for a split character (and no other
+ // data). This kind of a chunk would be exceptionally small, but we should
+ // still decode it correctly.
+ const char* reference = "\xec\x92\x81";
+ // The small chunk is at the beginning of the split character
+ {
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foob";
+ char chunk2[] = "XX";
+ char chunk3[] =
+ "Xr = 13;\n"
+ " return foob\xec\x92\x81r;\n"
+ "}\n";
+ chunk2[0] = reference[0];
+ chunk2[1] = reference[1];
+ chunk3[0] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, chunk3, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+ }
+ // The small chunk is at the end of a character
+ {
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foobX";
+ char chunk2[] = "XX";
+ char chunk3[] =
+ "r = 13;\n"
+ " return foob\xec\x92\x81r;\n"
+ "}\n";
+ chunk1[strlen(chunk1) - 1] = reference[0];
+ chunk2[0] = reference[1];
+ chunk2[1] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, chunk3, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+ }
+ // Case 2: the script ends with a multi-byte character. Make sure that it's
+ // decoded correctly and not just ignored.
+ {
+ char chunk1[] =
+ "var foob\xec\x92\x81 = 13;\n"
+ "foob\xec\x92\x81";
+ const char* chunks[] = {chunk1, NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+ }
+}
+
+
+TEST(StreamingUtf8ScriptWithSplitCharactersInvalidEdgeCases) {
+ // Test cases where a UTF-8 character is split over several chunks. Those
+ // cases are not supported (the embedder should give the data in big enough
+ // chunks), but we shouldn't crash, just produce a parse error.
+ const char* reference = "\xec\x92\x81";
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foobX";
+ char chunk2[] = "X";
+ char chunk3[] =
+ "Xr = 13;\n"
+ " return foob\xec\x92\x81r;\n"
+ "}\n";
+ chunk1[strlen(chunk1) - 1] = reference[0];
+ chunk2[0] = reference[1];
+ chunk3[0] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, chunk3, "foo();", NULL};
+
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, false);
+}
+
+
+TEST(StreamingProducesParserCache) {
+ i::FLAG_min_preparse_length = 0;
+ const char* chunks[] = {"function foo() { ret", "urn 13; } f", "oo(); ",
+ NULL};
+
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ v8::ScriptCompiler::StreamedSource source(
+ new TestSourceStream(chunks),
+ v8::ScriptCompiler::StreamedSource::ONE_BYTE);
+ v8::ScriptCompiler::ScriptStreamingTask* task =
+ v8::ScriptCompiler::StartStreamingScript(
+ isolate, &source, v8::ScriptCompiler::kProduceParserCache);
+
+ // TestSourceStream::GetMoreData won't block, so it's OK to just run the
+ // task here in the main thread.
+ task->Run();
+ delete task;
+
+ const v8::ScriptCompiler::CachedData* cached_data = source.GetCachedData();
+ CHECK(cached_data != NULL);
+ CHECK(cached_data->data != NULL);
+ CHECK_GT(cached_data->length, 0);
+}
+
+
+TEST(StreamingScriptWithInvalidUtf8) {
+ // Regression test for a crash: test that invalid UTF-8 bytes in the end of a
+ // chunk don't produce a crash.
+ const char* reference = "\xec\x92\x81\x80\x80";
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foobXXXXX"; // Too many bytes which look like incomplete chars!
+ char chunk2[] =
+ "r = 13;\n"
+ " return foob\xec\x92\x81\x80\x80r;\n"
+ "}\n";
+ for (int i = 0; i < 5; ++i) chunk1[strlen(chunk1) - 5 + i] = reference[i];
+
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, false);
+}
+
+
+TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit) {
+ // Regression test: Stream data where there are several multi-byte UTF-8
+ // characters in a sequence and one of them is split between two data chunks.
+ const char* reference = "\xec\x92\x81";
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foob\xec\x92\x81X";
+ char chunk2[] =
+ "XXr = 13;\n"
+ " return foob\xec\x92\x81\xec\x92\x81r;\n"
+ "}\n";
+ chunk1[strlen(chunk1) - 1] = reference[0];
+ chunk2[0] = reference[1];
+ chunk2[1] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit2) {
+ // Another regression test, similar to the previous one. The difference is
+ // that the split character is not the last one in the sequence.
+ const char* reference = "\xec\x92\x81";
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foobX";
+ char chunk2[] =
+ "XX\xec\x92\x81r = 13;\n"
+ " return foob\xec\x92\x81\xec\x92\x81r;\n"
+ "}\n";
+ chunk1[strlen(chunk1) - 1] = reference[0];
+ chunk2[0] = reference[1];
+ chunk2[1] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
}