~ubuntu-branches/ubuntu/trusty/libv8/trusty

« back to all changes in this revision

Viewing changes to test/cctest/test-api.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2012-02-20 14:08:17 UTC
  • mfrom: (15.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20120220140817-bsvmeoa4sxsj5hbz
Tags: 3.7.12.22-3
Fix mipsel build, allow test debug-step-3 to fail (non-crucial)

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
  CHECK_EQ(expected, *ascii);
81
81
}
82
82
 
 
83
static void ExpectInt32(const char* code, int expected) {
 
84
  Local<Value> result = CompileRun(code);
 
85
  CHECK(result->IsInt32());
 
86
  CHECK_EQ(expected, result->Int32Value());
 
87
}
83
88
 
84
89
static void ExpectBoolean(const char* code, bool expected) {
85
90
  Local<Value> result = CompileRun(code);
393
398
    CHECK(source->IsExternal());
394
399
    CHECK_EQ(resource,
395
400
             static_cast<TestResource*>(source->GetExternalStringResource()));
396
 
    HEAP->CollectAllGarbage(false);
 
401
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
397
402
    CHECK_EQ(0, dispose_count);
398
403
  }
399
404
  v8::internal::Isolate::Current()->compilation_cache()->Clear();
400
 
  HEAP->CollectAllGarbage(false);
 
405
  HEAP->CollectAllAvailableGarbage();
401
406
  CHECK_EQ(1, dispose_count);
402
407
}
403
408
 
415
420
    Local<Value> value = script->Run();
416
421
    CHECK(value->IsNumber());
417
422
    CHECK_EQ(7, value->Int32Value());
418
 
    HEAP->CollectAllGarbage(false);
 
423
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
419
424
    CHECK_EQ(0, dispose_count);
420
425
  }
421
426
  i::Isolate::Current()->compilation_cache()->Clear();
422
 
  HEAP->CollectAllGarbage(false);
 
427
  HEAP->CollectAllAvailableGarbage();
423
428
  CHECK_EQ(1, dispose_count);
424
429
}
425
430
 
441
446
    Local<Value> value = script->Run();
442
447
    CHECK(value->IsNumber());
443
448
    CHECK_EQ(7, value->Int32Value());
444
 
    HEAP->CollectAllGarbage(false);
 
449
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
445
450
    CHECK_EQ(0, dispose_count);
446
451
  }
447
452
  i::Isolate::Current()->compilation_cache()->Clear();
448
 
  HEAP->CollectAllGarbage(false);
 
453
  // TODO(1608): This should use kAbortIncrementalMarking.
 
454
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
449
455
  CHECK_EQ(1, dispose_count);
450
456
}
451
457
 
467
473
    Local<Value> value = script->Run();
468
474
    CHECK(value->IsNumber());
469
475
    CHECK_EQ(7, value->Int32Value());
470
 
    HEAP->CollectAllGarbage(false);
 
476
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
471
477
    CHECK_EQ(0, dispose_count);
472
478
  }
473
479
  i::Isolate::Current()->compilation_cache()->Clear();
474
 
  HEAP->CollectAllGarbage(false);
 
480
  // TODO(1608): This should use kAbortIncrementalMarking.
 
481
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
475
482
  CHECK_EQ(1, dispose_count);
476
483
}
477
484
 
484
491
  HEAP->CollectGarbage(i::NEW_SPACE);
485
492
  HEAP->CollectGarbage(i::NEW_SPACE);
486
493
 
487
 
  uint16_t* two_byte_string = AsciiToTwoByteString("small");
 
494
  uint16_t* two_byte_string = AsciiToTwoByteString("s1");
488
495
  Local<String> small_string = String::New(two_byte_string);
489
496
  i::DeleteArray(two_byte_string);
490
497
 
496
503
  // Old space strings should be accepted.
497
504
  CHECK(small_string->CanMakeExternal());
498
505
 
499
 
  two_byte_string = AsciiToTwoByteString("small 2");
 
506
  two_byte_string = AsciiToTwoByteString("small string 2");
500
507
  small_string = String::New(two_byte_string);
501
508
  i::DeleteArray(two_byte_string);
502
509
 
530
537
  HEAP->CollectGarbage(i::NEW_SPACE);
531
538
  HEAP->CollectGarbage(i::NEW_SPACE);
532
539
 
533
 
  Local<String> small_string = String::New("small");
 
540
  Local<String> small_string = String::New("s1");
534
541
  // We should refuse to externalize newly created small string.
535
542
  CHECK(!small_string->CanMakeExternal());
536
543
  // Trigger GCs so that the newly allocated string moves to old gen.
539
546
  // Old space strings should be accepted.
540
547
  CHECK(small_string->CanMakeExternal());
541
548
 
542
 
  small_string = String::New("small 2");
 
549
  small_string = String::New("small string 2");
543
550
  // We should refuse externalizing newly created small string.
544
551
  CHECK(!small_string->CanMakeExternal());
545
552
  for (int i = 0; i < 100; i++) {
572
579
    i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring);
573
580
    CHECK(isymbol->IsSymbol());
574
581
  }
575
 
  HEAP->CollectAllGarbage(false);
576
 
  HEAP->CollectAllGarbage(false);
 
582
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 
583
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
577
584
}
578
585
 
579
586
 
590
597
    i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring);
591
598
    CHECK(isymbol->IsSymbol());
592
599
  }
593
 
  HEAP->CollectAllGarbage(false);
594
 
  HEAP->CollectAllGarbage(false);
 
600
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 
601
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
595
602
}
596
603
 
597
604
 
672
679
    Local<Value> value = script->Run();
673
680
    CHECK(value->IsNumber());
674
681
    CHECK_EQ(7, value->Int32Value());
675
 
    HEAP->CollectAllGarbage(false);
 
682
    HEAP->CollectAllAvailableGarbage();
676
683
    CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
677
684
  }
678
685
  i::Isolate::Current()->compilation_cache()->Clear();
679
 
  HEAP->CollectAllGarbage(false);
 
686
  HEAP->CollectAllAvailableGarbage();
680
687
  CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
681
688
  CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
682
689
 
693
700
    Local<Value> value = script->Run();
694
701
    CHECK(value->IsNumber());
695
702
    CHECK_EQ(7, value->Int32Value());
696
 
    HEAP->CollectAllGarbage(false);
 
703
    HEAP->CollectAllAvailableGarbage();
697
704
    CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
698
705
  }
699
706
  i::Isolate::Current()->compilation_cache()->Clear();
700
 
  HEAP->CollectAllGarbage(false);
 
707
  HEAP->CollectAllAvailableGarbage();
701
708
  CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
702
709
  CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count);
703
710
}
744
751
    CHECK_EQ(68, value->Int32Value());
745
752
  }
746
753
  i::Isolate::Current()->compilation_cache()->Clear();
747
 
  HEAP->CollectAllGarbage(false);
748
 
  HEAP->CollectAllGarbage(false);
 
754
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 
755
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
749
756
}
750
757
 
751
758
 
1182
1189
  templ->Set("x", v8_num(200));
1183
1190
  templ->SetAccessor(v8_str("m"), GetM);
1184
1191
  LocalContext env(0, templ);
1185
 
  v8::Handle<v8::Object> obj = env->Global();
1186
 
  v8::Handle<Script> script = v8_compile("dummy()");
1187
 
  v8::Handle<Value> result = script->Run();
 
1192
  v8::Handle<v8::Object> obj(env->Global());
 
1193
  v8::Handle<Script> script(v8_compile("dummy()"));
 
1194
  v8::Handle<Value> result(script->Run());
1188
1195
  CHECK_EQ(13.4, result->NumberValue());
1189
1196
  CHECK_EQ(200, v8_compile("x")->Run()->Int32Value());
1190
1197
  CHECK_EQ(876, v8_compile("m")->Run()->Int32Value());
1294
1301
  return name;
1295
1302
}
1296
1303
 
 
1304
// Helper functions for Interceptor/Accessor interaction tests
 
1305
 
 
1306
Handle<Value> SimpleAccessorGetter(Local<String> name,
 
1307
                                   const AccessorInfo& info) {
 
1308
  Handle<Object> self = info.This();
 
1309
  return self->Get(String::Concat(v8_str("accessor_"), name));
 
1310
}
 
1311
 
 
1312
void SimpleAccessorSetter(Local<String> name, Local<Value> value,
 
1313
                          const AccessorInfo& info) {
 
1314
  Handle<Object> self = info.This();
 
1315
  self->Set(String::Concat(v8_str("accessor_"), name), value);
 
1316
}
 
1317
 
 
1318
Handle<Value> EmptyInterceptorGetter(Local<String> name,
 
1319
                                     const AccessorInfo& info) {
 
1320
  return Handle<Value>();
 
1321
}
 
1322
 
 
1323
Handle<Value> EmptyInterceptorSetter(Local<String> name,
 
1324
                                     Local<Value> value,
 
1325
                                     const AccessorInfo& info) {
 
1326
  return Handle<Value>();
 
1327
}
 
1328
 
 
1329
Handle<Value> InterceptorGetter(Local<String> name,
 
1330
                                const AccessorInfo& info) {
 
1331
  // Intercept names that start with 'interceptor_'.
 
1332
  String::AsciiValue ascii(name);
 
1333
  char* name_str = *ascii;
 
1334
  char prefix[] = "interceptor_";
 
1335
  int i;
 
1336
  for (i = 0; name_str[i] && prefix[i]; ++i) {
 
1337
    if (name_str[i] != prefix[i]) return Handle<Value>();
 
1338
  }
 
1339
  Handle<Object> self = info.This();
 
1340
  return self->GetHiddenValue(v8_str(name_str + i));
 
1341
}
 
