annotate gcc/go/gofrontend/runtime.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // runtime.cc -- runtime functions called by generated code
kono
parents:
diff changeset
2
kono
parents:
diff changeset
3 // Copyright 2011 The Go Authors. All rights reserved.
kono
parents:
diff changeset
4 // Use of this source code is governed by a BSD-style
kono
parents:
diff changeset
5 // license that can be found in the LICENSE file.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 #include "go-system.h"
kono
parents:
diff changeset
8
kono
parents:
diff changeset
9 #include "gogo.h"
kono
parents:
diff changeset
10 #include "types.h"
kono
parents:
diff changeset
11 #include "expressions.h"
kono
parents:
diff changeset
12 #include "runtime.h"
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14 // The frontend generates calls to various runtime functions. They
kono
parents:
diff changeset
15 // are implemented in libgo/runtime. This is how the runtime
kono
parents:
diff changeset
16 // functions are represented in the frontend. Note that there is
kono
parents:
diff changeset
17 // currently nothing which ensures that the compiler's understanding
kono
parents:
diff changeset
18 // of the runtime function matches the actual implementation in
kono
parents:
diff changeset
19 // libgo/runtime.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 // Parameter and result types used by runtime functions.
kono
parents:
diff changeset
22
kono
parents:
diff changeset
23 enum Runtime_function_type
kono
parents:
diff changeset
24 {
kono
parents:
diff changeset
25 // General indicator that value is not used.
kono
parents:
diff changeset
26 RFT_VOID,
kono
parents:
diff changeset
27 // Go untyped bool, C type _Bool.
kono
parents:
diff changeset
28 RFT_BOOL,
kono
parents:
diff changeset
29 // Go type *bool, C type _Bool*.
kono
parents:
diff changeset
30 RFT_BOOLPTR,
kono
parents:
diff changeset
31 // Go type int, C type intgo.
kono
parents:
diff changeset
32 RFT_INT,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
33 // Go type uint, C type uintgo.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
34 RFT_UINT,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
35 // Go type uint8, C type uint8_t.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
36 RFT_UINT8,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
37 // Go type uint16, C type uint16_t.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
38 RFT_UINT16,
111
kono
parents:
diff changeset
39 // Go type int32, C type int32_t.
kono
parents:
diff changeset
40 RFT_INT32,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
41 // Go type uint32, C type uint32_t.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
42 RFT_UINT32,
111
kono
parents:
diff changeset
43 // Go type int64, C type int64_t.
kono
parents:
diff changeset
44 RFT_INT64,
kono
parents:
diff changeset
45 // Go type uint64, C type uint64_t.
kono
parents:
diff changeset
46 RFT_UINT64,
kono
parents:
diff changeset
47 // Go type uintptr, C type uintptr_t.
kono
parents:
diff changeset
48 RFT_UINTPTR,
kono
parents:
diff changeset
49 // Go type rune, C type int32_t.
kono
parents:
diff changeset
50 RFT_RUNE,
kono
parents:
diff changeset
51 // Go type float64, C type double.
kono
parents:
diff changeset
52 RFT_FLOAT64,
kono
parents:
diff changeset
53 // Go type complex64, C type __complex float.
kono
parents:
diff changeset
54 RFT_COMPLEX64,
kono
parents:
diff changeset
55 // Go type complex128, C type __complex double.
kono
parents:
diff changeset
56 RFT_COMPLEX128,
kono
parents:
diff changeset
57 // Go type string, C type struct __go_string.
kono
parents:
diff changeset
58 RFT_STRING,
kono
parents:
diff changeset
59 // Go type unsafe.Pointer, C type "void *".
kono
parents:
diff changeset
60 RFT_POINTER,
kono
parents:
diff changeset
61 // Go type []any, C type struct __go_open_array.
kono
parents:
diff changeset
62 RFT_SLICE,
kono
parents:
diff changeset
63 // Go type map[any]any, C type struct __go_map *.
kono
parents:
diff changeset
64 RFT_MAP,
kono
parents:
diff changeset
65 // Go type chan any, C type struct __go_channel *.
kono
parents:
diff changeset
66 RFT_CHAN,
kono
parents:
diff changeset
67 // Go type non-empty interface, C type struct __go_interface.
kono
parents:
diff changeset
68 RFT_IFACE,
kono
parents:
diff changeset
69 // Go type interface{}, C type struct __go_empty_interface.
kono
parents:
diff changeset
70 RFT_EFACE,
kono
parents:
diff changeset
71 // Pointer to Go type descriptor.
kono
parents:
diff changeset
72 RFT_TYPE,
kono
parents:
diff changeset
73 // [2]string.
kono
parents:
diff changeset
74 RFT_ARRAY2STRING,
kono
parents:
diff changeset
75 // [3]string.
kono
parents:
diff changeset
76 RFT_ARRAY3STRING,
kono
parents:
diff changeset
77 // [4]string.
kono
parents:
diff changeset
78 RFT_ARRAY4STRING,
kono
parents:
diff changeset
79 // [5]string.
kono
parents:
diff changeset
80 RFT_ARRAY5STRING,
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 NUMBER_OF_RUNTIME_FUNCTION_TYPES
kono
parents:
diff changeset
83 };
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 // The Type structures for the runtime function types.
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 static Type* runtime_function_types[NUMBER_OF_RUNTIME_FUNCTION_TYPES];
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 // Get the Type for a Runtime_function_type code.
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 static Type*
kono
parents:
diff changeset
92 runtime_function_type(Runtime_function_type bft)
kono
parents:
diff changeset
93 {
kono
parents:
diff changeset
94 go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
kono
parents:
diff changeset
95 Type* any = Type::make_pointer_type(Type::make_void_type());
kono
parents:
diff changeset
96 if (runtime_function_types[bft] == NULL)
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 const Location bloc = Linemap::predeclared_location();
kono
parents:
diff changeset
99 Type* t;
kono
parents:
diff changeset
100 switch (bft)
kono
parents:
diff changeset
101 {
kono
parents:
diff changeset
102 default:
kono
parents:
diff changeset
103 case RFT_VOID:
kono
parents:
diff changeset
104 go_unreachable();
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 case RFT_BOOL:
kono
parents:
diff changeset
107 t = Type::make_boolean_type();
kono
parents:
diff changeset
108 break;
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 case RFT_BOOLPTR:
kono
parents:
diff changeset
111 t = Type::make_pointer_type(Type::lookup_bool_type());
kono
parents:
diff changeset
112 break;
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 case RFT_INT:
kono
parents:
diff changeset
115 t = Type::lookup_integer_type("int");
kono
parents:
diff changeset
116 break;
kono
parents:
diff changeset
117
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
118 case RFT_UINT:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
119 t = Type::lookup_integer_type("uint");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
120 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
121
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
122 case RFT_UINT8:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
123 t = Type::lookup_integer_type("uint8");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
124 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
125
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
126 case RFT_UINT16:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
127 t = Type::lookup_integer_type("uint16");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
128 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
129
111
kono
parents:
diff changeset
130 case RFT_INT32:
kono
parents:
diff changeset
131 t = Type::lookup_integer_type("int32");
kono
parents:
diff changeset
132 break;
kono
parents:
diff changeset
133
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
134 case RFT_UINT32:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
135 t = Type::lookup_integer_type("uint32");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
136 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
137
111
kono
parents:
diff changeset
138 case RFT_INT64:
kono
parents:
diff changeset
139 t = Type::lookup_integer_type("int64");
kono
parents:
diff changeset
140 break;
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 case RFT_UINT64:
kono
parents:
diff changeset
143 t = Type::lookup_integer_type("uint64");
kono
parents:
diff changeset
144 break;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 case RFT_RUNE:
kono
parents:
diff changeset
147 t = Type::lookup_integer_type("int32");
kono
parents:
diff changeset
148 break;
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 case RFT_UINTPTR:
kono
parents:
diff changeset
151 t = Type::lookup_integer_type("uintptr");
kono
parents:
diff changeset
152 break;
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 case RFT_FLOAT64:
kono
parents:
diff changeset
155 t = Type::lookup_float_type("float64");
kono
parents:
diff changeset
156 break;
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 case RFT_COMPLEX64:
kono
parents:
diff changeset
159 t = Type::lookup_complex_type("complex64");
kono
parents:
diff changeset
160 break;
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 case RFT_COMPLEX128:
kono
parents:
diff changeset
163 t = Type::lookup_complex_type("complex128");
kono
parents:
diff changeset
164 break;
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 case RFT_STRING:
kono
parents:
diff changeset
167 t = Type::lookup_string_type();
kono
parents:
diff changeset
168 break;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 case RFT_POINTER:
kono
parents:
diff changeset
171 t = Type::make_pointer_type(Type::make_void_type());
kono
parents:
diff changeset
172 break;
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 case RFT_SLICE:
kono
parents:
diff changeset
175 t = Type::make_array_type(any, NULL);
kono
parents:
diff changeset
176 break;
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 case RFT_MAP:
kono
parents:
diff changeset
179 t = Type::make_map_type(any, any, bloc);
kono
parents:
diff changeset
180 break;
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 case RFT_CHAN:
kono
parents:
diff changeset
183 t = Type::make_channel_type(true, true, any);
kono
parents:
diff changeset
184 break;
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 case RFT_IFACE:
kono
parents:
diff changeset
187 {
kono
parents:
diff changeset
188 Typed_identifier_list* methods = new Typed_identifier_list();
kono
parents:
diff changeset
189 Type* mtype = Type::make_function_type(NULL, NULL, NULL, bloc);
kono
parents:
diff changeset
190 methods->push_back(Typed_identifier("x", mtype, bloc));
kono
parents:
diff changeset
191 Interface_type* it = Type::make_interface_type(methods, bloc);
kono
parents:
diff changeset
192 it->finalize_methods();
kono
parents:
diff changeset
193 t = it;
kono
parents:
diff changeset
194 }
kono
parents:
diff changeset
195 break;
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 case RFT_EFACE:
kono
parents:
diff changeset
198 t = Type::make_empty_interface_type(bloc);
kono
parents:
diff changeset
199 break;
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 case RFT_TYPE:
kono
parents:
diff changeset
202 t = Type::make_type_descriptor_ptr_type();
kono
parents:
diff changeset
203 break;
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 case RFT_ARRAY2STRING:
kono
parents:
diff changeset
206 {
kono
parents:
diff changeset
207 Array_type* at =
kono
parents:
diff changeset
208 Type::make_array_type(Type::make_string_type(),
kono
parents:
diff changeset
209 Expression::make_integer_ul(2, NULL,
kono
parents:
diff changeset
210 bloc));
kono
parents:
diff changeset
211 at->set_is_array_incomparable();
kono
parents:
diff changeset
212 t = at;
kono
parents:
diff changeset
213 }
kono
parents:
diff changeset
214 break;
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 case RFT_ARRAY3STRING:
kono
parents:
diff changeset
217 {
kono
parents:
diff changeset
218 Array_type* at =
kono
parents:
diff changeset
219 Type::make_array_type(Type::make_string_type(),
kono
parents:
diff changeset
220 Expression::make_integer_ul(3, NULL,
kono
parents:
diff changeset
221 bloc));
kono
parents:
diff changeset
222 at->set_is_array_incomparable();
kono
parents:
diff changeset
223 t = at;
kono
parents:
diff changeset
224 }
kono
parents:
diff changeset
225 break;
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 case RFT_ARRAY4STRING:
kono
parents:
diff changeset
228 {
kono
parents:
diff changeset
229 Array_type* at =
kono
parents:
diff changeset
230 Type::make_array_type(Type::make_string_type(),
kono
parents:
diff changeset
231 Expression::make_integer_ul(4, NULL,
kono
parents:
diff changeset
232 bloc));
kono
parents:
diff changeset
233 at->set_is_array_incomparable();
kono
parents:
diff changeset
234 t = at;
kono
parents:
diff changeset
235 }
kono
parents:
diff changeset
236 break;
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 case RFT_ARRAY5STRING:
kono
parents:
diff changeset
239 {
kono
parents:
diff changeset
240 Array_type* at =
kono
parents:
diff changeset
241 Type::make_array_type(Type::make_string_type(),
kono
parents:
diff changeset
242 Expression::make_integer_ul(5, NULL,
kono
parents:
diff changeset
243 bloc));
kono
parents:
diff changeset
244 at->set_is_array_incomparable();
kono
parents:
diff changeset
245 t = at;
kono
parents:
diff changeset
246 }
kono
parents:
diff changeset
247 break;
kono
parents:
diff changeset
248 }
kono
parents:
diff changeset
249
kono
parents:
diff changeset
250 runtime_function_types[bft] = t;
kono
parents:
diff changeset
251 }
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 return runtime_function_types[bft];
kono
parents:
diff changeset
254 }
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 // Convert an expression to the type to pass to a runtime function.
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 static Expression*
kono
parents:
diff changeset
259 convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
kono
parents:
diff changeset
260 Location loc)
kono
parents:
diff changeset
261 {
kono
parents:
diff changeset
262 switch (bft)
kono
parents:
diff changeset
263 {
kono
parents:
diff changeset
264 default:
kono
parents:
diff changeset
265 case RFT_VOID:
kono
parents:
diff changeset
266 go_unreachable();
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 case RFT_BOOL:
kono
parents:
diff changeset
269 case RFT_BOOLPTR:
kono
parents:
diff changeset
270 case RFT_INT:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
271 case RFT_UINT:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
272 case RFT_UINT8:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
273 case RFT_UINT16:
111
kono
parents:
diff changeset
274 case RFT_INT32:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
275 case RFT_UINT32:
111
kono
parents:
diff changeset
276 case RFT_INT64:
kono
parents:
diff changeset
277 case RFT_UINT64:
kono
parents:
diff changeset
278 case RFT_UINTPTR:
kono
parents:
diff changeset
279 case RFT_RUNE:
kono
parents:
diff changeset
280 case RFT_FLOAT64:
kono
parents:
diff changeset
281 case RFT_COMPLEX64:
kono
parents:
diff changeset
282 case RFT_COMPLEX128:
kono
parents:
diff changeset
283 case RFT_STRING:
kono
parents:
diff changeset
284 case RFT_POINTER:
kono
parents:
diff changeset
285 {
kono
parents:
diff changeset
286 Type* t = runtime_function_type(bft);
kono
parents:
diff changeset
287 if (!Type::are_identical(t, e->type(), true, NULL))
kono
parents:
diff changeset
288 e = Expression::make_cast(t, e, loc);
kono
parents:
diff changeset
289 return e;
kono
parents:
diff changeset
290 }
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 case RFT_SLICE:
kono
parents:
diff changeset
293 case RFT_MAP:
kono
parents:
diff changeset
294 case RFT_CHAN:
kono
parents:
diff changeset
295 case RFT_IFACE:
kono
parents:
diff changeset
296 case RFT_EFACE:
kono
parents:
diff changeset
297 case RFT_ARRAY2STRING:
kono
parents:
diff changeset
298 case RFT_ARRAY3STRING:
kono
parents:
diff changeset
299 case RFT_ARRAY4STRING:
kono
parents:
diff changeset
300 case RFT_ARRAY5STRING:
kono
parents:
diff changeset
301 return Expression::make_unsafe_cast(runtime_function_type(bft), e, loc);
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 case RFT_TYPE:
kono
parents:
diff changeset
304 go_assert(e->type() == Type::make_type_descriptor_ptr_type());
kono
parents:
diff changeset
305 return e;
kono
parents:
diff changeset
306 }
kono
parents:
diff changeset
307 }
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 // Convert all the types used for runtime functions to the backend
kono
parents:
diff changeset
310 // representation.
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 void
kono
parents:
diff changeset
313 Runtime::convert_types(Gogo* gogo)
kono
parents:
diff changeset
314 {
kono
parents:
diff changeset
315 for (int i = 0; i < static_cast<int>(NUMBER_OF_RUNTIME_FUNCTION_TYPES); ++i)
kono
parents:
diff changeset
316 {
kono
parents:
diff changeset
317 Type* t = runtime_function_types[i];
kono
parents:
diff changeset
318 if (t != NULL && t->named_type() != NULL)
kono
parents:
diff changeset
319 {
kono
parents:
diff changeset
320 bool r = t->verify();
kono
parents:
diff changeset
321 go_assert(r);
kono
parents:
diff changeset
322 t->named_type()->convert(gogo);
kono
parents:
diff changeset
323 }
kono
parents:
diff changeset
324 }
kono
parents:
diff changeset
325 }
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 // The type used to define a runtime function.
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 struct Runtime_function
kono
parents:
diff changeset
330 {
kono
parents:
diff changeset
331 // Function name.
kono
parents:
diff changeset
332 const char* name;
kono
parents:
diff changeset
333 // Parameter types. Never more than 6, as it happens. RFT_VOID if
kono
parents:
diff changeset
334 // not used.
kono
parents:
diff changeset
335 Runtime_function_type parameter_types[6];
kono
parents:
diff changeset
336 // Result types. Never more than 2, as it happens. RFT_VOID if not
kono
parents:
diff changeset
337 // used.
kono
parents:
diff changeset
338 Runtime_function_type result_types[2];
kono
parents:
diff changeset
339 };
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 static const Runtime_function runtime_functions[] =
kono
parents:
diff changeset
342 {
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 #define DEF_GO_RUNTIME(CODE, NAME, PARAMS, RESULTS) { NAME, PARAMS, RESULTS } ,
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 #include "runtime.def"
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 #undef DEF_GO_RUNTIME
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 };
kono
parents:
diff changeset
351
kono
parents:
diff changeset
352 static Named_object*
kono
parents:
diff changeset
353 runtime_function_declarations[Runtime::NUMBER_OF_FUNCTIONS];
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 // Get the declaration of a runtime function.
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 Named_object*
kono
parents:
diff changeset
358 Runtime::runtime_declaration(Function code)
kono
parents:
diff changeset
359 {
kono
parents:
diff changeset
360 go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);
kono
parents:
diff changeset
361 if (runtime_function_declarations[code] == NULL)
kono
parents:
diff changeset
362 {
kono
parents:
diff changeset
363 const Runtime_function* pb = &runtime_functions[code];
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 Location bloc = Linemap::predeclared_location();
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 Typed_identifier_list* param_types = NULL;
kono
parents:
diff changeset
368 if (pb->parameter_types[0] != RFT_VOID)
kono
parents:
diff changeset
369 {
kono
parents:
diff changeset
370 param_types = new Typed_identifier_list();
kono
parents:
diff changeset
371 for (unsigned int i = 0;
kono
parents:
diff changeset
372 i < (sizeof(pb->parameter_types)
kono
parents:
diff changeset
373 / sizeof (pb->parameter_types[0]));
kono
parents:
diff changeset
374 i++)
kono
parents:
diff changeset
375 {
kono
parents:
diff changeset
376 if (pb->parameter_types[i] == RFT_VOID)
kono
parents:
diff changeset
377 break;
kono
parents:
diff changeset
378 Type* t = runtime_function_type(pb->parameter_types[i]);
kono
parents:
diff changeset
379 param_types->push_back(Typed_identifier("", t, bloc));
kono
parents:
diff changeset
380 }
kono
parents:
diff changeset
381 }
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 Typed_identifier_list* result_types = NULL;
kono
parents:
diff changeset
384 if (pb->result_types[0] != RFT_VOID)
kono
parents:
diff changeset
385 {
kono
parents:
diff changeset
386 result_types = new Typed_identifier_list();
kono
parents:
diff changeset
387 for (unsigned int i = 0;
kono
parents:
diff changeset
388 i < sizeof(pb->result_types) / sizeof(pb->result_types[0]);
kono
parents:
diff changeset
389 i++)
kono
parents:
diff changeset
390 {
kono
parents:
diff changeset
391 if (pb->result_types[i] == RFT_VOID)
kono
parents:
diff changeset
392 break;
kono
parents:
diff changeset
393 Type* t = runtime_function_type(pb->result_types[i]);
kono
parents:
diff changeset
394 result_types->push_back(Typed_identifier("", t, bloc));
kono
parents:
diff changeset
395 }
kono
parents:
diff changeset
396 }
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 Function_type* fntype = Type::make_function_type(NULL, param_types,
kono
parents:
diff changeset
399 result_types, bloc);
kono
parents:
diff changeset
400 const char* n = pb->name;
kono
parents:
diff changeset
401 const char* n1 = strchr(n, '.');
kono
parents:
diff changeset
402 if (n1 != NULL)
kono
parents:
diff changeset
403 n = n1 + 1;
kono
parents:
diff changeset
404 Named_object* no = Named_object::make_function_declaration(n, NULL,
kono
parents:
diff changeset
405 fntype, bloc);
kono
parents:
diff changeset
406 no->func_declaration_value()->set_asm_name(pb->name);
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 runtime_function_declarations[code] = no;
kono
parents:
diff changeset
409 }
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 return runtime_function_declarations[code];
kono
parents:
diff changeset
412 }
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 // Make a call to a runtime function.
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 Call_expression*
kono
parents:
diff changeset
417 Runtime::make_call(Runtime::Function code, Location loc,
kono
parents:
diff changeset
418 int param_count, ...)
kono
parents:
diff changeset
419 {
kono
parents:
diff changeset
420 go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 const Runtime_function* pb = &runtime_functions[code];
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 go_assert(static_cast<size_t>(param_count)
kono
parents:
diff changeset
425 <= sizeof(pb->parameter_types) / sizeof(pb->parameter_types[0]));
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 Named_object* no = runtime_declaration(code);
kono
parents:
diff changeset
428 Expression* func = Expression::make_func_reference(no, NULL, loc);
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 Expression_list* args = new Expression_list();
kono
parents:
diff changeset
431 args->reserve(param_count);
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 va_list ap;
kono
parents:
diff changeset
434 va_start(ap, param_count);
kono
parents:
diff changeset
435 for (int i = 0; i < param_count; ++i)
kono
parents:
diff changeset
436 {
kono
parents:
diff changeset
437 Expression* e = va_arg(ap, Expression*);
kono
parents:
diff changeset
438 Runtime_function_type rft = pb->parameter_types[i];
kono
parents:
diff changeset
439 args->push_back(convert_to_runtime_function_type(rft, e, loc));
kono
parents:
diff changeset
440 }
kono
parents:
diff changeset
441 va_end(ap);
kono
parents:
diff changeset
442
kono
parents:
diff changeset
443 return Expression::make_call(func, args, false, loc);
kono
parents:
diff changeset
444 }
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 // Get the runtime code for a named builtin function. This is used as a helper
kono
parents:
diff changeset
447 // when creating function references for call expressions. Every reference to
kono
parents:
diff changeset
448 // a builtin runtime function should have the associated runtime code. If the
kono
parents:
diff changeset
449 // name is ambiguous and can refer to many runtime codes, return
kono
parents:
diff changeset
450 // NUMBER_OF_FUNCTIONS.
kono
parents:
diff changeset
451
kono
parents:
diff changeset
452 Runtime::Function
kono
parents:
diff changeset
453 Runtime::name_to_code(const std::string& name)
kono
parents:
diff changeset
454 {
kono
parents:
diff changeset
455 Function code = Runtime::NUMBER_OF_FUNCTIONS;
kono
parents:
diff changeset
456
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
457 // Look through the known names for a match.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458 for (size_t i = 0; i < Runtime::NUMBER_OF_FUNCTIONS; i++)
111
kono
parents:
diff changeset
459 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
460 const char* runtime_function_name = runtime_functions[i].name;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
461 if (strcmp(runtime_function_name, name.c_str()) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
462 code = static_cast<Runtime::Function>(i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
463 // The names in the table have "runtime." prefix. We may be
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
464 // called with a name without the prefix. Try matching
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
465 // without the prefix as well.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
466 if (strncmp(runtime_function_name, "runtime.", 8) == 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
467 && strcmp(runtime_function_name + 8, name.c_str()) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
468 code = static_cast<Runtime::Function>(i);
111
kono
parents:
diff changeset
469 }
kono
parents:
diff changeset
470 return code;
kono
parents:
diff changeset
471 }