~ubuntu-branches/ubuntu/saucy/libv8/saucy

« 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-04-07 16:26:13 UTC
  • mfrom: (15.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120407162613-dqo1m6w9r3fh8tst
Tags: 3.8.9.16-3
* mipsel build fixes :
  + v8_use_mips_abi_hardfloat=false, this lowers EABI requirements.
  + v8_can_use_fpu_instructions=false, detect if FPU is present.
  + set -Wno-unused-but-set-variable only on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
1189
1189
  templ->Set("x", v8_num(200));
1190
1190
  templ->SetAccessor(v8_str("m"), GetM);
1191
1191
  LocalContext env(0, templ);
1192
 
  v8::Handle<v8::Object> obj(env->Global());
1193
1192
  v8::Handle<Script> script(v8_compile("dummy()"));
1194
1193
  v8::Handle<Value> result(script->Run());
1195
1194
  CHECK_EQ(13.4, result->NumberValue());
1423
1422
 
1424
1423
THREADED_TEST(SwitchFromInterceptorToAccessor) {
1425
1424
  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"),
 
1425
  Handle<FunctionTemplate> templ = FunctionTemplate::New();
 
1426
  AddAccessor(templ, v8_str("age"),
1430
1427
              SimpleAccessorGetter, SimpleAccessorSetter);
1431
 
  AddInterceptor(child, InterceptorGetter, InterceptorSetter);
 
1428
  AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
1432
1429
  LocalContext env;
1433
 
  env->Global()->Set(v8_str("Child"), child->GetFunction());
1434
 
  CompileRun("var child = new Child;"
1435
 
             "function setAge(i){ child.age = i; };"
 
1430
  env->Global()->Set(v8_str("Obj"), templ->GetFunction());
 
1431
  CompileRun("var obj = new Obj;"
 
1432
             "function setAge(i){ obj.age = i; };"
1436
1433
             "for(var i = 0; i <= 10000; i++) setAge(i);");
1437
1434
  // All i < 10000 go to the interceptor.
1438
 
  ExpectInt32("child.interceptor_age", 9999);
 
1435
  ExpectInt32("obj.interceptor_age", 9999);
1439
1436
  // The last i goes to the accessor.
1440
 
  ExpectInt32("child.accessor_age", 10000);
 
1437
  ExpectInt32("obj.accessor_age", 10000);
1441
1438
}
1442
1439
 
1443
1440
THREADED_TEST(SwitchFromAccessorToInterceptor) {
1444
1441
  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);
 
1442
  Handle<FunctionTemplate> templ = FunctionTemplate::New();
 
1443
  AddAccessor(templ, v8_str("age"),
 
1444
              SimpleAccessorGetter, SimpleAccessorSetter);
 
1445
  AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
 
1446
  LocalContext env;
 
1447
  env->Global()->Set(v8_str("Obj"), templ->GetFunction());
 
1448
  CompileRun("var obj = new Obj;"
 
1449
             "function setAge(i){ obj.age = i; };"
 
1450
             "for(var i = 20000; i >= 9999; i--) setAge(i);");
 
1451
  // All i >= 10000 go to the accessor.
 
1452
  ExpectInt32("obj.accessor_age", 10000);
 
1453
  // The last i goes to the interceptor.
 
1454
  ExpectInt32("obj.interceptor_age", 9999);
 
1455
}
 
1456
 
 
1457
THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) {
 
1458
  v8::HandleScope scope;
 
1459
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1460
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1461
  child->Inherit(parent);
 
1462
  AddAccessor(parent, v8_str("age"),
 
1463
              SimpleAccessorGetter, SimpleAccessorSetter);
 
1464
  AddInterceptor(child, InterceptorGetter, InterceptorSetter);
 
1465
  LocalContext env;
 
1466
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1467
  CompileRun("var child = new Child;"
 
1468
             "function setAge(i){ child.age = i; };"
 
1469
             "for(var i = 0; i <= 10000; i++) setAge(i);");
 
1470
  // All i < 10000 go to the interceptor.
 
1471
  ExpectInt32("child.interceptor_age", 9999);
 
1472
  // The last i goes to the accessor.
 
1473
  ExpectInt32("child.accessor_age", 10000);
 
1474
}
 
1475
 
 
1476
THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) {
 
1477
  v8::HandleScope scope;
 
1478
  Handle<FunctionTemplate> parent = FunctionTemplate::New();
 
1479
  Handle<FunctionTemplate> child = FunctionTemplate::New();
 
1480
  child->Inherit(parent);
 
1481
  AddAccessor(parent, v8_str("age"),
 
1482
              SimpleAccessorGetter, SimpleAccessorSetter);
 
1483
  AddInterceptor(child, InterceptorGetter, InterceptorSetter);
 
1484
  LocalContext env;
 
1485
  env->Global()->Set(v8_str("Child"), child->GetFunction());
 
1486
  CompileRun("var child = new Child;"
 
1487
             "function setAge(i){ child.age = i; };"
 
1488
             "for(var i = 20000; i >= 9999; i--) setAge(i);");
 
1489
  // All i >= 10000 go to the accessor.
 
1490
  ExpectInt32("child.accessor_age", 10000);
 
1491
  // The last i goes to the interceptor.
 
1492
  ExpectInt32("child.interceptor_age", 9999);
 
1493
}
 
1494
 
 
1495
THREADED_TEST(SwitchFromInterceptorToJSAccessor) {
 
1496
  v8::HandleScope scope;
 
1497
  Handle<FunctionTemplate> templ = FunctionTemplate::New();
 
1498
  AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
 
1499
  LocalContext env;
 
1500
  env->Global()->Set(v8_str("Obj"), templ->GetFunction());
 
1501
  CompileRun("var obj = new Obj;"
 
1502
             "function setter(i) { this.accessor_age = i; };"
 
1503
             "function getter() { return this.accessor_age; };"
 
1504
             "function setAge(i) { obj.age = i; };"
 
1505
             "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
 
1506
             "for(var i = 0; i <= 10000; i++) setAge(i);");
 
1507
  // All i < 10000 go to the interceptor.
 
1508
  ExpectInt32("obj.interceptor_age", 9999);
 
1509
  // The last i goes to the JavaScript accessor.
 
1510
  ExpectInt32("obj.accessor_age", 10000);
 
1511
  // The installed JavaScript getter is still intact.
 
1512
  // This last part is a regression test for issue 1651 and relies on the fact
 
1513
  // that both interceptor and accessor are being installed on the same object.
 
1514
  ExpectInt32("obj.age", 10000);
 
1515
  ExpectBoolean("obj.hasOwnProperty('age')", true);
 
1516
  ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value");
 
1517
}
 
