diff --git a/core/mem/raw.odin b/core/mem/raw.odin index 8322ace30..144b6c8ab 100644 --- a/core/mem/raw.odin +++ b/core/mem/raw.odin @@ -1,5 +1,6 @@ package mem +import "core:builtin" import "core:runtime" Raw_Any :: runtime.Raw_Any @@ -21,12 +22,7 @@ make_any :: proc "contextless" (data: rawptr, id: typeid) -> any { return transmute(any)Raw_Any{data, id} } -raw_array_data :: runtime.raw_array_data -raw_simd_data :: runtime.raw_simd_data -raw_string_data :: runtime.raw_string_data -raw_slice_data :: runtime.raw_slice_data -raw_dynamic_array_data :: runtime.raw_dynamic_array_data -raw_data :: runtime.raw_data +raw_data :: builtin.raw_data Poly_Raw_Map_Entry :: struct($Key, $Value: typeid) { diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index b5b003122..b0f4cb25c 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -731,34 +731,6 @@ card :: proc(s: $S/bit_set[$E; $U]) -> int { -@builtin -raw_array_data :: proc "contextless" (a: $P/^($T/[$N]$E)) -> [^]E { - return ([^]E)(a) -} -@builtin -raw_simd_data :: proc "contextless" (a: $P/^($T/#simd[$N]$E)) -> [^]E { - return ([^]E)(a) -} -@builtin -raw_slice_data :: proc "contextless" (s: $S/[]$E) -> [^]E { - ptr := (transmute(Raw_Slice)s).data - return ([^]E)(ptr) -} -@builtin -raw_dynamic_array_data :: proc "contextless" (s: $S/[dynamic]$E) -> [^]E { - ptr := (transmute(Raw_Dynamic_Array)s).data - return ([^]E)(ptr) -} -@builtin -raw_string_data :: proc "contextless" (s: $S/string) -> [^]u8 { - return (transmute(Raw_String)s).data -} - -@builtin -raw_data :: proc{raw_array_data, raw_slice_data, raw_dynamic_array_data, raw_string_data, raw_simd_data} - - - @builtin @(disabled=ODIN_DISABLE_ASSERT) assert :: proc(condition: bool, message := "", loc := #caller_location) { 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"