| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/unit_test.h" | 5 #include "vm/unit_test.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include "bin/builtin.h" | 9 #include "bin/builtin.h" |
| 10 #include "bin/dartutils.h" | 10 #include "bin/dartutils.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 while (test != NULL) { | 47 while (test != NULL) { |
| 48 test->RunTest(); | 48 test->RunTest(); |
| 49 test = test->next_; | 49 test = test->next_; |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 Dart_Isolate TestCase::CreateIsolate(const uint8_t* buffer, const char* name) { | 54 Dart_Isolate TestCase::CreateIsolate(const uint8_t* buffer, const char* name) { |
| 55 bin::IsolateData* isolate_data = new bin::IsolateData(name, NULL, NULL); | 55 bin::IsolateData* isolate_data = new bin::IsolateData(name, NULL, NULL); |
| 56 char* err; | 56 char* err; |
| 57 Dart_Isolate isolate = Dart_CreateIsolate( | 57 Dart_Isolate isolate = |
| 58 name, NULL, buffer, NULL, isolate_data, &err); | 58 Dart_CreateIsolate(name, NULL, buffer, NULL, isolate_data, &err); |
| 59 if (isolate == NULL) { | 59 if (isolate == NULL) { |
| 60 OS::Print("Creation of isolate failed '%s'\n", err); | 60 OS::Print("Creation of isolate failed '%s'\n", err); |
| 61 free(err); | 61 free(err); |
| 62 } | 62 } |
| 63 EXPECT(isolate != NULL); | 63 EXPECT(isolate != NULL); |
| 64 return isolate; | 64 return isolate; |
| 65 } | 65 } |
| 66 | 66 |
| 67 | 67 |
| 68 static const char* kPackageScheme = "package:"; | 68 static const char* kPackageScheme = "package:"; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 return NULL; | 113 return NULL; |
| 114 } | 114 } |
| 115 | 115 |
| 116 #ifndef PRODUCT | 116 #ifndef PRODUCT |
| 117 static bool IsIsolateReloadTestLib(const char* url_name) { | 117 static bool IsIsolateReloadTestLib(const char* url_name) { |
| 118 const char* kIsolateReloadTestLibUri = "test:isolate_reload_helper"; | 118 const char* kIsolateReloadTestLibUri = "test:isolate_reload_helper"; |
| 119 static const intptr_t kIsolateReloadTestLibUriLen = | 119 static const intptr_t kIsolateReloadTestLibUriLen = |
| 120 strlen(kIsolateReloadTestLibUri); | 120 strlen(kIsolateReloadTestLibUri); |
| 121 return (strncmp(url_name, | 121 return (strncmp(url_name, kIsolateReloadTestLibUri, |
| 122 kIsolateReloadTestLibUri, | |
| 123 kIsolateReloadTestLibUriLen) == 0); | 122 kIsolateReloadTestLibUriLen) == 0); |
| 124 } | 123 } |
| 125 | 124 |
| 126 | 125 |
| 127 static Dart_Handle IsolateReloadTestLibSource() { | 126 static Dart_Handle IsolateReloadTestLibSource() { |
| 128 // Special library with one function. | 127 // Special library with one function. |
| 129 return DartUtils::NewString("void reloadTest() native 'Reload_Test';\n"); | 128 return DartUtils::NewString("void reloadTest() native 'Reload_Test';\n"); |
| 130 } | 129 } |
| 131 | 130 |
| 132 | 131 |
| 133 static void ReloadTest(Dart_NativeArguments native_args) { | 132 static void ReloadTest(Dart_NativeArguments native_args) { |
| 134 DART_CHECK_VALID(TestCase::TriggerReload()); | 133 DART_CHECK_VALID(TestCase::TriggerReload()); |
| 135 } | 134 } |
| 136 | 135 |
| 137 | 136 |
| 138 static Dart_NativeFunction IsolateReloadTestNativeResolver( | 137 static Dart_NativeFunction IsolateReloadTestNativeResolver( |
| 139 Dart_Handle name, | 138 Dart_Handle name, |
| 140 int num_of_arguments, | 139 int num_of_arguments, |
| 141 bool* auto_setup_scope) { | 140 bool* auto_setup_scope) { |
| 142 return ReloadTest; | 141 return ReloadTest; |
| 143 } | 142 } |
| 144 #endif // !PRODUCT | 143 #endif // !PRODUCT |
| 145 | 144 |
| 146 | 145 |
| 147 static Dart_Handle ResolvePackageUri(const char* uri_chars) { | 146 static Dart_Handle ResolvePackageUri(const char* uri_chars) { |
| 148 const int kNumArgs = 1; | 147 const int kNumArgs = 1; |
| 149 Dart_Handle dart_args[kNumArgs]; | 148 Dart_Handle dart_args[kNumArgs]; |
| 150 dart_args[0] = DartUtils::NewString(uri_chars); | 149 dart_args[0] = DartUtils::NewString(uri_chars); |
| 151 return Dart_Invoke(DartUtils::BuiltinLib(), | 150 return Dart_Invoke(DartUtils::BuiltinLib(), |
| 152 DartUtils::NewString("_filePathFromUri"), | 151 DartUtils::NewString("_filePathFromUri"), kNumArgs, |
| 153 kNumArgs, | |
| 154 dart_args); | 152 dart_args); |
| 155 } | 153 } |
| 156 | 154 |
| 157 | 155 |
| 158 static ThreadLocalKey script_reload_key = kUnsetThreadLocalKey; | 156 static ThreadLocalKey script_reload_key = kUnsetThreadLocalKey; |
| 159 | 157 |
| 160 static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, | 158 static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, |
| 161 Dart_Handle library, | 159 Dart_Handle library, |
| 162 Dart_Handle url) { | 160 Dart_Handle url) { |
| 163 if (tag == Dart_kCanonicalizeUrl) { | 161 if (tag == Dart_kCanonicalizeUrl) { |
| 164 Dart_Handle library_url = Dart_LibraryUrl(library); | 162 Dart_Handle library_url = Dart_LibraryUrl(library); |
| 165 if (Dart_IsError(library_url)) { | 163 if (Dart_IsError(library_url)) { |
| 166 return library_url; | 164 return library_url; |
| 167 } | 165 } |
| 168 return Dart_DefaultCanonicalizeUrl(library_url, url); | 166 return Dart_DefaultCanonicalizeUrl(library_url, url); |
| 169 } | 167 } |
| 170 if (tag == Dart_kScriptTag) { | 168 if (tag == Dart_kScriptTag) { |
| 171 // Reload request. | 169 // Reload request. |
| 172 ASSERT(script_reload_key != kUnsetThreadLocalKey); | 170 ASSERT(script_reload_key != kUnsetThreadLocalKey); |
| 173 const char* script_source = | 171 const char* script_source = reinterpret_cast<const char*>( |
| 174 reinterpret_cast<const char*>( | 172 OSThread::GetThreadLocal(script_reload_key)); |
| 175 OSThread::GetThreadLocal(script_reload_key)); | |
| 176 ASSERT(script_source != NULL); | 173 ASSERT(script_source != NULL); |
| 177 OSThread::SetThreadLocal(script_reload_key, 0); | 174 OSThread::SetThreadLocal(script_reload_key, 0); |
| 178 return Dart_LoadScript(url, | 175 return Dart_LoadScript(url, Dart_Null(), NewString(script_source), 0, 0); |
| 179 Dart_Null(), | |
| 180 NewString(script_source), | |
| 181 0, | |
| 182 0); | |
| 183 } | 176 } |
| 184 if (!Dart_IsLibrary(library)) { | 177 if (!Dart_IsLibrary(library)) { |
| 185 return Dart_NewApiError("not a library"); | 178 return Dart_NewApiError("not a library"); |
| 186 } | 179 } |
| 187 if (!Dart_IsString(url)) { | 180 if (!Dart_IsString(url)) { |
| 188 return Dart_NewApiError("url is not a string"); | 181 return Dart_NewApiError("url is not a string"); |
| 189 } | 182 } |
| 190 const char* url_chars = NULL; | 183 const char* url_chars = NULL; |
| 191 Dart_Handle result = Dart_StringToCString(url, &url_chars); | 184 Dart_Handle result = Dart_StringToCString(url, &url_chars); |
| 192 if (Dart_IsError(result)) { | 185 if (Dart_IsError(result)) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 210 return Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); | 203 return Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); |
| 211 } else { | 204 } else { |
| 212 return DartUtils::NewError("Do not know how to load '%s'", url_chars); | 205 return DartUtils::NewError("Do not know how to load '%s'", url_chars); |
| 213 } | 206 } |
| 214 } | 207 } |
| 215 const char* lib_source = TestCase::GetTestLib(url_chars); | 208 const char* lib_source = TestCase::GetTestLib(url_chars); |
| 216 if (lib_source != NULL) { | 209 if (lib_source != NULL) { |
| 217 Dart_Handle source = Dart_NewStringFromCString(lib_source); | 210 Dart_Handle source = Dart_NewStringFromCString(lib_source); |
| 218 return Dart_LoadLibrary(url, Dart_Null(), source, 0, 0); | 211 return Dart_LoadLibrary(url, Dart_Null(), source, 0, 0); |
| 219 } | 212 } |
| 220 NOT_IN_PRODUCT( | 213 #if !defined(PRODUCT) |
| 221 if (IsIsolateReloadTestLib(url_chars)) { | 214 if (IsIsolateReloadTestLib(url_chars)) { |
| 222 Dart_Handle library = | 215 Dart_Handle library = |
| 223 Dart_LoadLibrary(url, Dart_Null(), IsolateReloadTestLibSource(), 0, 0); | 216 Dart_LoadLibrary(url, Dart_Null(), IsolateReloadTestLibSource(), 0, 0); |
| 224 DART_CHECK_VALID(library); | 217 DART_CHECK_VALID(library); |
| 225 Dart_SetNativeResolver(library, IsolateReloadTestNativeResolver, 0); | 218 Dart_SetNativeResolver(library, IsolateReloadTestNativeResolver, 0); |
| 226 return library; | 219 return library; |
| 227 }) | 220 } |
| 221 #endif |
| 228 if (is_io_library) { | 222 if (is_io_library) { |
| 229 ASSERT(tag == Dart_kSourceTag); | 223 ASSERT(tag == Dart_kSourceTag); |
| 230 return Dart_LoadSource(library, | 224 return Dart_LoadSource(library, url, Dart_Null(), |
| 231 url, Dart_Null(), | 225 Builtin::PartSource(Builtin::kIOLibrary, url_chars), |
| 232 Builtin::PartSource(Builtin::kIOLibrary, | |
| 233 url_chars), | |
| 234 0, 0); | 226 0, 0); |
| 235 } | 227 } |
| 236 Dart_Handle resolved_url = url; | 228 Dart_Handle resolved_url = url; |
| 237 const char* resolved_url_chars = url_chars; | 229 const char* resolved_url_chars = url_chars; |
| 238 if (IsPackageSchemeURL(url_chars)) { | 230 if (IsPackageSchemeURL(url_chars)) { |
| 239 resolved_url = ResolvePackageUri(url_chars); | 231 resolved_url = ResolvePackageUri(url_chars); |
| 240 DART_CHECK_VALID(resolved_url); | 232 DART_CHECK_VALID(resolved_url); |
| 241 if (Dart_IsError(Dart_StringToCString(resolved_url, &resolved_url_chars))) { | 233 if (Dart_IsError(Dart_StringToCString(resolved_url, &resolved_url_chars))) { |
| 242 return Dart_NewApiError("unable to convert resolved uri to string"); | 234 return Dart_NewApiError("unable to convert resolved uri to string"); |
| 243 } | 235 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 return Api::Success(); | 363 return Api::Success(); |
| 372 } | 364 } |
| 373 | 365 |
| 374 | 366 |
| 375 char* TestCase::BigintToHexValue(Dart_CObject* bigint) { | 367 char* TestCase::BigintToHexValue(Dart_CObject* bigint) { |
| 376 return bin::CObject::BigintToHexValue(bigint); | 368 return bin::CObject::BigintToHexValue(bigint); |
| 377 } | 369 } |
| 378 | 370 |
| 379 | 371 |
| 380 void AssemblerTest::Assemble() { | 372 void AssemblerTest::Assemble() { |
| 381 const String& function_name = String::ZoneHandle( | 373 const String& function_name = |
| 382 Symbols::New(Thread::Current(), name_)); | 374 String::ZoneHandle(Symbols::New(Thread::Current(), name_)); |
| 383 | 375 |
| 384 // We make a dummy script so that exception objects can be composed for | 376 // We make a dummy script so that exception objects can be composed for |
| 385 // assembler instructions that do runtime calls, in particular on DBC. | 377 // assembler instructions that do runtime calls, in particular on DBC. |
| 386 const char* kDummyScript = "assembler_test_dummy_function() {}"; | 378 const char* kDummyScript = "assembler_test_dummy_function() {}"; |
| 387 const Script& script = Script::Handle(Script::New( | 379 const Script& script = Script::Handle( |
| 388 function_name, | 380 Script::New(function_name, String::Handle(String::New(kDummyScript)), |
| 389 String::Handle(String::New(kDummyScript)), | 381 RawScript::kSourceTag)); |
| 390 RawScript::kSourceTag)); | |
| 391 script.Tokenize(String::Handle()); | 382 script.Tokenize(String::Handle()); |
| 392 const Library& lib = Library::Handle(Library::CoreLibrary()); | 383 const Library& lib = Library::Handle(Library::CoreLibrary()); |
| 393 const Class& cls = Class::ZoneHandle( | 384 const Class& cls = Class::ZoneHandle( |
| 394 Class::New(lib, | 385 Class::New(lib, function_name, script, TokenPosition::kMinSource)); |
| 395 function_name, | |
| 396 script, | |
| 397 TokenPosition::kMinSource)); | |
| 398 Function& function = Function::ZoneHandle( | 386 Function& function = Function::ZoneHandle( |
| 399 Function::New(function_name, RawFunction::kRegularFunction, | 387 Function::New(function_name, RawFunction::kRegularFunction, true, false, |
| 400 true, false, false, false, false, cls, | 388 false, false, false, cls, TokenPosition::kMinSource)); |
| 401 TokenPosition::kMinSource)); | |
| 402 code_ = Code::FinalizeCode(function, assembler_); | 389 code_ = Code::FinalizeCode(function, assembler_); |
| 403 code_.set_owner(function); | 390 code_.set_owner(function); |
| 404 code_.set_exception_handlers(Object::empty_exception_handlers()); | 391 code_.set_exception_handlers(Object::empty_exception_handlers()); |
| 405 #ifndef PRODUCT | 392 #ifndef PRODUCT |
| 406 if (FLAG_disassemble) { | 393 if (FLAG_disassemble) { |
| 407 OS::Print("Code for test '%s' {\n", name_); | 394 OS::Print("Code for test '%s' {\n", name_); |
| 408 const Instructions& instructions = | 395 const Instructions& instructions = |
| 409 Instructions::Handle(code_.instructions()); | 396 Instructions::Handle(code_.instructions()); |
| 410 uword start = instructions.PayloadStart(); | 397 uword start = instructions.PayloadStart(); |
| 411 Disassembler::Disassemble(start, start + assembler_->CodeSize()); | 398 Disassembler::Disassemble(start, start + assembler_->CodeSize()); |
| 412 OS::Print("}\n"); | 399 OS::Print("}\n"); |
| 413 } | 400 } |
| 414 #endif // !PRODUCT | 401 #endif // !PRODUCT |
| 415 } | 402 } |
| 416 | 403 |
| 417 | 404 |
| 418 CodeGenTest::CodeGenTest(const char* name) | 405 CodeGenTest::CodeGenTest(const char* name) |
| 419 : function_(Function::ZoneHandle()), | 406 : function_(Function::ZoneHandle()), |
| 420 node_sequence_(new SequenceNode(TokenPosition::kMinSource, | 407 node_sequence_(new SequenceNode(TokenPosition::kMinSource, |
| 421 new LocalScope(NULL, 0, 0))), | 408 new LocalScope(NULL, 0, 0))), |
| 422 default_parameter_values_(new ZoneGrowableArray<const Instance*> ()) { | 409 default_parameter_values_(new ZoneGrowableArray<const Instance*>()) { |
| 423 ASSERT(name != NULL); | 410 ASSERT(name != NULL); |
| 424 const String& function_name = String::ZoneHandle( | 411 const String& function_name = |
| 425 Symbols::New(Thread::Current(), name)); | 412 String::ZoneHandle(Symbols::New(Thread::Current(), name)); |
| 426 // Add function to a class and that class to the class dictionary so that | 413 // Add function to a class and that class to the class dictionary so that |
| 427 // frame walking can be used. | 414 // frame walking can be used. |
| 428 Library& lib = Library::Handle(Library::CoreLibrary()); | 415 Library& lib = Library::Handle(Library::CoreLibrary()); |
| 429 const Class& cls = Class::ZoneHandle( | 416 const Class& cls = Class::ZoneHandle(Class::New( |
| 430 Class::New(lib, function_name, Script::Handle(), | 417 lib, function_name, Script::Handle(), TokenPosition::kMinSource)); |
| 431 TokenPosition::kMinSource)); | 418 function_ = |
| 432 function_ = Function::New( | 419 Function::New(function_name, RawFunction::kRegularFunction, true, false, |
| 433 function_name, RawFunction::kRegularFunction, | 420 false, false, false, cls, TokenPosition::kMinSource); |
| 434 true, false, false, false, false, cls, TokenPosition::kMinSource); | |
| 435 function_.set_result_type(Type::Handle(Type::DynamicType())); | 421 function_.set_result_type(Type::Handle(Type::DynamicType())); |
| 436 const Array& functions = Array::Handle(Array::New(1)); | 422 const Array& functions = Array::Handle(Array::New(1)); |
| 437 functions.SetAt(0, function_); | 423 functions.SetAt(0, function_); |
| 438 cls.SetFunctions(functions); | 424 cls.SetFunctions(functions); |
| 439 lib.AddClass(cls); | 425 lib.AddClass(cls); |
| 440 } | 426 } |
| 441 | 427 |
| 442 | 428 |
| 443 void CodeGenTest::Compile() { | 429 void CodeGenTest::Compile() { |
| 444 if (function_.HasCode()) return; | 430 if (function_.HasCode()) return; |
| 445 ParsedFunction* parsed_function = | 431 ParsedFunction* parsed_function = |
| 446 new ParsedFunction(Thread::Current(), function_); | 432 new ParsedFunction(Thread::Current(), function_); |
| 447 parsed_function->SetNodeSequence(node_sequence_); | 433 parsed_function->SetNodeSequence(node_sequence_); |
| 448 parsed_function->set_instantiator(NULL); | 434 parsed_function->set_instantiator(NULL); |
| 449 parsed_function->set_default_parameter_values(default_parameter_values_); | 435 parsed_function->set_default_parameter_values(default_parameter_values_); |
| 450 node_sequence_->scope()->AddVariable( | 436 node_sequence_->scope()->AddVariable(parsed_function->current_context_var()); |
| 451 parsed_function->current_context_var()); | |
| 452 parsed_function->EnsureExpressionTemp(); | 437 parsed_function->EnsureExpressionTemp(); |
| 453 node_sequence_->scope()->AddVariable(parsed_function->expression_temp_var()); | 438 node_sequence_->scope()->AddVariable(parsed_function->expression_temp_var()); |
| 454 parsed_function->AllocateVariables(); | 439 parsed_function->AllocateVariables(); |
| 455 const Error& error = | 440 const Error& error = |
| 456 Error::Handle(Compiler::CompileParsedFunction(parsed_function)); | 441 Error::Handle(Compiler::CompileParsedFunction(parsed_function)); |
| 457 EXPECT(error.IsNull()); | 442 EXPECT(error.IsNull()); |
| 458 } | 443 } |
| 459 | 444 |
| 460 | 445 |
| 461 bool CompilerTest::TestCompileScript(const Library& library, | 446 bool CompilerTest::TestCompileScript(const Library& library, |
| 462 const Script& script) { | 447 const Script& script) { |
| 463 Isolate* isolate = Isolate::Current(); | 448 Isolate* isolate = Isolate::Current(); |
| 464 ASSERT(isolate != NULL); | 449 ASSERT(isolate != NULL); |
| 465 const Error& error = Error::Handle(Compiler::Compile(library, script)); | 450 const Error& error = Error::Handle(Compiler::Compile(library, script)); |
| 466 if (!error.IsNull()) { | 451 if (!error.IsNull()) { |
| 467 OS::Print("Error compiling test script:\n%s\n", | 452 OS::Print("Error compiling test script:\n%s\n", error.ToErrorCString()); |
| 468 error.ToErrorCString()); | |
| 469 } | 453 } |
| 470 return error.IsNull(); | 454 return error.IsNull(); |
| 471 } | 455 } |
| 472 | 456 |
| 473 | 457 |
| 474 bool CompilerTest::TestCompileFunction(const Function& function) { | 458 bool CompilerTest::TestCompileFunction(const Function& function) { |
| 475 Thread* thread = Thread::Current(); | 459 Thread* thread = Thread::Current(); |
| 476 ASSERT(thread != NULL); | 460 ASSERT(thread != NULL); |
| 477 ASSERT(ClassFinalizer::AllClassesFinalized()); | 461 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 478 const Error& error = Error::Handle(Compiler::CompileFunction(thread, | 462 const Error& error = |
| 479 function)); | 463 Error::Handle(Compiler::CompileFunction(thread, function)); |
| 480 return error.IsNull(); | 464 return error.IsNull(); |
| 481 } | 465 } |
| 482 | 466 |
| 483 | 467 |
| 484 void ElideJSONSubstring(const char* prefix, const char* in, char* out) { | 468 void ElideJSONSubstring(const char* prefix, const char* in, char* out) { |
| 485 const char* pos = strstr(in, prefix); | 469 const char* pos = strstr(in, prefix); |
| 486 while (pos != NULL) { | 470 while (pos != NULL) { |
| 487 // Copy up to pos into the output buffer. | 471 // Copy up to pos into the output buffer. |
| 488 while (in < pos) { | 472 while (in < pos) { |
| 489 *out++ = *in++; | 473 *out++ = *in++; |
| 490 } | 474 } |
| 491 | 475 |
| 492 // Skip to the close quote. | 476 // Skip to the close quote. |
| 493 in += strcspn(in, "\""); | 477 in += strcspn(in, "\""); |
| 494 pos = strstr(in, prefix); | 478 pos = strstr(in, prefix); |
| 495 } | 479 } |
| 496 // Copy the remainder of in to out. | 480 // Copy the remainder of in to out. |
| 497 while (*in != '\0') { | 481 while (*in != '\0') { |
| 498 *out++ = *in++; | 482 *out++ = *in++; |
| 499 } | 483 } |
| 500 *out = '\0'; | 484 *out = '\0'; |
| 501 } | 485 } |
| 502 | 486 |
| 503 | 487 |
| 504 } // namespace dart | 488 } // namespace dart |
| OLD | NEW |