1518
 
 
1519
THREADED_TEST(SwitchFromJSAccessorToInterceptor) {
 
1520
  v8::HandleScope scope;
 
1521
  Handle<FunctionTemplate> templ = FunctionTemplate::New();
 
1522
  AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
 
1523
  LocalContext env;
 
1524
  env->Global()->Set(v8_str("Obj"), templ->GetFunction());
 
1525
  CompileRun("var obj = new Obj;"
 
1526
             "function setter(i) { this.accessor_age = i; };"
 
1527
             "function getter() { return this.accessor_age; };"
 
1528
             "function setAge(i) { obj.age = i; };"
 
1529
             "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
 
1530
             "for(var i = 20000; i >= 9999; i--) setAge(i);");
 
1531
  // All i >= 10000 go to the accessor.
 
1532
  ExpectInt32("obj.accessor_age", 10000);
 
1533
  // The last i goes to the interceptor.
 
1534
  ExpectInt32("obj.interceptor_age", 9999);
 
1535
  // The installed JavaScript getter is still intact.
 
1536
  // This last part is a regression test for issue 1651 and relies on the fact
 
1537
  // that both interceptor and accessor are being installed on the same object.
 
1538
  ExpectInt32("obj.age", 10000);
 
1539
  ExpectBoolean("obj.hasOwnProperty('age')", true);
 
1540
  ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value");
1460
1541
}
1461
1542
 
1462
1543
THREADED_TEST(SwitchFromInterceptorToProperty) {
1765
1846
 
1766
1847
  env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
1767
1848
  call_recursively_script = v8_compile("callScriptRecursively()");
1768
 
  v8::Handle<Value> result(call_recursively_script->Run());
 
1849
  call_recursively_script->Run();
1769
1850
  call_recursively_script = v8::Handle<Script>();
1770
1851
 
1771
1852
  env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
2785
2866
  obj = env->Global()->Get(v8_str("obj"));
2786
2867
  CHECK(!obj->IsInt32());
2787
2868
  CHECK(!obj->IsUint32());
 
2869
  // Positive zero
 
2870
  CompileRun("var obj = 0.0;");
 
2871
  obj = env->Global()->Get(v8_str("obj"));
 
2872
  CHECK(obj->IsInt32());
 
2873
  CHECK(obj->IsUint32());
 
2874
  // Positive zero
 
2875
  CompileRun("var obj = -0.0;");
 
2876
  obj = env->Global()->Get(v8_str("obj"));
 
2877
  CHECK(!obj->IsInt32());
 
2878
  CHECK(!obj->IsUint32());
2788
2879
}
2789
2880
 
2790
2881
 
4384
4475
 
4385
4476
  source = v8_str("undetectable.y = 2000;");
4386
4477
  script = Script::Compile(source);
4387
 
  Local<Value> result(script->Run());
 
4478
  script->Run();
4388
4479
  ExpectBoolean("undetectable.y == undefined", true);
4389
4480
}
4390
4481
 
4737
4828
  const char* extension_names[] = { name };
4738
4829
  v8::ExtensionConfiguration extensions(1, extension_names);
4739
4830
  v8::Handle<Context> context(Context::New(&extensions));
4740
 
  ASSERT(context.IsEmpty());
 
4831
  CHECK(context.IsEmpty());
4741
4832
}
4742
4833
 
 
4834
 
4743
4835
THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
4744
4836
  v8::HandleScope handle_scope;
4745
4837
  const char* name = "nativedeclerresc";
4751
4843
  const char* extension_names[] = { name };
4752
4844
  v8::ExtensionConfiguration extensions(1, extension_names);
4753
4845
  v8::Handle<Context> context(Context::New(&extensions));
4754
 
  ASSERT(context.IsEmpty());
 
4846
  CHECK(context.IsEmpty());
4755
4847
}
4756
4848
 
4757
4849
 
4917
5009
  Local<Script> script =
4918
5010
      Script::Compile(String::New(js_code_causing_huge_string_flattening));
4919
5011
  last_location = NULL;
4920
 
  Local<Value> result(script->Run());
 
5012
  script->Run();
4921
5013
 
4922
5014
  CHECK(false);  // Should not return.
4923
5015
}
5695
5787
  v8::Handle<String> message = v8_str("message");
5696
5788
  v8::Handle<Value> range_error = v8::Exception::RangeError(foo);
5697
5789
  CHECK(range_error->IsObject());
5698
 
  v8::Handle<v8::Object> range_obj(range_error.As<v8::Object>());
5699
5790
  CHECK(range_error.As<v8::Object>()->Get(message)->Equals(foo));
5700
5791
  v8::Handle<Value> reference_error = v8::Exception::ReferenceError(foo);
5701
5792
  CHECK(reference_error->IsObject());
7265
7356
    // Create new environment reusing the global object.
7266
7357
    LocalContext env(NULL, instance_template, global_object);
7267
7358
    env->Global()->Set(v8_str("foo"), foo);
7268
 
    Local<Value> value(Script::Compile(v8_str("foo()"))->Run());
 
7359
    Script::Compile(v8_str("foo()"))->Run();
7269
7360
  }
7270
7361
}
7271
7362
 
7591
7682
  context->Global()->Set(v8_str("Fun"), cons);
7592
7683
  Local<v8::Object> inst = cons->NewInstance();
7593
7684
  i::Handle<i::JSObject> obj(v8::Utils::OpenHandle(*inst));
 
