Browse Source

Make `raw_data` an intrinsic rather a `@(builtin)` runtime procedure

gingerBill 2 years ago
parent
commit
6a14c3edb4

+ 2 - 6
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) {

+ 0 - 28
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) {

+ 53 - 0
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;

+ 4 - 0
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
 
 

+ 31 - 0
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"