241 {
242 const char* name_;
244 int argument_count_;
246
250 bool* auto_setup_scope) {
254 ASSERT(function_name !=
nullptr);
255 ASSERT(auto_setup_scope !=
nullptr);
256 *auto_setup_scope = true;
257 int num_entries =
sizeof(
ReloadEntries) /
sizeof(
struct NativeEntries);
258 for (int i = 0; i < num_entries; i++) {
260 if ((strcmp(function_name, entry->name_) == 0) &&
263 }
264 }
265 return nullptr;
266}
267
270 0);
273 }
274}
275
277 TransitionNativeToVM transition(Thread::Current());
278 GCTestHelper::CollectNewSpace();
279}
280
282 TransitionNativeToVM transition(Thread::Current());
283 GCTestHelper::CollectOldSpace();
284}
285
286#endif
287
289#ifndef PRODUCT
293 IsolateReloadTestNativeResolver);
295 }
296#endif
297}
298
299char* TestCase::CompileTestScriptWithDFE(const char* url,
301 const uint8_t** kernel_buffer,
302 intptr_t* kernel_buffer_size,
303 bool incrementally,
304 bool allow_compile_errors,
305 const char* multiroot_filepaths,
306 const char* multiroot_scheme) {
307
309 {
311 },
312 {
313 "file:///.packages", ""
314 }};
315
316 return CompileTestScriptWithDFE(
318 kernel_buffer, kernel_buffer_size, incrementally, allow_compile_errors,
319 multiroot_filepaths, multiroot_scheme);
320}
321
322char* TestCase::CompileTestScriptWithDFE(const char* url,
323 int sourcefiles_count,
325 const uint8_t** kernel_buffer,
326 intptr_t* kernel_buffer_size,
327 bool incrementally,
328 bool allow_compile_errors,
329 const char* multiroot_filepaths,
330 const char* multiroot_scheme) {
331 Zone* zone = Thread::Current()->zone();
333 url, platform_strong_dill, platform_strong_dill_size, sourcefiles_count,
334 sourcefiles, incrementally, false,
335 true, nullptr, multiroot_filepaths, multiroot_scheme);
337 if (KernelIsolate::AcceptCompilation().status !=
340 "An error occurred in the CFE while accepting the most recent"
341 " compilation results.");
342 }
343 }
344 return ValidateCompilationResult(zone,
result, kernel_buffer,
345 kernel_buffer_size, allow_compile_errors);
346}
347
348char* TestCase::ValidateCompilationResult(
349 Zone* zone,
351 const uint8_t** kernel_buffer,
352 intptr_t* kernel_buffer_size,
353 bool allow_compile_errors) {
354 if (!allow_compile_errors &&
357 OS::SCreate(zone,
"Compilation failed %s", compilation_result.
error);
358 free(compilation_result.
error);
359 if (compilation_result.
kernel !=
nullptr) {
360 free(
const_cast<uint8_t*
>(compilation_result.
kernel));
361 }
362 *kernel_buffer = nullptr;
363 *kernel_buffer_size = 0;
365 }
366 *kernel_buffer = compilation_result.
kernel;
367 *kernel_buffer_size = compilation_result.
kernel_size;
368 if (compilation_result.
error !=
nullptr) {
369 free(compilation_result.
error);
370 }
371 if (kernel_buffer == nullptr) {
372 return OS::SCreate(zone, "front end generated a nullptr kernel file");
373 }
374 return nullptr;
375}
376
383 return library_url;
384 }
386 }
389}
390
393 const char* script,
395 ASSERT(sourcefiles !=
nullptr);
396 ASSERT(script !=
nullptr);
397
398 intptr_t num_test_libs = 0;
399 if (test_libs_ != nullptr) {
401 }
402
404 (*sourcefiles)[0].
uri = script_url;
405 (*sourcefiles)[0].source =
script;
406 for (intptr_t i = 0; i < num_test_libs; ++i) {
407 (*sourcefiles)[i + 1].uri =
test_libs_->At(i).url;
408 (*sourcefiles)[i + 1].source =
test_libs_->At(i).source;
409 }
410 return num_test_libs + 1;
411}
412
414 const char* script,
416 const char* lib_url,
417 bool finalize_classes) {
418 return LoadTestScript(script, resolver, lib_url, finalize_classes,
true);
419}
420
421Dart_Handle TestCase::LoadTestScript(
const char* script,
423 const char* lib_url,
424 bool finalize_classes,
425 bool allow_compile_errors) {
430 LoadTestScriptWithDFE(num_sources, sourcefiles, resolver,
431 finalize_classes, true, allow_compile_errors);
432 delete[] sourcefiles;
434}
435
437 free(peer);
438}
439
440Dart_Handle TestCase::LoadTestLibrary(
const char* lib_uri,
441 const char* script,
444 const char* prefixed_lib_uri =
445 OS::SCreate(Thread::Current()->zone(), "file:///%s", lib_uri);
447 const uint8_t* kernel_buffer = nullptr;
448 intptr_t kernel_buffer_size = 0;
450 char*
error = TestCase::CompileTestScriptWithDFE(
451 sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_buffer,
452 &kernel_buffer_size, true);
453 if ((kernel_buffer ==
nullptr) && (
error !=
nullptr)) {
455 }
456
459 kernel_buffer_size, const_cast<uint8_t*>(kernel_buffer),
460 kernel_buffer_size, MallocFinalizer);
464
465
470
472 return lib;
473}
474
475Dart_Handle TestCase::LoadTestScriptWithDFE(
int sourcefiles_count,
478 bool finalize,
479 bool incrementally,
480 bool allow_compile_errors,
481 const char* entry_script_uri,
482 const char* multiroot_filepaths,
483 const char* multiroot_scheme) {
484
487 const uint8_t* kernel_buffer = nullptr;
488 intptr_t kernel_buffer_size = 0;
489 char*
error = TestCase::CompileTestScriptWithDFE(
490 entry_script_uri != nullptr ? entry_script_uri : sourcefiles[0].uri,
491 sourcefiles_count, sourcefiles, &kernel_buffer, &kernel_buffer_size,
492 incrementally, allow_compile_errors, multiroot_filepaths,
493 multiroot_scheme);
494 if ((kernel_buffer ==
nullptr) &&
error !=
nullptr) {
496 }
497
500 kernel_buffer_size, const_cast<uint8_t*>(kernel_buffer),
501 kernel_buffer_size, MallocFinalizer);
505
506
508 entry_script_uri != nullptr ? entry_script_uri : sourcefiles[0].uri));
512
515 if (finalize) {
518 }
519 return lib;
520}
521
522#ifndef PRODUCT
523
524Dart_Handle TestCase::SetReloadTestScript(
const char* script) {
525
526
527 FLAG_gc_during_reload = true;
528 FLAG_force_evacuation = true;
529
533 KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
534 delete[] sourcefiles;
537 free(compilation_result.
error);
539 }
540 return Api::Success();
541}
542
544 std::function<bool(IsolateGroup*, JSONStream*)> do_reload) {
545 Thread* thread = Thread::Current();
546 IsolateGroup* isolate_group = thread->isolate_group();
548 bool success = false;
549 {
550 TransitionNativeToVM transition(thread);
551 success = do_reload(isolate_group, &js);
552 OS::PrintErr(
"RELOAD REPORT:\n%s\n",
js.ToCString());
553 }
554
556 if (success) {
558 }
559
561
562 } else if (isolate_group->reload_context()->reload_aborted()) {
563 TransitionNativeToVM transition(thread);
564 result = Api::NewHandle(thread, isolate_group->program_reload_context()
565 ->group_reload_context()
566 ->error());
567 } else {
569 }
570
571 TransitionNativeToVM transition(thread);
572 if (isolate_group->program_reload_context() != nullptr) {
573 isolate_group->DeleteReloadContext();
574 }
575
577}
578
579Dart_Handle TestCase::TriggerReload(
const char* root_script_url) {
580 return TriggerReload([&](IsolateGroup* isolate_group, JSONStream* js) {
581 return isolate_group->ReloadSources(js,
582 false, root_script_url,
583 nullptr,
584 true);
585 });
586}
587
588Dart_Handle TestCase::TriggerReload(
const uint8_t* kernel_buffer,
589 intptr_t kernel_buffer_size) {
590 return TriggerReload([&](IsolateGroup* isolate_group, JSONStream* js) {
591 return isolate_group->ReloadKernel(js,
592 false, kernel_buffer,
593 kernel_buffer_size,
594 true);
595 });
596}
597
598Dart_Handle TestCase::ReloadTestScript(
const char* script) {
602 KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
603 delete[] sourcefiles;
606 free(compilation_result.
error);
607 if (compilation_result.
kernel !=
nullptr) {
608 free(
const_cast<uint8_t*
>(compilation_result.
kernel));
609 }
611 }
612
613 return TriggerReload(nullptr, 0);
614}
615
616Dart_Handle TestCase::ReloadTestKernel(
const uint8_t* kernel_buffer,
617 intptr_t kernel_buffer_size) {
618 return TriggerReload(kernel_buffer, kernel_buffer_size);
619}
620
621#endif
622
623Dart_Handle TestCase::LoadCoreTestScript(
const char* script,
626}
627
633 return lib;
634}
635
640 return url;
641 }
642 return Api::Success();
643}
644
645Dart_Handle TestCase::EvaluateExpression(
const Library& lib,
646 const String& expr,
647 const Array& param_names,
648 const Array& param_values) {
649 Thread* thread = Thread::Current();
650
651 Object& val = Object::Handle();
652 if (!KernelIsolate::IsRunning()) {
654 } else {
656 KernelIsolate::CompileExpressionToKernel(
657 nullptr, 0,
658 expr.ToCString(), param_names, Array::empty_array(),
659 Array::empty_array(), Array::empty_array(), Array::empty_array(),
660 String::Handle(lib.url()).ToCString(),
661 nullptr,
662 nullptr,
663 TokenPosition::kNoSource,
664 String::Handle(lib.url()).ToCString(),
665 true);
667 return Api::NewError(
"%s", compilation_result.
error);
668 }
669
670 const ExternalTypedData& kernel_buffer =
671 ExternalTypedData::Handle(ExternalTypedData::NewFinalizeWithFree(
672 const_cast<uint8_t*
>(compilation_result.
kernel),
674
675 val = lib.EvaluateCompiledExpression(kernel_buffer, Array::empty_array(),
676 param_values,
677 TypeArguments::null_type_arguments());
678 }
679 return Api::NewHandle(thread, val.ptr());
680}
681
682#if !defined(PRODUCT) && (defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64))
683static bool IsHex(int c) {
684 return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f');
685}
686#endif
687
688void AssemblerTest::Assemble() {
689 auto thread = Thread::Current();
690 const String&
function_name = String::ZoneHandle(Symbols::New(thread, name_));
691
692
693
694 const char* kDummyScript = "assembler_test_dummy_function() {}";
695 const Script&
script = Script::Handle(
696 Script::New(function_name, String::Handle(String::New(kDummyScript))));
697 const Library& lib = Library::Handle(Library::CoreLibrary());
698 const Class& cls = Class::ZoneHandle(
699 Class::New(lib, function_name, script, TokenPosition::kMinSource));
700 const FunctionType& signature = FunctionType::ZoneHandle(FunctionType::New());
701 Function& function = Function::ZoneHandle(Function::New(
702 signature, function_name, UntaggedFunction::kRegularFunction, true, false,
703 false, false, false, cls, TokenPosition::kMinSource));
704 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
705 code_ = Code::FinalizeCodeAndNotify(function, nullptr, assembler_,
706 Code::PoolAttachment::kAttachPool);
707 code_.set_owner(function);
708 code_.set_exception_handlers(Object::empty_exception_handlers());
709#ifndef PRODUCT
710
711 SetFlagScope<bool> sfs(&FLAG_disassemble_relative, true);
713 if (FLAG_disassemble) {
714 OS::PrintErr("Code for test '%s' {\n", name_);
715 Disassembler::Disassemble(
start,
start + assembler_->CodeSize());
716 OS::PrintErr("}\n");
717 }
718 Disassembler::Disassemble(
start,
start + assembler_->CodeSize(), disassembly_,
719 DISASSEMBLY_SIZE);
720#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
721
722
723
724
725 bool in_hex_constant = false;
726 for (
char* p = disassembly_; *
p !=
'\0';
p++) {
727 if (in_hex_constant) {
728 if (IsHex(*p)) {
730 } else {
731 in_hex_constant = false;
732 }
733 } else {
734#if defined(TARGET_ARCH_IA32)
735 if (*p == '[' && *(p + 1) == '0' && *(p + 2) == 'x' && IsHex(*(p + 3)) &&
736 IsHex(*(p + 4))) {
738 in_hex_constant = true;
739 }
740#endif
741#if defined(TARGET_ARCH_X64)
742 if (*p == '[' && *(p + 1) == 't' && *(p + 2) == 'h' && *(p + 3) == 'r' &&
743 *(p + 4) == '+' && *(p + 5) == '0' && *(p + 6) == 'x' &&
744 IsHex(*(p + 7)) && IsHex(*(p + 8))) {
746 in_hex_constant = true;
747 }
748#endif
749 }
750 }
751#endif
752#endif
753}
754
755const Code& AssemblerTest::Generate(
757 const std::function<void(compiler::Assembler* assembler)>& generator) {
758 compiler::ObjectPoolBuilder object_pool_builder;
759 compiler::Assembler assembler(&object_pool_builder, 0);
760 AssemblerTest
test(
name, &assembler, Thread::Current()->zone());
761 assembler.Ret();
764}
765
766bool CompilerTest::TestCompileFunction(const Function& function) {
767 Thread* thread = Thread::Current();
768 ASSERT(thread !=
nullptr);
769 ASSERT(ClassFinalizer::AllClassesFinalized());
771 Object::Handle(Compiler::CompileFunction(thread, function));
773}
774
776 const char* in,
777 char* out,
778 const char* postfix) {
779 const char*
pos = strstr(in, prefix);
780 while (
pos !=
nullptr) {
781
784 }
785
786
787 in += strlen(prefix);
788 in += strcspn(in, postfix);
789 pos = strstr(in, prefix);
790 }
791
792 while (*in != '\0') {
794 }
796}
797
801}
802
803}
#define FUNCTION_NAME(name)
DART_EXPORT Dart_Handle Dart_SetNativeResolver(Dart_Handle library, Dart_NativeEntryResolver resolver, Dart_NativeEntrySymbol symbol)
@ Dart_KernelCompilationStatus_Ok
struct _Dart_Handle * Dart_Handle
DART_EXPORT void Dart_PropagateError(Dart_Handle handle)
Dart_NativeFunction(* Dart_NativeEntryResolver)(Dart_Handle name, int num_of_arguments, bool *auto_setup_scope)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_FinalizeLoading(bool complete_futures)
DART_EXPORT Dart_Handle Dart_NewExternalTypedDataWithFinalizer(Dart_TypedData_Type type, void *data, intptr_t length, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
struct _Dart_NativeArguments * Dart_NativeArguments
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_LoadLibrary(Dart_Handle kernel_buffer)
DART_EXPORT Dart_Handle Dart_NewApiError(const char *error)
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle str, const char **cstr)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
void(* Dart_NativeFunction)(Dart_NativeArguments arguments)
DART_EXPORT Dart_Handle Dart_DefaultCanonicalizeUrl(Dart_Handle base_url, Dart_Handle url)
DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT bool Dart_IsLibrary(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler)
DART_EXPORT Dart_Handle Dart_RootLibrary(void)
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library)
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
#define REGISTER_FUNCTION(name, count)
void ElideJSONSubstring(const char *prefix, const char *in, char *out, const char *postfix)
LibraryPtr LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri)
static intptr_t BuildSourceFilesArray(Dart_SourceFile **sourcefiles, const char *script, const char *script_url=RESOLVED_USER_TEST_URI)
static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
static MallocGrowableArray< TestLibEntry > * test_libs_
static const char * IsolateReloadTestLibUri()
static struct dart::NativeEntries ReloadEntries[]
static void LoadIsolateReloadTestLibIfNeeded(const char *script)
static Dart_NativeFunction IsolateReloadTestNativeResolver(Dart_Handle name, int argument_count, bool *auto_setup_scope)
const char *const function_name
static void MallocFinalizer(void *isolate_callback_data, void *peer)
void StripTokenPositions(char *buffer)
Dart_KernelCompilationStatus status
#define RELOAD_NATIVE_LIST(V)
Dart_Handle NewString(const char *str)
#define RESOLVED_USER_TEST_URI
#define EXPECT_VALID(handle)