7685
  CHECK(obj->IsJSObject());
7594
7686
  Local<Value> value = CompileRun("(new Fun()).constructor === Fun");
7595
7687
  CHECK(value->BooleanValue());
7596
7688
}
7859
7951
  other->SetSecurityToken(token);
7860
7952
  current->SetSecurityToken(token);
7861
7953
 
7862
 
  // Setup reference from current to other.
 
7954
  // Set up reference from current to other.
7863
7955
  current->Global()->Set(v8_str("other"), other->Global());
7864
7956
 
7865
7957
  // Check that new variables are introduced in other context.
7939
8031
  v8::Persistent<Context> context0 = Context::New();
7940
8032
  v8::Persistent<Context> context1 = Context::New();
7941
8033
 
7942
 
  // Setup function in context0 that uses eval from context0.
 
8034
  // Set up function in context0 that uses eval from context0.
7943
8035
  context0->Enter();
7944
8036
  v8::Handle<v8::Value> fun =
7945
8037
      CompileRun("var x = 42;"
7977
8069
  other->SetSecurityToken(token);
7978
8070
  current->SetSecurityToken(token);
7979
8071
 
7980
 
  // Setup reference from current to other.
 
8072
  // Set up reference from current to other.
7981
8073
  current->Global()->Set(v8_str("other"), other->Global());
7982
8074
 
7983
8075
  // Trigger lazy loading in other context.
8062
8154
 
8063
8155
  { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
8064
8156
    Local<ObjectTemplate> instance_template(t->InstanceTemplate());
 
8157
    USE(instance_template);
8065
8158
    Local<v8::Object> instance = t->GetFunction()->NewInstance();
8066
8159
    context->Global()->Set(v8_str("obj2"), instance);
8067
8160
    v8::TryCatch try_catch;
8691
8784
                                 0, 0, 0, v8_str("data"));
8692
8785
  LocalContext context;
8693
8786
  context->Global()->Set(v8_str("o"), templ->NewInstance());
8694
 
  v8::Handle<Value> value(CompileRun(
8695
 
    "for (var i = 0; i < 1000; i++) {"
8696
 
    "  o.x = 42;"
8697
 
    "}"));
 
8787
  CompileRun(
 
8788
      "for (var i = 0; i < 1000; i++) {"
 
8789
      "  o.x = 42;"
 
8790
      "}");
8698
8791
}
8699
8792
 
8700
8793
 
8820
8913
}
8821
8914
 
8822
8915
 
8823
 
static v8::Handle<Value> call_ic_function5;
8824
 
static v8::Handle<Value> InterceptorCallICGetter5(Local<String> name,
8825
 
                                                  const AccessorInfo& info) {
8826
 
  ApiTestFuzzer::Fuzz();
8827
 
  if (v8_str("x")->Equals(name))
8828
 
    return call_ic_function5;
8829
 
  else
8830
 
    return Local<Value>();
8831
 
}
8832
 
 
8833
 
 
8834
8916
// This test checks that if interceptor doesn't provide a function,
8835
8917
// cached constant function is used
8836
8918
THREADED_TEST(InterceptorCallICConstantFunctionUsed) {
8851
8933
}
8852
8934
 
8853
8935
 
 
8936
static v8::Handle<Value> call_ic_function5;
 
8937
static v8::Handle<Value> InterceptorCallICGetter5(Local<String> name,
 
8938
                                                  const AccessorInfo& info) {
 
8939
  ApiTestFuzzer::Fuzz();
 
8940
  if (v8_str("x")->Equals(name))
 
8941
    return call_ic_function5;
 
8942
  else
 
8943
    return Local<Value>();
 
8944
}
 
8945
 
 
8946
 
8854
8947
// This test checks that if interceptor provides a function,
8855
8948
// even if we cached constant function, interceptor's function
8856
8949
// is invoked
8874
8967
}
8875
8968
 
8876
8969
 
 
8970
static v8::Handle<Value> call_ic_function6;
 
8971
static v8::Handle<Value> InterceptorCallICGetter6(Local<String> name,
 
8972
                                                  const AccessorInfo& info) {
 
8973
  ApiTestFuzzer::Fuzz();
 
8974
  if (v8_str("x")->Equals(name))
 
8975
    return call_ic_function6;
 
8976
  else
 
8977
    return Local<Value>();
 
8978
}
 
8979
 
 
8980
 
 
8981
// Same test as above, except the code is wrapped in a function
 
8982
// to test the optimized compiler.
 
8983
THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) {
 
8984
  i::FLAG_allow_natives_syntax = true;
 
8985
  v8::HandleScope scope;
 
8986
  v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
 
8987
  templ->SetNamedPropertyHandler(InterceptorCallICGetter6);
 
8988
  LocalContext context;
 
8989
  context->Global()->Set(v8_str("o"), templ->NewInstance());
 
8990
  call_ic_function6 =
 
8991
      v8_compile("function f(x) { return x - 1; }; f")->Run();
 
8992
  v8::Handle<Value> value = CompileRun(
 
8993
    "function inc(x) { return x + 1; };"
 
8994
    "inc(1);"
 
8995
    "o.x = inc;"
 
8996
    "function test() {"
 
8997
    "  var result = 0;"
 
8998
    "  for (var i = 0; i < 1000; i++) {"
 
8999
    "    result = o.x(42);"
 
9000
    "  }"
 
9001
    "  return result;"
 
9002
    "};"
 
9003
    "test();"
 
9004
    "test();"
 
9005
    "test();"
 
9006
    "%OptimizeFunctionOnNextCall(test);"
 
9007
    "test()");
 
9008
  CHECK_EQ(41, value->Int32Value());
 
9009
}
 
9010
 
 
9011
 
