summaryrefslogtreecommitdiff
path: root/deps/v8/test
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2010-03-26 09:09:40 -0700
committerRyan Dahl <ry@tinyclouds.org>2010-03-26 09:09:40 -0700
commit6192b8659a3dedb86393cfb78121a26f2a3e31e6 (patch)
tree78b74bbdc1a7cdd8989e32db309050d6e51ba346 /deps/v8/test
parentbb00fef3cd2ff446aa5c1894fb4830f83750018a (diff)
downloadnode-new-6192b8659a3dedb86393cfb78121a26f2a3e31e6.tar.gz
Upgrade V8 to 2.1.10
Diffstat (limited to 'deps/v8/test')
-rw-r--r--deps/v8/test/cctest/test-api.cc62
-rw-r--r--deps/v8/test/cctest/test-conversions.cc87
-rw-r--r--deps/v8/test/cctest/test-heap.cc112
-rw-r--r--deps/v8/test/mjsunit/str-to-num.js22
4 files changed, 283 insertions, 0 deletions
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index e57914370d..84fdd68b4b 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -2644,6 +2644,36 @@ THREADED_TEST(NamedInterceptorPropertyRead) {
}
+THREADED_TEST(NamedInterceptorDictionaryIC) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ 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"));
+ for (int i = 0; i < 10; i++) {
+ Local<Value> result = script->Run();
+ CHECK_EQ(result, v8_str("x"));
+ }
+ // Create a slow case object and a function accessing a property in
+ // that slow case object (with dictionary probing in generated
+ // code). Then force object with a named interceptor into slow-case,
+ // pass it to the function, and check that the interceptor is called
+ // instead of accessing the local property.
+ Local<Value> result =
+ CompileRun("function get_x(o) { return o.x; };"
+ "var obj = { x : 42, y : 0 };"
+ "delete obj.y;"
+ "for (var i = 0; i < 10; i++) get_x(obj);"
+ "interceptor_obj.x = 42;"
+ "interceptor_obj.y = 10;"
+ "delete interceptor_obj.y;"
+ "get_x(interceptor_obj)");
+ CHECK_EQ(result, v8_str("x"));
+}
+
+
static v8::Handle<Value> SetXOnPrototypeGetter(Local<String> property,
const AccessorInfo& info) {
// Set x on the prototype object and do not handle the get request.
@@ -5974,6 +6004,38 @@ THREADED_TEST(InterceptorLoadICInvalidatedField) {
}
+static int interceptor_load_not_handled_calls = 0;
+static v8::Handle<Value> InterceptorLoadNotHandled(Local<String> name,
+ const AccessorInfo& info) {
+ ++interceptor_load_not_handled_calls;
+ return v8::Handle<v8::Value>();
+}
+
+
+// Test how post-interceptor lookups are done in the non-cacheable
+// case: the interceptor should not be invoked during this lookup.
+THREADED_TEST(InterceptorLoadICPostInterceptor) {
+ interceptor_load_not_handled_calls = 0;
+ CheckInterceptorLoadIC(InterceptorLoadNotHandled,
+ "receiver = new Object();"
+ "receiver.__proto__ = o;"
+ "proto = new Object();"
+ "/* Make proto a slow-case object. */"
+ "for (var i = 0; i < 1000; i++) {"
+ " proto[\"xxxxxxxx\" + i] = [];"
+ "}"
+ "proto.x = 17;"
+ "o.__proto__ = proto;"
+ "var result = 0;"
+ "for (var i = 0; i < 1000; i++) {"
+ " result += receiver.x;"
+ "}"
+ "result;",
+ 17 * 1000);
+ CHECK_EQ(1000, interceptor_load_not_handled_calls);
+}
+
+
// Test the case when we stored field into
// a stub, but it got invalidated later on due to override on
// global object which is between interceptor and fields' holders.
diff --git a/deps/v8/test/cctest/test-conversions.cc b/deps/v8/test/cctest/test-conversions.cc
index 35ab46f250..abcd426ec4 100644
--- a/deps/v8/test/cctest/test-conversions.cc
+++ b/deps/v8/test/cctest/test-conversions.cc
@@ -41,6 +41,10 @@ TEST(Octal) {
CHECK_EQ(7.0, StringToDouble("07", ALLOW_HEX));
CHECK_EQ(10.0, StringToDouble("010", ALLOW_HEX));
CHECK_EQ(77.0, StringToDouble("077", ALLOW_HEX));
+
+ const double x = 010000000000; // Power of 2, no rounding errors.
+ CHECK_EQ(x * x * x * x * x, StringToDouble("01" "0000000000" "0000000000"
+ "0000000000" "0000000000" "0000000000", ALLOW_OCTALS));
}
@@ -80,6 +84,8 @@ TEST(MalformedOctal) {
TEST(TrailingJunk) {
CHECK_EQ(8.0, StringToDouble("8q", ALLOW_TRAILING_JUNK));
CHECK_EQ(63.0, StringToDouble("077qqq", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+ CHECK_EQ(10.0, StringToDouble("10e", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+ CHECK_EQ(10.0, StringToDouble("10e-", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
}
@@ -91,6 +97,87 @@ TEST(NonStrDecimalLiteral) {
CHECK_EQ(0.0, StringToDouble(" ", NO_FLAGS));
}
+TEST(IntegerStrLiteral) {
+ CHECK_EQ(0.0, StringToDouble("0.0", NO_FLAGS));
+ CHECK_EQ(0.0, StringToDouble("0", NO_FLAGS));
+ CHECK_EQ(0.0, StringToDouble("00", NO_FLAGS));
+ CHECK_EQ(0.0, StringToDouble("000", NO_FLAGS));
+ CHECK_EQ(1.0, StringToDouble("1", NO_FLAGS));
+ CHECK_EQ(-1.0, StringToDouble("-1", NO_FLAGS));
+ CHECK_EQ(-1.0, StringToDouble(" - 1 ", NO_FLAGS));
+ CHECK_EQ(1.0, StringToDouble(" + 1 ", NO_FLAGS));
+
+ CHECK_EQ(0.0, StringToDouble("0e0", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble("0e1", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble("0e-1", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble("0e-100000", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble("0e+100000", ALLOW_HEX | ALLOW_OCTALS));
+ CHECK_EQ(0.0, StringToDouble("0.", ALLOW_HEX | ALLOW_OCTALS));
+}
+
+TEST(LongNumberStr) {
+ CHECK_EQ(1e10, StringToDouble("1" "0000000000", NO_FLAGS));
+ CHECK_EQ(1e20, StringToDouble("1" "0000000000" "0000000000", NO_FLAGS));
+
+ CHECK_EQ(1e60, StringToDouble("1" "0000000000" "0000000000" "0000000000"
+ "0000000000" "0000000000" "0000000000", NO_FLAGS));
+
+ CHECK_EQ(1e-2, StringToDouble("." "0" "1", NO_FLAGS));
+ CHECK_EQ(1e-11, StringToDouble("." "0000000000" "1", NO_FLAGS));
+ CHECK_EQ(1e-21, StringToDouble("." "0000000000" "0000000000" "1", NO_FLAGS));
+
+ CHECK_EQ(1e-61, StringToDouble("." "0000000000" "0000000000" "0000000000"
+ "0000000000" "0000000000" "0000000000" "1", NO_FLAGS));
+
+
+ // x = 24414062505131248.0 and y = 24414062505131252.0 are representable in
+ // double. Check chat z = (x + y) / 2 is rounded to x...
+ CHECK_EQ(24414062505131248.0,
+ StringToDouble("24414062505131250.0", NO_FLAGS));
+
+ // ... and z = (x + y) / 2 + delta is rounded to y.
+ CHECK_EQ(24414062505131252.0,
+ StringToDouble("24414062505131250.000000001", NO_FLAGS));
+}
+
+
+extern "C" double gay_strtod(const char* s00, const char** se);
+
+
+TEST(MaximumSignificantDigits) {
+ char num[] =
+ "4.4501477170144020250819966727949918635852426585926051135169509"
+ "122872622312493126406953054127118942431783801370080830523154578"
+ "251545303238277269592368457430440993619708911874715081505094180"
+ "604803751173783204118519353387964161152051487413083163272520124"
+ "606023105869053620631175265621765214646643181420505164043632222"
+ "668006474326056011713528291579642227455489682133472873831754840"
+ "341397809846934151055619529382191981473003234105366170879223151"
+ "087335413188049110555339027884856781219017754500629806224571029"
+ "581637117459456877330110324211689177656713705497387108207822477"
+ "584250967061891687062782163335299376138075114200886249979505279"
+ "101870966346394401564490729731565935244123171539810221213221201"
+ "847003580761626016356864581135848683152156368691976240370422601"
+ "6998291015625000000000000000000000000000000000e-308";
+
+ CHECK_EQ(gay_strtod(num, NULL), StringToDouble(num, NO_FLAGS));
+
+ // Changes the result of strtod (at least in glibc implementation).
+ num[sizeof(num) - 8] = '1';
+
+ CHECK_EQ(gay_strtod(num, NULL), StringToDouble(num, NO_FLAGS));
+}
+
+
+TEST(ExponentNumberStr) {
+ CHECK_EQ(1e1, StringToDouble("1e1", NO_FLAGS));
+ CHECK_EQ(1e1, StringToDouble("1e+1", NO_FLAGS));
+ CHECK_EQ(1e-1, StringToDouble("1e-1", NO_FLAGS));
+ CHECK_EQ(1e100, StringToDouble("1e+100", NO_FLAGS));
+ CHECK_EQ(1e-100, StringToDouble("1e-100", NO_FLAGS));
+ CHECK_EQ(1e-106, StringToDouble(".000001e-100", NO_FLAGS));
+}
+
class OneBit1: public BitField<uint32_t, 0, 1> {};
class OneBit2: public BitField<uint32_t, 7, 1> {};
class EightBit1: public BitField<uint32_t, 0, 8> {};
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index 2b88f0f94e..bfadd208b6 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -852,3 +852,115 @@ TEST(LargeObjectSpaceContains) {
CHECK(Heap::new_space()->Contains(addr));
CHECK(!Heap::lo_space()->Contains(addr));
}
+
+
+TEST(EmptyHandleEscapeFrom) {
+ InitializeVM();
+
+ v8::HandleScope scope;
+ Handle<JSObject> runaway;
+
+ {
+ v8::HandleScope nested;
+ Handle<JSObject> empty;
+ runaway = empty.EscapeFrom(&nested);
+ }
+
+ CHECK(runaway.is_null());
+}
+
+
+static int LenFromSize(int size) {
+ return (size - FixedArray::kHeaderSize) / kPointerSize;
+}
+
+
+TEST(Regression39128) {
+ // Test case for crbug.com/39128.
+ InitializeVM();
+
+ // Increase the chance of 'bump-the-pointer' allocation in old space.
+ bool force_compaction = true;
+ Heap::CollectAllGarbage(force_compaction);
+
+ v8::HandleScope scope;
+
+ // The plan: create JSObject which references objects in new space.
+ // Then clone this object (forcing it to go into old space) and check
+ // that only bits pertaining to the object are updated in remembered set.
+
+ // Step 1: prepare a map for the object. We add 1 inobject property to it.
+ Handle<JSFunction> object_ctor(Top::global_context()->object_function());
+ CHECK(object_ctor->has_initial_map());
+ Handle<Map> object_map(object_ctor->initial_map());
+ // Create a map with single inobject property.
+ Handle<Map> my_map = Factory::CopyMap(object_map, 1);
+ int n_properties = my_map->inobject_properties();
+ CHECK_GT(n_properties, 0);
+
+ int object_size = my_map->instance_size();
+
+ // Step 2: allocate a lot of objects so to almost fill new space: we need
+ // just enough room to allocate JSObject and thus fill the newspace.
+
+ int allocation_amount = Min(FixedArray::kMaxSize,
+ Heap::MaxObjectSizeInNewSpace());
+ int allocation_len = LenFromSize(allocation_amount);
+ NewSpace* new_space = Heap::new_space();
+ Address* top_addr = new_space->allocation_top_address();
+ Address* limit_addr = new_space->allocation_limit_address();
+ while ((*limit_addr - *top_addr) > allocation_amount) {
+ CHECK(!Heap::always_allocate());
+ Object* array = Heap::AllocateFixedArray(allocation_len);
+ CHECK(!array->IsFailure());
+ CHECK(new_space->Contains(array));
+ }
+
+ // Step 3: now allocate fixed array and JSObject to fill the whole new space.
+ int to_fill = *limit_addr - *top_addr - object_size;
+ int fixed_array_len = LenFromSize(to_fill);
+ CHECK(fixed_array_len < FixedArray::kMaxLength);
+
+ CHECK(!Heap::always_allocate());
+ Object* array = Heap::AllocateFixedArray(fixed_array_len);
+ CHECK(!array->IsFailure());
+ CHECK(new_space->Contains(array));
+
+ Object* object = Heap::AllocateJSObjectFromMap(*my_map);
+ CHECK(!object->IsFailure());
+ CHECK(new_space->Contains(object));
+ JSObject* jsobject = JSObject::cast(object);
+ CHECK_EQ(0, jsobject->elements()->length());
+ CHECK_EQ(0, jsobject->properties()->length());
+ // Create a reference to object in new space in jsobject.
+ jsobject->FastPropertyAtPut(-1, array);
+
+ CHECK_EQ(0L, (*limit_addr - *top_addr));
+
+ // Step 4: clone jsobject, but force always allocate first to create a clone
+ // in old pointer space.
+ Address old_pointer_space_top = Heap::old_pointer_space()->top();
+ AlwaysAllocateScope aa_scope;
+ Object* clone_obj = Heap::CopyJSObject(jsobject);
+ CHECK(!object->IsFailure());
+ JSObject* clone = JSObject::cast(clone_obj);
+ if (clone->address() != old_pointer_space_top) {
+ // Alas, got allocated from free list, we cannot do checks.
+ return;
+ }
+ CHECK(Heap::old_pointer_space()->Contains(clone->address()));
+
+ // Step 5: verify validity of remembered set.
+ Address clone_addr = clone->address();
+ Page* page = Page::FromAddress(clone_addr);
+ // Check that remembered set tracks a reference from inobject property 1.
+ CHECK(page->IsRSetSet(clone_addr, object_size - kPointerSize));
+ // Probe several addresses after the object.
+ for (int i = 0; i < 7; i++) {
+ int offset = object_size + i * kPointerSize;
+ if (clone_addr + offset >= page->ObjectAreaEnd()) {
+ break;
+ }
+ CHECK(!page->IsRSetSet(clone_addr, offset));
+ }
+}
diff --git a/deps/v8/test/mjsunit/str-to-num.js b/deps/v8/test/mjsunit/str-to-num.js
index 12a3716247..f7a9c2d709 100644
--- a/deps/v8/test/mjsunit/str-to-num.js
+++ b/deps/v8/test/mjsunit/str-to-num.js
@@ -29,6 +29,19 @@ function toNumber(val) {
return Number(val);
}
+function repeat(s, num) {
+ var result = '';
+ while (num > 0) {
+ if ((num & 1) != 0) result += s;
+ s += s;
+ num >>= 1;
+ }
+
+ return result;
+}
+
+assertEquals('0000000000', repeat('0', 10));
+
// assertEquals(, toNumber());
@@ -61,6 +74,7 @@ assertEquals(Infinity, toNumber("+Infinity "), "+Infinity");
assertEquals(0, toNumber("0"));
assertEquals(0, toNumber("+0"));
assertEquals(-0, toNumber("-0"));
+assertEquals(-Infinity, 1 / toNumber("-0"));
assertEquals(1, toNumber("1"));
assertEquals(1, toNumber("+1"));
@@ -130,11 +144,16 @@ assertEquals(15, toNumber("0Xf"));
assertEquals(15, toNumber("0XF"));
assertEquals(0, toNumber("0x000"));
+assertEquals(-Infinity, 1 / toNumber("-0x000"));
+assertEquals(0, toNumber("0x000" + repeat('0', 1000)));
assertEquals(9, toNumber("0x009"));
assertEquals(10, toNumber("0x00a"));
assertEquals(10, toNumber("0x00A"));
assertEquals(15, toNumber("0x00f"));
assertEquals(15, toNumber("0x00F"));
+assertEquals(Infinity, toNumber("0x" + repeat('0', 1000) + '1'
+ + repeat('0', 1000)));
+assertEquals(-Infinity, toNumber("-0x1" + repeat('0', 1000)));
assertEquals(0, toNumber("00"));
assertEquals(1, toNumber("01"));
@@ -156,3 +175,6 @@ assertTrue(isNaN(toNumber("0x100 junk")), "0x100 junk");
assertTrue(isNaN(toNumber("100.0 junk")), "100.0 junk");
assertTrue(isNaN(toNumber(".1e4 junk")), ".1e4 junk");
assertTrue(isNaN(toNumber("Infinity junk")), "Infinity junk");
+assertTrue(isNaN(toNumber("1e")), "1e");
+assertTrue(isNaN(toNumber("1e ")), "1e_");
+assertTrue(isNaN(toNumber("1" + repeat('0', 1000) + 'junk')), "1e1000 junk");