diff --git a/runtime/tests/vm/dart/entrypoints_verification_test.dart b/runtime/tests/vm/dart/entrypoints_verification_test.dart index b76f0b9ab901..e74bbd6f4daa 100644 --- a/runtime/tests/vm/dart/entrypoints_verification_test.dart +++ b/runtime/tests/vm/dart/entrypoints_verification_test.dart @@ -2,7 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // -// VMOptions=--verify-entry-points=true // SharedObjects=entrypoints_verification_test import 'dart:ffi'; diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc index b49812e39473..a2869b04afb8 100644 --- a/runtime/vm/compiler/backend/il_test.cc +++ b/runtime/vm/compiler/backend/il_test.cc @@ -62,6 +62,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_EliminateWriteBarrier) { Container x = Container(); + @pragma("vm:entry-point", "call") foo() { for (int i = 0; i < 10; ++i) { x[i] = i; @@ -689,6 +690,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_LoadThread) { auto kScript = R"( import 'dart:ffi'; + @pragma("vm:entry-point", "call") int myFunction() { return 100; } @@ -780,6 +782,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_CachableIdempotentCall) { return increment(); } + @pragma("vm:entry-point", "call") int multipleIncrement() { int returnValue = 0; for(int i = 0; i < 10; i++) { @@ -943,6 +946,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_FfiCallInstrLeafDoesntSpill) { void placeholder() {} // Will call the "doFfiCall" and exercise its code. + @pragma("vm:entry-point", "call") bool invokeDoFfiCall() { final double result = doFfiCall(1, 2, 3, 1.0, 2.0, 3.0); if (result != (2 + 3 + 4 + 2.0 + 3.0 + 4.0)) { @@ -971,6 +975,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_FfiCallInstrLeafDoesntSpill) { typedef NT = Void Function(); typedef DT = void Function(); Pointer> ptr = Pointer.fromAddress(0); + @pragma("vm:entry-point", "call") DT getFfiTrampolineClosure() => ptr.asFunction(isLeaf:true); )"; diff --git a/runtime/vm/compiler/backend/memory_copy_test.cc b/runtime/vm/compiler/backend/memory_copy_test.cc index 014d6465509e..f27e6541258c 100644 --- a/runtime/vm/compiler/backend/memory_copy_test.cc +++ b/runtime/vm/compiler/backend/memory_copy_test.cc @@ -157,12 +157,14 @@ static void RunMemoryCopyInstrTest(intptr_t src_start, CStringUniquePtr kScript(OS::SCreate(nullptr, R"( import 'dart:ffi'; + @pragma("vm:entry-point", "call") void copyConst() { final pointer = Pointer.fromAddress(%s%p); final pointer2 = Pointer.fromAddress(%s%p); noop(); } + @pragma("vm:entry-point", "call") void callNonConstCopy() { final pointer = Pointer.fromAddress(%s%p); final pointer2 = Pointer.fromAddress(%s%p); diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc index 6a163f1de646..829a6e61739e 100644 --- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc +++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc @@ -1480,6 +1480,7 @@ ISOLATE_UNIT_TEST_CASE(DelayAllocations_DelayAcrossCalls) { @pragma("vm:never-inline") dynamic use(v) {} + @pragma("vm:entry-point", "call") void test() { A a = new A(foo(1), foo(2)); use(a); @@ -1738,10 +1739,12 @@ ISOLATE_UNIT_TEST_CASE(AllocationSinking_NoViewDataMaterialization) { return x is int; } + @pragma("vm:entry-point", "call") bool %s() { return %s(0xABCC); } + @pragma("vm:entry-point", "call") bool %s() { return %s(1.0); } diff --git a/runtime/vm/compiler/backend/yield_position_test.cc b/runtime/vm/compiler/backend/yield_position_test.cc index edad7052e16f..3cda44cc1c14 100644 --- a/runtime/vm/compiler/backend/yield_position_test.cc +++ b/runtime/vm/compiler/backend/yield_position_test.cc @@ -52,6 +52,7 @@ void RunTestInMode(CompilerPass::PipelineMode mode) { R"( import 'dart:async'; + @pragma("vm:entry-point", "call") Future foo() async { print('pos-0'); await 0; @@ -81,9 +82,9 @@ void RunTestInMode(CompilerPass::PipelineMode mode) { auto validate_indices = [](const YieldPoints& yield_points) { EXPECT_EQ(3, yield_points.length()); - EXPECT_EQ(88, yield_points[0].Pos()); - EXPECT_EQ(129, yield_points[1].Pos()); - EXPECT_EQ(170, yield_points[2].Pos()); + EXPECT_EQ(128, yield_points[0].Pos()); + EXPECT_EQ(169, yield_points[1].Pos()); + EXPECT_EQ(210, yield_points[2].Pos()); }; validate_indices(*GetYieldPointsFromGraph(flow_graph)); diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc index 81a6e3903a1d..fe1c6f25493c 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph_test.cc @@ -15,6 +15,7 @@ ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_ConstFoldStringConcats) { // "Adjacent strings are implicitly concatenated to form a single string // literal." const char* kScript = R"( + @pragma("vm:entry-point", "call") test() { var s = 'aaaa' 'bbbb' @@ -252,6 +253,7 @@ ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_ConcatStringLits) { ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_InvariantFlagInListLiterals) { const char* kScript = R"( + @pragma("vm:entry-point", "call") test() { return [...[], 42]; } @@ -314,6 +316,7 @@ ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_TypedClosureCall) { // const char* kScript = R"( int callClosure(int Function(int) fun, int value) => fun(value); + @pragma("vm:entry-point", "call") test() => callClosure((int a) => a + 1, 10); )"; @@ -354,6 +357,7 @@ ISOLATE_UNIT_TEST_CASE( StreamingFlowGraphBuilder_StaticGetFinalFieldWithTrivialInitializer) { const char* kScript = R"( final int x = 0xFEEDFEED; + @pragma("vm:entry-point", "call") test() { return x; } diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h index 4edaf53372cc..02d46c56a365 100644 --- a/runtime/vm/flag_list.h +++ b/runtime/vm/flag_list.h @@ -69,8 +69,6 @@ constexpr bool FLAG_support_il_printer = false; // * R elease flags: Generally available flags except when building product. // * pre C ompile flags: Generally available flags except when building product // or precompiled runtime. -// * A ot flags: Generally available flags except when building precompiled -// runtime. (Unlike C, these flags are available in product mode.) // * D ebug flags: Can only be set in debug VMs, which also have C++ assertions // enabled. // @@ -78,9 +76,8 @@ constexpr bool FLAG_support_il_printer = false; // P(name, type, default_value, comment) // R(name, product_value, type, default_value, comment) // C(name, precompiled_value, product_value, type, default_value, comment) -// A(name, precompiled_value, type, default_value, comment) // D(name, type, default_value, comment) -#define FLAG_LIST(P, R, C, A, D) \ +#define FLAG_LIST(P, R, C, D) \ VM_GLOBAL_FLAG_LIST(P, R, C, D) \ DISASSEMBLE_FLAGS(P, R, C, D) \ P(abort_on_oom, bool, false, \ @@ -249,7 +246,7 @@ constexpr bool FLAG_support_il_printer = false; R(eliminate_type_checks, true, bool, true, \ "Eliminate type checks when allowed by static type analysis.") \ D(support_rr, bool, false, "Support running within RR.") \ - A(verify_entry_points, true, bool, false, \ + P(verify_entry_points, bool, true, \ "Throw API error on invalid member access through native API. See " \ "entry_point_pragma.md") \ C(branch_coverage, false, false, bool, false, "Enable branch coverage") \ diff --git a/runtime/vm/flags.cc b/runtime/vm/flags.cc index afe54da5851c..ca0b4ae8a875 100644 --- a/runtime/vm/flags.cc +++ b/runtime/vm/flags.cc @@ -35,8 +35,6 @@ DEFINE_FLAG(bool, // Nothing to be done for the precompilation flag definitions. #define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, \ default_value, comment) -// Nothing to be done for the AOT flag definitions. -#define AOT_FLAG_MACRO(name, pre_value, type, default_value, comment) #elif defined(PRODUCT) // !PRECOMPILED // Nothing to be done for the product flag definitions. @@ -44,9 +42,6 @@ DEFINE_FLAG(bool, // Nothing to be done for the precompilation flag definitions. #define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, \ default_value, comment) -#define AOT_FLAG_MACRO(name, pre_value, type, default_value, comment) \ - type FLAG_##name = \ - Flags::Register_##type(&FLAG_##name, #name, default_value, comment); #elif defined(DART_PRECOMPILED_RUNTIME) // !PRODUCT #define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \ @@ -55,8 +50,6 @@ DEFINE_FLAG(bool, // Nothing to be done for the precompilation flag definitions. #define PRECOMPILE_FLAG_MACRO(name, pre_value, product_value, type, \ default_value, comment) -// Nothing to be done for the AOT flag definitions. -#define AOT_FLAG_MACRO(name, pre_value, type, default_value, comment) #else // !PRODUCT && !PRECOMPILED #define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \ @@ -66,22 +59,17 @@ DEFINE_FLAG(bool, default_value, comment) \ type FLAG_##name = \ Flags::Register_##type(&FLAG_##name, #name, default_value, comment); -#define AOT_FLAG_MACRO(name, pre_value, type, default_value, comment) \ - type FLAG_##name = \ - Flags::Register_##type(&FLAG_##name, #name, default_value, comment); #endif // Define all of the non-product flags here. FLAG_LIST(PRODUCT_FLAG_MACRO, RELEASE_FLAG_MACRO, PRECOMPILE_FLAG_MACRO, - AOT_FLAG_MACRO, DEBUG_FLAG_MACRO) #undef PRODUCT_FLAG_MACRO #undef RELEASE_FLAG_MACRO #undef PRECOMPILE_FLAG_MACRO -#undef AOT_FLAG_MACRO #undef DEBUG_FLAG_MACRO #if defined(DART_PRECOMPILER) diff --git a/runtime/vm/flags.h b/runtime/vm/flags.h index e61ddb2efe42..d9d1850a2324 100644 --- a/runtime/vm/flags.h +++ b/runtime/vm/flags.h @@ -124,8 +124,6 @@ class Flags { #define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \ default_value, comment) \ const type FLAG_##name = precompiled_value; -#define AOT_FLAG_MACRO(name, precompiled_value, type, default_value, comment) \ - const type FLAG_##name = precompiled_value; #elif defined(PRODUCT) // !PRECOMPILED #define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \ @@ -133,8 +131,6 @@ class Flags { #define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \ default_value, comment) \ const type FLAG_##name = product_value; -#define AOT_FLAG_MACRO(name, precompiled_value, type, default_value, comment) \ - extern type FLAG_##name; #elif defined(DART_PRECOMPILED_RUNTIME) // !PRODUCT #define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \ @@ -142,8 +138,6 @@ class Flags { #define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \ default_value, comment) \ const type FLAG_##name = precompiled_value; -#define AOT_FLAG_MACRO(name, precompiled_value, type, default_value, comment) \ - const type FLAG_##name = precompiled_value; #else // !PRODUCT && !PRECOMPILED #define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \ @@ -151,8 +145,6 @@ class Flags { #define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \ default_value, comment) \ extern type FLAG_##name; -#define AOT_FLAG_MACRO(name, precompiled_value, type, default_value, comment) \ - extern type FLAG_##name; #endif @@ -160,13 +152,11 @@ class Flags { FLAG_LIST(PRODUCT_FLAG_MACRO, RELEASE_FLAG_MACRO, PRECOMPILE_FLAG_MACRO, - AOT_FLAG_MACRO, DEBUG_FLAG_MACRO) #undef RELEASE_FLAG_MACRO #undef DEBUG_FLAG_MACRO #undef PRODUCT_FLAG_MACRO -#undef AOT_FLAG_MACRO #undef PRECOMPILE_FLAG_MACRO #if defined(DART_PRECOMPILER) diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc index 4d68968b5e36..92b9b99ef719 100644 --- a/runtime/vm/object_test.cc +++ b/runtime/vm/object_test.cc @@ -8436,15 +8436,23 @@ static void SubtypeTestCacheTest(Thread* thread, intptr_t num_classes, bool expect_hash) { TextBuffer buffer(MB); - buffer.AddString("class D {}\n"); - buffer.AddString("D createInstanceD() => D();"); - buffer.AddString("D Function() createClosureD() => () => D();\n"); + buffer.AddString(R"( + class D {} + + @pragma('vm:entry-point', 'call') + D createInstanceD() => D(); + + @pragma('vm:entry-point', 'call') + D Function() createClosureD() => () => D(); + )"); for (intptr_t i = 0; i < num_classes; i++) { buffer.Printf(R"(class C%)" Pd R"( extends D {} )" + "@pragma('vm:entry-point', 'call')\n" R"(C%)" Pd R"( createInstanceC%)" Pd R"(() => C%)" Pd R"((); )" + "@pragma('vm:entry-point', 'call')\n" R"(C%)" Pd R"( Function() createClosureC%)" Pd R"(() => () => C%)" Pd R"((); diff --git a/runtime/vm/type_testing_stubs_test.cc b/runtime/vm/type_testing_stubs_test.cc index 2123a00db8cb..852bc63d915a 100644 --- a/runtime/vm/type_testing_stubs_test.cc +++ b/runtime/vm/type_testing_stubs_test.cc @@ -865,20 +865,35 @@ const char* kSubtypeRangeCheckScript = genericFun() {} + @pragma("vm:entry-point", "call") createI() => I(); + @pragma("vm:entry-point", "call") createI2() => I2(); + @pragma("vm:entry-point", "call") createBaseInt() => Base(); + @pragma("vm:entry-point", "call") createBaseNull() => Base(); + @pragma("vm:entry-point", "call") createBaseNever() => Base(); + @pragma("vm:entry-point", "call") createA() => A(); + @pragma("vm:entry-point", "call") createA1() => A1(); + @pragma("vm:entry-point", "call") createA2() => A2(); + @pragma("vm:entry-point", "call") createB() => B(); + @pragma("vm:entry-point", "call") createB1() => B1(); + @pragma("vm:entry-point", "call") createB2() => B2(); + @pragma("vm:entry-point", "call") createBaseIStringDouble() => Base>(); + @pragma("vm:entry-point", "call") createBaseA2Int() => Base>(); + @pragma("vm:entry-point", "call") createBaseA2A1() => Base>(); + @pragma("vm:entry-point", "call") createBaseB2Int() => Base>(); )"; @@ -1218,17 +1233,28 @@ const char* kRecordSubtypeRangeCheckScript = class D {} getType() => T; + @pragma("vm:entry-point", "call") getRecordType1() => getType<(int, A)>(); + @pragma("vm:entry-point", "call") getRecordType2() => getType<(A, int, String)>(); + @pragma("vm:entry-point", "call") getRecordType3() => getType<(int, D)>(); + @pragma("vm:entry-point", "call") createObj1() => (1, B()); + @pragma("vm:entry-point", "call") createObj2() => (1, 'bye'); + @pragma("vm:entry-point", "call") createObj3() => (1, foo: B()); + @pragma("vm:entry-point", "call") createObj4() => (1, B(), 2); + @pragma("vm:entry-point", "call") createObj5() => (C(), 2, 'hi'); + @pragma("vm:entry-point", "call") createObj6() => (D(), 2, 'hi'); + @pragma("vm:entry-point", "call") createObj7() => (3, D()); + @pragma("vm:entry-point", "call") createObj8() => (D(), 3); )"; @@ -1280,6 +1306,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Generic_Implements_Instantiated_Interface) { abstract class I {} class B implements I {} + @pragma("vm:entry-point", "call") createBInt() => B(); )"; @@ -1308,8 +1335,11 @@ ISOLATE_UNIT_TEST_CASE(TTS_Future) { R"( import "dart:async"; + @pragma("vm:entry-point", "call") Future createFutureInt() async => 3; + @pragma("vm:entry-point", "call") Future createFutureFunction() async => () => 3; + @pragma("vm:entry-point", "call") Future createFutureNullableFunction() async => (() => 3) as int Function()?; )"; @@ -1689,8 +1719,11 @@ ISOLATE_UNIT_TEST_CASE(TTS_Regress40964) { class B {} class C {} + @pragma("vm:entry-point", "call") createACint() => A>(); + @pragma("vm:entry-point", "call") createBCint() => B>(); + @pragma("vm:entry-point", "call") createBCnum() => B>(); )"; @@ -1726,7 +1759,9 @@ ISOLATE_UNIT_TEST_CASE(TTS_TypeParameter) { } H genericFun(dynamic x) => x as H; + @pragma("vm:entry-point", "call") createAInt() => A(); + @pragma("vm:entry-point", "call") createAString() => A(); )"; @@ -1859,11 +1894,16 @@ ISOLATE_UNIT_TEST_CASE(TTS_Function) { R"( class A {} + @pragma("vm:entry-point", "call") createF() => (){}; + @pragma("vm:entry-point", "call") createG() => () => 3; + @pragma("vm:entry-point", "call") createH() => (int x, String y, {int z = 0}) => x + z; + @pragma("vm:entry-point", "call") createAInt() => A(); + @pragma("vm:entry-point", "call") createAFunction() => A(); )"; @@ -1904,9 +1944,13 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial) { class E extends D {} F() {} + @pragma("vm:entry-point", "call") createBE() => B(); + @pragma("vm:entry-point", "call") createBENullable() => B(); + @pragma("vm:entry-point", "call") createBNull() => B(); + @pragma("vm:entry-point", "call") createBNever() => B(); )"; @@ -2021,6 +2065,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial_Incremental) { const char* kFirstScript = R"( class B {} + @pragma("vm:entry-point", "call") createB() => B(); )"; @@ -2030,6 +2075,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial_Incremental) { R"( import ")" FIRST_PARTIAL_LIBRARY_NAME R"("; class B2 extends B {} + @pragma("vm:entry-point", "call") createB2() => B2(); )"; @@ -2038,6 +2084,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial_Incremental) { R"( import ")" FIRST_PARTIAL_LIBRARY_NAME R"("; class B3 extends B {} + @pragma("vm:entry-point", "call") createB3() => B3(); )"; @@ -2201,11 +2248,16 @@ static const char* kLoadedScript = R"( class A {} + @pragma("vm:entry-point", "call") createAInt() => A(); + @pragma("vm:entry-point", "call") createAString() => A(); + @pragma("vm:entry-point", "call") (int, int) createRecordIntInt() => (1, 2); + @pragma("vm:entry-point", "call") (String, int) createRecordStringInt() => ("foo", 2); + @pragma("vm:entry-point", "call") (int, String) createRecordIntString() => (1, "bar"); )"; @@ -2214,13 +2266,20 @@ static const char* kReloadedScript = class A {} class A2 extends A {} + @pragma("vm:entry-point", "call") createAInt() => A(); + @pragma("vm:entry-point", "call") createAString() => A(); + @pragma("vm:entry-point", "call") createA2Int() => A2(); + @pragma("vm:entry-point", "call") createA2String() => A2(); + @pragma("vm:entry-point", "call") (int, int) createRecordIntInt() => (1, 2); + @pragma("vm:entry-point", "call") (String, int) createRecordStringInt() => ("foo", 2); + @pragma("vm:entry-point", "call") (int, String) createRecordIntString() => (1, "bar"); )"; @@ -2426,6 +2485,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Regress_CidRangeChecks) { final x = 1; } + @pragma("vm:entry-point", "call") createI() => I(); )"); @@ -2470,10 +2530,14 @@ struct STCTestResults { static STCTestResults SubtypeTestCacheTest(Thread* thread, intptr_t num_classes) { TextBuffer buffer(MB); - buffer.AddString("class D {}\n"); - buffer.AddString("D Function() createClosureD() => () => D();\n"); + buffer.AddString(R"( + class D {} + @pragma('vm:entry-point', 'call') + D Function() createClosureD() => () => D(); + )"); for (intptr_t i = 0; i < num_classes; i++) { buffer.Printf(R"(class C%)" Pd R"( extends D {} + @pragma('vm:entry-point', 'call') C%)" Pd R"( Function() createClosureC%)" Pd R"(() => () => C%)" Pd R"((); )", diff --git a/samples/embedder/hello.dart b/samples/embedder/hello.dart index 8101c81b9020..cbd3e888b524 100644 --- a/samples/embedder/hello.dart +++ b/samples/embedder/hello.dart @@ -4,6 +4,7 @@ import 'package:collection/collection.dart'; +@pragma('vm:entry-point') void main(List? args) { final greetee = args?.singleOrNull ?? 'world'; print('Hello, $greetee!');