8877
9012
// Test the case when we stored constant function into
8878
9013
// a stub, but it got invalidated later on
8879
9014
THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) {
9120
9255
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9121
9256
  GenerateSomeGarbage();
9122
9257
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9123
 
  v8::Handle<Value> value(CompileRun(
 
9258
  CompileRun(
9124
9259
      "var result = 0;"
9125
9260
      "for (var i = 0; i < 100; i++) {"
9126
9261
      "  result = o.method(41);"
9127
 
      "}"));
 
9262
      "}");
9128
9263
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
9129
9264
  CHECK_EQ(100, interceptor_call_count);
9130
9265
}
9147
9282
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9148
9283
  GenerateSomeGarbage();
9149
9284
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9150
 
  v8::Handle<Value> value(CompileRun(
 
9285
  CompileRun(
9151
9286
      "o.foo = 17;"
9152
9287
      "var receiver = {};"
9153
9288
      "receiver.__proto__ = o;"
9154
9289
      "var result = 0;"
9155
9290
      "for (var i = 0; i < 100; i++) {"
9156
9291
      "  result = receiver.method(41);"
9157
 
      "}"));
 
9292
      "}");
9158
9293
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
9159
9294
  CHECK_EQ(100, interceptor_call_count);
9160
9295
}
9177
9312
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9178
9313
  GenerateSomeGarbage();
9179
9314
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9180
 
  v8::Handle<Value> value(CompileRun(
 
9315
  CompileRun(
9181
9316
      "o.foo = 17;"
9182
9317
      "var receiver = {};"
9183
9318
      "receiver.__proto__ = o;"
9189
9324
      "    saved_result = result;"
9190
9325
      "    receiver = {method: function(x) { return x - 1 }};"
9191
9326
      "  }"
9192
 
      "}"));
 
9327
      "}");
9193
9328
  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
9194
9329
  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
9195
9330
  CHECK_GE(interceptor_call_count, 50);
9213
9348
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9214
9349
  GenerateSomeGarbage();
9215
9350
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9216
 
  v8::Handle<Value> value(CompileRun(
 
9351
  CompileRun(
9217
9352
      "o.foo = 17;"
9218
9353
      "var receiver = {};"
9219
9354
      "receiver.__proto__ = o;"
9225
9360
      "    saved_result = result;"
9226
9361
      "    o.method = function(x) { return x - 1 };"
9227
9362
      "  }"
9228
 
      "}"));
 
9363
      "}");
9229
9364
  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
9230
9365
  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
9231
9366
  CHECK_GE(interceptor_call_count, 50);
9250
9385
  GenerateSomeGarbage();
9251
9386
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9252
9387
  v8::TryCatch try_catch;
9253
 
  v8::Handle<Value> value(CompileRun(
 
9388
  CompileRun(
9254
9389
      "o.foo = 17;"
9255
9390
      "var receiver = {};"
9256
9391
      "receiver.__proto__ = o;"
9262
9397
      "    saved_result = result;"
9263
9398
      "    receiver = 333;"
9264
9399
      "  }"
9265
 
      "}"));
 
9400
      "}");
9266
9401
  CHECK(try_catch.HasCaught());
9267
9402
  CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
9268
9403
           try_catch.Exception()->ToString());
9289
9424
  GenerateSomeGarbage();
9290
9425
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9291
9426
  v8::TryCatch try_catch;
9292
 
  v8::Handle<Value> value(CompileRun(
 
9427
  CompileRun(
9293
9428
      "o.foo = 17;"
9294
9429
      "var receiver = {};"
9295
9430
      "receiver.__proto__ = o;"
9301
9436
      "    saved_result = result;"
9302
9437
      "    receiver = {method: receiver.method};"
9303
9438
      "  }"
9304
 
      "}"));
 
9439
      "}");
9305
9440
  CHECK(try_catch.HasCaught());
9306
9441
  CHECK_EQ(v8_str("TypeError: Illegal invocation"),
9307
9442
           try_catch.Exception()->ToString());
9319
9454
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
9320
9455
  proto_templ->Set(v8_str("method"), method_templ);
9321
9456
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
 
9457
  USE(templ);
9322
9458
  LocalContext context;
9323
9459
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9324
9460
  GenerateSomeGarbage();
9325
9461
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9326
 
  v8::Handle<Value> value(CompileRun(
 
9462
  CompileRun(
9327
9463
      "var result = 0;"
9328
9464
      "for (var i = 0; i < 100; i++) {"
9329
9465
      "  result = o.method(41);"
9330
 
      "}"));
 
9466
      "}");
9331
9467
 
9332
9468
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
9333
9469
}
9342
9478
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
9343
9479
  proto_templ->Set(v8_str("method"), method_templ);
9344
9480
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
 
9481
  CHECK(!templ.IsEmpty());
9345
9482
  LocalContext context;
9346
9483
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9347
9484
  GenerateSomeGarbage();
9348
9485
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9349
 
  v8::Handle<Value> value(CompileRun(
 
9486
  CompileRun(
9350
9487
      "o.foo = 17;"
9351
9488
      "var receiver = {};"
9352
9489
      "receiver.__proto__ = o;"
9353
9490
      "var result = 0;"
9354
9491
      "for (var i = 0; i < 100; i++) {"
9355
9492
      "  result = receiver.method(41);"
9356
 
      "}"));
 
9493
      "}");
9357
9494
 
9358
9495
  CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
9359
9496
}
9368
9505
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
9369
9506
  proto_templ->Set(v8_str("method"), method_templ);
9370
9507
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
 
9508
  CHECK(!templ.IsEmpty());
9371
9509
  LocalContext context;
9372
9510
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9373
9511
  GenerateSomeGarbage();
9374
9512
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9375
 
  v8::Handle<Value> value(CompileRun(
 
9513
  CompileRun(
9376
9514
      "o.foo = 17;"
9377
9515
      "var receiver = {};"
9378
9516
      "receiver.__proto__ = o;"
9384
9522
      "    saved_result = result;"
9385
9523
      "    receiver = {method: function(x) { return x - 1 }};"
9386
9524
      "  }"
9387
 
      "}"));
 
9525
      "}");
9388
9526
  CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value());
9389
9527
  CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
9390
9528
}
9399
9537
  v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
9400
9538
  proto_templ->Set(v8_str("method"), method_templ);
