1 // runtime.cc -- runtime functions called by generated code
3 // Copyright 2011 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
11 #include "expressions.h"
14 // The frontend generates calls to various runtime functions. They
15 // are implemented in libgo/runtime. This is how the runtime
16 // functions are represented in the frontend. Note that there is
17 // currently nothing which ensures that the compiler's understanding
18 // of the runtime function matches the actual implementation in
21 // Parameter and result types used by runtime functions.
23 enum Runtime_function_type
25 // General indicator that value is not used.
27 // Go untyped bool, C type _Bool.
29 // Go type *bool, C type _Bool*.
31 // Go type int, C type intgo.
33 // Go type uint, C type uintgo.
35 // Go type uint8, C type uint8_t.
37 // Go type uint16, C type uint16_t.
39 // Go type int32, C type int32_t.
41 // Go type uint32, C type uint32_t.
43 // Go type int64, C type int64_t.
45 // Go type uint64, C type uint64_t.
47 // Go type uintptr, C type uintptr_t.
49 // Go type rune, C type int32_t.
51 // Go type float64, C type double.
53 // Go type complex64, C type __complex float.
55 // Go type complex128, C type __complex double.
57 // Go type string, C type struct __go_string.
59 // Go type unsafe.Pointer, C type "void *".
61 // Go type []any, C type struct __go_open_array.
63 // Go type map[any]any, C type struct __go_map *.
65 // Go type chan any, C type struct __go_channel *.
67 // Go type non-empty interface, C type struct __go_interface.
69 // Go type interface{}, C type struct __go_empty_interface.
71 // Pointer to Go type descriptor.
82 NUMBER_OF_RUNTIME_FUNCTION_TYPES
85 // The Type structures for the runtime function types.
87 static Type
* runtime_function_types
[NUMBER_OF_RUNTIME_FUNCTION_TYPES
];
89 // Get the Type for a Runtime_function_type code.
92 runtime_function_type(Runtime_function_type bft
)
94 go_assert(bft
< NUMBER_OF_RUNTIME_FUNCTION_TYPES
);
95 Type
* any
= Type::make_pointer_type(Type::make_void_type());
96 if (runtime_function_types
[bft
] == NULL
)
98 const Location bloc
= Linemap::predeclared_location();
107 t
= Type::make_boolean_type();
111 t
= Type::make_pointer_type(Type::lookup_bool_type());
115 t
= Type::lookup_integer_type("int");
119 t
= Type::lookup_integer_type("uint");
123 t
= Type::lookup_integer_type("uint8");
127 t
= Type::lookup_integer_type("uint16");
131 t
= Type::lookup_integer_type("int32");
135 t
= Type::lookup_integer_type("uint32");
139 t
= Type::lookup_integer_type("int64");
143 t
= Type::lookup_integer_type("uint64");
147 t
= Type::lookup_integer_type("int32");
151 t
= Type::lookup_integer_type("uintptr");
155 t
= Type::lookup_float_type("float64");
159 t
= Type::lookup_complex_type("complex64");
163 t
= Type::lookup_complex_type("complex128");
167 t
= Type::lookup_string_type();
171 t
= Type::make_pointer_type(Type::make_void_type());
175 t
= Type::make_array_type(any
, NULL
);
179 t
= Type::make_map_type(any
, any
, bloc
);
183 t
= Type::make_channel_type(true, true, any
);
188 Typed_identifier_list
* methods
= new Typed_identifier_list();
189 Type
* mtype
= Type::make_function_type(NULL
, NULL
, NULL
, bloc
);
190 methods
->push_back(Typed_identifier("x", mtype
, bloc
));
191 Interface_type
* it
= Type::make_interface_type(methods
, bloc
);
192 it
->finalize_methods();
198 t
= Type::make_empty_interface_type(bloc
);
202 t
= Type::make_type_descriptor_ptr_type();
205 case RFT_ARRAY2STRING
:
208 Type::make_array_type(Type::make_string_type(),
209 Expression::make_integer_ul(2, NULL
,
211 at
->set_is_array_incomparable();
216 case RFT_ARRAY3STRING
:
219 Type::make_array_type(Type::make_string_type(),
220 Expression::make_integer_ul(3, NULL
,
222 at
->set_is_array_incomparable();
227 case RFT_ARRAY4STRING
:
230 Type::make_array_type(Type::make_string_type(),
231 Expression::make_integer_ul(4, NULL
,
233 at
->set_is_array_incomparable();
238 case RFT_ARRAY5STRING
:
241 Type::make_array_type(Type::make_string_type(),
242 Expression::make_integer_ul(5, NULL
,
244 at
->set_is_array_incomparable();
250 runtime_function_types
[bft
] = t
;
253 return runtime_function_types
[bft
];
256 // Convert an expression to the type to pass to a runtime function.
259 convert_to_runtime_function_type(Gogo
* gogo
, Runtime_function_type bft
,
260 Expression
* e
, Location loc
)
286 Type
* t
= runtime_function_type(bft
);
287 Type_context
context(t
, false);
288 e
->determine_type(gogo
, &context
);
289 if (!Type::are_identical(t
, e
->type(), true, NULL
))
290 e
= Expression::make_cast(t
, e
, loc
);
299 case RFT_ARRAY2STRING
:
300 case RFT_ARRAY3STRING
:
301 case RFT_ARRAY4STRING
:
302 case RFT_ARRAY5STRING
:
303 return Expression::make_unsafe_cast(runtime_function_type(bft
), e
, loc
);
306 go_assert(e
->type() == Type::make_type_descriptor_ptr_type());
311 // Convert all the types used for runtime functions to the backend
315 Runtime::convert_types(Gogo
* gogo
)
317 for (int i
= 0; i
< static_cast<int>(NUMBER_OF_RUNTIME_FUNCTION_TYPES
); ++i
)
319 Type
* t
= runtime_function_types
[i
];
320 if (t
!= NULL
&& t
->named_type() != NULL
)
322 bool r
= t
->verify(gogo
);
324 t
->named_type()->convert(gogo
);
329 // The type used to define a runtime function.
331 struct Runtime_function
335 // Parameter types. Never more than 6, as it happens. RFT_VOID if
337 Runtime_function_type parameter_types
[6];
338 // Result types. Never more than 2, as it happens. RFT_VOID if not
340 Runtime_function_type result_types
[2];
343 static const Runtime_function runtime_functions
[] =
346 #define DEF_GO_RUNTIME(CODE, NAME, PARAMS, RESULTS) { NAME, PARAMS, RESULTS } ,
348 #include "runtime.def"
350 #undef DEF_GO_RUNTIME
355 runtime_function_declarations
[Runtime::NUMBER_OF_FUNCTIONS
];
357 // Get the declaration of a runtime function.
360 Runtime::runtime_declaration(Function code
)
362 go_assert(code
< Runtime::NUMBER_OF_FUNCTIONS
);
363 if (runtime_function_declarations
[code
] == NULL
)
365 const Runtime_function
* pb
= &runtime_functions
[code
];
367 Location bloc
= Linemap::predeclared_location();
369 Typed_identifier_list
* param_types
= NULL
;
370 if (pb
->parameter_types
[0] != RFT_VOID
)
372 param_types
= new Typed_identifier_list();
373 for (unsigned int i
= 0;
374 i
< (sizeof(pb
->parameter_types
)
375 / sizeof (pb
->parameter_types
[0]));
378 if (pb
->parameter_types
[i
] == RFT_VOID
)
380 Type
* t
= runtime_function_type(pb
->parameter_types
[i
]);
381 param_types
->push_back(Typed_identifier("", t
, bloc
));
385 Typed_identifier_list
* result_types
= NULL
;
386 if (pb
->result_types
[0] != RFT_VOID
)
388 result_types
= new Typed_identifier_list();
389 for (unsigned int i
= 0;
390 i
< sizeof(pb
->result_types
) / sizeof(pb
->result_types
[0]);
393 if (pb
->result_types
[i
] == RFT_VOID
)
395 Type
* t
= runtime_function_type(pb
->result_types
[i
]);
396 result_types
->push_back(Typed_identifier("", t
, bloc
));
400 Function_type
* fntype
= Type::make_function_type(NULL
, param_types
,
402 const char* n
= pb
->name
;
403 const char* n1
= strchr(n
, '.');
406 Named_object
* no
= Named_object::make_function_declaration(n
, NULL
,
408 no
->func_declaration_value()->set_asm_name(pb
->name
);
410 runtime_function_declarations
[code
] = no
;
413 return runtime_function_declarations
[code
];
416 // Make a call to a runtime function.
419 Runtime::make_call(Gogo
* gogo
, Runtime::Function code
, Location loc
,
420 int param_count
, ...)
422 go_assert(code
< Runtime::NUMBER_OF_FUNCTIONS
);
424 const Runtime_function
* pb
= &runtime_functions
[code
];
426 go_assert(static_cast<size_t>(param_count
)
427 <= sizeof(pb
->parameter_types
) / sizeof(pb
->parameter_types
[0]));
429 Named_object
* no
= runtime_declaration(code
);
430 Expression
* func
= Expression::make_func_reference(no
, NULL
, loc
);
432 Expression_list
* args
= new Expression_list();
433 args
->reserve(param_count
);
436 va_start(ap
, param_count
);
437 for (int i
= 0; i
< param_count
; ++i
)
439 Expression
* e
= va_arg(ap
, Expression
*);
440 Runtime_function_type rft
= pb
->parameter_types
[i
];
441 args
->push_back(convert_to_runtime_function_type(gogo
, rft
, e
, loc
));
445 return Expression::make_call(func
, args
, false, loc
);
448 // Get the runtime code for a named builtin function. This is used as a helper
449 // when creating function references for call expressions. Every reference to
450 // a builtin runtime function should have the associated runtime code. If the
451 // name is ambiguous and can refer to many runtime codes, return
452 // NUMBER_OF_FUNCTIONS.
455 Runtime::name_to_code(const std::string
& name
)
457 Function code
= Runtime::NUMBER_OF_FUNCTIONS
;
459 // Look through the known names for a match.
460 for (size_t i
= 0; i
< Runtime::NUMBER_OF_FUNCTIONS
; i
++)
462 const char* runtime_function_name
= runtime_functions
[i
].name
;
463 if (strcmp(runtime_function_name
, name
.c_str()) == 0)
464 code
= static_cast<Runtime::Function
>(i
);
465 // The names in the table have "runtime." prefix. We may be
466 // called with a name without the prefix. Try matching
467 // without the prefix as well.
468 if (strncmp(runtime_function_name
, "runtime.", 8) == 0
469 && strcmp(runtime_function_name
+ 8, name
.c_str()) == 0)
470 code
= static_cast<Runtime::Function
>(i
);