1342
 
 
1343
Handle<Value> InterceptorSetter(Local<String> name,
 
1344
                                Local<Value> value,
 
1345
                                const AccessorInfo& info) {
 
1346
  // Intercept accesses that set certain integer values.
 
1347
  if (value->IsInt32() && value->Int32Value() < 10000) {
 
1348
    Handle<Object> self = info.This();
 
1349
    self->SetHiddenValue(name, value);
 
1350
    return value;
 
1351
  }
 
1352
  return Handle<Value>();
 
1353
}
 
1354
 
 
1355
void AddAccessor(Handle<FunctionTemplate> templ,
 
1356
                 Handle<String> name,
 
1357
                 v8::AccessorGetter getter,
 
1358
                 v8::AccessorSetter setter) {
 
1359
  templ->PrototypeTemplate()->SetAccessor(name, getter, setter);
 
1360
}
 
1361
 
 
1362
void AddInterceptor(Handle<FunctionTemplate> templ,
 
1363
                    v8::NamedPropertyGetter getter,
 
1364
                    v8::NamedPropertySetter setter) {
 
1365
  templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter);
 
1366
}
 
1367
 
 
1368
THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
 
1369
  v8::HandleScope scope;
 
1370
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1371
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1372
  child->Inherit(parent);
 
1373
  AddAccessor(parent, v8_str("age"),
 
1374
              SimpleAccessorGetter, SimpleAccessorSetter);
 
1375
  AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
 
1376
  LocalContext env;
 
1377
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1378
  CompileRun("var child = new Child;"
 
1379
             "child.age = 10;");
 
1380
  ExpectBoolean("child.hasOwnProperty('age')", false);
 
1381
  ExpectInt32("child.age", 10);
 
1382
  ExpectInt32("child.accessor_age", 10);
 
1383
}
 
1384
 
 
1385
THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) {
 
1386
  v8::HandleScope scope;
 
1387
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1388
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1389
  child->Inherit(parent);
 
1390
  AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
 
1391
  LocalContext env;
 
1392
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1393
  CompileRun("var child = new Child;"
 
1394
             "var parent = child.__proto__;"
 
1395
             "Object.defineProperty(parent, 'age', "
 
1396
             "  {get: function(){ return this.accessor_age; }, "
 
1397
             "   set: function(v){ this.accessor_age = v; }, "
 
1398
             "   enumerable: true, configurable: true});"
 
1399
             "child.age = 10;");
 
1400
  ExpectBoolean("child.hasOwnProperty('age')", false);
 
1401
  ExpectInt32("child.age", 10);
 
1402
  ExpectInt32("child.accessor_age", 10);
 
1403
}
 
1404
 
 
1405
THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) {
 
1406
  v8::HandleScope scope;
 
1407
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1408
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1409
  child->Inherit(parent);
 
1410
  AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
 
1411
  LocalContext env;
 
1412
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1413
  CompileRun("var child = new Child;"
 
1414
             "var parent = child.__proto__;"
 
1415
             "parent.name = 'Alice';");
 
1416
  ExpectBoolean("child.hasOwnProperty('name')", false);
 
1417
  ExpectString("child.name", "Alice");
 
1418
  CompileRun("child.name = 'Bob';");
 
1419
  ExpectString("child.name", "Bob");
 
1420
  ExpectBoolean("child.hasOwnProperty('name')", true);
 
1421
  ExpectString("parent.name", "Alice");
 
1422
}
 
1423
 
 
1424
THREADED_TEST(SwitchFromInterceptorToAccessor) {
 
1425
  v8::HandleScope scope;
 
1426
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1427
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1428
  child->Inherit(parent);
 
1429
  AddAccessor(parent, v8_str("age"),
 
1430
              SimpleAccessorGetter, SimpleAccessorSetter);
 
1431
  AddInterceptor(child, InterceptorGetter, InterceptorSetter);
 
1432
  LocalContext env;
 
1433
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1434
  CompileRun("var child = new Child;"
 
1435
             "function setAge(i){ child.age = i; };"
 
1436
             "for(var i = 0; i <= 10000; i++) setAge(i);");
 
1437
  // All i < 10000 go to the interceptor.
 
1438
  ExpectInt32("child.interceptor_age", 9999);
 
1439
  // The last i goes to the accessor.
 
1440
  ExpectInt32("child.accessor_age", 10000);
 
1441
}
 
1442
 
 
1443
THREADED_TEST(SwitchFromAccessorToInterceptor) {
 
1444
  v8::HandleScope scope;
 
1445
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1446
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1447
  child->Inherit(parent);
 
1448
  AddAccessor(parent, v8_str("age"),
 
1449
              SimpleAccessorGetter, SimpleAccessorSetter);
 
1450
  AddInterceptor(child, InterceptorGetter, InterceptorSetter);
 
1451
  LocalContext env;
 
1452
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1453
  CompileRun("var child = new Child;"
 
1454
             "function setAge(i){ child.age = i; };"
 
1455
             "for(var i = 20000; i >= 9999; i--) setAge(i);");
 
1456
  // All i >= 10000 go to the accessor.
 
1457
  ExpectInt32("child.accessor_age", 10000);
 
1458
  // The last i goes to the interceptor.
 
1459
  ExpectInt32("child.interceptor_age", 9999);
 
1460
}
 
1461
 
 
1462
THREADED_TEST(SwitchFromInterceptorToProperty) {
 
1463
  v8::HandleScope scope;
 
1464
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1465
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1466
  child->Inherit(parent);
 
1467
  AddInterceptor(child, InterceptorGetter, InterceptorSetter);
 
1468
  LocalContext env;
 
1469
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1470
  CompileRun("var child = new Child;"
 
1471
             "function setAge(i){ child.age = i; };"
 
1472
             "for(var i = 0; i <= 10000; i++) setAge(i);");
 
1473
  // All i < 10000 go to the interceptor.
 
1474
  ExpectInt32("child.interceptor_age", 9999);
 
1475
  // The last i goes to child's own property.
 
1476
  ExpectInt32("child.age", 10000);
 
1477
}
 
1478
 
 
1479
THREADED_TEST(SwitchFromPropertyToInterceptor) {
 
1480
  v8::HandleScope scope;
 
1481
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1482
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1483
  child->Inherit(parent);
 
1484
  AddInterceptor(child, InterceptorGetter, InterceptorSetter);
 
1485
  LocalContext env;
 
1486
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1487
  CompileRun("var child = new Child;"
 
1488
             "function setAge(i){ child.age = i; };"
 
1489
             "for(var i = 20000; i >= 9999; i--) setAge(i);");
 
1490
  // All i >= 10000 go to child's own property.
 
1491
  ExpectInt32("child.age", 10000);
 
1492
  // The last i goes to the interceptor.
 
1493
  ExpectInt32("child.interceptor_age", 9999);
 
1494
}
1297
1495
 
1298
1496
THREADED_TEST(NamedPropertyHandlerGetter) {
1299
1497
  echo_named_call_count = 0;
1567
1765
 
1568
1766
  env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
1569
1767
  call_recursively_script = v8_compile("callScriptRecursively()");
1570
 
  v8::Handle<Value> result = call_recursively_script->Run();
 
1768
  v8::Handle<Value> result(call_recursively_script->Run());
1571
1769
  call_recursively_script = v8::Handle<Script>();
1572
1770
 
1573
1771
  env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
1666
1864
 
1667
1865
  // Check reading and writing aligned pointers.
1668
1866
  obj->SetPointerInInternalField(0, aligned);
1669
 
  HEAP->CollectAllGarbage(false);
 
1867
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1670
1868
  CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
1671
1869
 
1672
1870
  // Check reading and writing unaligned pointers.
1673
1871
  obj->SetPointerInInternalField(0, unaligned);
1674
 
  HEAP->CollectAllGarbage(false);
 
1872
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1675
1873
  CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
1676
1874
 
1677
1875
  delete[] data;
1697
1895
  CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1));
1698
1896
 
1699
1897
  obj->SetPointerInInternalField(0, aligned);
1700
 
  HEAP->CollectAllGarbage(false);
 
1898
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1701
1899
  CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0)));
1702
1900
 
1703
1901
  obj->SetPointerInInternalField(0, unaligned);
1704
 
  HEAP->CollectAllGarbage(false);
 
1902
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1705
1903
  CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0)));
1706
1904
 
1707
1905
  obj->SetInternalField(0, v8::External::Wrap(aligned));
1708
 
  HEAP->CollectAllGarbage(false);
 
1906
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1709
1907
  CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
1710
1908
 
1711
1909
  obj->SetInternalField(0, v8::External::Wrap(unaligned));
1712
 
  HEAP->CollectAllGarbage(false);
 
1910
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1713
1911
  CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
1714
1912
 
1715
1913
  delete[] data;
1722
1920
 
1723
1921
  // Ensure that the test starts with an fresh heap to test whether the hash
1724
1922
  // code is based on the address.
1725
 
  HEAP->CollectAllGarbage(false);
 
1923
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1726
1924
  Local<v8::Object> obj = v8::Object::New();
1727
1925
  int hash = obj->GetIdentityHash();
1728
1926
  int hash1 = obj->GetIdentityHash();
1732
1930
  // objects should not be assigned the same hash code. If the test below fails