9401
9539
  v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
 
9540
  CHECK(!templ.IsEmpty());
9402
9541
  LocalContext context;
9403
9542
  v8::Handle<v8::Function> fun = fun_templ->GetFunction();
9404
9543
  GenerateSomeGarbage();
9405
9544
  context->Global()->Set(v8_str("o"), fun->NewInstance());
9406
9545
  v8::TryCatch try_catch;
9407
 
  v8::Handle<Value> value(CompileRun(
 
9546
  CompileRun(
9408
9547
      "o.foo = 17;"
9409
9548
      "var receiver = {};"
9410
9549
      "receiver.__proto__ = o;"
9416
9555
      "    saved_result = result;"
9417
9556
      "    receiver = 333;"
9418
9557
      "  }"
9419
 
      "}"));
 
9558
      "}");
9420
9559
  CHECK(try_catch.HasCaught());
9421
9560
  CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
9422
9561
           try_catch.Exception()->ToString());
9444
9583
  templ->SetNamedPropertyHandler(NoBlockGetterX);
9445
9584
  LocalContext context;
9446
9585
  context->Global()->Set(v8_str("o"), templ->NewInstance());
9447
 
  v8::Handle<Value> value(CompileRun(
 
9586
  CompileRun(
9448
9587
    "proto = new Object();"
9449
9588
    "proto.y = function(x) { return x + 1; };"
9450
9589
    "proto.z = function(x) { return x - 1; };"
9454
9593
    "for (var i = 0; i < 10; i++) {"
9455
9594
    "  if (i == 5) { method = 'z'; };"
9456
9595
    "  result += o[method](41);"
9457
 
    "}"));
 
9596
    "}");
9458
9597
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9459
9598
}
9460
9599
 
9470
9609
  context->Global()->Set(v8_str("proto1"), templ->NewInstance());
9471
9610
  keyed_call_ic_function =
9472
9611
      v8_compile("function f(x) { return x - 1; }; f")->Run();
9473
 
  v8::Handle<Value> value(CompileRun(
 
9612
  CompileRun(
9474
9613
    "o = new Object();"
9475
9614
    "proto2 = new Object();"
9476
9615
    "o.y = function(x) { return x + 1; };"
9482
9621
    "for (var i = 0; i < 10; i++) {"
9483
9622
    "  if (i == 5) { method = 'y'; };"
9484
9623
    "  result += o[method](41);"
9485
 
    "}"));
 
9624
    "}");
9486
9625
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9487
9626
}
9488
9627
 
9495
9634
  templ->SetNamedPropertyHandler(NoBlockGetterX);
9496
9635
  LocalContext context;
9497
9636
  context->Global()->Set(v8_str("o"), templ->NewInstance());
9498
 
  v8::Handle<Value> value(CompileRun(
 
9637
  CompileRun(
9499
9638
    "function inc(x) { return x + 1; };"
9500
9639
    "inc(1);"
9501
9640
    "function dec(x) { return x - 1; };"
9508
9647
    "for (var i = 0; i < 10; i++) {"
9509
9648
    "  if (i == 5) { method = 'y'; };"
9510
9649
    "  result += o[method](41);"
9511
 
    "}"));
 
9650
    "}");
9512
9651
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9513
9652
}
9514
9653
 
9521
9660
  LocalContext context;
9522
9661
  context->Global()->Set(v8_str("o"), templ_o->NewInstance());
9523
9662
 
9524
 
  v8::Handle<Value> value(CompileRun(
 
9663
  CompileRun(
9525
9664
    "function len(x) { return x.length; };"
9526
9665
    "o.__proto__ = this;"
9527
9666
    "var m = 'parseFloat';"
9532
9671
    "    saved_result = result;"
9533
9672
    "  };"
9534
9673
    "  result = o[m]('239');"
9535
 
    "}"));
 
9674
    "}");
9536
9675
  CHECK_EQ(3, context->Global()->Get(v8_str("result"))->Int32Value());
9537
9676
  CHECK_EQ(239, context->Global()->Get(v8_str("saved_result"))->Int32Value());
9538
9677
}
9545
9684
  LocalContext context;
9546
9685
  context->Global()->Set(v8_str("proto"), templ_o->NewInstance());
9547
9686
 
9548
 
  v8::Handle<Value> value(CompileRun(
 
9687
  CompileRun(
9549
9688
    "var o = new Object();"
9550
9689
    "o.__proto__ = proto;"
9551
9690
    "o.method = function(x) { return x + 1; };"
9554
9693
    "for (var i = 0; i < 10; i++) {"
9555
9694
    "  if (i == 5) { o.method = function(x) { return x - 1; }; };"
9556
9695
    "  result += o[m](41);"
9557
 
    "}"));
 
9696
    "}");
9558
9697
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9559
9698
}
9560
9699
 
9567
9706
  LocalContext context;
9568
9707
  context->Global()->Set(v8_str("o"), templ_o->NewInstance());
9569
9708
 
9570
 
  v8::Handle<Value> value(CompileRun(
 
9709
  CompileRun(
9571
9710
    "var proto = new Object();"
9572
9711
    "o.__proto__ = proto;"
9573
9712
    "proto.method = function(x) { return x + 1; };"
9576
9715
    "for (var i = 0; i < 10; i++) {"
9577
9716
    "  if (i == 5) { proto.method = function(x) { return x - 1; }; };"
9578
9717
    "  result += o[m](41);"
9579
 
    "}"));
 
9718
    "}");
9580
9719
  CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value());
9581
9720
}
9582
9721
 
10088
10227
static unsigned linear_congruential_generator;
10089
10228
 
10090
10229
 
10091
 
