1// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
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.
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include "./include/dart_api.h"
9#include "./include/dart_native_api.h"
10
11#define CHECK(H) \
12 do { \
13 Dart_Handle __handle__ = H; \
14 if (Dart_IsError(__handle__)) { \
15 const char* message = Dart_GetError(__handle__); \
16 fprintf(stderr, "Check \"" #H "\" failed: %s", message); \
17 abort(); \
18 } \
19 } while (false)
20
21#define ASSERT(E) \
22 if (!(E)) { \
23 fprintf(stderr, "Assertion \"" #E "\" failed at %s:%d!\n", __FILE__, \
24 __LINE__); \
25 abort(); \
26 }
27
28bool isDartPrecompiledRuntime = true;
29
30// Some invalid accesses are allowed in AOT since we don't retain @pragma
31// annotations. Therefore we skip the negative tests in AOT.
32#define FAIL(name, result) \
33 if (!isDartPrecompiledRuntime) { \
34 Fail(name, result); \
35 }
36
37void Fail(const char* name, Dart_Handle result) {
38 ASSERT(Dart_IsApiError(result));
39 const char* error = Dart_GetError(result);
40 ASSERT(strstr(error, name));
41 ASSERT(strstr(error, "It is illegal to access"));
42}
43
44#define FAIL_INVOKE_FIELD(name, result) \
45 if (!isDartPrecompiledRuntime) { \
46 FailInvokeField(name, result); \
47 }
48
49void FailInvokeField(const char* name, Dart_Handle result) {
50 ASSERT(Dart_IsApiError(result));
51 const char* error = Dart_GetError(result);
52 ASSERT(strstr(error, name));
53 ASSERT(strstr(error, "Entry-points do not allow invoking fields"));
54}
55
56void FailClosurizeConstructor(const char* name, Dart_Handle result) {
57 ASSERT(Dart_IsUnhandledExceptionError(result));
58 const char* error = Dart_GetError(result);
59 ASSERT(strstr(error, name));
60 ASSERT(strstr(error, "No static getter"));
61}
62
63void TestFields(Dart_Handle target) {
64 FAIL("fld0", Dart_GetField(target, Dart_NewStringFromCString("fld0")));
65 FAIL("fld0",
66 Dart_SetField(target, Dart_NewStringFromCString("fld0"), Dart_Null()));
67
68 FAIL_INVOKE_FIELD(
69 "fld0",
70 Dart_Invoke(target, Dart_NewStringFromCString("fld0"), 0, nullptr));
71
72 CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld1")));
73 CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld1"), Dart_Null()));
74 FAIL_INVOKE_FIELD(
75 "fld1",
76 Dart_Invoke(target, Dart_NewStringFromCString("fld1"), 0, nullptr));
77
78 CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld2")));
79 FAIL("fld2",
80 Dart_SetField(target, Dart_NewStringFromCString("fld2"), Dart_Null()));
81 FAIL_INVOKE_FIELD(
82 "fld2",
83 Dart_Invoke(target, Dart_NewStringFromCString("fld2"), 0, nullptr));
84
85 FAIL("fld3", Dart_GetField(target, Dart_NewStringFromCString("fld3")));
86 CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld3"), Dart_Null()));
87 FAIL_INVOKE_FIELD(
88 "fld3",
89 Dart_Invoke(target, Dart_NewStringFromCString("fld3"), 0, nullptr));
90}
91
92void RunTests(Dart_NativeArguments arguments) {
93 Dart_Handle lib = Dart_RootLibrary();
94
95 //////// Test allocation and constructor invocation.
96
97 FAIL("C", Dart_GetClass(lib, Dart_NewStringFromCString("C")));
98
99 Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D"));
100 CHECK(D_class);
101
102 CHECK(Dart_Allocate(D_class));
103
104 FAIL("D.", Dart_New(D_class, Dart_Null(), 0, nullptr));
105
106 CHECK(Dart_New(D_class, Dart_NewStringFromCString("defined"), 0, nullptr));
107 Dart_Handle D =
108 Dart_New(D_class, Dart_NewStringFromCString("fact"), 0, nullptr);
109 CHECK(D);
110
111 //////// Test actions against methods
112
113 FailClosurizeConstructor(
114 "defined", Dart_GetField(D_class, Dart_NewStringFromCString("defined")));
115 FailClosurizeConstructor(
116 "fact", Dart_GetField(D_class, Dart_NewStringFromCString("fact")));
117
118 FAIL("fn0", Dart_Invoke(D, Dart_NewStringFromCString("fn0"), 0, nullptr));
119
120 CHECK(Dart_Invoke(D, Dart_NewStringFromCString("fn1"), 0, nullptr));
121 FAIL("fn1", Dart_Invoke(D, Dart_NewStringFromCString("fn1_get"), 0, nullptr));
122 CHECK(Dart_Invoke(D, Dart_NewStringFromCString("fn1_call"), 0, nullptr));
123
124 FAIL("fn0", Dart_GetField(D, Dart_NewStringFromCString("fn0")));
125
126 CHECK(Dart_GetField(D, Dart_NewStringFromCString("fn1")));
127 CHECK(Dart_GetField(D, Dart_NewStringFromCString("fn1_get")));
128 FAIL("fn1", Dart_GetField(D, Dart_NewStringFromCString("fn1_call")));
129
130 FAIL("fn2",
131 Dart_Invoke(D_class, Dart_NewStringFromCString("fn2"), 0, nullptr));
132
133 CHECK(Dart_Invoke(D_class, Dart_NewStringFromCString("fn3"), 0, nullptr));
134 CHECK(
135 Dart_Invoke(D_class, Dart_NewStringFromCString("fn3_call"), 0, nullptr));
136 FAIL("fn3",
137 Dart_Invoke(D_class, Dart_NewStringFromCString("fn3_get"), 0, nullptr));
138
139 FAIL("fn2", Dart_GetField(D_class, Dart_NewStringFromCString("fn2")));
140
141 CHECK(Dart_GetField(D_class, Dart_NewStringFromCString("fn3")));
142 FAIL("fn3_call",
143 Dart_GetField(D_class, Dart_NewStringFromCString("fn3_call")));
144 CHECK(Dart_GetField(D_class, Dart_NewStringFromCString("fn3_get")));
145
146 FAIL("fn0", Dart_Invoke(lib, Dart_NewStringFromCString("fn0"), 0, nullptr));
147
148 CHECK(Dart_Invoke(lib, Dart_NewStringFromCString("fn1"), 0, nullptr));
149 FAIL("fn1",
150 Dart_Invoke(lib, Dart_NewStringFromCString("fn1_get"), 0, nullptr));
151 CHECK(Dart_Invoke(lib, Dart_NewStringFromCString("fn1_call"), 0, nullptr));
152
153 FAIL("fn0", Dart_GetField(lib, Dart_NewStringFromCString("fn0")));
154
155 CHECK(Dart_GetField(lib, Dart_NewStringFromCString("fn1")));
156 CHECK(Dart_GetField(lib, Dart_NewStringFromCString("fn1_get")));
157 FAIL("fn1", Dart_GetField(lib, Dart_NewStringFromCString("fn1_call")));
158
159 //////// Test actions against fields
160
161 TestFields(D);
162
163 Dart_Handle F_class = Dart_GetClass(lib, Dart_NewStringFromCString("F"));
164 TestFields(F_class);
165
166 TestFields(lib);
167}
168
169Dart_NativeFunction ResolveName(Dart_Handle name,
170 int argc,
171 bool* auto_setup_scope) {
172 if (auto_setup_scope == NULL) {
173 return NULL;
174 }
175 *auto_setup_scope = true;
176 return RunTests;
177}
178
179DART_EXPORT Dart_Handle
180entrypoints_verification_test_extension_Init(Dart_Handle parent_library) {
181 isDartPrecompiledRuntime = Dart_IsPrecompiledRuntime();
182
183 if (Dart_IsError(parent_library)) {
184 return parent_library;
185 }
186
187 Dart_Handle result_code =
188 Dart_SetNativeResolver(parent_library, ResolveName, NULL);
189 if (Dart_IsError(result_code)) {
190 return result_code;
191 }
192
193 return Dart_Null();
194}
195