1733
1931
  // the random number generator should be evaluated.
1734
1932
  CHECK_NE(hash, hash2);
1735
 
  HEAP->CollectAllGarbage(false);
 
1933
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1736
1934
  int hash3 = v8::Object::New()->GetIdentityHash();
1737
1935
  // Make sure that the identity hash is not based on the initial address of
1738
1936
  // the object alone. If the test below fails the random number generator
1769
1967
  v8::Local<v8::String> empty = v8_str("");
1770
1968
  v8::Local<v8::String> prop_name = v8_str("prop_name");
1771
1969
 
1772
 
  HEAP->CollectAllGarbage(false);
 
1970
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1773
1971
 
1774
1972
  // Make sure delete of a non-existent hidden value works
1775
1973
  CHECK(obj->DeleteHiddenValue(key));
1779
1977
  CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002)));
1780
1978
  CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
1781
1979
 
1782
 
  HEAP->CollectAllGarbage(false);
 
1980
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1783
1981
 
1784
1982
  // Make sure we do not find the hidden property.
1785
1983
  CHECK(!obj->Has(empty));
1790
1988
  CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
1791
1989
  CHECK_EQ(2003, obj->Get(empty)->Int32Value());
1792
1990
 
1793
 
  HEAP->CollectAllGarbage(false);
 
1991
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1794
1992
 
1795
1993
  // Add another property and delete it afterwards to force the object in
1796
1994
  // slow case.
1801
1999
  CHECK(obj->Delete(prop_name));
1802
2000
  CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
1803
2001
 
1804
 
  HEAP->CollectAllGarbage(false);
 
2002
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
1805
2003
 
1806
2004
  CHECK(obj->DeleteHiddenValue(key));
1807
2005
  CHECK(obj->GetHiddenValue(key).IsEmpty());
1908
2106
}
1909
2107
 
1910
2108
 
1911
 
static int NumberOfWeakCalls = 0;
 
2109
class WeakCallCounter {
 
2110
 public:
 
2111
  explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { }
 
2112
  int id() { return id_; }
 
2113
  void increment() { number_of_weak_calls_++; }
 
2114
  int NumberOfWeakCalls() { return number_of_weak_calls_; }
 
2115
 private:
 
2116
  int id_;
 
2117
  int number_of_weak_calls_;
 
2118
};
 
2119
 
 
2120
 
1912
2121
static void WeakPointerCallback(Persistent<Value> handle, void* id) {
1913
 
  CHECK_EQ(reinterpret_cast<void*>(1234), id);
1914
 
  NumberOfWeakCalls++;
 
2122
  WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id);
 
2123
  CHECK_EQ(1234, counter->id());
 
2124
  counter->increment();
1915
2125
  handle.Dispose();
1916
2126
}
1917
2127
 
 
2128
 
1918
2129
THREADED_TEST(ApiObjectGroups) {
1919
2130
  HandleScope scope;
1920
2131
  LocalContext env;
1921
2132
 
1922
 
  NumberOfWeakCalls = 0;
1923
 
 
1924
2133
  Persistent<Object> g1s1;
1925
2134
  Persistent<Object> g1s2;
1926
2135
  Persistent<Object> g1c1;
1928
2137
  Persistent<Object> g2s2;
1929
2138
  Persistent<Object> g2c1;
1930
2139
 
 
2140
  WeakCallCounter counter(1234);
 
2141
 
1931
2142
  {
1932
2143
    HandleScope scope;
1933
2144
    g1s1 = Persistent<Object>::New(Object::New());
1934
2145
    g1s2 = Persistent<Object>::New(Object::New());
1935
2146
    g1c1 = Persistent<Object>::New(Object::New());
1936
 
    g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
1937
 
    g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
1938
 
    g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2147
    g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2148
    g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2149
    g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
1939
2150
 
1940
2151
    g2s1 = Persistent<Object>::New(Object::New());
1941
2152
    g2s2 = Persistent<Object>::New(Object::New());
1942
2153
    g2c1 = Persistent<Object>::New(Object::New());
1943
 
    g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
1944
 
    g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
1945
 
    g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2154
    g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2155
    g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2156
    g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
1946
2157
  }
1947
2158
 
1948
2159
  Persistent<Object> root = Persistent<Object>::New(g1s1);  // make a root.
1961
2172
    V8::AddObjectGroup(g2_objects, 2);
1962
2173
    V8::AddImplicitReferences(g2s2, g2_children, 1);
1963
2174
  }
1964
 
  // Do a full GC
1965
 
  HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
 
2175
  // Do a single full GC. Use kMakeHeapIterableMask to ensure that
 
2176
  // incremental garbage collection is stopped.
 
2177
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
1966
2178
 
1967
2179
  // All object should be alive.
1968
 
  CHECK_EQ(0, NumberOfWeakCalls);
 
2180
  CHECK_EQ(0, counter.NumberOfWeakCalls());
1969
2181
 
1970
2182
  // Weaken the root.
1971
 
  root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2183
  root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
1972
2184
  // But make children strong roots---all the objects (except for children)
1973
2185
  // should be collectable now.
1974
2186
  g1c1.ClearWeak();
1986
2198
    V8::AddImplicitReferences(g2s2, g2_children, 1);
1987
2199
  }
1988
2200
 
1989
 
  HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
 
2201
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
1990
2202
 
1991
2203
  // All objects should be gone. 5 global handles in total.
1992
 
  CHECK_EQ(5, NumberOfWeakCalls);
 
2204
  CHECK_EQ(5, counter.NumberOfWeakCalls());
1993
2205
 
1994
2206
  // And now make children weak again and collect them.
1995
 
  g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
1996
 
  g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2207
  g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2208
  g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
1997
2209
 
1998
 
  HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
1999
 
  CHECK_EQ(7, NumberOfWeakCalls);
 
2210
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
 
2211
  CHECK_EQ(7, counter.NumberOfWeakCalls());
2000
2212
}
2001
2213
 
2002
2214
 
2004
2216
  HandleScope scope;
2005
2217
  LocalContext env;
2006
2218
 
2007
 
  NumberOfWeakCalls = 0;
 
2219
  WeakCallCounter counter(1234);
2008
2220
 
2009
2221
  Persistent<Object> g1s1;
2010
2222
  Persistent<Object> g1s2;
2017
2229
    HandleScope scope;
2018
2230
    g1s1 = Persistent<Object>::New(Object::New());
2019
2231
    g1s2 = Persistent<Object>::New(Object::New());
2020
 
    g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
2021
 
    g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2232
    g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2233
    g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
2022
2234
 
2023
2235
    g2s1 = Persistent<Object>::New(Object::New());
2024
2236
    g2s2 = Persistent<Object>::New(Object::New());
2025
 
    g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
2026
 
    g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2237
    g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2238
    g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
2027
2239
 
2028
2240
    g3s1 = Persistent<Object>::New(Object::New());
2029
2241
    g3s2 = Persistent<Object>::New(Object::New());
2030
 
    g3s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
2031
 
    g3s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2242
    g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
 
2243
    g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
2032
2244
  }
2033
2245
 
2034
2246
  Persistent<Object> root = Persistent<Object>::New(g1s1);  // make a root.
2050
2262
    V8::AddObjectGroup(g3_objects, 2);
2051
2263
    V8::AddImplicitReferences(g3s1, g3_children, 1);
2052
2264
  }
2053
 
  // Do a full GC
2054
 
  HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
 
2265
  // Do a single full GC
 
2266
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
2055
2267
 
2056
2268
  // All object should be alive.
2057
 
  CHECK_EQ(0, NumberOfWeakCalls);
 
2269
  CHECK_EQ(0, counter.NumberOfWeakCalls());
2058
2270
 
2059
2271
  // Weaken the root.
2060
 
  root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
 
2272
  root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
2061
2273
 
2062
2274
  // Groups are deleted, rebuild groups.
2063
2275
  {
2075
2287
    V8::AddImplicitReferences(g3s1, g3_children, 1);
2076
2288
  }
2077
2289
 
2078
 
  HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
 
2290
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
2079
2291
 
2080
2292
  // All objects should be gone. 7 global handles in total.
2081
 
  CHECK_EQ(7, NumberOfWeakCalls);
 
2293
  CHECK_EQ(7, counter.NumberOfWeakCalls());
2082
2294
}
2083
2295
 
2084
2296
 
4172
4384
 
4173
4385
  source = v8_str("undetectable.y = 2000;");
4174
4386
  script = Script::Compile(source);
4175
 
  Local<Value> result = script->Run();
 
4387
  Local<Value> result(script->Run());
4176
4388
  ExpectBoolean("undetectable.y == undefined", true);
4177
4389
}
4178
4390
 
4305
4517
}
4306
4518
 
4307
4519
 
 
4520
static const char* kEmbeddedExtensionSource =
 
4521
    "function Ret54321(){return 54321;}~~@@$"
 
4522
    "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS.";
 
4523
static const int kEmbeddedExtensionSourceValidLen = 34;
 
4524
 
 
4525
 
 
4526
THREADED_TEST(ExtensionMissingSourceLength) {
 
4527
  v8::HandleScope handle_scope;
 
4528
  v8::RegisterExtension(new Extension("srclentest_fail",
 
4529
                                      kEmbeddedExtensionSource));
 
4530
  const char* extension_names[] = { "srclentest_fail" };
 
4531
  v8::ExtensionConfiguration extensions(1, extension_names);
 
4532
  v8::Handle<Context> context = Context::New(&extensions);
 
4533
  CHECK_EQ(0, *context);
 
4534
}
 