void ApiTestFuzzer::Setup(PartOfTest part) {
 
10230
void ApiTestFuzzer::SetUp(PartOfTest part) {
10092
10231
  linear_congruential_generator = i::FLAG_testing_prng_seed;
10093
10232
  fuzzing_ = true;
10094
10233
  int count = RegisterThreadedTest::count();
10152
10291
 
10153
10292
// Lets not be needlessly self-referential.
10154
10293
TEST(Threading) {
10155
 
  ApiTestFuzzer::Setup(ApiTestFuzzer::FIRST_PART);
 
10294
  ApiTestFuzzer::SetUp(ApiTestFuzzer::FIRST_PART);
10156
10295
  ApiTestFuzzer::RunAllTests();
10157
10296
  ApiTestFuzzer::TearDown();
10158
10297
}
10159
10298
 
10160
10299
TEST(Threading2) {
10161
 
  ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART);
 
10300
  ApiTestFuzzer::SetUp(ApiTestFuzzer::SECOND_PART);
10162
10301
  ApiTestFuzzer::RunAllTests();
10163
10302
  ApiTestFuzzer::TearDown();
10164
10303
}
10165
10304
 
10166
10305
TEST(Threading3) {
10167
 
  ApiTestFuzzer::Setup(ApiTestFuzzer::THIRD_PART);
 
10306
  ApiTestFuzzer::SetUp(ApiTestFuzzer::THIRD_PART);
10168
10307
  ApiTestFuzzer::RunAllTests();
10169
10308
  ApiTestFuzzer::TearDown();
10170
10309
}
10171
10310
 
10172
10311
TEST(Threading4) {
10173
 
  ApiTestFuzzer::Setup(ApiTestFuzzer::FOURTH_PART);
 
10312
  ApiTestFuzzer::SetUp(ApiTestFuzzer::FOURTH_PART);
10174
10313
  ApiTestFuzzer::RunAllTests();
10175
10314
  ApiTestFuzzer::TearDown();
10176
10315
}
10493
10632
  env->Enter();
10494
10633
  v8::Handle<Value> value = NestedScope(env);
10495
10634
  v8::Handle<String> str(value->ToString());
 
10635
  CHECK(!str.IsEmpty());
10496
10636
  env->Exit();
10497
10637
  env.Dispose();
10498
10638
}
10501
10641
THREADED_TEST(ExternalAllocatedMemory) {
10502
10642
  v8::HandleScope outer;
10503
10643
  v8::Persistent<Context> env(Context::New());
 
10644
  CHECK(!env.IsEmpty());
10504
10645
  const int kSize = 1024*1024;
10505
10646
  CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize), kSize);
10506
10647
  CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize), 0);
10839
10980
      i::FunctionTemplateInfo::cast(internal_template->constructor()));
10840
10981
  CHECK(!constructor->access_check_info()->IsUndefined());
10841
10982
  v8::Persistent<Context> context0(Context::New(NULL, global_template));
 
10983
  CHECK(!context0.IsEmpty());
10842
10984
  CHECK(!constructor->access_check_info()->IsUndefined());
10843
10985
}
10844
10986
 
12029
12171
                                  callback_templ->GetFunction());
12030
12172
  calling_context0->Exit();
12031
12173
 
12032
 
  // Expose context0 in context1 and setup a function that calls the
 
12174
  // Expose context0 in context1 and set up a function that calls the
12033
12175
  // callback function.
12034
12176
  calling_context1->Enter();
