OLD | NEW |
1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 #include "api.h" | 32 #include "api.h" |
33 #include "compilation-cache.h" | 33 #include "compilation-cache.h" |
34 #include "execution.h" | 34 #include "execution.h" |
35 #include "snapshot.h" | 35 #include "snapshot.h" |
36 #include "platform.h" | 36 #include "platform.h" |
37 #include "top.h" | 37 #include "top.h" |
38 #include "utils.h" | 38 #include "utils.h" |
39 #include "cctest.h" | 39 #include "cctest.h" |
40 | 40 |
41 static const bool kLogThreading = false; | |
42 | |
43 static bool IsNaN(double x) { | 41 static bool IsNaN(double x) { |
44 #ifdef WIN32 | 42 #ifdef WIN32 |
45 return _isnan(x); | 43 return _isnan(x); |
46 #else | 44 #else |
47 return isnan(x); | 45 return isnan(x); |
48 #endif | 46 #endif |
49 } | 47 } |
50 | 48 |
51 using ::v8::ObjectTemplate; | 49 using ::v8::ObjectTemplate; |
52 using ::v8::Value; | 50 using ::v8::Value; |
53 using ::v8::Context; | 51 using ::v8::Context; |
54 using ::v8::Local; | 52 using ::v8::Local; |
55 using ::v8::String; | 53 using ::v8::String; |
56 using ::v8::Script; | 54 using ::v8::Script; |
57 using ::v8::Function; | 55 using ::v8::Function; |
58 using ::v8::AccessorInfo; | 56 using ::v8::AccessorInfo; |
59 using ::v8::Extension; | 57 using ::v8::Extension; |
60 | 58 |
61 namespace i = ::v8::internal; | 59 namespace i = ::v8::internal; |
62 | 60 |
| 61 static Local<Value> v8_num(double x) { |
| 62 return v8::Number::New(x); |
| 63 } |
| 64 |
| 65 |
| 66 static Local<String> v8_str(const char* x) { |
| 67 return String::New(x); |
| 68 } |
| 69 |
| 70 |
| 71 static Local<Script> v8_compile(const char* x) { |
| 72 return Script::Compile(v8_str(x)); |
| 73 } |
| 74 |
| 75 |
| 76 // A LocalContext holds a reference to a v8::Context. |
| 77 class LocalContext { |
| 78 public: |
| 79 LocalContext(v8::ExtensionConfiguration* extensions = 0, |
| 80 v8::Handle<ObjectTemplate> global_template = |
| 81 v8::Handle<ObjectTemplate>(), |
| 82 v8::Handle<Value> global_object = v8::Handle<Value>()) |
| 83 : context_(Context::New(extensions, global_template, global_object)) { |
| 84 context_->Enter(); |
| 85 } |
| 86 |
| 87 virtual ~LocalContext() { |
| 88 context_->Exit(); |
| 89 context_.Dispose(); |
| 90 } |
| 91 |
| 92 Context* operator->() { return *context_; } |
| 93 Context* operator*() { return *context_; } |
| 94 Local<Context> local() { return Local<Context>::New(context_); } |
| 95 bool IsReady() { return !context_.IsEmpty(); } |
| 96 |
| 97 private: |
| 98 v8::Persistent<Context> context_; |
| 99 }; |
| 100 |
| 101 |
| 102 // Switches between all the Api tests using the threading support. |
| 103 // In order to get a surprising but repeatable pattern of thread |
| 104 // switching it has extra semaphores to control the order in which |
| 105 // the tests alternate, not relying solely on the big V8 lock. |
| 106 // |
| 107 // A test is augmented with calls to ApiTestFuzzer::Fuzz() in its |
| 108 // callbacks. This will have no effect when we are not running the |
| 109 // thread fuzzing test. In the thread fuzzing test it will |
| 110 // pseudorandomly select a successor thread and switch execution |
| 111 // to that thread, suspending the current test. |
| 112 class ApiTestFuzzer: public v8::internal::Thread { |
| 113 public: |
| 114 void CallTest(); |
| 115 explicit ApiTestFuzzer(int num) |
| 116 : test_number_(num), |
| 117 gate_(v8::internal::OS::CreateSemaphore(0)), |
| 118 active_(true) { |
| 119 } |
| 120 ~ApiTestFuzzer() { delete gate_; } |
| 121 |
| 122 // The ApiTestFuzzer is also a Thread, so it has a Run method. |
| 123 virtual void Run(); |
| 124 |
| 125 enum PartOfTest { FIRST_PART, SECOND_PART }; |
| 126 |
| 127 static void Setup(PartOfTest part); |
| 128 static void RunAllTests(); |
| 129 static void TearDown(); |
| 130 // This method switches threads if we are running the Threading test. |
| 131 // Otherwise it does nothing. |
| 132 static void Fuzz(); |
| 133 private: |
| 134 static bool fuzzing_; |
| 135 static int tests_being_run_; |
| 136 static int current_; |
| 137 static int active_tests_; |
| 138 static bool NextThread(); |
| 139 int test_number_; |
| 140 v8::internal::Semaphore* gate_; |
| 141 bool active_; |
| 142 void ContextSwitch(); |
| 143 static int GetNextTestNumber(); |
| 144 static v8::internal::Semaphore* all_tests_done_; |
| 145 }; |
| 146 |
| 147 |
| 148 #define THREADED_TEST(Name) \ |
| 149 static void Test##Name(); \ |
| 150 RegisterThreadedTest register_##Name(Test##Name); \ |
| 151 /* */ TEST(Name) |
| 152 |
| 153 |
| 154 class RegisterThreadedTest { |
| 155 public: |
| 156 explicit RegisterThreadedTest(CcTest::TestFunction* callback) |
| 157 : fuzzer_(NULL), callback_(callback) { |
| 158 prev_ = first_; |
| 159 first_ = this; |
| 160 count_++; |
| 161 } |
| 162 static int count() { return count_; } |
| 163 static RegisterThreadedTest* nth(int i) { |
| 164 CHECK(i < count()); |
| 165 RegisterThreadedTest* current = first_; |
| 166 while (i > 0) { |
| 167 i--; |
| 168 current = current->prev_; |
| 169 } |
| 170 return current; |
| 171 } |
| 172 CcTest::TestFunction* callback() { return callback_; } |
| 173 ApiTestFuzzer* fuzzer_; |
| 174 |
| 175 private: |
| 176 static RegisterThreadedTest* first_; |
| 177 static int count_; |
| 178 CcTest::TestFunction* callback_; |
| 179 RegisterThreadedTest* prev_; |
| 180 }; |
| 181 |
| 182 |
| 183 RegisterThreadedTest *RegisterThreadedTest::first_ = NULL; |
| 184 int RegisterThreadedTest::count_ = 0; |
| 185 |
63 | 186 |
64 static int signature_callback_count; | 187 static int signature_callback_count; |
65 static v8::Handle<Value> IncrementingSignatureCallback( | 188 static v8::Handle<Value> IncrementingSignatureCallback( |
66 const v8::Arguments& args) { | 189 const v8::Arguments& args) { |
67 ApiTestFuzzer::Fuzz(); | 190 ApiTestFuzzer::Fuzz(); |
68 signature_callback_count++; | 191 signature_callback_count++; |
69 v8::Handle<v8::Array> result = v8::Array::New(args.Length()); | 192 v8::Handle<v8::Array> result = v8::Array::New(args.Length()); |
70 for (int i = 0; i < args.Length(); i++) | 193 for (int i = 0; i < args.Length(); i++) |
71 result->Set(v8::Integer::New(i), args[i]); | 194 result->Set(v8::Integer::New(i), args[i]); |
72 return result; | 195 return result; |
(...skipping 28 matching lines...) Expand all Loading... |
101 | 224 |
102 const char* c_source = "1 + 2 + 3"; | 225 const char* c_source = "1 + 2 + 3"; |
103 Local<String> source = String::New(c_source); | 226 Local<String> source = String::New(c_source); |
104 Local<Script> script = Script::Compile(source); | 227 Local<Script> script = Script::Compile(source); |
105 CHECK_EQ(6, script->Run()->Int32Value()); | 228 CHECK_EQ(6, script->Run()->Int32Value()); |
106 | 229 |
107 local_env->Exit(); | 230 local_env->Exit(); |
108 } | 231 } |
109 | 232 |
110 | 233 |
| 234 // Helper function that compiles and runs the source. |
| 235 static Local<Value> CompileRun(const char* source) { |
| 236 return Script::Compile(String::New(source))->Run(); |
| 237 } |
| 238 |
111 THREADED_TEST(ReceiverSignature) { | 239 THREADED_TEST(ReceiverSignature) { |
112 v8::HandleScope scope; | 240 v8::HandleScope scope; |
113 LocalContext env; | 241 LocalContext env; |
114 v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(); | 242 v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(); |
115 v8::Handle<v8::Signature> sig = v8::Signature::New(fun); | 243 v8::Handle<v8::Signature> sig = v8::Signature::New(fun); |
116 fun->PrototypeTemplate()->Set( | 244 fun->PrototypeTemplate()->Set( |
117 v8_str("m"), | 245 v8_str("m"), |
118 v8::FunctionTemplate::New(IncrementingSignatureCallback, | 246 v8::FunctionTemplate::New(IncrementingSignatureCallback, |
119 v8::Handle<Value>(), | 247 v8::Handle<Value>(), |
120 sig)); | 248 sig)); |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 // other_instance. | 713 // other_instance. |
586 CHECK_EQ(derived_instance2, | 714 CHECK_EQ(derived_instance2, |
587 other_instance->FindInstanceInPrototypeChain(base)); | 715 other_instance->FindInstanceInPrototypeChain(base)); |
588 CHECK_EQ(derived_instance2, | 716 CHECK_EQ(derived_instance2, |
589 other_instance->FindInstanceInPrototypeChain(derived)); | 717 other_instance->FindInstanceInPrototypeChain(derived)); |
590 CHECK_EQ(other_instance, | 718 CHECK_EQ(other_instance, |
591 other_instance->FindInstanceInPrototypeChain(other)); | 719 other_instance->FindInstanceInPrototypeChain(other)); |
592 } | 720 } |
593 | 721 |
594 | 722 |
| 723 static v8::Handle<Value> handle_property(Local<String> name, |
| 724 const AccessorInfo&) { |
| 725 ApiTestFuzzer::Fuzz(); |
| 726 return v8_num(900); |
| 727 } |
| 728 |
| 729 |
| 730 THREADED_TEST(PropertyHandler) { |
| 731 v8::HandleScope scope; |
| 732 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
| 733 fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property); |
| 734 LocalContext env; |
| 735 Local<Function> fun = fun_templ->GetFunction(); |
| 736 env->Global()->Set(v8_str("Fun"), fun); |
| 737 Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;"); |
| 738 CHECK_EQ(900, getter->Run()->Int32Value()); |
| 739 Local<Script> setter = v8_compile("obj.foo = 901;"); |
| 740 CHECK_EQ(901, setter->Run()->Int32Value()); |
| 741 } |
| 742 |
| 743 |
595 THREADED_TEST(TinyInteger) { | 744 THREADED_TEST(TinyInteger) { |
596 v8::HandleScope scope; | 745 v8::HandleScope scope; |
597 LocalContext env; | 746 LocalContext env; |
598 int32_t value = 239; | 747 int32_t value = 239; |
599 Local<v8::Integer> value_obj = v8::Integer::New(value); | 748 Local<v8::Integer> value_obj = v8::Integer::New(value); |
600 CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); | 749 CHECK_EQ(static_cast<int64_t>(value), value_obj->Value()); |
601 } | 750 } |
602 | 751 |
603 | 752 |
604 THREADED_TEST(BigSmiInteger) { | 753 THREADED_TEST(BigSmiInteger) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 LocalContext env(0, templ); | 900 LocalContext env(0, templ); |
752 v8::Handle<v8::Object> obj = env->Global(); | 901 v8::Handle<v8::Object> obj = env->Global(); |
753 v8::Handle<Script> script = v8_compile("dummy()"); | 902 v8::Handle<Script> script = v8_compile("dummy()"); |
754 v8::Handle<Value> result = script->Run(); | 903 v8::Handle<Value> result = script->Run(); |
755 CHECK_EQ(13.4, result->NumberValue()); | 904 CHECK_EQ(13.4, result->NumberValue()); |
756 CHECK_EQ(200, v8_compile("x")->Run()->Int32Value()); | 905 CHECK_EQ(200, v8_compile("x")->Run()->Int32Value()); |
757 CHECK_EQ(876, v8_compile("m")->Run()->Int32Value()); | 906 CHECK_EQ(876, v8_compile("m")->Run()->Int32Value()); |
758 } | 907 } |
759 | 908 |
760 | 909 |
| 910 static v8::Handle<Value> GetIntValue(Local<String> property, |
| 911 const AccessorInfo& info) { |
| 912 ApiTestFuzzer::Fuzz(); |
| 913 int* value = |
| 914 static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); |
| 915 return v8_num(*value); |
| 916 } |
| 917 |
| 918 static void SetIntValue(Local<String> property, |
| 919 Local<Value> value, |
| 920 const AccessorInfo& info) { |
| 921 int* field = |
| 922 static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); |
| 923 *field = value->Int32Value(); |
| 924 } |
| 925 |
| 926 int foo, bar, baz; |
| 927 |
| 928 THREADED_TEST(GlobalVariableAccess) { |
| 929 foo = 0; |
| 930 bar = -4; |
| 931 baz = 10; |
| 932 v8::HandleScope scope; |
| 933 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
| 934 templ->InstanceTemplate()->SetAccessor(v8_str("foo"), |
| 935 GetIntValue, |
| 936 SetIntValue, |
| 937 v8::External::New(&foo)); |
| 938 templ->InstanceTemplate()->SetAccessor(v8_str("bar"), |
| 939 GetIntValue, |
| 940 SetIntValue, |
| 941 v8::External::New(&bar)); |
| 942 templ->InstanceTemplate()->SetAccessor(v8_str("baz"), |
| 943 GetIntValue, |
| 944 SetIntValue, |
| 945 v8::External::New(&baz)); |
| 946 LocalContext env(0, templ->InstanceTemplate()); |
| 947 v8_compile("foo = (++bar) + baz")->Run(); |
| 948 CHECK_EQ(bar, -3); |
| 949 CHECK_EQ(foo, 7); |
| 950 } |
| 951 |
| 952 |
761 THREADED_TEST(ObjectTemplate) { | 953 THREADED_TEST(ObjectTemplate) { |
762 v8::HandleScope scope; | 954 v8::HandleScope scope; |
763 Local<ObjectTemplate> templ1 = ObjectTemplate::New(); | 955 Local<ObjectTemplate> templ1 = ObjectTemplate::New(); |
764 templ1->Set("x", v8_num(10)); | 956 templ1->Set("x", v8_num(10)); |
765 templ1->Set("y", v8_num(13)); | 957 templ1->Set("y", v8_num(13)); |
766 LocalContext env; | 958 LocalContext env; |
767 Local<v8::Object> instance1 = templ1->NewInstance(); | 959 Local<v8::Object> instance1 = templ1->NewInstance(); |
768 env->Global()->Set(v8_str("p"), instance1); | 960 env->Global()->Set(v8_str("p"), instance1); |
769 CHECK(v8_compile("(p.x == 10)")->Run()->BooleanValue()); | 961 CHECK(v8_compile("(p.x == 10)")->Run()->BooleanValue()); |
770 CHECK(v8_compile("(p.y == 13)")->Run()->BooleanValue()); | 962 CHECK(v8_compile("(p.y == 13)")->Run()->BooleanValue()); |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 env->Global()->Set(v8_str("obj"), obj->NewInstance()); | 1358 env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
1167 v8::Handle<Value> otto = Script::Compile(v8_str( | 1359 v8::Handle<Value> otto = Script::Compile(v8_str( |
1168 "try { with (obj) { otto; } } catch (e) { e; }"))->Run(); | 1360 "try { with (obj) { otto; } } catch (e) { e; }"))->Run(); |
1169 CHECK_EQ(v8_str("otto"), otto); | 1361 CHECK_EQ(v8_str("otto"), otto); |
1170 v8::Handle<Value> netto = Script::Compile(v8_str( | 1362 v8::Handle<Value> netto = Script::Compile(v8_str( |
1171 "try { with (obj) { netto = 4; } } catch (e) { e; }"))->Run(); | 1363 "try { with (obj) { netto = 4; } } catch (e) { e; }"))->Run(); |
1172 CHECK_EQ(v8_str("netto"), netto); | 1364 CHECK_EQ(v8_str("netto"), netto); |
1173 } | 1365 } |
1174 | 1366 |
1175 | 1367 |
| 1368 static v8::Handle<Value> ThrowingGetAccessor(Local<String> name, |
| 1369 const AccessorInfo& info) { |
| 1370 ApiTestFuzzer::Fuzz(); |
| 1371 return v8::ThrowException(v8_str("g")); |
| 1372 } |
| 1373 |
| 1374 |
| 1375 static void ThrowingSetAccessor(Local<String> name, |
| 1376 Local<Value> value, |
| 1377 const AccessorInfo& info) { |
| 1378 v8::ThrowException(value); |
| 1379 } |
| 1380 |
| 1381 |
| 1382 THREADED_TEST(Regress1054726) { |
| 1383 v8::HandleScope scope; |
| 1384 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 1385 obj->SetAccessor(v8_str("x"), |
| 1386 ThrowingGetAccessor, |
| 1387 ThrowingSetAccessor, |
| 1388 Local<Value>()); |
| 1389 |
| 1390 LocalContext env; |
| 1391 env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
| 1392 |
| 1393 // Use the throwing property setter/getter in a loop to force |
| 1394 // the accessor ICs to be initialized. |
| 1395 v8::Handle<Value> result; |
| 1396 result = Script::Compile(v8_str( |
| 1397 "var result = '';" |
| 1398 "for (var i = 0; i < 5; i++) {" |
| 1399 " try { obj.x; } catch (e) { result += e; }" |
| 1400 "}; result"))->Run(); |
| 1401 CHECK_EQ(v8_str("ggggg"), result); |
| 1402 |
| 1403 result = Script::Compile(String::New( |
| 1404 "var result = '';" |
| 1405 "for (var i = 0; i < 5; i++) {" |
| 1406 " try { obj.x = i; } catch (e) { result += e; }" |
| 1407 "}; result"))->Run(); |
| 1408 CHECK_EQ(v8_str("01234"), result); |
| 1409 } |
| 1410 |
| 1411 |
1176 THREADED_TEST(FunctionPrototype) { | 1412 THREADED_TEST(FunctionPrototype) { |
1177 v8::HandleScope scope; | 1413 v8::HandleScope scope; |
1178 Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(); | 1414 Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(); |
1179 Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); | 1415 Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); |
1180 LocalContext env; | 1416 LocalContext env; |
1181 env->Global()->Set(v8_str("Foo"), Foo->GetFunction()); | 1417 env->Global()->Set(v8_str("Foo"), Foo->GetFunction()); |
1182 Local<Script> script = Script::Compile(v8_str("Foo.prototype.plak")); | 1418 Local<Script> script = Script::Compile(v8_str("Foo.prototype.plak")); |
1183 CHECK_EQ(script->Run()->Int32Value(), 321); | 1419 CHECK_EQ(script->Run()->Int32Value(), 321); |
1184 } | 1420 } |
1185 | 1421 |
(...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2941 THREADED_TEST(Arguments) { | 3177 THREADED_TEST(Arguments) { |
2942 v8::HandleScope scope; | 3178 v8::HandleScope scope; |
2943 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); | 3179 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); |
2944 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); | 3180 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); |
2945 LocalContext context(NULL, global); | 3181 LocalContext context(NULL, global); |
2946 args_fun = v8::Handle<Function>::Cast(context->Global()->Get(v8_str("f"))); | 3182 args_fun = v8::Handle<Function>::Cast(context->Global()->Get(v8_str("f"))); |
2947 v8_compile("f(1, 2, 3)")->Run(); | 3183 v8_compile("f(1, 2, 3)")->Run(); |
2948 } | 3184 } |
2949 | 3185 |
2950 | 3186 |
| 3187 static int x_register = 0; |
| 3188 static v8::Handle<v8::Object> x_receiver; |
| 3189 static v8::Handle<v8::Object> x_holder; |
| 3190 |
| 3191 |
| 3192 static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) { |
| 3193 ApiTestFuzzer::Fuzz(); |
| 3194 CHECK_EQ(x_receiver, info.This()); |
| 3195 CHECK_EQ(x_holder, info.Holder()); |
| 3196 return v8_num(x_register); |
| 3197 } |
| 3198 |
| 3199 |
| 3200 static void XSetter(Local<String> name, |
| 3201 Local<Value> value, |
| 3202 const AccessorInfo& info) { |
| 3203 CHECK_EQ(x_holder, info.This()); |
| 3204 CHECK_EQ(x_holder, info.Holder()); |
| 3205 x_register = value->Int32Value(); |
| 3206 } |
| 3207 |
| 3208 |
| 3209 THREADED_TEST(AccessorIC) { |
| 3210 v8::HandleScope scope; |
| 3211 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 3212 obj->SetAccessor(v8_str("x"), XGetter, XSetter); |
| 3213 LocalContext context; |
| 3214 x_holder = obj->NewInstance(); |
| 3215 context->Global()->Set(v8_str("holder"), x_holder); |
| 3216 x_receiver = v8::Object::New(); |
| 3217 context->Global()->Set(v8_str("obj"), x_receiver); |
| 3218 v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun( |
| 3219 "obj.__proto__ = holder;" |
| 3220 "var result = [];" |
| 3221 "for (var i = 0; i < 10; i++) {" |
| 3222 " holder.x = i;" |
| 3223 " result.push(obj.x);" |
| 3224 "}" |
| 3225 "result")); |
| 3226 CHECK_EQ(10, array->Length()); |
| 3227 for (int i = 0; i < 10; i++) { |
| 3228 v8::Handle<Value> entry = array->Get(v8::Integer::New(i)); |
| 3229 CHECK_EQ(v8::Integer::New(i), entry); |
| 3230 } |
| 3231 } |
| 3232 |
| 3233 |
2951 static v8::Handle<Value> NoBlockGetterX(Local<String> name, | 3234 static v8::Handle<Value> NoBlockGetterX(Local<String> name, |
2952 const AccessorInfo&) { | 3235 const AccessorInfo&) { |
2953 return v8::Handle<Value>(); | 3236 return v8::Handle<Value>(); |
2954 } | 3237 } |
2955 | 3238 |
2956 | 3239 |
2957 static v8::Handle<Value> NoBlockGetterI(uint32_t index, | 3240 static v8::Handle<Value> NoBlockGetterI(uint32_t index, |
2958 const AccessorInfo&) { | 3241 const AccessorInfo&) { |
2959 return v8::Handle<Value>(); | 3242 return v8::Handle<Value>(); |
2960 } | 3243 } |
(...skipping 2843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5804 if (!fuzzing_) return; | 6087 if (!fuzzing_) return; |
5805 ApiTestFuzzer* test = RegisterThreadedTest::nth(current_)->fuzzer_; | 6088 ApiTestFuzzer* test = RegisterThreadedTest::nth(current_)->fuzzer_; |
5806 test->ContextSwitch(); | 6089 test->ContextSwitch(); |
5807 } | 6090 } |
5808 | 6091 |
5809 | 6092 |
5810 // Let the next thread go. Since it is also waiting on the V8 lock it may | 6093 // Let the next thread go. Since it is also waiting on the V8 lock it may |
5811 // not start immediately. | 6094 // not start immediately. |
5812 bool ApiTestFuzzer::NextThread() { | 6095 bool ApiTestFuzzer::NextThread() { |
5813 int test_position = GetNextTestNumber(); | 6096 int test_position = GetNextTestNumber(); |
5814 const char* test_name = RegisterThreadedTest::nth(current_)->name(); | 6097 int test_number = RegisterThreadedTest::nth(current_)->fuzzer_->test_number_; |
5815 if (test_position == current_) { | 6098 if (test_position == current_) { |
5816 if (kLogThreading) | 6099 printf("Stay with %d\n", test_number); |
5817 printf("Stay with %s\n", test_name); | |
5818 return false; | 6100 return false; |
5819 } | 6101 } |
5820 if (kLogThreading) { | 6102 printf("Switch from %d to %d\n", |
5821 printf("Switch from %s to %s\n", | 6103 current_ < 0 ? 0 : test_number, test_position < 0 ? 0 : test_number); |
5822 test_name, | |
5823 RegisterThreadedTest::nth(test_position)->name()); | |
5824 } | |
5825 current_ = test_position; | 6104 current_ = test_position; |
5826 RegisterThreadedTest::nth(current_)->fuzzer_->gate_->Signal(); | 6105 RegisterThreadedTest::nth(current_)->fuzzer_->gate_->Signal(); |
5827 return true; | 6106 return true; |
5828 } | 6107 } |
5829 | 6108 |
5830 | 6109 |
5831 void ApiTestFuzzer::Run() { | 6110 void ApiTestFuzzer::Run() { |
5832 // When it is our turn... | 6111 // When it is our turn... |
5833 gate_->Wait(); | 6112 gate_->Wait(); |
5834 { | 6113 { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5923 } | 6202 } |
5924 | 6203 |
5925 TEST(Threading2) { | 6204 TEST(Threading2) { |
5926 ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART); | 6205 ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART); |
5927 ApiTestFuzzer::RunAllTests(); | 6206 ApiTestFuzzer::RunAllTests(); |
5928 ApiTestFuzzer::TearDown(); | 6207 ApiTestFuzzer::TearDown(); |
5929 } | 6208 } |
5930 | 6209 |
5931 | 6210 |
5932 void ApiTestFuzzer::CallTest() { | 6211 void ApiTestFuzzer::CallTest() { |
5933 if (kLogThreading) | 6212 printf("Start test %d\n", test_number_); |
5934 printf("Start test %d\n", test_number_); | |
5935 CallTestNumber(test_number_); | 6213 CallTestNumber(test_number_); |
5936 if (kLogThreading) | 6214 printf("End test %d\n", test_number_); |
5937 printf("End test %d\n", test_number_); | |
5938 } | 6215 } |
5939 | 6216 |
5940 | 6217 |
5941 static v8::Handle<Value> ThrowInJS(const v8::Arguments& args) { | 6218 static v8::Handle<Value> ThrowInJS(const v8::Arguments& args) { |
5942 CHECK(v8::Locker::IsLocked()); | 6219 CHECK(v8::Locker::IsLocked()); |
5943 ApiTestFuzzer::Fuzz(); | 6220 ApiTestFuzzer::Fuzz(); |
5944 v8::Unlocker unlocker; | 6221 v8::Unlocker unlocker; |
5945 const char* code = "throw 7;"; | 6222 const char* code = "throw 7;"; |
5946 { | 6223 { |
5947 v8::Locker nested_locker; | 6224 v8::Locker nested_locker; |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6415 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); | 6692 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); |
6416 int elmc2 = 3; | 6693 int elmc2 = 3; |
6417 const char* elmv2[] = {"0", "1", "2"}; | 6694 const char* elmv2[] = {"0", "1", "2"}; |
6418 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); | 6695 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); |
6419 int elmc3 = 4; | 6696 int elmc3 = 4; |
6420 const char* elmv3[] = {"w", "z", "x", "y"}; | 6697 const char* elmv3[] = {"w", "z", "x", "y"}; |
6421 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); | 6698 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); |
6422 } | 6699 } |
6423 | 6700 |
6424 | 6701 |
| 6702 static v8::Handle<Value> AccessorProhibitsOverwritingGetter( |
| 6703 Local<String> name, |
| 6704 const AccessorInfo& info) { |
| 6705 ApiTestFuzzer::Fuzz(); |
| 6706 return v8::True(); |
| 6707 } |
| 6708 |
| 6709 |
| 6710 THREADED_TEST(AccessorProhibitsOverwriting) { |
| 6711 v8::HandleScope scope; |
| 6712 LocalContext context; |
| 6713 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
| 6714 templ->SetAccessor(v8_str("x"), |
| 6715 AccessorProhibitsOverwritingGetter, |
| 6716 0, |
| 6717 v8::Handle<Value>(), |
| 6718 v8::PROHIBITS_OVERWRITING, |
| 6719 v8::ReadOnly); |
| 6720 Local<v8::Object> instance = templ->NewInstance(); |
| 6721 context->Global()->Set(v8_str("obj"), instance); |
| 6722 Local<Value> value = CompileRun( |
| 6723 "obj.__defineGetter__('x', function() { return false; });" |
| 6724 "obj.x"); |
| 6725 CHECK(value->BooleanValue()); |
| 6726 value = CompileRun( |
| 6727 "var setter_called = false;" |
| 6728 "obj.__defineSetter__('x', function() { setter_called = true; });" |
| 6729 "obj.x = 42;" |
| 6730 "setter_called"); |
| 6731 CHECK(!value->BooleanValue()); |
| 6732 value = CompileRun( |
| 6733 "obj2 = {};" |
| 6734 "obj2.__proto__ = obj;" |
| 6735 "obj2.__defineGetter__('x', function() { return false; });" |
| 6736 "obj2.x"); |
| 6737 CHECK(value->BooleanValue()); |
| 6738 value = CompileRun( |
| 6739 "var setter_called = false;" |
| 6740 "obj2 = {};" |
| 6741 "obj2.__proto__ = obj;" |
| 6742 "obj2.__defineSetter__('x', function() { setter_called = true; });" |
| 6743 "obj2.x = 42;" |
| 6744 "setter_called"); |
| 6745 CHECK(!value->BooleanValue()); |
| 6746 } |
| 6747 |
| 6748 |
6425 static bool NamedSetAccessBlocker(Local<v8::Object> obj, | 6749 static bool NamedSetAccessBlocker(Local<v8::Object> obj, |
6426 Local<Value> name, | 6750 Local<Value> name, |
6427 v8::AccessType type, | 6751 v8::AccessType type, |
6428 Local<Value> data) { | 6752 Local<Value> data) { |
6429 return type != v8::ACCESS_SET; | 6753 return type != v8::ACCESS_SET; |
6430 } | 6754 } |
6431 | 6755 |
6432 | 6756 |
6433 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, | 6757 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, |
6434 uint32_t key, | 6758 uint32_t key, |
(...skipping 1729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8164 THREADED_TEST(GetHeapStatistics) { | 8488 THREADED_TEST(GetHeapStatistics) { |
8165 v8::HandleScope scope; | 8489 v8::HandleScope scope; |
8166 LocalContext c1; | 8490 LocalContext c1; |
8167 v8::HeapStatistics heap_statistics; | 8491 v8::HeapStatistics heap_statistics; |
8168 CHECK_EQ(heap_statistics.total_heap_size(), 0); | 8492 CHECK_EQ(heap_statistics.total_heap_size(), 0); |
8169 CHECK_EQ(heap_statistics.used_heap_size(), 0); | 8493 CHECK_EQ(heap_statistics.used_heap_size(), 0); |
8170 v8::V8::GetHeapStatistics(&heap_statistics); | 8494 v8::V8::GetHeapStatistics(&heap_statistics); |
8171 CHECK_NE(heap_statistics.total_heap_size(), 0); | 8495 CHECK_NE(heap_statistics.total_heap_size(), 0); |
8172 CHECK_NE(heap_statistics.used_heap_size(), 0); | 8496 CHECK_NE(heap_statistics.used_heap_size(), 0); |
8173 } | 8497 } |
OLD | NEW |