4535
 
 
4536
 
 
4537
THREADED_TEST(ExtensionWithSourceLength) {
 
4538
  for (int source_len = kEmbeddedExtensionSourceValidLen - 1;
 
4539
       source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) {
 
4540
    v8::HandleScope handle_scope;
 
4541
    i::ScopedVector<char> extension_name(32);
 
4542
    i::OS::SNPrintF(extension_name, "ext #%d", source_len);
 
4543
    v8::RegisterExtension(new Extension(extension_name.start(),
 
4544
                                        kEmbeddedExtensionSource, 0, 0,
 
4545
                                        source_len));
 
4546
    const char* extension_names[1] = { extension_name.start() };
 
4547
    v8::ExtensionConfiguration extensions(1, extension_names);
 
4548
    v8::Handle<Context> context = Context::New(&extensions);
 
4549
    if (source_len == kEmbeddedExtensionSourceValidLen) {
 
4550
      Context::Scope lock(context);
 
4551
      v8::Handle<Value> result = Script::Compile(v8_str("Ret54321()"))->Run();
 
4552
      CHECK_EQ(v8::Integer::New(54321), result);
 
4553
    } else {
 
4554
      // Anything but exactly the right length should fail to compile.
 
4555
      CHECK_EQ(0, *context);
 
4556
    }
 
4557
  }
 
4558
}
 
4559
 
 
4560
 
4308
4561
static const char* kEvalExtensionSource1 =
4309
4562
  "function UseEval1() {"
4310
4563
  "  var x = 42;"
4483
4736
                                                    "native\nfunction foo();"));
4484
4737
  const char* extension_names[] = { name };
4485
4738
  v8::ExtensionConfiguration extensions(1, extension_names);
4486
 
  v8::Handle<Context> context = Context::New(&extensions);
 
4739
  v8::Handle<Context> context(Context::New(&extensions));
4487
4740
  ASSERT(context.IsEmpty());
4488
4741
}
4489
4742
 
4497
4750
      "nativ\\u0065 function foo();"));
4498
4751
  const char* extension_names[] = { name };
4499
4752
  v8::ExtensionConfiguration extensions(1, extension_names);
4500
 
  v8::Handle<Context> context = Context::New(&extensions);
 
4753
  v8::Handle<Context> context(Context::New(&extensions));
4501
4754
  ASSERT(context.IsEmpty());
4502
4755
}
4503
4756
 
4664
4917
  Local<Script> script =
4665
4918
      Script::Compile(String::New(js_code_causing_huge_string_flattening));
4666
4919
  last_location = NULL;
4667
 
  Local<Value> result = script->Run();
 
4920
  Local<Value> result(script->Run());
4668
4921
 
4669
4922
  CHECK(false);  // Should not return.
4670
4923
}
4805
5058
 
4806
5059
 
4807
5060
static void InvokeMarkSweep() {
4808
 
  HEAP->CollectAllGarbage(false);
 
5061
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
4809
5062
}
4810
5063
 
4811
5064
 
4898
5151
  CHECK_EQ(v8::Integer::New(3), args[2]);
4899
5152
  CHECK_EQ(v8::Undefined(), args[3]);
4900
5153
  v8::HandleScope scope;
4901
 
  HEAP->CollectAllGarbage(false);
 
5154
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
4902
5155
  return v8::Undefined();
4903
5156
}
4904
5157
 
5185
5438
 
5186
5439
 
5187
5440
THREADED_TEST(StringWrite) {
 
5441
  LocalContext context;
5188
5442
  v8::HandleScope scope;
5189
5443
  v8::Handle<String> str = v8_str("abcde");
5190
5444
  // abc<Icelandic eth><Unicode snowman>.
5191
5445
  v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203");
 
5446
  const int kStride = 4;  // Must match stride in for loops in JS below.
 
5447
  CompileRun(
 
5448
      "var left = '';"
 
5449
      "for (var i = 0; i < 0xd800; i += 4) {"
 
5450
      "  left = left + String.fromCharCode(i);"
 
5451
      "}");
 
5452
  CompileRun(
 
5453
      "var right = '';"
 
5454
      "for (var i = 0; i < 0xd800; i += 4) {"
 
5455
      "  right = String.fromCharCode(i) + right;"
 
5456
      "}");
 
5457
  v8::Handle<v8::Object> global = Context::GetCurrent()->Global();
 
5458
  Handle<String> left_tree = global->Get(v8_str("left")).As<String>();
 
5459
  Handle<String> right_tree = global->Get(v8_str("right")).As<String>();
5192
5460
 
5193
5461
  CHECK_EQ(5, str2->Length());
 
5462
  CHECK_EQ(0xd800 / kStride, left_tree->Length());
 
5463
  CHECK_EQ(0xd800 / kStride, right_tree->Length());
5194
5464
 
5195
5465
  char buf[100];
5196
 
  char utf8buf[100];
 
5466
  char utf8buf[0xd800 * 3];
5197
5467
  uint16_t wbuf[100];
5198
5468
  int len;
5199
5469
  int charlen;
5200
5470
 
5201
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5471
  memset(utf8buf, 0x1, 1000);
5202
5472
  len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen);
5203
5473
  CHECK_EQ(9, len);
5204
5474
  CHECK_EQ(5, charlen);
5205
5475
  CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203"));
5206
5476
 
5207
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5477
  memset(utf8buf, 0x1, 1000);
5208
5478
  len = str2->WriteUtf8(utf8buf, 8, &charlen);
5209
5479
  CHECK_EQ(8, len);
5210
5480
  CHECK_EQ(5, charlen);
5211
5481
  CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\342\230\203\1", 9));
5212
5482
 
5213
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5483
  memset(utf8buf, 0x1, 1000);
5214
5484
  len = str2->WriteUtf8(utf8buf, 7, &charlen);
5215
5485
  CHECK_EQ(5, len);
5216
5486
  CHECK_EQ(4, charlen);
5217
5487
  CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
5218
5488
 
5219
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5489
  memset(utf8buf, 0x1, 1000);
5220
5490
  len = str2->WriteUtf8(utf8buf, 6, &charlen);
5221
5491
  CHECK_EQ(5, len);
5222
5492
  CHECK_EQ(4, charlen);
5223
5493
  CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
5224
5494
 
5225
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5495
  memset(utf8buf, 0x1, 1000);
5226
5496
  len = str2->WriteUtf8(utf8buf, 5, &charlen);
5227
5497
  CHECK_EQ(5, len);
5228
5498
  CHECK_EQ(4, charlen);
5229
5499
  CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
5230
5500
 
5231
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5501
  memset(utf8buf, 0x1, 1000);
5232
5502
  len = str2->WriteUtf8(utf8buf, 4, &charlen);
5233
5503
  CHECK_EQ(3, len);
5234
5504
  CHECK_EQ(3, charlen);
5235
5505
  CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
5236
5506
 
5237
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5507
  memset(utf8buf, 0x1, 1000);
5238
5508
  len = str2->WriteUtf8(utf8buf, 3, &charlen);
5239
5509
  CHECK_EQ(3, len);
5240
5510
  CHECK_EQ(3, charlen);
5241
5511
  CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
5242
5512
 
5243
 
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5513
  memset(utf8buf, 0x1, 1000);
5244
5514
  len = str2->WriteUtf8(utf8buf, 2, &charlen);
5245
5515
  CHECK_EQ(2, len);
5246
5516
  CHECK_EQ(2, charlen);
5247
5517
  CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3));
5248
5518
 
 
5519
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5520
  len = left_tree->Utf8Length();
 
5521
  int utf8_expected =
 
5522
      (0x80 + (0x800 - 0x80) * 2 + (0xd800 - 0x800) * 3) / kStride;
 
5523
  CHECK_EQ(utf8_expected, len);
 
5524
  len = left_tree->WriteUtf8(utf8buf, utf8_expected, &charlen);
 
5525
  CHECK_EQ(utf8_expected, len);
 
5526
  CHECK_EQ(0xd800 / kStride, charlen);
 
5527
  CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[utf8_expected - 3]));
 
5528
  CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[utf8_expected - 2]));
 
5529
  CHECK_EQ(0xc0 - kStride,
 
5530
           static_cast<unsigned char>(utf8buf[utf8_expected - 1]));
 
5531
  CHECK_EQ(1, utf8buf[utf8_expected]);
 
5532
 
 
5533
  memset(utf8buf, 0x1, sizeof(utf8buf));
 
5534
  len = right_tree->Utf8Length();
 
5535
  CHECK_EQ(utf8_expected, len);
 
5536
  len = right_tree->WriteUtf8(utf8buf, utf8_expected, &charlen);
 
5537
  CHECK_EQ(utf8_expected, len);
 
5538
  CHECK_EQ(0xd800 / kStride, charlen);
 
5539
  CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[0]));
 
5540
  CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[1]));
 
5541
  CHECK_EQ(0xc0 - kStride, static_cast<unsigned char>(utf8buf[2]));
 
5542
  CHECK_EQ(1, utf8buf[utf8_expected]);
 
5543
 
5249
5544
  memset(buf, 0x1, sizeof(buf));
5250
5545
  memset(wbuf, 0x1, sizeof(wbuf));
5251
5546
  len = str->WriteAscii(buf);
5400
5695
  v8::Handle<String> message = v8_str("message");
5401
5696
  v8::Handle<Value> range_error = v8::Exception::RangeError(foo);