12035
12177
  calling_context1->Global()->Set(v8_str("context0"),
12187
12329
 
12188
12330
  i::Handle<i::Smi> value(i::Smi::FromInt(2));
12189
12331
  i::Handle<i::Object> no_failure;
12190
 
  no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
 
12332
  no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
12191
12333
  ASSERT(!no_failure.is_null());
12192
12334
  i::USE(no_failure);
12193
12335
  CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
12194
12336
  *value.location() = i::Smi::FromInt(256);
12195
 
  no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
 
12337
  no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
12196
12338
  ASSERT(!no_failure.is_null());
12197
12339
  i::USE(no_failure);
12198
12340
  CHECK_EQ(255,
12199
12341
           i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
12200
12342
  *value.location() = i::Smi::FromInt(-1);
12201
 
  no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
 
12343
  no_failure = i::JSObject::SetElement(jsobj, 1, value, i::kNonStrictMode);
12202
12344
  ASSERT(!no_failure.is_null());
12203
12345
  i::USE(no_failure);
12204
12346
  CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
12914
13056
    const int kLargeElementCount = kXSize * kYSize * 4;
12915
13057
    ElementType* large_array_data =
12916
13058
        static_cast<ElementType*>(malloc(kLargeElementCount * element_size));
12917
 
    i::Handle<ExternalArrayClass> large_array(
12918
 
        i::Handle<ExternalArrayClass>::cast(
12919
 
            FACTORY->NewExternalArray(kLargeElementCount,
12920
 
                                      array_type,
12921
 
                                      array_data)));
12922
13059
    v8::Handle<v8::Object> large_obj = v8::Object::New();
12923
13060
    // Set the elements to be the external array.
12924
13061
    large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data,
13319
13456
  v8::Handle<v8::String> overview_src = v8::String::New(overview_source);
13320
13457
  v8::Handle<Value> overview_result(
13321
13458
      v8::Script::New(overview_src, origin)->Run());
13322
 
  ASSERT(!overview_result.IsEmpty());
13323
 
  ASSERT(overview_result->IsObject());
 
13459
  CHECK(!overview_result.IsEmpty());
 
13460
  CHECK(overview_result->IsObject());
13324
13461
 
13325
13462
  // Test getting DETAILED information.
13326
13463
  const char *detailed_source =
13339
13476
  v8::Handle<v8::Script> detailed_script(
13340
13477
      v8::Script::New(detailed_src, &detailed_origin));
13341
13478
  v8::Handle<Value> detailed_result(detailed_script->Run());
13342
 
  ASSERT(!detailed_result.IsEmpty());
13343
 
  ASSERT(detailed_result->IsObject());
 
13479
  CHECK(!detailed_result.IsEmpty());
 
13480
  CHECK(detailed_result->IsObject());
13344
13481
}
13345
13482
 
13346
13483
 
13438
13575
 
13439
13576
 
13440
13577
// Test that idle notification can be handled and eventually returns true.
 
13578
// This just checks the contract of the IdleNotification() function,
 
13579
// and does not verify that it does reasonable work.
13441
13580
THREADED_TEST(IdleNotification) {
 
13581
  v8::HandleScope scope;
 
13582
  LocalContext env;
 
13583
  CompileRun("function binom(n, m) {"
 
13584
             "  var C = [[1]];"
 
13585
             "  for (var i = 1; i <= n; ++i) {"
 
13586
             "    C[i] = [1];"
 
13587
             "    for (var j = 1; j < i; ++j) {"
 
13588
             "      C[i][j] = C[i-1][j-1] + C[i-1][j];"
 
13589
             "    }"
 
13590
             "    C[i][i] = 1;"
 
13591
             "  }"
 
13592
             "  return C[n][m];"
 
13593
             "};"
 
13594
             "binom(1000, 500)");
13442
13595
  bool rv = false;
13443
13596
  for (int i = 0; i < 100; i++) {
13444
13597
    rv = v8::V8::IdleNotification();
13448
13601
  CHECK(rv == true);
13449
13602
}
13450
13603
 
 
13604
// Test that idle notification can be handled and eventually returns true.
 
13605
// This just checks the contract of the IdleNotification() function,
 
13606
// and does not verify that it does reasonable work.
 
13607
TEST(IdleNotificationWithHint) {
 
13608
  v8::HandleScope scope;
 
13609
  LocalContext env;
 
13610
  {
 
13611
    i::AlwaysAllocateScope always_allocate;
 
13612
    CompileRun("function binom(n, m) {"
 
13613
               "  var C = [[1]];"
 
13614
               "  for (var i = 1; i <= n; ++i) {"
 
13615
               "    C[i] = [1];"
 
13616
               "    for (var j = 1; j < i; ++j) {"
 
13617
               "      C[i][j] = C[i-1][j-1] + C[i-1][j];"
 
13618
               "    }"
 
13619
               "    C[i][i] = 1;"
 
13620
               "  }"
 
13621
               "  return C[n][m];"
 
13622
               "};"
 
13623
               "binom(1000, 500)");
 
13624
  }
 
13625
  bool rv = false;
 
13626
  intptr_t old_size = HEAP->SizeOfObjects();
 
13627
  bool no_idle_work = v8::V8::IdleNotification(10);
 
13628
  for (int i = 0; i < 200; i++) {
 
13629
    rv = v8::V8::IdleNotification(10);
 
13630
    if (rv)
 
13631
      break;
 
13632
  }
 
13633
  CHECK(rv == true);
 
13634
  intptr_t new_size = HEAP->SizeOfObjects();
 
13635
  CHECK(no_idle_work || new_size < old_size);
 
13636
}
 
13637
 
13451
13638
 
13452
13639
static uint32_t* stack_limit;
13453
13640
 
13536
13723
}
13537
13724
 
13538
13725
 
 
13726
class VisitorImpl : public v8::ExternalResourceVisitor {
 
13727
 public:
 
13728
  VisitorImpl(TestResource* r1, TestResource* r2)
 
13729
      : resource1_(r1),
 
13730
        resource2_(r2),
 
13731
        found_resource1_(false),
 
13732
        found_resource2_(false) {}
 
13733
  virtual ~VisitorImpl() {}
 
13734
  virtual void VisitExternalString(v8::Handle<v8::String> string) {
 
13735
    if (!string->IsExternal()) {
 
13736
      CHECK(string->IsExternalAscii());
 
13737
      return;
 
13738
    }
 
13739
    v8::String::ExternalStringResource* resource =
 
13740
        string->GetExternalStringResource();
 
13741
    CHECK(resource);
 
13742
    if (resource1_ == resource) {
 
13743
      CHECK(!found_resource1_);
 
13744
      found_resource1_ = true;
 
13745
    }
 
13746
    if (resource2_ == resource) {
 
13747
      CHECK(!found_resource2_);
 
13748
      found_resource2_ = true;
 
13749
    }
 
13750
  }
 
13751
  void CheckVisitedResources() {
 
13752
    CHECK(found_resource1_);
 
13753
    CHECK(found_resource2_);
 
13754
  }
 
13755
 
 
13756
 private:
 
13757
  v8::String::ExternalStringResource* resource1_;
 
13758
  v8::String::ExternalStringResource* resource2_;
 
13759
  bool found_resource1_;
 
13760
  bool found_resource2_;
 
13761
};
 
13762
 
 
13763
TEST(VisitExternalStrings) {
 
13764
  v8::HandleScope scope;
 
13765
  LocalContext env;
 
13766
  const char* string = "Some string";
 
13767
  uint16_t* two_byte_string = AsciiToTwoByteString(string);
 
13768
  TestResource* resource1 = new TestResource(two_byte_string);
 
13769
  v8::Local<v8::String> string1 = v8::String::NewExternal(resource1);
 
13770
  TestResource* resource2 = new TestResource(two_byte_string);
 
13771
  v8::Local<v8::String> string2 = v8::String::NewExternal(resource2);
 
13772
 
 
13773
  // We need to add usages for string1 and string2 to avoid warnings in GCC 4.7
 
13774
  CHECK(string1->IsExternal());
 
13775
  CHECK(string2->IsExternal());
 
13776
 
 
13777
  VisitorImpl visitor(resource1, resource2);
 
13778
  v8::V8::VisitExternalResources(&visitor);
 
13779
  visitor.CheckVisitedResources();
 
13780
}
 
13781
 
 
13782
 
13539
13783
static double DoubleFromBits(uint64_t value) {
13540
13784
  double target;
13541
13785
  memcpy(&target, &value, sizeof(target));
13653
13897
  v8::HandleScope scope;
13654
13898
  v8::TryCatch tc;
13655
13899
  v8::Handle<v8::String> str(args[0]->ToString());
 
13900
  USE(str);
13656
13901
  if (tc.HasCaught())
13657
13902
    return tc.ReThrow();
13658
13903
  return v8::Undefined();
13797
14042
  CHECK_EQ(0, script_origin_g.ResourceLineOffset()->Int32Value());
13798
14043
}
13799
14044
 
 
14045
THREADED_TEST(FunctionGetInferredName) {
 
14046
  v8::HandleScope scope;
 
14047
  LocalContext env;
 
14048
  v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
 
14049
  v8::Handle<v8::String> script = v8::String::New(
 
14050
      "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;");
 
14051
  v8::Script::Compile(script, &origin)->Run();
 
14052
  v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
 
14053
      env->Global()->Get(v8::String::New("f")));
 
14054
  CHECK_EQ("foo.bar.baz", *v8::String::AsciiValue(f->GetInferredName()));
 
14055
}
13800
14056
 
