Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(531)

Side by Side Diff: test/cctest/test-api.cc

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/cctest.status ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 Local<String> source = 422 Local<String> source =
423 String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); 423 String::NewExternal(new TestAsciiResource(i::StrDup(c_source)));
424 Local<Script> script = Script::Compile(source); 424 Local<Script> script = Script::Compile(source);
425 Local<Value> value = script->Run(); 425 Local<Value> value = script->Run();
426 CHECK(value->IsNumber()); 426 CHECK(value->IsNumber());
427 CHECK_EQ(7, value->Int32Value()); 427 CHECK_EQ(7, value->Int32Value());
428 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 428 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
429 CHECK_EQ(0, TestAsciiResource::dispose_count); 429 CHECK_EQ(0, TestAsciiResource::dispose_count);
430 } 430 }
431 i::Isolate::Current()->compilation_cache()->Clear(); 431 i::Isolate::Current()->compilation_cache()->Clear();
432 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); 432 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
433 CHECK_EQ(1, TestAsciiResource::dispose_count); 433 CHECK_EQ(1, TestAsciiResource::dispose_count);
434 } 434 }
435 435
436 436
437 THREADED_TEST(ScriptMakingExternalString) { 437 THREADED_TEST(ScriptMakingExternalString) {
438 TestResource::dispose_count = 0; 438 TestResource::dispose_count = 0;
439 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); 439 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3");
440 { 440 {
441 v8::HandleScope scope; 441 v8::HandleScope scope;
442 LocalContext env; 442 LocalContext env;
(...skipping 2589 matching lines...) Expand 10 before | Expand all | Expand 10 after
3032 result = script_define->Run(); 3032 result = script_define->Run();
3033 CHECK_EQ(result, v8_num(43)); 3033 CHECK_EQ(result, v8_num(43));
3034 result = script_desc->Run(); 3034 result = script_desc->Run();
3035 CHECK_EQ(result->BooleanValue(), false); 3035 CHECK_EQ(result->BooleanValue(), false);
3036 3036
3037 // Make sure that it is not possible to redefine again 3037 // Make sure that it is not possible to redefine again
3038 v8::TryCatch try_catch; 3038 v8::TryCatch try_catch;
3039 result = script_define->Run(); 3039 result = script_define->Run();
3040 CHECK(try_catch.HasCaught()); 3040 CHECK(try_catch.HasCaught());
3041 String::AsciiValue exception_value(try_catch.Exception()); 3041 String::AsciiValue exception_value(try_catch.Exception());
3042 CHECK_EQ(*exception_value, 3042 CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
3043 "TypeError: Cannot redefine property: defineProperty");
3044 } 3043 }
3045 3044
3046 THREADED_TEST(DefinePropertyOnDefineGetterSetter) { 3045 THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
3047 v8::HandleScope scope; 3046 v8::HandleScope scope;
3048 Local<ObjectTemplate> templ = ObjectTemplate::New(); 3047 Local<ObjectTemplate> templ = ObjectTemplate::New();
3049 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); 3048 templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"));
3050 LocalContext context; 3049 LocalContext context;
3051 context->Global()->Set(v8_str("obj"), templ->NewInstance()); 3050 context->Global()->Set(v8_str("obj"), templ->NewInstance());
3052 3051
3053 Local<Script> script_desc = Script::Compile(v8_str("var prop =" 3052 Local<Script> script_desc = Script::Compile(v8_str("var prop ="
(...skipping 24 matching lines...) Expand all
3078 result = script_define->Run(); 3077 result = script_define->Run();
3079 CHECK_EQ(result, v8_num(43)); 3078 CHECK_EQ(result, v8_num(43));
3080 result = script_desc->Run(); 3079 result = script_desc->Run();
3081 3080
3082 CHECK_EQ(result->BooleanValue(), false); 3081 CHECK_EQ(result->BooleanValue(), false);
3083 3082
3084 v8::TryCatch try_catch; 3083 v8::TryCatch try_catch;
3085 result = script_define->Run(); 3084 result = script_define->Run();
3086 CHECK(try_catch.HasCaught()); 3085 CHECK(try_catch.HasCaught());
3087 String::AsciiValue exception_value(try_catch.Exception()); 3086 String::AsciiValue exception_value(try_catch.Exception());
3088 CHECK_EQ(*exception_value, 3087 CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
3089 "TypeError: Cannot redefine property: defineProperty");
3090 } 3088 }
3091 3089
3092 3090
3093 static v8::Handle<v8::Object> GetGlobalProperty(LocalContext* context, 3091 static v8::Handle<v8::Object> GetGlobalProperty(LocalContext* context,
3094 char const* name) { 3092 char const* name) {
3095 return v8::Handle<v8::Object>::Cast((*context)->Global()->Get(v8_str(name))); 3093 return v8::Handle<v8::Object>::Cast((*context)->Global()->Get(v8_str(name)));
3096 } 3094 }
3097 3095
3098 3096
3099 THREADED_TEST(DefineAPIAccessorOnObject) { 3097 THREADED_TEST(DefineAPIAccessorOnObject) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3197 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); 3195 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
3198 CHECK(!GetGlobalProperty(&context, "obj2")-> 3196 CHECK(!GetGlobalProperty(&context, "obj2")->
3199 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); 3197 SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
3200 3198
3201 { 3199 {
3202 v8::TryCatch try_catch; 3200 v8::TryCatch try_catch;
3203 CompileRun("Object.defineProperty(obj1, 'x'," 3201 CompileRun("Object.defineProperty(obj1, 'x',"
3204 "{get: function() { return 'func'; }})"); 3202 "{get: function() { return 'func'; }})");
3205 CHECK(try_catch.HasCaught()); 3203 CHECK(try_catch.HasCaught());
3206 String::AsciiValue exception_value(try_catch.Exception()); 3204 String::AsciiValue exception_value(try_catch.Exception());
3207 CHECK_EQ(*exception_value, 3205 CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
3208 "TypeError: Cannot redefine property: defineProperty");
3209 } 3206 }
3210 { 3207 {
3211 v8::TryCatch try_catch; 3208 v8::TryCatch try_catch;
3212 CompileRun("Object.defineProperty(obj2, 'x'," 3209 CompileRun("Object.defineProperty(obj2, 'x',"
3213 "{get: function() { return 'func'; }})"); 3210 "{get: function() { return 'func'; }})");
3214 CHECK(try_catch.HasCaught()); 3211 CHECK(try_catch.HasCaught());
3215 String::AsciiValue exception_value(try_catch.Exception()); 3212 String::AsciiValue exception_value(try_catch.Exception());
3216 CHECK_EQ(*exception_value, 3213 CHECK_EQ(*exception_value, "TypeError: Cannot redefine property: x");
3217 "TypeError: Cannot redefine property: defineProperty");
3218 } 3214 }
3219 } 3215 }
3220 3216
3221 3217
3222 static v8::Handle<Value> Get239Value(Local<String> name, 3218 static v8::Handle<Value> Get239Value(Local<String> name,
3223 const AccessorInfo& info) { 3219 const AccessorInfo& info) {
3224 ApiTestFuzzer::Fuzz(); 3220 ApiTestFuzzer::Fuzz();
3225 CHECK_EQ(info.Data(), v8_str("donut")); 3221 CHECK_EQ(info.Data(), v8_str("donut"));
3226 CHECK_EQ(name, v8_str("239")); 3222 CHECK_EQ(name, v8_str("239"));
3227 return name; 3223 return name;
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
3859 3855
3860 3856
3861 ExpectBoolean("undetectable===null", false); 3857 ExpectBoolean("undetectable===null", false);
3862 ExpectBoolean("null===undetectable", false); 3858 ExpectBoolean("null===undetectable", false);
3863 ExpectBoolean("undetectable===undefined", false); 3859 ExpectBoolean("undetectable===undefined", false);
3864 ExpectBoolean("undefined===undetectable", false); 3860 ExpectBoolean("undefined===undetectable", false);
3865 ExpectBoolean("undetectable===undetectable", true); 3861 ExpectBoolean("undetectable===undetectable", true);
3866 } 3862 }
3867 3863
3868 3864
3865 THREADED_TEST(VoidLiteral) {
3866 v8::HandleScope scope;
3867 LocalContext env;
3868
3869 Local<v8::FunctionTemplate> desc =
3870 v8::FunctionTemplate::New(0, v8::Handle<Value>());
3871 desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
3872
3873 Local<v8::Object> obj = desc->GetFunction()->NewInstance();
3874 env->Global()->Set(v8_str("undetectable"), obj);
3875
3876 ExpectBoolean("undefined == void 0", true);
3877 ExpectBoolean("undetectable == void 0", true);
3878 ExpectBoolean("null == void 0", true);
3879 ExpectBoolean("undefined === void 0", true);
3880 ExpectBoolean("undetectable === void 0", false);
3881 ExpectBoolean("null === void 0", false);
3882
3883 ExpectBoolean("void 0 == undefined", true);
3884 ExpectBoolean("void 0 == undetectable", true);
3885 ExpectBoolean("void 0 == null", true);
3886 ExpectBoolean("void 0 === undefined", true);
3887 ExpectBoolean("void 0 === undetectable", false);
3888 ExpectBoolean("void 0 === null", false);
3889
3890 ExpectString("(function() {"
3891 " try {"
3892 " return x === void 0;"
3893 " } catch(e) {"
3894 " return e.toString();"
3895 " }"
3896 "})()",
3897 "ReferenceError: x is not defined");
3898 ExpectString("(function() {"
3899 " try {"
3900 " return void 0 === x;"
3901 " } catch(e) {"
3902 " return e.toString();"
3903 " }"
3904 "})()",
3905 "ReferenceError: x is not defined");
3906 }
3907
3869 3908
3870 THREADED_TEST(ExtensibleOnUndetectable) { 3909 THREADED_TEST(ExtensibleOnUndetectable) {
3871 v8::HandleScope scope; 3910 v8::HandleScope scope;
3872 LocalContext env; 3911 LocalContext env;
3873 3912
3874 Local<v8::FunctionTemplate> desc = 3913 Local<v8::FunctionTemplate> desc =
3875 v8::FunctionTemplate::New(0, v8::Handle<Value>()); 3914 v8::FunctionTemplate::New(0, v8::Handle<Value>());
3876 desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable 3915 desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
3877 3916
3878 Local<v8::Object> obj = desc->GetFunction()->NewInstance(); 3917 Local<v8::Object> obj = desc->GetFunction()->NewInstance();
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 kNativeCallInExtensionSource)); 4193 kNativeCallInExtensionSource));
4155 const char* extension_names[] = { "nativecall" }; 4194 const char* extension_names[] = { "nativecall" };
4156 v8::ExtensionConfiguration extensions(1, extension_names); 4195 v8::ExtensionConfiguration extensions(1, extension_names);
4157 v8::Handle<Context> context = Context::New(&extensions); 4196 v8::Handle<Context> context = Context::New(&extensions);
4158 Context::Scope lock(context); 4197 Context::Scope lock(context);
4159 v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run(); 4198 v8::Handle<Value> result = Script::Compile(v8_str(kNativeCallTest))->Run();
4160 CHECK_EQ(result, v8::Integer::New(3)); 4199 CHECK_EQ(result, v8::Integer::New(3));
4161 } 4200 }
4162 4201
4163 4202
4203 class NativeFunctionExtension : public Extension {
4204 public:
4205 NativeFunctionExtension(const char* name,
4206 const char* source,
4207 v8::InvocationCallback fun = &Echo)
4208 : Extension(name, source),
4209 function_(fun) { }
4210
4211 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
4212 v8::Handle<v8::String> name) {
4213 return v8::FunctionTemplate::New(function_);
4214 }
4215
4216 static v8::Handle<v8::Value> Echo(const v8::Arguments& args) {
4217 if (args.Length() >= 1) return (args[0]);
4218 return v8::Undefined();
4219 }
4220 private:
4221 v8::InvocationCallback function_;
4222 };
4223
4224
4225 THREADED_TEST(NativeFunctionDeclaration) {
4226 v8::HandleScope handle_scope;
4227 const char* name = "nativedecl";
4228 v8::RegisterExtension(new NativeFunctionExtension(name,
4229 "native function foo();"));
4230 const char* extension_names[] = { name };
4231 v8::ExtensionConfiguration extensions(1, extension_names);
4232 v8::Handle<Context> context = Context::New(&extensions);
4233 Context::Scope lock(context);
4234 v8::Handle<Value> result = Script::Compile(v8_str("foo(42);"))->Run();
4235 CHECK_EQ(result, v8::Integer::New(42));
4236 }
4237
4238
4239 THREADED_TEST(NativeFunctionDeclarationError) {
4240 v8::HandleScope handle_scope;
4241 const char* name = "nativedeclerr";
4242 // Syntax error in extension code.
4243 v8::RegisterExtension(new NativeFunctionExtension(name,
4244 "native\nfunction foo();"));
4245 const char* extension_names[] = { name };
4246 v8::ExtensionConfiguration extensions(1, extension_names);
4247 v8::Handle<Context> context = Context::New(&extensions);
4248 ASSERT(context.IsEmpty());
4249 }
4250
4251 THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
4252 v8::HandleScope handle_scope;
4253 const char* name = "nativedeclerresc";
4254 // Syntax error in extension code - escape code in "native" means that
4255 // it's not treated as a keyword.
4256 v8::RegisterExtension(new NativeFunctionExtension(
4257 name,
4258 "nativ\\u0065 function foo();"));
4259 const char* extension_names[] = { name };
4260 v8::ExtensionConfiguration extensions(1, extension_names);
4261 v8::Handle<Context> context = Context::New(&extensions);
4262 ASSERT(context.IsEmpty());
4263 }
4264
4265
4164 static void CheckDependencies(const char* name, const char* expected) { 4266 static void CheckDependencies(const char* name, const char* expected) {
4165 v8::HandleScope handle_scope; 4267 v8::HandleScope handle_scope;
4166 v8::ExtensionConfiguration config(1, &name); 4268 v8::ExtensionConfiguration config(1, &name);
4167 LocalContext context(&config); 4269 LocalContext context(&config);
4168 CHECK_EQ(String::New(expected), context->Global()->Get(v8_str("loaded"))); 4270 CHECK_EQ(String::New(expected), context->Global()->Get(v8_str("loaded")));
4169 } 4271 }
4170 4272
4171 4273
4172 /* 4274 /*
4173 * Configuration: 4275 * Configuration:
(...skipping 2483 matching lines...) Expand 10 before | Expand all | Expand 10 after
6657 Local<Value>(), 6759 Local<Value>(),
6658 signature)); 6760 signature));
6659 proto->Set(v8_str("x"), v8_num(12)); 6761 proto->Set(v8_str("x"), v8_num(12));
6660 6762
6661 instance->SetAccessor(v8_str("y"), ShadowYGetter, ShadowYSetter); 6763 instance->SetAccessor(v8_str("y"), ShadowYGetter, ShadowYSetter);
6662 6764
6663 Local<Value> o = t->GetFunction()->NewInstance(); 6765 Local<Value> o = t->GetFunction()->NewInstance();
6664 context->Global()->Set(v8_str("__proto__"), o); 6766 context->Global()->Set(v8_str("__proto__"), o);
6665 6767
6666 Local<Value> value = 6768 Local<Value> value =
6667 Script::Compile(v8_str("propertyIsEnumerable(0)"))->Run(); 6769 Script::Compile(v8_str("this.propertyIsEnumerable(0)"))->Run();
6668 CHECK(value->IsBoolean()); 6770 CHECK(value->IsBoolean());
6669 CHECK(!value->BooleanValue()); 6771 CHECK(!value->BooleanValue());
6670 6772
6671 value = Script::Compile(v8_str("x"))->Run(); 6773 value = Script::Compile(v8_str("x"))->Run();
6672 CHECK_EQ(12, value->Int32Value()); 6774 CHECK_EQ(12, value->Int32Value());
6673 6775
6674 value = Script::Compile(v8_str("f()"))->Run(); 6776 value = Script::Compile(v8_str("f()"))->Run();
6675 CHECK_EQ(42, value->Int32Value()); 6777 CHECK_EQ(42, value->Int32Value());
6676 6778
6677 Script::Compile(v8_str("y = 42"))->Run(); 6779 Script::Compile(v8_str("y = 42"))->Run();
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
6776 Local<Value> proto1 = o1->GetPrototype(); 6878 Local<Value> proto1 = o1->GetPrototype();
6777 CHECK(proto1->IsObject()); 6879 CHECK(proto1->IsObject());
6778 CHECK_EQ(proto1.As<v8::Object>(), o2); 6880 CHECK_EQ(proto1.As<v8::Object>(), o2);
6779 6881
6780 Local<Value> proto2 = o2->GetPrototype(); 6882 Local<Value> proto2 = o2->GetPrototype();
6781 CHECK(proto2->IsObject()); 6883 CHECK(proto2->IsObject());
6782 CHECK_EQ(proto2.As<v8::Object>(), o3); 6884 CHECK_EQ(proto2.As<v8::Object>(), o3);
6783 } 6885 }
6784 6886
6785 6887
6888 THREADED_TEST(SetPrototypeProperties) {
6889 v8::HandleScope handle_scope;
6890 LocalContext context;
6891
6892 Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
6893 t1->SetPrototypeAttributes(v8::DontDelete);
6894 context->Global()->Set(v8_str("func1"), t1->GetFunction());
6895 CHECK(CompileRun(
6896 "(function() {"
6897 " descriptor = Object.getOwnPropertyDescriptor(func1, 'prototype');"
6898 " return (descriptor['writable'] == true) &&"
6899 " (descriptor['enumerable'] == true) &&"
6900 " (descriptor['configurable'] == false);"
6901 "})()")->BooleanValue());
6902
6903 Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
6904 t2->SetPrototypeAttributes(v8::DontEnum);
6905 context->Global()->Set(v8_str("func2"), t2->GetFunction());
6906 CHECK(CompileRun(
6907 "(function() {"
6908 " descriptor = Object.getOwnPropertyDescriptor(func2, 'prototype');"
6909 " return (descriptor['writable'] == true) &&"
6910 " (descriptor['enumerable'] == false) &&"
6911 " (descriptor['configurable'] == true);"
6912 "})()")->BooleanValue());
6913
6914 Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
6915 t3->SetPrototypeAttributes(v8::ReadOnly);
6916 context->Global()->Set(v8_str("func3"), t3->GetFunction());
6917 CHECK(CompileRun(
6918 "(function() {"
6919 " descriptor = Object.getOwnPropertyDescriptor(func3, 'prototype');"
6920 " return (descriptor['writable'] == false) &&"
6921 " (descriptor['enumerable'] == true) &&"
6922 " (descriptor['configurable'] == true);"
6923 "})()")->BooleanValue());
6924
6925 Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
6926 t4->SetPrototypeAttributes(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
6927 context->Global()->Set(v8_str("func4"), t4->GetFunction());
6928 CHECK(CompileRun(
6929 "(function() {"
6930 " descriptor = Object.getOwnPropertyDescriptor(func4, 'prototype');"
6931 " return (descriptor['writable'] == false) &&"
6932 " (descriptor['enumerable'] == false) &&"
6933 " (descriptor['configurable'] == false);"
6934 "})()")->BooleanValue());
6935 }
6936
6937
6786 THREADED_TEST(SetPrototypeThrows) { 6938 THREADED_TEST(SetPrototypeThrows) {
6787 v8::HandleScope handle_scope; 6939 v8::HandleScope handle_scope;
6788 LocalContext context; 6940 LocalContext context;
6789 6941
6790 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); 6942 Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
6791 6943
6792 Local<v8::Object> o0 = t->GetFunction()->NewInstance(); 6944 Local<v8::Object> o0 = t->GetFunction()->NewInstance();
6793 Local<v8::Object> o1 = t->GetFunction()->NewInstance(); 6945 Local<v8::Object> o1 = t->GetFunction()->NewInstance();
6794 6946
6795 CHECK(o0->SetPrototype(o1)); 6947 CHECK(o0->SetPrototype(o1));
(...skipping 2539 matching lines...) Expand 10 before | Expand all | Expand 10 after
9335 9487
9336 9488
9337 void ApiTestFuzzer::Setup(PartOfTest part) { 9489 void ApiTestFuzzer::Setup(PartOfTest part) {
9338 linear_congruential_generator = i::FLAG_testing_prng_seed; 9490 linear_congruential_generator = i::FLAG_testing_prng_seed;
9339 fuzzing_ = true; 9491 fuzzing_ = true;
9340 int count = RegisterThreadedTest::count(); 9492 int count = RegisterThreadedTest::count();
9341 int start = count * part / (LAST_PART + 1); 9493 int start = count * part / (LAST_PART + 1);
9342 int end = (count * (part + 1) / (LAST_PART + 1)) - 1; 9494 int end = (count * (part + 1) / (LAST_PART + 1)) - 1;
9343 active_tests_ = tests_being_run_ = end - start + 1; 9495 active_tests_ = tests_being_run_ = end - start + 1;
9344 for (int i = 0; i < tests_being_run_; i++) { 9496 for (int i = 0; i < tests_being_run_; i++) {
9345 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer( 9497 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer(i + start);
9346 i::Isolate::Current(), i + start);
9347 } 9498 }
9348 for (int i = 0; i < active_tests_; i++) { 9499 for (int i = 0; i < active_tests_; i++) {
9349 RegisterThreadedTest::nth(i)->fuzzer_->Start(); 9500 RegisterThreadedTest::nth(i)->fuzzer_->Start();
9350 } 9501 }
9351 } 9502 }
9352 9503
9353 9504
9354 static void CallTestNumber(int test_number) { 9505 static void CallTestNumber(int test_number) {
9355 (RegisterThreadedTest::nth(test_number)->callback())(); 9506 (RegisterThreadedTest::nth(test_number)->callback())();
9356 } 9507 }
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
9908 v8::Handle<v8::Object> obj = val.As<v8::Object>(); 10059 v8::Handle<v8::Object> obj = val.As<v8::Object>();
9909 v8::Handle<v8::Array> props = obj->GetPropertyNames(); 10060 v8::Handle<v8::Array> props = obj->GetPropertyNames();
9910 CHECK_EQ(elmc, props->Length()); 10061 CHECK_EQ(elmc, props->Length());
9911 for (int i = 0; i < elmc; i++) { 10062 for (int i = 0; i < elmc; i++) {
9912 v8::String::Utf8Value elm(props->Get(v8::Integer::New(i))); 10063 v8::String::Utf8Value elm(props->Get(v8::Integer::New(i)));
9913 CHECK_EQ(elmv[i], *elm); 10064 CHECK_EQ(elmv[i], *elm);
9914 } 10065 }
9915 } 10066 }
9916 10067
9917 10068
10069 void CheckOwnProperties(v8::Handle<v8::Value> val,
10070 int elmc,
10071 const char* elmv[]) {
10072 v8::Handle<v8::Object> obj = val.As<v8::Object>();
10073 v8::Handle<v8::Array> props = obj->GetOwnPropertyNames();
10074 CHECK_EQ(elmc, props->Length());
10075 for (int i = 0; i < elmc; i++) {
10076 v8::String::Utf8Value elm(props->Get(v8::Integer::New(i)));
10077 CHECK_EQ(elmv[i], *elm);
10078 }
10079 }
10080
10081
9918 THREADED_TEST(PropertyEnumeration) { 10082 THREADED_TEST(PropertyEnumeration) {
9919 v8::HandleScope scope; 10083 v8::HandleScope scope;
9920 LocalContext context; 10084 LocalContext context;
9921 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( 10085 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New(
9922 "var result = [];" 10086 "var result = [];"
9923 "result[0] = {};" 10087 "result[0] = {};"
9924 "result[1] = {a: 1, b: 2};" 10088 "result[1] = {a: 1, b: 2};"
9925 "result[2] = [1, 2, 3];" 10089 "result[2] = [1, 2, 3];"
9926 "var proto = {x: 1, y: 2, z: 3};" 10090 "var proto = {x: 1, y: 2, z: 3};"
9927 "var x = { __proto__: proto, w: 0, z: 1 };" 10091 "var x = { __proto__: proto, w: 0, z: 1 };"
9928 "result[3] = x;" 10092 "result[3] = x;"
9929 "result;"))->Run(); 10093 "result;"))->Run();
9930 v8::Handle<v8::Array> elms = obj.As<v8::Array>(); 10094 v8::Handle<v8::Array> elms = obj.As<v8::Array>();
9931 CHECK_EQ(4, elms->Length()); 10095 CHECK_EQ(4, elms->Length());
9932 int elmc0 = 0; 10096 int elmc0 = 0;
9933 const char** elmv0 = NULL; 10097 const char** elmv0 = NULL;
9934 CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); 10098 CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
10099 CheckOwnProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0);
9935 int elmc1 = 2; 10100 int elmc1 = 2;
9936 const char* elmv1[] = {"a", "b"}; 10101 const char* elmv1[] = {"a", "b"};
9937 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); 10102 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
10103 CheckOwnProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1);
9938 int elmc2 = 3; 10104 int elmc2 = 3;
9939 const char* elmv2[] = {"0", "1", "2"}; 10105 const char* elmv2[] = {"0", "1", "2"};
9940 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); 10106 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
10107 CheckOwnProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2);
9941 int elmc3 = 4; 10108 int elmc3 = 4;
9942 const char* elmv3[] = {"w", "z", "x", "y"}; 10109 const char* elmv3[] = {"w", "z", "x", "y"};
9943 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); 10110 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3);
10111 int elmc4 = 2;
10112 const char* elmv4[] = {"w", "z"};
10113 CheckOwnProperties(elms->Get(v8::Integer::New(3)), elmc4, elmv4);
9944 } 10114 }
9945 10115
9946 THREADED_TEST(PropertyEnumeration2) { 10116 THREADED_TEST(PropertyEnumeration2) {
9947 v8::HandleScope scope; 10117 v8::HandleScope scope;
9948 LocalContext context; 10118 LocalContext context;
9949 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( 10119 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New(
9950 "var result = [];" 10120 "var result = [];"
9951 "result[0] = {};" 10121 "result[0] = {};"
9952 "result[1] = {a: 1, b: 2};" 10122 "result[1] = {a: 1, b: 2};"
9953 "result[2] = [1, 2, 3];" 10123 "result[2] = [1, 2, 3];"
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
10453 class RegExpInterruptTest { 10623 class RegExpInterruptTest {
10454 public: 10624 public:
10455 RegExpInterruptTest() : block_(NULL) {} 10625 RegExpInterruptTest() : block_(NULL) {}
10456 ~RegExpInterruptTest() { delete block_; } 10626 ~RegExpInterruptTest() { delete block_; }
10457 void RunTest() { 10627 void RunTest() {
10458 block_ = i::OS::CreateSemaphore(0); 10628 block_ = i::OS::CreateSemaphore(0);
10459 gc_count_ = 0; 10629 gc_count_ = 0;
10460 gc_during_regexp_ = 0; 10630 gc_during_regexp_ = 0;
10461 regexp_success_ = false; 10631 regexp_success_ = false;
10462 gc_success_ = false; 10632 gc_success_ = false;
10463 GCThread gc_thread(i::Isolate::Current(), this); 10633 GCThread gc_thread(this);
10464 gc_thread.Start(); 10634 gc_thread.Start();
10465 v8::Locker::StartPreemption(1); 10635 v8::Locker::StartPreemption(1);
10466 10636
10467 LongRunningRegExp(); 10637 LongRunningRegExp();
10468 { 10638 {
10469 v8::Unlocker unlock; 10639 v8::Unlocker unlock;
10470 gc_thread.Join(); 10640 gc_thread.Join();
10471 } 10641 }
10472 v8::Locker::StopPreemption(); 10642 v8::Locker::StopPreemption();
10473 CHECK(regexp_success_); 10643 CHECK(regexp_success_);
10474 CHECK(gc_success_); 10644 CHECK(gc_success_);
10475 } 10645 }
10646
10476 private: 10647 private:
10477 // Number of garbage collections required. 10648 // Number of garbage collections required.
10478 static const int kRequiredGCs = 5; 10649 static const int kRequiredGCs = 5;
10479 10650
10480 class GCThread : public i::Thread { 10651 class GCThread : public i::Thread {
10481 public: 10652 public:
10482 explicit GCThread(i::Isolate* isolate, RegExpInterruptTest* test) 10653 explicit GCThread(RegExpInterruptTest* test)
10483 : Thread(isolate, "GCThread"), test_(test) {} 10654 : Thread("GCThread"), test_(test) {}
10484 virtual void Run() { 10655 virtual void Run() {
10485 test_->CollectGarbage(); 10656 test_->CollectGarbage();
10486 } 10657 }
10487 private: 10658 private:
10488 RegExpInterruptTest* test_; 10659 RegExpInterruptTest* test_;
10489 }; 10660 };
10490 10661
10491 void CollectGarbage() { 10662 void CollectGarbage() {
10492 block_->Wait(); 10663 block_->Wait();
10493 while (gc_during_regexp_ < kRequiredGCs) { 10664 while (gc_during_regexp_ < kRequiredGCs) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
10575 class ApplyInterruptTest { 10746 class ApplyInterruptTest {
10576 public: 10747 public:
10577 ApplyInterruptTest() : block_(NULL) {} 10748 ApplyInterruptTest() : block_(NULL) {}
10578 ~ApplyInterruptTest() { delete block_; } 10749 ~ApplyInterruptTest() { delete block_; }
10579 void RunTest() { 10750 void RunTest() {
10580 block_ = i::OS::CreateSemaphore(0); 10751 block_ = i::OS::CreateSemaphore(0);
10581 gc_count_ = 0; 10752 gc_count_ = 0;
10582 gc_during_apply_ = 0; 10753 gc_during_apply_ = 0;
10583 apply_success_ = false; 10754 apply_success_ = false;
10584 gc_success_ = false; 10755 gc_success_ = false;
10585 GCThread gc_thread(i::Isolate::Current(), this); 10756 GCThread gc_thread(this);
10586 gc_thread.Start(); 10757 gc_thread.Start();
10587 v8::Locker::StartPreemption(1); 10758 v8::Locker::StartPreemption(1);
10588 10759
10589 LongRunningApply(); 10760 LongRunningApply();
10590 { 10761 {
10591 v8::Unlocker unlock; 10762 v8::Unlocker unlock;
10592 gc_thread.Join(); 10763 gc_thread.Join();
10593 } 10764 }
10594 v8::Locker::StopPreemption(); 10765 v8::Locker::StopPreemption();
10595 CHECK(apply_success_); 10766 CHECK(apply_success_);
10596 CHECK(gc_success_); 10767 CHECK(gc_success_);
10597 } 10768 }
10769
10598 private: 10770 private:
10599 // Number of garbage collections required. 10771 // Number of garbage collections required.
10600 static const int kRequiredGCs = 2; 10772 static const int kRequiredGCs = 2;
10601 10773
10602 class GCThread : public i::Thread { 10774 class GCThread : public i::Thread {
10603 public: 10775 public:
10604 explicit GCThread(i::Isolate* isolate, ApplyInterruptTest* test) 10776 explicit GCThread(ApplyInterruptTest* test)
10605 : Thread(isolate, "GCThread"), test_(test) {} 10777 : Thread("GCThread"), test_(test) {}
10606 virtual void Run() { 10778 virtual void Run() {
10607 test_->CollectGarbage(); 10779 test_->CollectGarbage();
10608 } 10780 }
10609 private: 10781 private:
10610 ApplyInterruptTest* test_; 10782 ApplyInterruptTest* test_;
10611 }; 10783 };
10612 10784
10613 void CollectGarbage() { 10785 void CollectGarbage() {
10614 block_->Wait(); 10786 block_->Wait();
10615 while (gc_during_apply_ < kRequiredGCs) { 10787 while (gc_during_apply_ < kRequiredGCs) {
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
10869 11041
10870 // Inject the input as a global variable. 11042 // Inject the input as a global variable.
10871 i::Handle<i::String> input_name = 11043 i::Handle<i::String> input_name =
10872 FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5)); 11044 FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5));
10873 i::Isolate::Current()->global_context()->global()->SetProperty( 11045 i::Isolate::Current()->global_context()->global()->SetProperty(
10874 *input_name, 11046 *input_name,
10875 *input_, 11047 *input_,
10876 NONE, 11048 NONE,
10877 i::kNonStrictMode)->ToObjectChecked(); 11049 i::kNonStrictMode)->ToObjectChecked();
10878 11050
10879 MorphThread morph_thread(i::Isolate::Current(), this); 11051 MorphThread morph_thread(this);
10880 morph_thread.Start(); 11052 morph_thread.Start();
10881 v8::Locker::StartPreemption(1); 11053 v8::Locker::StartPreemption(1);
10882 LongRunningRegExp(); 11054 LongRunningRegExp();
10883 { 11055 {
10884 v8::Unlocker unlock; 11056 v8::Unlocker unlock;
10885 morph_thread.Join(); 11057 morph_thread.Join();
10886 } 11058 }
10887 v8::Locker::StopPreemption(); 11059 v8::Locker::StopPreemption();
10888 CHECK(regexp_success_); 11060 CHECK(regexp_success_);
10889 CHECK(morph_success_); 11061 CHECK(morph_success_);
10890 } 11062 }
11063
10891 private: 11064 private:
10892
10893 // Number of string modifications required. 11065 // Number of string modifications required.
10894 static const int kRequiredModifications = 5; 11066 static const int kRequiredModifications = 5;
10895 static const int kMaxModifications = 100; 11067 static const int kMaxModifications = 100;
10896 11068
10897 class MorphThread : public i::Thread { 11069 class MorphThread : public i::Thread {
10898 public: 11070 public:
10899 explicit MorphThread(i::Isolate* isolate, 11071 explicit MorphThread(RegExpStringModificationTest* test)
10900 RegExpStringModificationTest* test) 11072 : Thread("MorphThread"), test_(test) {}
10901 : Thread(isolate, "MorphThread"), test_(test) {}
10902 virtual void Run() { 11073 virtual void Run() {
10903 test_->MorphString(); 11074 test_->MorphString();
10904 } 11075 }
10905 private: 11076 private:
10906 RegExpStringModificationTest* test_; 11077 RegExpStringModificationTest* test_;
10907 }; 11078 };
10908 11079
10909 void MorphString() { 11080 void MorphString() {
10910 block_->Wait(); 11081 block_->Wait();
10911 while (morphs_during_regexp_ < kRequiredModifications && 11082 while (morphs_during_regexp_ < kRequiredModifications &&
(...skipping 2801 matching lines...) Expand 10 before | Expand all | Expand 10 after
13713 " return fib(n-1) + fib(n-2);" 13884 " return fib(n-1) + fib(n-2);"
13714 "}" 13885 "}"
13715 "fib(%d)", limit); 13886 "fib(%d)", limit);
13716 Local<Value> value = CompileRun(code.start()); 13887 Local<Value> value = CompileRun(code.start());
13717 CHECK(value->IsNumber()); 13888 CHECK(value->IsNumber());
13718 return static_cast<int>(value->NumberValue()); 13889 return static_cast<int>(value->NumberValue());
13719 } 13890 }
13720 13891
13721 class IsolateThread : public v8::internal::Thread { 13892 class IsolateThread : public v8::internal::Thread {
13722 public: 13893 public:
13723 explicit IsolateThread(v8::Isolate* isolate, int fib_limit) 13894 IsolateThread(v8::Isolate* isolate, int fib_limit)
13724 : Thread(NULL, "IsolateThread"), 13895 : Thread("IsolateThread"),
13725 isolate_(isolate), 13896 isolate_(isolate),
13726 fib_limit_(fib_limit), 13897 fib_limit_(fib_limit),
13727 result_(0) { } 13898 result_(0) { }
13728 13899
13729 void Run() { 13900 void Run() {
13730 result_ = CalcFibonacci(isolate_, fib_limit_); 13901 result_ = CalcFibonacci(isolate_, fib_limit_);
13731 } 13902 }
13732 13903
13733 int result() { return result_; } 13904 int result() { return result_; }
13734 13905
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
13794 enum TestCase { 13965 enum TestCase {
13795 IgnoreOOM, 13966 IgnoreOOM,
13796 SetResourceConstraints, 13967 SetResourceConstraints,
13797 SetFatalHandler, 13968 SetFatalHandler,
13798 SetCounterFunction, 13969 SetCounterFunction,
13799 SetCreateHistogramFunction, 13970 SetCreateHistogramFunction,
13800 SetAddHistogramSampleFunction 13971 SetAddHistogramSampleFunction
13801 }; 13972 };
13802 13973
13803 explicit InitDefaultIsolateThread(TestCase testCase) 13974 explicit InitDefaultIsolateThread(TestCase testCase)
13804 : Thread(NULL, "InitDefaultIsolateThread"), 13975 : Thread("InitDefaultIsolateThread"),
13805 testCase_(testCase), 13976 testCase_(testCase),
13806 result_(false) { } 13977 result_(false) { }
13807 13978
13808 void Run() { 13979 void Run() {
13809 switch (testCase_) { 13980 switch (testCase_) {
13810 case IgnoreOOM: 13981 case IgnoreOOM:
13811 v8::V8::IgnoreOutOfMemoryException(); 13982 v8::V8::IgnoreOutOfMemoryException();
13812 break; 13983 break;
13813 13984
13814 case SetResourceConstraints: { 13985 case SetResourceConstraints: {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
14037 " try {" 14208 " try {"
14038 " return readCell();" 14209 " return readCell();"
14039 " } catch(e) {" 14210 " } catch(e) {"
14040 " return e.toString();" 14211 " return e.toString();"
14041 " }" 14212 " }"
14042 "})()", 14213 "})()",
14043 "ReferenceError: cell is not defined"); 14214 "ReferenceError: cell is not defined");
14044 } 14215 }
14045 14216
14046 14217
14047 TEST(GlobalLoadICGC) {
14048 const char* function_code =
14049 "function readCell() { while (true) { return cell; } }";
14050
14051 // Check inline load code for a don't delete cell is cleared during
14052 // GC.
14053 {
14054 v8::HandleScope scope;
14055 LocalContext context;
14056 CompileRun("var cell = \"value\";");
14057 ExpectBoolean("delete cell", false);
14058 CompileRun(function_code);
14059 ExpectString("readCell()", "value");
14060 ExpectString("readCell()", "value");
14061 }
14062 {
14063 v8::HandleScope scope;
14064 LocalContext context2;
14065 // Hold the code object in the second context.
14066 CompileRun(function_code);
14067 CheckSurvivingGlobalObjectsCount(1);
14068 }
14069
14070 // Check inline load code for a deletable cell is cleared during GC.
14071 {
14072 v8::HandleScope scope;
14073 LocalContext context;
14074 CompileRun("cell = \"value\";");
14075 CompileRun(function_code);
14076 ExpectString("readCell()", "value");
14077 ExpectString("readCell()", "value");
14078 }
14079 {
14080 v8::HandleScope scope;
14081 LocalContext context2;
14082 // Hold the code object in the second context.
14083 CompileRun(function_code);
14084 CheckSurvivingGlobalObjectsCount(1);
14085 }
14086 }
14087
14088
14089 TEST(RegExp) { 14218 TEST(RegExp) {
14090 v8::HandleScope scope; 14219 v8::HandleScope scope;
14091 LocalContext context; 14220 LocalContext context;
14092 14221
14093 v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone); 14222 v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone);
14094 CHECK(re->IsRegExp()); 14223 CHECK(re->IsRegExp());
14095 CHECK(re->GetSource()->Equals(v8_str("foo"))); 14224 CHECK(re->GetSource()->Equals(v8_str("foo")));
14096 CHECK_EQ(re->GetFlags(), v8::RegExp::kNone); 14225 CHECK_EQ(re->GetFlags(), v8::RegExp::kNone);
14097 14226
14098 re = v8::RegExp::New(v8_str("bar"), 14227 re = v8::RegExp::New(v8_str("bar"),
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
14506 14635
14507 THREADED_TEST(CallAPIFunctionOnNonObject) { 14636 THREADED_TEST(CallAPIFunctionOnNonObject) {
14508 v8::HandleScope scope; 14637 v8::HandleScope scope;
14509 LocalContext context; 14638 LocalContext context;
14510 Handle<FunctionTemplate> templ = v8::FunctionTemplate::New(NonObjectThis); 14639 Handle<FunctionTemplate> templ = v8::FunctionTemplate::New(NonObjectThis);
14511 Handle<Function> function = templ->GetFunction(); 14640 Handle<Function> function = templ->GetFunction();
14512 context->Global()->Set(v8_str("f"), function); 14641 context->Global()->Set(v8_str("f"), function);
14513 TryCatch try_catch; 14642 TryCatch try_catch;
14514 CompileRun("f.call(2)"); 14643 CompileRun("f.call(2)");
14515 } 14644 }
14645
14646
14647 // Regression test for issue 1470.
14648 THREADED_TEST(ReadOnlyIndexedProperties) {
14649 v8::HandleScope scope;
14650 Local<ObjectTemplate> templ = ObjectTemplate::New();
14651
14652 LocalContext context;
14653 Local<v8::Object> obj = templ->NewInstance();
14654 context->Global()->Set(v8_str("obj"), obj);
14655 obj->Set(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly);
14656 obj->Set(v8_str("1"), v8_str("foobar"));
14657 CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("1")));
14658 obj->Set(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly);
14659 obj->Set(v8_num(2), v8_str("foobar"));
14660 CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_num(2)));
14661
14662 // Test non-smi case.
14663 obj->Set(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly);
14664 obj->Set(v8_str("2000000000"), v8_str("foobar"));
14665 CHECK_EQ(v8_str("DONT_CHANGE"), obj->Get(v8_str("2000000000")));
14666 }
14667
14668
14669 THREADED_TEST(Regress1516) {
14670 v8::HandleScope scope;
14671
14672 LocalContext context;
14673 { v8::HandleScope temp_scope;
14674 CompileRun("({'a': 0})");
14675 }
14676
14677 int elements;
14678 { i::MapCache* map_cache =
14679 i::MapCache::cast(i::Isolate::Current()->context()->map_cache());
14680 elements = map_cache->NumberOfElements();
14681 CHECK_LE(1, elements);
14682 }
14683
14684 i::Isolate::Current()->heap()->CollectAllGarbage(true);
14685 { i::Object* raw_map_cache = i::Isolate::Current()->context()->map_cache();
14686 if (raw_map_cache != i::Isolate::Current()->heap()->undefined_value()) {
14687 i::MapCache* map_cache = i::MapCache::cast(raw_map_cache);
14688 CHECK_GT(elements, map_cache->NumberOfElements());
14689 }
14690 }
14691 }
OLDNEW
« no previous file with comments | « test/cctest/cctest.status ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698