5402
5697
  CHECK(range_error->IsObject());
5403
 
  v8::Handle<v8::Object> range_obj = range_error.As<v8::Object>();
 
5698
  v8::Handle<v8::Object> range_obj(range_error.As<v8::Object>());
5404
5699
  CHECK(range_error.As<v8::Object>()->Get(message)->Equals(foo));
5405
5700
  v8::Handle<Value> reference_error = v8::Exception::ReferenceError(foo);
5406
5701
  CHECK(reference_error->IsObject());
6970
7265
    // Create new environment reusing the global object.
6971
7266
    LocalContext env(NULL, instance_template, global_object);
6972
7267
    env->Global()->Set(v8_str("foo"), foo);
6973
 
    Local<Value> value = Script::Compile(v8_str("foo()"))->Run();
 
7268
    Local<Value> value(Script::Compile(v8_str("foo()"))->Run());
6974
7269
  }
6975
7270
}
6976
7271
 
7158
7453
}
7159
7454
 
7160
7455
 
 
7456
// Getting property names of an object with a prototype chain that
 
7457
// triggers dictionary elements in GetLocalPropertyNames() shouldn't
 
7458
// crash the runtime.
 
7459
THREADED_TEST(Regress91517) {
 
7460
  i::FLAG_allow_natives_syntax = true;
 
7461
  v8::HandleScope handle_scope;
 
7462
  LocalContext context;
 
7463
 
 
7464
  Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
 
7465
  t1->SetHiddenPrototype(true);
 
7466
  t1->InstanceTemplate()->Set(v8_str("foo"), v8_num(1));
 
7467
  Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
 
7468
  t2->SetHiddenPrototype(true);
 
7469
  t2->InstanceTemplate()->Set(v8_str("fuz1"), v8_num(2));
 
7470
  t2->InstanceTemplate()->Set(v8_str("objects"), v8::Object::New());
 
7471
  t2->InstanceTemplate()->Set(v8_str("fuz2"), v8_num(2));
 
7472
  Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
 
7473
  t3->SetHiddenPrototype(true);
 
7474
  t3->InstanceTemplate()->Set(v8_str("boo"), v8_num(3));
 
7475
  Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
 
7476
  t4->InstanceTemplate()->Set(v8_str("baz"), v8_num(4));
 
7477
 
 
7478
  // Force dictionary-based properties.
 
7479
  i::ScopedVector<char> name_buf(1024);
 
7480
  for (int i = 1; i <= 1000; i++) {
 
7481
    i::OS::SNPrintF(name_buf, "sdf%d", i);
 
7482
    t2->InstanceTemplate()->Set(v8_str(name_buf.start()), v8_num(2));
 
7483
  }
 
7484
 
 
7485
  Local<v8::Object> o1 = t1->GetFunction()->NewInstance();
 
7486
  Local<v8::Object> o2 = t2->GetFunction()->NewInstance();
 
7487
  Local<v8::Object> o3 = t3->GetFunction()->NewInstance();
 
7488
  Local<v8::Object> o4 = t4->GetFunction()->NewInstance();
 
7489
 
 
7490
  // Create prototype chain of hidden prototypes.
 
7491
  CHECK(o4->SetPrototype(o3));
 
7492
  CHECK(o3->SetPrototype(o2));
 
7493
  CHECK(o2->SetPrototype(o1));
 
7494
 
 
7495
  // Call the runtime version of GetLocalPropertyNames() on the natively
 
7496
  // created object through JavaScript.
 
7497
  context->Global()->Set(v8_str("obj"), o4);
 
7498
  CompileRun("var names = %GetLocalPropertyNames(obj);");
 
7499
 
 
7500
  ExpectInt32("names.length", 1006);
 
7501
  ExpectTrue("names.indexOf(\"baz\") >= 0");
 
7502
  ExpectTrue("names.indexOf(\"boo\") >= 0");
 
7503
  ExpectTrue("names.indexOf(\"foo\") >= 0");
 
7504
  ExpectTrue("names.indexOf(\"fuz1\") >= 0");
 
7505
  ExpectTrue("names.indexOf(\"fuz2\") >= 0");
 
7506
  ExpectFalse("names[1005] == undefined");
 
7507
}
 
7508
 
 
7509
 
7161
7510
THREADED_TEST(FunctionReadOnlyPrototype) {
7162
7511
  v8::HandleScope handle_scope;
7163
7512
  LocalContext context;
7241
7590
  Local<Function> cons = templ->GetFunction();
7242
7591
  context->Global()->Set(v8_str("Fun"), cons);
7243
7592
  Local<v8::Object> inst = cons->NewInstance();
7244
 
  i::Handle<i::JSObject> obj = v8::Utils::OpenHandle(*inst);
 
7593
  i::Handle<i::JSObject> obj(v8::Utils::OpenHandle(*inst));
7245
7594
  Local<Value> value = CompileRun("(new Fun()).constructor === Fun");
7246
7595
  CHECK(value->BooleanValue());
7247
7596
}
7492
7841
                           "  var bar = 2;"
7493
7842
                           "  with (x) { return eval('bar'); }"
7494
7843
                           "}"
7495
 
                           "f(this)"));
 
7844
                           "result4 = f(this)"));
7496
7845
  script->Run();
7497
 
  CHECK(try_catch.HasCaught());
 
7846
  CHECK(!try_catch.HasCaught());
 
7847
  CHECK_EQ(2, current->Global()->Get(v8_str("result4"))->Int32Value());
 
7848
 
7498
7849
  try_catch.Reset();
7499
7850
}
7500
7851
 
7710
8061
  }
7711
8062
 
7712
8063
  { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
7713
 
    Local<ObjectTemplate> instance_template = t->InstanceTemplate();
 
8064
    Local<ObjectTemplate> instance_template(t->InstanceTemplate());
7714
8065
    Local<v8::Object> instance = t->GetFunction()->NewInstance();
7715
8066
    context->Global()->Set(v8_str("obj2"), instance);
7716
8067
    v8::TryCatch try_catch;
7815
8166
  v8::HandleScope scope;
7816
8167
  if (depth == 0) return CountHandles();
7817
8168
  for (int i = 0; i < iterations; i++) {
7818
 
    Local<v8::Number> n = v8::Integer::New(42);
 
8169
    Local<v8::Number> n(v8::Integer::New(42));
7819
8170
  }
7820
8171
  return Recurse(depth - 1, iterations);
7821
8172
}
7829
8180
    v8::HandleScope scope1;
7830
8181
    CHECK_EQ(0, CountHandles());
7831
8182
    for (int i = 0; i < kIterations; i++) {
7832
 
      Local<v8::Number> n = v8::Integer::New(42);
 
8183
      Local<v8::Number> n(v8::Integer::New(42));
7833
8184
      CHECK_EQ(i + 1, CountHandles());
7834
8185
    }
7835
8186
 
7837
8188
    {
7838
8189
      v8::HandleScope scope2;
7839
8190
      for (int j = 0; j < kIterations; j++) {
7840
 
        Local<v8::Number> n = v8::Integer::New(42);
 
8191
        Local<v8::Number> n(v8::Integer::New(42));
7841
8192
        CHECK_EQ(j + 1 + kIterations, CountHandles());
7842
8193
      }
7843
8194
    }
7883
8234
    Local<String> name,
7884
8235
    const AccessorInfo& info) {
7885
8236
  ApiTestFuzzer::Fuzz();
7886
 
  HEAP->CollectAllGarbage(false);
 
8237
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
7887
8238
  return v8::Handle<Value>();
7888
8239
}
7889
8240
 
8340
8691
                                 0, 0, 0, v8_str("data"));
8341
8692
  LocalContext context;
8342
8693
  context->Global()->Set(v8_str("o"), templ->NewInstance());
8343
 
  v8::Handle<Value> value = CompileRun(
 
8694
  v8::Handle<Value> value(CompileRun(
8344
8695
    "for (var i = 0; i < 1000; i++) {"
8345
8696
    "  o.x = 42;"
8346
 
    "}");
 
8697
    "}"));
8347
8698
}
8348
8699
 
8349
8700
 
8613
8964
  int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
8614
8965
  ++(*call_count);
8615
8966
  if ((*call_count) % 20 == 0) {
8616
 
    HEAP->CollectAllGarbage(true);
 
8967
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
8617
8968
  }
8618
8969
  return v8::Handle<Value>();
8619
8970
}
8769
9120
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
8770
9121
  GenerateSomeGarbage();
8771
9122
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8772
 
  v8::Handle<Value> value = CompileRun(
 
9123
  v8::Handle<Value> value(CompileRun(
8773
9124
      "var result = 0;"
8774
9125
      "for (var i = 0; i < 100; i++) {"
8775
9126
      "  result = o.method(41);"
8776
 
      "}");
 
9127
      "}"));
8777
9128
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
8778
9129
  CHECK_EQ(100, interceptor_call_count);
8779
9130
}
8796
9147
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
8797
9148
  GenerateSomeGarbage();
8798
9149
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8799
 
  v8::Handle<Value> value = CompileRun(
 
9150
  v8::Handle<Value> value(CompileRun(
8800
9151
      "o.foo = 17;"
8801
9152
      "var receiver = {};"
8802
9153
      "receiver.__proto__ = o;"
8803
9154
      "var result = 0;"
8804
9155
      "for (var i = 0; i < 100; i++) {"
8805
9156
      "  result = receiver.method(41);"
8806
 
      "}");
 
9157
      "}"));