13801
14057
THREADED_TEST(ScriptLineNumber) {
13802
14058
  v8::HandleScope scope;
14109
14365
      "  for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);"
14110
14366
      "  for (var i = 0; i < 16; i++) {"
14111
14367
      "    var v = %_GetFromCache(0, keys[i]);"
14112
 
      "    if (v !== values[i])"
 
14368
      "    if (v.toString() !== values[i].toString())"
14113
14369
      "      return 'Wrong value for ' + "
14114
14370
      "          keys[i] + ': ' + v + ' vs. ' + values[i];"
14115
14371
      "  };"
14951
15207
  // RegExps are objects on which you can set properties.
14952
15208
  re->Set(v8_str("property"), v8::Integer::New(32));
14953
15209
  v8::Handle<v8::Value> value(CompileRun("re.property"));
14954
 
  ASSERT_EQ(32, value->Int32Value());
 
15210
  CHECK_EQ(32, value->Int32Value());
14955
15211
 
14956
15212
  v8::TryCatch try_catch;
14957
15213
  re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone);
15597
15853
 
15598
15854
  foreign_context.Dispose();
15599
15855
}
 
15856
 
 
15857
 
 
15858
uint8_t callback_fired = 0;
 
15859
 
 
15860
 
 
15861
void CallCompletedCallback1() {
 
15862
  i::OS::Print("Firing callback 1.\n");
 
15863
  callback_fired ^= 1;  // Toggle first bit.
 
15864
}
 
15865
 
 
15866
 
 
15867
void CallCompletedCallback2() {
 
15868
  i::OS::Print("Firing callback 2.\n");
 
15869
  callback_fired ^= 2;  // Toggle second bit.
 
15870
}
 
15871
 
 
15872
 
 
15873
Handle<Value> RecursiveCall(const Arguments& args) {
 
15874
  int32_t level = args[0]->Int32Value();
 
15875
  if (level < 3) {
 
15876
    level++;
 
15877
    i::OS::Print("Entering recursion level %d.\n", level);
 
15878
    char script[64];
 
15879
    i::Vector<char> script_vector(script, sizeof(script));
 
15880
    i::OS::SNPrintF(script_vector, "recursion(%d)", level);
 
15881
    CompileRun(script_vector.start());
 
15882
    i::OS::Print("Leaving recursion level %d.\n", level);
 
15883
    CHECK_EQ(0, callback_fired);
 
15884
  } else {
 
15885
    i::OS::Print("Recursion ends.\n");
 
15886
    CHECK_EQ(0, callback_fired);
 
15887
  }
 
15888
  return Undefined();
 
15889
}
 
15890
 
 
15891
 
 
15892
TEST(CallCompletedCallback) {
 
15893
  v8::HandleScope scope;
 
15894
  LocalContext env;
 
15895
  v8::Handle<v8::FunctionTemplate> recursive_runtime =
 
15896
      v8::FunctionTemplate::New(RecursiveCall);
 
15897
  env->Global()->Set(v8_str("recursion"),
 
15898
                     recursive_runtime->GetFunction());
 
15899
  // Adding the same callback a second time has no effect.
 
15900
  v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
 
15901
  v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
 
15902
  v8::V8::AddCallCompletedCallback(CallCompletedCallback2);
 
15903
  i::OS::Print("--- Script (1) ---\n");
 
15904
  Local<Script> script =
 
15905
      v8::Script::Compile(v8::String::New("recursion(0)"));
 
15906
  script->Run();
 
15907
  CHECK_EQ(3, callback_fired);
 
15908
 
 
15909
  i::OS::Print("\n--- Script (2) ---\n");
 
15910
  callback_fired = 0;
 
15911
  v8::V8::RemoveCallCompletedCallback(CallCompletedCallback1);
 
15912
  script->Run();
 
15913
  CHECK_EQ(2, callback_fired);
 
15914
 
 
15915
  i::OS::Print("\n--- Function ---\n");
 
15916
  callback_fired = 0;
 
15917
  Local<Function> recursive_function =
 
15918
      Local<Function>::Cast(env->Global()->Get(v8_str("recursion")));
 
15919
  v8::Handle<Value> args[] = { v8_num(0) };
 
15920
  recursive_function->Call(env->Global(), 1, args);
 
15921
  CHECK_EQ(2, callback_fired);
 
15922
}
 
15923
 
 
15924
 
 
15925
void CallCompletedCallbackNoException() {
 
15926
  v8::HandleScope scope;
 
15927
  CompileRun("1+1;");
 
15928
}
 
15929
 
 
15930
 
 
15931
void CallCompletedCallbackException() {
 
15932
  v8::HandleScope scope;
 
15933
  CompileRun("throw 'second exception';");
 
15934
}
 
15935
 
 
15936
 
 
15937
TEST(CallCompletedCallbackOneException) {
 
15938
  v8::HandleScope scope;
 
15939
  LocalContext env;
 
15940
  v8::V8::AddCallCompletedCallback(CallCompletedCallbackNoException);
 
15941
  CompileRun("throw 'exception';");
 
15942
}
 
15943
 
 
15944
 
 
15945
TEST(CallCompletedCallbackTwoExceptions) {
 
15946
  v8::HandleScope scope;
 
15947
  LocalContext env;
 
15948
  v8::V8::AddCallCompletedCallback(CallCompletedCallbackException);
 
15949
  CompileRun("throw 'first exception';");
 
15950
}