2021-01-18 13:20:06 +01:00
|
|
|
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
2019-06-23 04:21:30 +02:00
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
2019-06-22 20:20:28 +02:00
|
|
|
module builtin
|
|
|
|
|
|
|
|
// isnil returns true if an object is nil (only for C objects).
|
2021-05-05 23:31:25 +02:00
|
|
|
[inline]
|
2019-06-22 20:20:28 +02:00
|
|
|
pub fn isnil(v voidptr) bool {
|
|
|
|
return v == 0
|
|
|
|
}
|
|
|
|
|
2020-02-04 08:29:50 +01:00
|
|
|
/*
|
2019-12-19 21:52:45 +01:00
|
|
|
fn on_panic(f fn(int)int) {
|
2019-06-22 20:20:28 +02:00
|
|
|
// TODO
|
|
|
|
}
|
2020-02-04 08:29:50 +01:00
|
|
|
*/
|
2019-06-22 20:20:28 +02:00
|
|
|
|
2020-12-12 15:04:30 +01:00
|
|
|
// print_backtrace shows a backtrace of the current call stack on stdout
|
2019-12-19 21:52:45 +01:00
|
|
|
pub fn print_backtrace() {
|
2021-05-23 11:37:23 +02:00
|
|
|
// At the time of backtrace_symbols_fd call, the C stack would look something like this:
|
|
|
|
// * print_backtrace_skipping_top_frames
|
|
|
|
// * print_backtrace itself
|
|
|
|
// * the rest of the backtrace frames
|
2019-08-27 22:29:13 +02:00
|
|
|
// => top 2 frames should be skipped, since they will not be informative to the developer
|
2021-05-23 11:37:23 +02:00
|
|
|
$if !no_backtrace ? {
|
|
|
|
$if freestanding {
|
|
|
|
println(bare_backtrace())
|
|
|
|
} $else {
|
|
|
|
$if tinyc {
|
|
|
|
C.tcc_backtrace(c'Backtrace')
|
|
|
|
} $else {
|
|
|
|
print_backtrace_skipping_top_frames(2)
|
|
|
|
}
|
|
|
|
}
|
2021-04-14 07:50:50 +02:00
|
|
|
}
|
2019-06-22 20:20:28 +02:00
|
|
|
}
|
|
|
|
|
2021-01-30 17:54:05 +01:00
|
|
|
struct VCastTypeIndexName {
|
|
|
|
tindex int
|
|
|
|
tname string
|
|
|
|
}
|
|
|
|
|
2021-05-19 09:35:56 +02:00
|
|
|
// will be filled in cgen
|
|
|
|
__global as_cast_type_indexes []VCastTypeIndexName
|
2020-02-03 07:02:54 +01:00
|
|
|
|
2020-10-15 12:32:28 +02:00
|
|
|
fn __as_cast(obj voidptr, obj_type int, expected_type int) voidptr {
|
2020-04-25 08:36:53 +02:00
|
|
|
if obj_type != expected_type {
|
2021-03-14 08:37:38 +01:00
|
|
|
mut obj_name := as_cast_type_indexes[0].tname.clone()
|
|
|
|
mut expected_name := as_cast_type_indexes[0].tname.clone()
|
2021-01-30 17:54:05 +01:00
|
|
|
for x in as_cast_type_indexes {
|
|
|
|
if x.tindex == obj_type {
|
2021-03-14 08:37:38 +01:00
|
|
|
obj_name = x.tname.clone()
|
2021-01-30 17:54:05 +01:00
|
|
|
}
|
|
|
|
if x.tindex == expected_type {
|
2021-03-14 08:37:38 +01:00
|
|
|
expected_name = x.tname.clone()
|
2021-01-30 17:54:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
panic('as cast: cannot cast `$obj_name` to `$expected_name`')
|
2020-04-25 08:36:53 +02:00
|
|
|
}
|
|
|
|
return obj
|
|
|
|
}
|
2020-06-01 13:43:31 +02:00
|
|
|
|
|
|
|
// VAssertMetaInfo is used during assertions. An instance of it
|
|
|
|
// is filled in by compile time generated code, when an assertion fails.
|
2020-07-01 00:53:53 +02:00
|
|
|
pub struct VAssertMetaInfo {
|
2020-06-01 13:43:31 +02:00
|
|
|
pub:
|
|
|
|
fpath string // the source file path of the assertion
|
|
|
|
line_nr int // the line number of the assertion
|
|
|
|
fn_name string // the function name in which the assertion is
|
|
|
|
src string // the actual source line of the assertion
|
|
|
|
op string // the operation of the assertion, i.e. '==', '<', 'call', etc ...
|
|
|
|
llabel string // the left side of the infix expressions as source
|
|
|
|
rlabel string // the right side of the infix expressions as source
|
|
|
|
lvalue string // the stringified *actual value* of the left side of a failed assertion
|
|
|
|
rvalue string // the stringified *actual value* of the right side of a failed assertion
|
|
|
|
}
|
2021-01-30 17:54:05 +01:00
|
|
|
|
2020-06-01 13:43:31 +02:00
|
|
|
fn __print_assert_failure(i &VAssertMetaInfo) {
|
2021-01-30 17:54:05 +01:00
|
|
|
eprintln('$i.fpath:${i.line_nr + 1}: FAIL: fn $i.fn_name: assert $i.src')
|
2020-06-13 16:20:45 +02:00
|
|
|
if i.op.len > 0 && i.op != 'call' {
|
2021-01-30 17:54:05 +01:00
|
|
|
eprintln(' left value: $i.llabel = $i.lvalue')
|
2020-06-22 16:52:03 +02:00
|
|
|
if i.rlabel == i.rvalue {
|
|
|
|
eprintln(' right value: $i.rlabel')
|
2021-01-30 17:54:05 +01:00
|
|
|
} else {
|
|
|
|
eprintln(' right value: $i.rlabel = $i.rvalue')
|
2020-06-22 16:52:03 +02:00
|
|
|
}
|
2020-06-01 13:43:31 +02:00
|
|
|
}
|
|
|
|
}
|
2020-07-03 15:10:39 +02:00
|
|
|
|
2021-02-05 21:02:29 +01:00
|
|
|
// MethodArgs holds type information for function and/or method arguments.
|
2020-08-27 15:00:44 +02:00
|
|
|
pub struct MethodArgs {
|
2020-07-03 15:10:39 +02:00
|
|
|
pub:
|
2021-03-07 14:28:43 +01:00
|
|
|
typ int
|
|
|
|
name string
|
2020-07-03 15:10:39 +02:00
|
|
|
}
|
2020-07-25 00:02:44 +02:00
|
|
|
|
2021-02-05 21:02:29 +01:00
|
|
|
// FunctionData holds information about a parsed function.
|
2020-07-25 00:02:44 +02:00
|
|
|
pub struct FunctionData {
|
|
|
|
pub:
|
2020-09-28 06:13:38 +02:00
|
|
|
name string
|
|
|
|
attrs []string
|
|
|
|
args []MethodArgs
|
|
|
|
return_type int
|
|
|
|
typ int
|
2020-07-25 00:02:44 +02:00
|
|
|
}
|
|
|
|
|
2021-02-05 21:02:29 +01:00
|
|
|
// FieldData holds information about a field. Fields reside on structs.
|
2020-07-25 00:02:44 +02:00
|
|
|
pub struct FieldData {
|
|
|
|
pub:
|
2021-06-16 19:33:30 +02:00
|
|
|
name string
|
|
|
|
attrs []string
|
|
|
|
is_pub bool
|
|
|
|
is_mut bool
|
|
|
|
is_shared bool
|
|
|
|
typ int
|
2020-07-25 00:02:44 +02:00
|
|
|
}
|
2021-04-25 17:29:26 +02:00
|
|
|
|
2021-07-23 11:33:55 +02:00
|
|
|
pub enum AttributeKind {
|
2021-04-25 17:29:26 +02:00
|
|
|
plain // [name]
|
|
|
|
string // ['name']
|
|
|
|
number // [123]
|
|
|
|
comptime_define // [if name]
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct StructAttribute {
|
|
|
|
pub:
|
|
|
|
name string
|
|
|
|
has_arg bool
|
|
|
|
arg string
|
|
|
|
kind AttributeKind
|
|
|
|
}
|