8807
9158
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
8808
9159
  CHECK_EQ(100, interceptor_call_count);
8809
9160
}
8826
9177
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
8827
9178
  GenerateSomeGarbage();
8828
9179
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8829
 
  v8::Handle<Value> value = CompileRun(
 
9180
  v8::Handle<Value> value(CompileRun(
8830
9181
      "o.foo = 17;"
8831
9182
      "var receiver = {};"
8832
9183
      "receiver.__proto__ = o;"
8838
9189
      "    saved_result = result;"
8839
9190
      "    receiver = {method: function(x) { return x - 1 }};"
8840
9191
      "  }"
8841
 
      "}");
 
9192
      "}"));
8842
9193
  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
8843
9194
  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
8844
9195
  CHECK_GE(interceptor_call_count, 50);
8862
9213
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
8863
9214
  GenerateSomeGarbage();
8864
9215
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8865
 
  v8::Handle<Value> value = CompileRun(
 
9216
  v8::Handle<Value> value(CompileRun(
8866
9217
      "o.foo = 17;"
8867
9218
      "var receiver = {};"
8868
9219
      "receiver.__proto__ = o;"
8874
9225
      "    saved_result = result;"
8875
9226
      "    o.method = function(x) { return x - 1 };"
8876
9227
      "  }"
8877
 
      "}");
 
9228
      "}"));
8878
9229
  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
8879
9230
  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
8880
9231
  CHECK_GE(interceptor_call_count, 50);
8899
9250
  GenerateSomeGarbage();
8900
9251
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8901
9252
  v8::TryCatch try_catch;
8902
 
  v8::Handle<Value> value = CompileRun(
 
9253
  v8::Handle<Value> value(CompileRun(
8903
9254
      "o.foo = 17;"
8904
9255
      "var receiver = {};"
8905
9256
      "receiver.__proto__ = o;"
8911
9262
      "    saved_result = result;"
8912
9263
      "    receiver = 333;"
8913
9264
      "  }"
8914
 
      "}");
 
9265
      "}"));
8915
9266
  CHECK(try_catch.HasCaught());
8916
9267
  CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
8917
9268
           try_catch.Exception()->ToString());
8938
9289
  GenerateSomeGarbage();
8939
9290
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8940
9291
  v8::TryCatch try_catch;
8941
 
  v8::Handle<Value> value = CompileRun(
 
9292
  v8::Handle<Value> value(CompileRun(
8942
9293
      "o.foo = 17;"
8943
9294
      "var receiver = {};"
8944
9295
      "receiver.__proto__ = o;"
8950
9301
      "    saved_result = result;"
8951
9302
      "    receiver = {method: receiver.method};"
8952
9303
      "  }"
8953
 
      "}");
 
9304
      "}"));
8954
9305
  CHECK(try_catch.HasCaught());
8955
9306
  CHECK_EQ(v8_str("TypeError: Illegal invocation"),
8956
9307
           try_catch.Exception()->ToString());
8967
9318
                                v8::Handle<v8::Signature>());
8968
9319
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
8969
9320
  proto_templ->Set(v8_str("method"), method_templ);
8970
 
  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
 
9321
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
8971
9322
  LocalContext context;
8972
9323
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
8973
9324
  GenerateSomeGarbage();
8974
9325
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8975
 
  v8::Handle<Value> value = CompileRun(
 
9326
  v8::Handle<Value> value(CompileRun(
8976
9327
      "var result = 0;"
8977
9328
      "for (var i = 0; i < 100; i++) {"
8978
9329
      "  result = o.method(41);"
8979
 
      "}");
 
9330
      "}"));
8980
9331
 
8981
9332
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
8982
9333
}
8990
9341
                                v8::Signature::New(fun_templ));
8991
9342
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
8992
9343
  proto_templ->Set(v8_str("method"), method_templ);
8993
 
  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
 
9344
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
8994
9345
  LocalContext context;
8995
9346
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
8996
9347
  GenerateSomeGarbage();
8997
9348
  context->Global()->Set(v8_str("o"), fun->NewInstance());
8998
 
  v8::Handle<Value> value = CompileRun(
 
9349
  v8::Handle<Value> value(CompileRun(
8999
9350
      "o.foo = 17;"
9000
9351
      "var receiver = {};"
9001
9352
      "receiver.__proto__ = o;"
9002
9353
      "var result = 0;"
9003
9354
      "for (var i = 0; i < 100; i++) {"
9004
9355
      "  result = receiver.method(41);"
9005
 
      "}");
 
9356
      "}"));
9006
9357
 
9007
9358
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
9008
9359
}
9016
9367
                                v8::Signature::New(fun_templ));
9017
9368
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
9018
9369
  proto_templ->Set(v8_str("method"), method_templ);
9019
 
  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
 
9370
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
9020
9371
  LocalContext context;
9021
9372
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9022
9373
  GenerateSomeGarbage();
9023
9374
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9024
 
  v8::Handle<Value> value = CompileRun(
 
9375
  v8::Handle<Value> value(CompileRun(
9025
9376
      "o.foo = 17;"
9026
9377
      "var receiver = {};"
9027
9378
      "receiver.__proto__ = o;"
9033
9384
      "    saved_result = result;"
9034
9385
      "    receiver = {method: function(x) { return x - 1 }};"
9035
9386
      "  }"
9036
 
      "}");
 
9387
      "}"));
9037
9388
  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
9038
9389
  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
9039
9390
}
9047
9398
                                v8::Signature::New(fun_templ));
9048
9399
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
9049
9400
  proto_templ->Set(v8_str("method"), method_templ);
9050
 
  v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
 
9401
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
9051
9402
  LocalContext context;
9052
9403
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9053
9404
  GenerateSomeGarbage();
9054
9405
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9055
9406
  v8::TryCatch try_catch;
9056
 
  v8::Handle<Value> value = CompileRun(
 
9407
  v8::Handle<Value> value(CompileRun(
9057
9408
      "o.foo = 17;"
9058
9409
      "var receiver = {};"
9059
9410
      "receiver.__proto__ = o;"
9065
9416
      "    saved_result = result;"
9066
9417
      "    receiver = 333;"
9067
9418
      "  }"
9068
 
      "}");
 
9419
      "}"));
9069
9420
  CHECK(try_catch.HasCaught());
9070
9421
  CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
9071
9422
           try_catch.Exception()->ToString());
9093
9444
  templ->SetNamedPropertyHandler(NoBlockGetterX);
9094
9445
  LocalContext context;
9095
9446
  context->Global()->Set(v8_str("o"), templ->NewInstance());
9096
 
  v8::Handle<Value> value = CompileRun(
 
9447
  v8::Handle<Value> value(CompileRun(
9097
9448
    "proto = new Object();"
9098
9449
    "proto.y = function(x) { return x + 1; };"
9099
9450
    "proto.z = function(x) { return x - 1; };"
9103
9454
    "for (var i = 0; i < 10; i++) {"
9104
9455
    "  if (i == 5) { method = 'z'; };"
9105
9456
    "  result += o[method](41);"
9106
 
    "}");
 
9457
    "}"));
9107
9458
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9108
9459
}
9109
9460
 
9119
9470
  context->Global()->Set(v8_str("proto1"), templ->NewInstance());
9120
9471
  keyed_call_ic_function =
9121
9472
      v8_compile("function f(x) { return x - 1; }; f")->Run();
9122
 
  v8::Handle<Value> value = CompileRun(
 
9473
  v8::Handle<Value> value(CompileRun(
9123
9474
    "o = new Object();"
9124
9475
    "proto2 = new Object();"
9125
9476
    "o.y = function(x) { return x + 1; };"
9131
9482
    "for (var i = 0; i < 10; i++) {"
9132
9483
    "  if (i == 5) { method = 'y'; };"
9133
9484
    "  result += o[method](41);"
9134
 
    "}");
 
9485
    "}"));
9135
9486
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9136
9487
}
9137
9488
 
9144
9495
  templ->SetNamedPropertyHandler(NoBlockGetterX);
9145
9496
  LocalContext context;
9146
9497
  context->Global()->Set(v8_str("o"), templ->NewInstance());
9147
 
  v8::Handle<Value> value = CompileRun(
 
9498
  v8::Handle<Value> value(CompileRun(
9148
9499
    "function inc(x) { return x + 1; };"
9149
9500
    "inc(1);"
9150
9501
    "function dec(x) { return x - 1; };"
9157
9508
    "for (var i = 0; i < 10; i++) {"
9158
9509
    "  if (i == 5) { method = 'y'; };"
9159
9510
    "  result += o[method](41);"
9160
 
    "}");
 
9511
    "}"));
9161
9512
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9162
9513
}
9163
9514
 
9170
9521
  LocalContext context;
9171
9522
  context->Global()->Set(v8_str("o"), templ_o->NewInstance());
9172
9523
 
9173
 
  v8::Handle<Value> value = CompileRun(
 
9524
  v8::Handle<Value> value(CompileRun(
9174
9525
    "function len(x) { return x.length; };"
9175
9526
    "o.__proto__ = this;"
9176
9527
    "var m = 'parseFloat';"
9181
9532
    "    saved_result = result;"
9182
9533
    "  };"
9183
9534
    "  result = o[m]('239');"
9184
 
    "}");
 
9535
    "}"));
9185
9536
  CHECK_EQ(3, context->Global()->Get(v8_str("result"))->Int32Value());
9186
9537
  CHECK_EQ(239, context->Global()->Get(v8_str("saved_result"))->Int32Value());
