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 |