diff options
| author | gingerBill <bill@gingerbill.org> | 2022-10-30 22:05:29 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-10-30 22:05:29 +0000 |
| commit | 6a14c3edb42fbbcc9ab0df962458f1da16f6f508 (patch) | |
| tree | 1ff3d2f93a65e65aaa12a304c4bf09764a50163d /src | |
| parent | 2cd895c50b788c6bec8a198820611c6a31ee31a7 (diff) | |
Make `raw_data` an intrinsic rather a `@(builtin)` runtime procedure
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_builtin.cpp | 53 | ||||
| -rw-r--r-- | src/checker_builtin_procs.hpp | 4 | ||||
| -rw-r--r-- | src/llvm_backend_proc.cpp | 31 |
3 files changed, 88 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index fc889fb28..b8bf1bcc7 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3651,6 +3651,59 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->mode = Addressing_NoValue; break; + case BuiltinProc_raw_data: + { + Operand x = {}; + check_expr(c, &x, ce->args[0]); + if (x.mode == Addressing_Invalid) { + return false; + } + if (!is_operand_value(x)) { + gbString s = expr_to_string(x.expr); + error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s); + gb_string_free(s); + return false; + } + Type *t = base_type(x.type); + + operand->mode = Addressing_Value; + operand->type = nullptr; + switch (t->kind) { + case Type_Slice: + operand->type = alloc_type_multi_pointer(t->MultiPointer.elem); + break; + case Type_DynamicArray: + operand->type = alloc_type_multi_pointer(t->DynamicArray.elem); + break; + case Type_Basic: + if (t->Basic.kind == Basic_string) { + operand->type = alloc_type_multi_pointer(t_u8); + } + break; + case Type_Pointer: + case Type_MultiPointer: + { + Type *base = base_type(type_deref(t, true)); + switch (base->kind) { + case Type_Array: + case Type_EnumeratedArray: + case Type_SimdVector: + operand->type = alloc_type_multi_pointer(base_array_type(base)); + break; + } + } + break; + } + + if (operand->type == nullptr) { + gbString s = type_to_string(x.type); + error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s); + gb_string_free(s); + return false; + } + } + break; + case BuiltinProc_read_cycle_counter: operand->mode = Addressing_Value; operand->type = t_i64; diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index b8cd84cc6..c59ae7867 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -42,6 +42,8 @@ enum BuiltinProcId { BuiltinProc_unreachable, + BuiltinProc_raw_data, + BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures // "Intrinsics" @@ -338,6 +340,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("unreachable"), 0, false, Expr_Expr, BuiltinProcPkg_builtin, /*diverging*/true}, + {STR_LIT("raw_data"), 1, false, Expr_Expr, BuiltinProcPkg_builtin}, + {STR_LIT(""), 0, true, Expr_Expr, BuiltinProcPkg_builtin}, // DIRECTIVE diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 4d7896c8a..a88c8f2ee 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1850,6 +1850,37 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, lb_emit_unreachable(p); return {}; + case BuiltinProc_raw_data: + { + lbValue x = lb_build_expr(p, ce->args[0]); + Type *t = base_type(x.type); + lbValue res = {}; + switch (t->kind) { + case Type_Slice: + res = lb_slice_elem(p, x); + res = lb_emit_conv(p, res, tv.type); + break; + case Type_DynamicArray: + res = lb_dynamic_array_elem(p, x); + res = lb_emit_conv(p, res, tv.type); + break; + case Type_Basic: + if (t->Basic.kind == Basic_string) { + res = lb_string_elem(p, x); + res = lb_emit_conv(p, res, tv.type); + } else if (t->Basic.kind == Basic_cstring) { + res = lb_emit_conv(p, x, tv.type); + } + break; + case Type_Pointer: + case Type_MultiPointer: + res = lb_emit_conv(p, x, tv.type); + break; + } + GB_ASSERT(res.value != nullptr); + return res; + } + // "Intrinsics" |