9187
9538
}
9194
9545
  LocalContext context;
9195
9546
  context->Global()->Set(v8_str("proto"), templ_o->NewInstance());
9196
9547
 
9197
 
  v8::Handle<Value> value = CompileRun(
 
9548
  v8::Handle<Value> value(CompileRun(
9198
9549
    "var o = new Object();"
9199
9550
    "o.__proto__ = proto;"
9200
9551
    "o.method = function(x) { return x + 1; };"
9203
9554
    "for (var i = 0; i < 10; i++) {"
9204
9555
    "  if (i == 5) { o.method = function(x) { return x - 1; }; };"
9205
9556
    "  result += o[m](41);"
9206
 
    "}");
 
9557
    "}"));
9207
9558
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9208
9559
}
9209
9560
 
9216
9567
  LocalContext context;
9217
9568
  context->Global()->Set(v8_str("o"), templ_o->NewInstance());
9218
9569
 
9219
 
  v8::Handle<Value> value = CompileRun(
 
9570
  v8::Handle<Value> value(CompileRun(
9220
9571
    "var proto = new Object();"
9221
9572
    "o.__proto__ = proto;"
9222
9573
    "proto.method = function(x) { return x + 1; };"
9225
9576
    "for (var i = 0; i < 10; i++) {"
9226
9577
    "  if (i == 5) { proto.method = function(x) { return x - 1; }; };"
9227
9578
    "  result += o[m](41);"
9228
 
    "}");
 
9579
    "}"));
9229
9580
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9230
9581
}
9231
9582
 
9964
10315
 
9965
10316
 
9966
10317
static int GetGlobalObjectsCount() {
 
10318
  i::Isolate::Current()->heap()->EnsureHeapIsIterable();
9967
10319
  int count = 0;
9968
10320
  i::HeapIterator it;
9969
10321
  for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
9978
10330
  // the first garbage collection but some of the maps have already
9979
10331
  // been marked at that point.  Therefore some of the maps are not
9980
10332
  // collected until the second garbage collection.
9981
 
  HEAP->global_context_map();
9982
 
  HEAP->CollectAllGarbage(false);
9983
 
  HEAP->CollectAllGarbage(false);
 
10333
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 
10334
  HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
9984
10335
  int count = GetGlobalObjectsCount();
9985
10336
#ifdef DEBUG
9986
10337
  if (count != expected) HEAP->TracePathToGlobal();
10049
10400
  // weak callback of the first handle would be able to 'reallocate' it.
10050
10401
  handle1.MakeWeak(NULL, NewPersistentHandleCallback);
10051
10402
  handle2.Dispose();
10052
 
  HEAP->CollectAllGarbage(false);
 
10403
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
10053
10404
}
10054
10405
 
10055
10406
 
10057
10408
 
10058
10409
void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) {
10059
10410
  to_be_disposed.Dispose();
10060
 
  HEAP->CollectAllGarbage(false);
 
10411
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
10061
10412
  handle.Dispose();
10062
10413
}
10063
10414
 
10073
10424
  }
10074
10425
  handle1.MakeWeak(NULL, DisposeAndForceGcCallback);
10075
10426
  to_be_disposed = handle2;
10076
 
  HEAP->CollectAllGarbage(false);
 
10427
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
10077
10428
}
10078
10429
 
10079
10430
void DisposingCallback(v8::Persistent<v8::Value> handle, void*) {
10099
10450
  }
10100
10451
  handle2.MakeWeak(NULL, DisposingCallback);
10101
10452
  handle3.MakeWeak(NULL, HandleCreatingCallback);
10102
 
  HEAP->CollectAllGarbage(false);
 
10453
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
10103
10454
}
10104
10455
 
10105
10456
 
10141
10492
  v8::Persistent<Context> env = Context::New();
10142
10493
  env->Enter();
10143
10494
  v8::Handle<Value> value = NestedScope(env);
10144
 
  v8::Handle<String> str = value->ToString();
 
10495
  v8::Handle<String> str(value->ToString());
10145
10496
  env->Exit();
10146
10497
  env.Dispose();
10147
10498
}
10149
10500
 
10150
10501
THREADED_TEST(ExternalAllocatedMemory) {
10151
10502
  v8::HandleScope outer;
10152
 
  v8::Persistent<Context> env = Context::New();
 
10503
  v8::Persistent<Context> env(Context::New());
10153
10504
  const int kSize = 1024*1024;
10154
10505
  CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize), kSize);
10155
10506
  CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize), 0);
10487
10838
  i::Handle<i::FunctionTemplateInfo> constructor(
10488
10839
      i::FunctionTemplateInfo::cast(internal_template->constructor()));
10489
10840
  CHECK(!constructor->access_check_info()->IsUndefined());
10490
 
  v8::Persistent<Context> context0 = Context::New(NULL, global_template);
 
10841
  v8::Persistent<Context> context0(Context::New(NULL, global_template));
10491
10842
  CHECK(!constructor->access_check_info()->IsUndefined());
10492
10843
}
10493
10844
 
10915
11266
      {
10916
11267
        v8::Locker lock;
10917
11268
        // TODO(lrn): Perhaps create some garbage before collecting.
10918
 
        HEAP->CollectAllGarbage(false);
 
11269
        HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
10919
11270
        gc_count_++;
10920
11271
      }
10921
11272
      i::OS::Sleep(1);
11037
11388
    while (gc_during_apply_ < kRequiredGCs) {
11038
11389
      {
11039
11390
        v8::Locker lock;
11040
 
        HEAP->CollectAllGarbage(false);
 
11391
        HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
11041
11392
        gc_count_++;
11042
11393
      }
11043
11394
      i::OS::Sleep(1);
11187
11538
// Test that we can still flatten a string if the components it is built up
11188
11539
// from have been turned into 16 bit strings in the mean time.
11189
11540
THREADED_TEST(MorphCompositeStringTest) {
 
11541
  char utf_buffer[129];
11190
11542
  const char* c_string = "Now is the time for all good men"
11191
11543
                         " to come to the aid of the party";
11192
11544
  uint16_t* two_byte_string = AsciiToTwoByteString(c_string);
11215
11567
    MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource);
11216
11568
    MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource);
11217
11569
 
 
11570
    // This should UTF-8 without flattening, since everything is ASCII.
 
11571
    Handle<String> cons = v8_compile("cons")->Run().As<String>();
 
11572
    CHECK_EQ(128, cons->Utf8Length());
 
11573
    int nchars = -1;
 
11574
    CHECK_EQ(129, cons->WriteUtf8(utf_buffer, -1, &nchars));
 
11575
    CHECK_EQ(128, nchars);
 
11576
    CHECK_EQ(0, strcmp(
 
11577
        utf_buffer,
 
11578
        "Now is the time for all good men to come to the aid of the party"
 
11579
        "Now is the time for all good men to come to the aid of the party"));
 
11580
 
11218
11581
    // Now do some stuff to make sure the strings are flattened, etc.
11219
11582
    CompileRun(
11220
11583
        "/[^a-z]/.test(cons);"
11753
12116
  i::Handle<i::ExternalPixelArray> pixels =
11754
12117
      i::Handle<i::ExternalPixelArray>::cast(
11755
12118
          FACTORY->NewExternalArray(kElementCount,
11756
 
                                       v8::kExternalPixelArray,
11757
 
                                       pixel_data));
11758
 
  HEAP->CollectAllGarbage(false);  // Force GC to trigger verification.
 
12119
                                    v8::kExternalPixelArray,
 
12120
                                    pixel_data));
 
12121
  // Force GC to trigger verification.
 
12122
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
11759
12123
  for (int i = 0; i < kElementCount; i++) {
11760
12124
    pixels->set(i, i % 256);
11761
12125
  }
11762
 
  HEAP->CollectAllGarbage(false);  // Force GC to trigger verification.
 
12126
  // Force GC to trigger verification.
 
12127
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
11763
12128
  for (int i = 0; i < kElementCount; i++) {
11764
12129
    CHECK_EQ(i % 256, pixels->get_scalar(i));
11765
12130
    CHECK_EQ(i % 256, pixel_data[i]);
12235
12600
  i::Handle<ExternalArrayClass> array =
12236
12601
      i::Handle<ExternalArrayClass>::cast(
12237
12602
          FACTORY->NewExternalArray(kElementCount, array_type, array_data));
12238
 
  HEAP->CollectAllGarbage(false);  // Force GC to trigger verification.
 
12603
  // Force GC to trigger verification.
 
12604
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
12239
12605
  for (int i = 0; i < kElementCount; i++) {
12240
12606
    array->set(i, static_cast<ElementType>(i));
12241
12607
  }
12242
 
  HEAP->CollectAllGarbage(false);  // Force GC to trigger verification.
 
12608
  // Force GC to trigger verification.
 
12609
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
12243
12610
  for (int i = 0; i < kElementCount; i++) {
12244
12611
    CHECK_EQ(static_cast<int64_t>(i),
12245
12612
             static_cast<int64_t>(array->get_scalar(i)));
12357
12724
                      "  }"
12358
12725
                      "}"
12359
12726
                      "sum;");
12360
 
  HEAP->CollectAllGarbage(false);  // Force GC to trigger verification.
 
12727
  // Force GC to trigger verification.
 
12728
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
12361
12729
  CHECK_EQ(28, result->Int32Value());
12362
12730
 
12363
12731
  // Make sure out-of-range loads do not throw.
12546
12914
    const int kLargeElementCount = kXSize * kYSize * 4;
12547
12915
    ElementType* large_array_data =
12548
12916
        static_cast<ElementType*>(malloc(kLargeElementCount * element_size));
12549
 
    i::Handle<ExternalArrayClass> large_array =
 
12917
    i::Handle<ExternalArrayClass> large_array(
12550
12918
        i::Handle<ExternalArrayClass>::cast(
12551
12919
            FACTORY->NewExternalArray(kLargeElementCount,
12552
 
                                         array_type,
12553
 
                                         array_data));
 
12920
                                      array_type,
 
12921
                                      array_data)));
