[vm] Turn on entry point checking in JIT mode.
Now that Flutter tests that access entry points from native code have been annotated[1], we can turn on entry point checking in JIT mode. This CL also removes the A flag category from flag_list.h and the AOT_FLAG_MACRO definitions and uses from flags.[cc,h], as they were created as a temporary measure until this flag could be unconditionally defaulted to true. [1] See the following PRs: * https://github.com/flutter/engine/pull/57158 * https://github.com/flutter/flutter/pull/160158 * https://github.com/flutter/flutter/pull/160421 TEST=vm/dart/entrypoints_verification_test vm/cc/IRTest vm/cc/StreamingFlowGraphBuilder vm/cc/STC vm/cc/TTS Issue: https://github.com/dart-lang/sdk/issues/50649 Issue: https://github.com/flutter/flutter/issues/118608 Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-product-arm64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-linux-release-x64-try,vm-appjit-linux-product-x64-try Change-Id: Ibe5b21bb74f1a6fb88824b71ff87b9e555216dbf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400301 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
committed by
Commit Queue
parent
04530d578f
commit
982b9fad44
@@ -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';
|
||||
|
||||
@@ -62,6 +62,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_EliminateWriteBarrier) {
|
||||
|
||||
Container<int> x = Container<int>();
|
||||
|
||||
@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<NativeFunction<NT>> ptr = Pointer.fromAddress(0);
|
||||
@pragma("vm:entry-point", "call")
|
||||
DT getFfiTrampolineClosure() => ptr.asFunction(isLeaf:true);
|
||||
)";
|
||||
|
||||
|
||||
@@ -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<Uint8>.fromAddress(%s%p);
|
||||
final pointer2 = Pointer<Uint8>.fromAddress(%s%p);
|
||||
noop();
|
||||
}
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
void callNonConstCopy() {
|
||||
final pointer = Pointer<Uint8>.fromAddress(%s%p);
|
||||
final pointer2 = Pointer<Uint8>.fromAddress(%s%p);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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") \
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"(();
|
||||
|
||||
@@ -865,20 +865,35 @@ const char* kSubtypeRangeCheckScript =
|
||||
|
||||
genericFun<A, B>() {}
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
createI() => I<int, String>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createI2() => I2();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBaseInt() => Base<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBaseNull() => Base<Null>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBaseNever() => Base<Never>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createA() => A();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createA1() => A1();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createA2() => A2<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createB() => B();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createB1() => B1();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createB2() => B2<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBaseIStringDouble() => Base<I<String, double>>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBaseA2Int() => Base<A2<int>>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBaseA2A1() => Base<A2<A1>>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBaseB2Int() => Base<B2<int>>();
|
||||
)";
|
||||
|
||||
@@ -1218,17 +1233,28 @@ const char* kRecordSubtypeRangeCheckScript =
|
||||
class D<T> {}
|
||||
|
||||
getType<T>() => 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<int>());
|
||||
@pragma("vm:entry-point", "call")
|
||||
createObj8() => (D<int>(), 3);
|
||||
)";
|
||||
|
||||
@@ -1280,6 +1306,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Generic_Implements_Instantiated_Interface) {
|
||||
abstract class I<T> {}
|
||||
class B<R> implements I<String> {}
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBInt() => B<int>();
|
||||
)";
|
||||
|
||||
@@ -1308,8 +1335,11 @@ ISOLATE_UNIT_TEST_CASE(TTS_Future) {
|
||||
R"(
|
||||
import "dart:async";
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
Future<int> createFutureInt() async => 3;
|
||||
@pragma("vm:entry-point", "call")
|
||||
Future<int Function()> createFutureFunction() async => () => 3;
|
||||
@pragma("vm:entry-point", "call")
|
||||
Future<int Function()?> createFutureNullableFunction() async =>
|
||||
(() => 3) as int Function()?;
|
||||
)";
|
||||
@@ -1689,8 +1719,11 @@ ISOLATE_UNIT_TEST_CASE(TTS_Regress40964) {
|
||||
class B<T> {}
|
||||
class C<T> {}
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
createACint() => A<C<int>>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBCint() => B<C<int>>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBCnum() => B<C<num>>();
|
||||
)";
|
||||
|
||||
@@ -1726,7 +1759,9 @@ ISOLATE_UNIT_TEST_CASE(TTS_TypeParameter) {
|
||||
}
|
||||
H genericFun<H>(dynamic x) => x as H;
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
createAInt() => A<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createAString() => A<String>();
|
||||
)";
|
||||
|
||||
@@ -1859,11 +1894,16 @@ ISOLATE_UNIT_TEST_CASE(TTS_Function) {
|
||||
R"(
|
||||
class A<T> {}
|
||||
|
||||
@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<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createAFunction() => A<Function>();
|
||||
)";
|
||||
|
||||
@@ -1904,9 +1944,13 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial) {
|
||||
class E extends D {}
|
||||
|
||||
F<A>() {}
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBE() => B<E>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBENullable() => B<E?>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBNull() => B<Null>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createBNever() => B<Never>();
|
||||
)";
|
||||
|
||||
@@ -2021,6 +2065,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial_Incremental) {
|
||||
const char* kFirstScript =
|
||||
R"(
|
||||
class B<T> {}
|
||||
@pragma("vm:entry-point", "call")
|
||||
createB() => B<int>();
|
||||
)";
|
||||
|
||||
@@ -2030,6 +2075,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial_Incremental) {
|
||||
R"(
|
||||
import ")" FIRST_PARTIAL_LIBRARY_NAME R"(";
|
||||
class B2<T> extends B<T> {}
|
||||
@pragma("vm:entry-point", "call")
|
||||
createB2() => B2<int>();
|
||||
)";
|
||||
|
||||
@@ -2038,6 +2084,7 @@ ISOLATE_UNIT_TEST_CASE(TTS_Partial_Incremental) {
|
||||
R"(
|
||||
import ")" FIRST_PARTIAL_LIBRARY_NAME R"(";
|
||||
class B3<T> extends B<T> {}
|
||||
@pragma("vm:entry-point", "call")
|
||||
createB3() => B3<int>();
|
||||
)";
|
||||
|
||||
@@ -2201,11 +2248,16 @@ static const char* kLoadedScript =
|
||||
R"(
|
||||
class A<T> {}
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
createAInt() => A<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createAString() => A<String>();
|
||||
|
||||
@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<T> {}
|
||||
class A2<T> extends A<T> {}
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
createAInt() => A<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createAString() => A<String>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createA2Int() => A2<int>();
|
||||
@pragma("vm:entry-point", "call")
|
||||
createA2String() => A2<String>();
|
||||
|
||||
@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<S> {}\n");
|
||||
buffer.AddString("D<int> Function() createClosureD() => () => D<int>();\n");
|
||||
buffer.AddString(R"(
|
||||
class D<S> {}
|
||||
@pragma('vm:entry-point', 'call')
|
||||
D<int> Function() createClosureD() => () => D<int>();
|
||||
)");
|
||||
for (intptr_t i = 0; i < num_classes; i++) {
|
||||
buffer.Printf(R"(class C%)" Pd R"(<S> extends D<S> {}
|
||||
@pragma('vm:entry-point', 'call')
|
||||
C%)" Pd R"(<int> Function() createClosureC%)" Pd R"(() => () => C%)" Pd
|
||||
R"(<int>();
|
||||
)",
|
||||
|
||||
Reference in New Issue
Block a user