12554
12922
    v8::Handle<v8::Object> large_obj = v8::Object::New();
12555
12923
    // Set the elements to be the external array.
12556
12924
    large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data,
12949
13317
    "}\n"
12950
13318
    "var x;eval('new foo();');";
12951
13319
  v8::Handle<v8::String> overview_src = v8::String::New(overview_source);
12952
 
  v8::Handle<Value> overview_result =
12953
 
      v8::Script::New(overview_src, origin)->Run();
 
13320
  v8::Handle<Value> overview_result(
 
13321
      v8::Script::New(overview_src, origin)->Run());
12954
13322
  ASSERT(!overview_result.IsEmpty());
12955
13323
  ASSERT(overview_result->IsObject());
12956
13324
 
12970
13338
  v8::ScriptOrigin detailed_origin(origin, line_offset, column_offset);
12971
13339
  v8::Handle<v8::Script> detailed_script(
12972
13340
      v8::Script::New(detailed_src, &detailed_origin));
12973
 
  v8::Handle<Value> detailed_result = detailed_script->Run();
 
13341
  v8::Handle<Value> detailed_result(detailed_script->Run());
12974
13342
  ASSERT(!detailed_result.IsEmpty());
12975
13343
  ASSERT(detailed_result->IsObject());
12976
13344
}
13250
13618
    } else {
13251
13619
      uint64_t stored_bits = DoubleToBits(stored_number);
13252
13620
      // Check if quiet nan (bits 51..62 all set).
 
13621
#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
 
13622
      // Most significant fraction bit for quiet nan is set to 0
 
13623
      // on MIPS architecture. Allowed by IEEE-754.
 
13624
      CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
 
13625
#else
13253
13626
      CHECK_EQ(0xfff, static_cast<int>((stored_bits >> 51) & 0xfff));
 
13627
#endif
13254
13628
    }
13255
13629
 
13256
13630
    // Check that Date::New preserves non-NaNs in the date range and
13263
13637
    } else {
13264
13638
      uint64_t stored_bits = DoubleToBits(stored_date);
13265
13639
      // Check if quiet nan (bits 51..62 all set).
 
13640
#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
 
13641
      // Most significant fraction bit for quiet nan is set to 0
 
13642
      // on MIPS architecture. Allowed by IEEE-754.
 
13643
      CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
 
13644
#else
13266
13645
      CHECK_EQ(0xfff, static_cast<int>((stored_bits >> 51) & 0xfff));
 
13646
#endif
13267
13647
    }
13268
13648
  }
13269
13649
}
13272
13652
static v8::Handle<Value> SpaghettiIncident(const v8::Arguments& args) {
13273
13653
  v8::HandleScope scope;
13274
13654
  v8::TryCatch tc;
13275
 
  v8::Handle<v8::String> str = args[0]->ToString();
 
13655
  v8::Handle<v8::String> str(args[0]->ToString());
13276
13656
  if (tc.HasCaught())
13277
13657
    return tc.ReThrow();
13278
13658
  return v8::Undefined();
13337
13717
    other_context->Enter();
13338
13718
    CompileRun(source_simple);
13339
13719
    other_context->Exit();
13340
 
    HEAP->CollectAllGarbage(false);
 
13720
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13341
13721
    if (GetGlobalObjectsCount() == 1) break;
13342
13722
  }
13343
13723
  CHECK_GE(2, gc_count);
13359
13739
    other_context->Enter();
13360
13740
    CompileRun(source_eval);
13361
13741
    other_context->Exit();
13362
 
    HEAP->CollectAllGarbage(false);
 
13742
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13363
13743
    if (GetGlobalObjectsCount() == 1) break;
13364
13744
  }
13365
13745
  CHECK_GE(2, gc_count);
13386
13766
    other_context->Enter();
13387
13767
    CompileRun(source_exception);
13388
13768
    other_context->Exit();
13389
 
    HEAP->CollectAllGarbage(false);
 
13769
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13390
13770
    if (GetGlobalObjectsCount() == 1) break;
13391
13771
  }
13392
13772
  CHECK_GE(2, gc_count);
13434
13814
}
13435
13815
 
13436
13816
 
 
13817
THREADED_TEST(ScriptColumnNumber) {
 
13818
  v8::HandleScope scope;
 
13819
  LocalContext env;
 
13820
  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"),
 
13821
      v8::Integer::New(3), v8::Integer::New(2));
 
13822
  v8::Handle<v8::String> script = v8::String::New(
 
13823
      "function foo() {}\n\n     function bar() {}");
 
13824
  v8::Script::Compile(script, &origin)->Run();
 
13825
  v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
 
13826
      env->Global()->Get(v8::String::New("foo")));
 
13827
  v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
 
13828
      env->Global()->Get(v8::String::New("bar")));
 
13829
  CHECK_EQ(14, foo->GetScriptColumnNumber());
 
13830
  CHECK_EQ(17, bar->GetScriptColumnNumber());
 
13831
}
 
13832
 
 
13833
 
 
13834
THREADED_TEST(FunctionGetScriptId) {
 
13835
  v8::HandleScope scope;
 
13836
  LocalContext env;
 
13837
  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"),
 
13838
      v8::Integer::New(3), v8::Integer::New(2));
 
13839
  v8::Handle<v8::String> scriptSource = v8::String::New(
 
13840
      "function foo() {}\n\n     function bar() {}");
 
13841
  v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin));
 
13842
  script->Run();
 
13843
  v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
 
13844
      env->Global()->Get(v8::String::New("foo")));
 
13845
  v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
 
13846
      env->Global()->Get(v8::String::New("bar")));
 
13847
  CHECK_EQ(script->Id(), foo->GetScriptId());
 
13848
  CHECK_EQ(script->Id(), bar->GetScriptId());
 
13849
}
 
13850
 
 
13851
 
13437
13852
static v8::Handle<Value> GetterWhichReturns42(Local<String> name,
13438
13853
                                              const AccessorInfo& info) {
13439
13854
  return v8_num(42);
13604
14019
  v8::V8::AddGCEpilogueCallback(EpilogueCallback);
13605
14020
  CHECK_EQ(0, prologue_call_count);
13606
14021
  CHECK_EQ(0, epilogue_call_count);
13607
 
  HEAP->CollectAllGarbage(false);
 
14022
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13608
14023
  CHECK_EQ(1, prologue_call_count);
13609
14024
  CHECK_EQ(1, epilogue_call_count);
13610
14025
  v8::V8::AddGCPrologueCallback(PrologueCallbackSecond);
13611
14026
  v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond);
13612
 
  HEAP->CollectAllGarbage(false);
 
14027
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13613
14028
  CHECK_EQ(2, prologue_call_count);
13614
14029
  CHECK_EQ(2, epilogue_call_count);
13615
14030
  CHECK_EQ(1, prologue_call_count_second);
13616
14031
  CHECK_EQ(1, epilogue_call_count_second);
13617
14032
  v8::V8::RemoveGCPrologueCallback(PrologueCallback);
13618
14033
  v8::V8::RemoveGCEpilogueCallback(EpilogueCallback);
13619
 
  HEAP->CollectAllGarbage(false);
 
14034
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13620
14035
  CHECK_EQ(2, prologue_call_count);
13621
14036
  CHECK_EQ(2, epilogue_call_count);
13622
14037
  CHECK_EQ(2, prologue_call_count_second);
13623
14038
  CHECK_EQ(2, epilogue_call_count_second);
13624
14039
  v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond);
13625
14040
  v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond);
13626
 
  HEAP->CollectAllGarbage(false);
 
14041
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13627
14042
  CHECK_EQ(2, prologue_call_count);
13628
14043
  CHECK_EQ(2, epilogue_call_count);
13629
14044
  CHECK_EQ(2, prologue_call_count_second);
13840
14255
void FailedAccessCheckCallbackGC(Local<v8::Object> target,
13841
14256
                                 v8::AccessType type,
13842
14257
                                 Local<v8::Value> data) {
13843
 
  HEAP->CollectAllGarbage(true);
 
14258
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
13844
14259
}
13845
14260
 
13846
14261
 
14414
14829
                 "})()",
14415
14830
                 "ReferenceError: cell is not defined");
14416
14831
    CompileRun("cell = \"new_second\";");
14417
 
    HEAP->CollectAllGarbage(true);
 
14832
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
14418
14833
    ExpectString("readCell()", "new_second");
14419
14834
    ExpectString("readCell()", "new_second");
14420
14835
  }
14535
14950
 
14536
14951
  // RegExps are objects on which you can set properties.
14537
14952
  re->Set(v8_str("property"), v8::Integer::New(32));
14538
 
  v8::Handle<v8::Value> value = CompileRun("re.property");
 
14953
  v8::Handle<v8::Value> value(CompileRun("re.property"));
14539
14954
  ASSERT_EQ(32, value->Int32Value());
14540
14955
 
14541
14956
  v8::TryCatch try_catch;