Skip to content

Commit

Permalink
remove []u8 casting syntax. add @bytesToSlice and @sliceToBytes
Browse files Browse the repository at this point in the history
See #1061
  • Loading branch information
andrewrk committed Jun 18, 2018
1 parent 5d705fc commit 1aafbae
Show file tree
Hide file tree
Showing 15 changed files with 277 additions and 96 deletions.
45 changes: 33 additions & 12 deletions doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -1456,8 +1456,7 @@ test "pointer array access" {
// Taking an address of an individual element gives a
// pointer to a single item. This kind of pointer
// does not support pointer arithmetic.

var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
var array = []u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const ptr = &array[2];
assert(@typeOf(ptr) == *u8);

Expand All @@ -1469,7 +1468,7 @@ test "pointer array access" {
test "pointer slicing" {
// In Zig, we prefer using slices over null-terminated pointers.
// You can turn an array into a slice using slice syntax:
var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
var array = []u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const slice = array[2..4];
assert(slice.len == 2);

Expand Down Expand Up @@ -1541,13 +1540,13 @@ test "pointer casting" {
// To convert one pointer type to another, use @ptrCast. This is an unsafe
// operation that Zig cannot protect you against. Use @ptrCast only when other
// conversions are not possible.
const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};
const bytes align(@alignOf(u32)) = []u8{ 0x12, 0x12, 0x12, 0x12 };
const u32_ptr = @ptrCast(*const u32, &bytes[0]);
assert(u32_ptr.* == 0x12121212);

// Even this example is contrived - there are better ways to do the above than
// pointer casting. For example, using a slice narrowing cast:
const u32_value = ([]const u32)(bytes[0..])[0];
const u32_value = @bytesToSlice(u32, bytes[0..])[0];
assert(u32_value == 0x12121212);

// And even another way, the most straightforward way to do it:
Expand Down Expand Up @@ -1630,13 +1629,13 @@ test "function alignment" {
const assert = @import("std").debug.assert;

test "pointer alignment safety" {
var array align(4) = []u32{0x11111111, 0x11111111};
const bytes = ([]u8)(array[0..]);
var array align(4) = []u32{ 0x11111111, 0x11111111 };
const bytes = @sliceToBytes(array[0..]);
assert(foo(bytes) == 0x11111111);
}
fn foo(bytes: []u8) u32 {
const slice4 = bytes[1..5];
const int_slice = ([]u32)(@alignCast(4, slice4));
const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
return int_slice[0];
}
{#code_end#}
Expand Down Expand Up @@ -1728,8 +1727,8 @@ test "slice pointer" {
test "slice widening" {
// Zig supports slice widening and slice narrowing. Cast a slice of u8
// to a slice of anything else, and Zig will perform the length conversion.
const array align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13};
const slice = ([]const u32)(array[0..]);
const array align(@alignOf(u32)) = []u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 };
const slice = @bytesToSlice(u32, array[0..]);
assert(slice.len == 2);
assert(slice[0] == 0x12121212);
assert(slice[1] == 0x13131313);
Expand Down Expand Up @@ -4651,6 +4650,18 @@ comptime {
</p>
{#header_close#}

{#header_open|@bytesToSlice#}
<pre><code class="zig">@bytesToSlice(comptime Element: type, bytes: []u8) []Element</code></pre>
<p>
Converts a slice of bytes or array of bytes into a slice of <code>Element</code>.
The resulting slice has the same {#link|pointer|Pointers#} properties as the parameter.
</p>
<p>
Attempting to convert a number of bytes with a length that does not evenly divide into a slice of
elements results in {#link|Undefined Behavior#}.
</p>
{#header_close#}

{#header_open|@cDefine#}
<pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre>
<p>
Expand Down Expand Up @@ -5467,15 +5478,25 @@ pub const FloatMode = enum {
</p>
{#see_also|@shlExact|@shlWithOverflow#}
{#header_close#}

{#header_open|@sizeOf#}
<pre><code class="zig">@sizeOf(comptime T: type) (number literal)</code></pre>
<pre><code class="zig">@sizeOf(comptime T: type) comptime_int</code></pre>
<p>
This function returns the number of bytes it takes to store <code>T</code> in memory.
</p>
<p>
The result is a target-specific compile time constant.
</p>
{#header_close#}

{#header_open|@sliceToBytes#}
<pre><code class="zig">@sliceToBytes(value: var) []u8</code></pre>
<p>
Converts a slice or array to a slice of <code>u8</code>. The resulting slice has the same
{#link|pointer|Pointers#} properties as the parameter.
</p>
{#header_close#}

{#header_open|@sqrt#}
<pre><code class="zig">@sqrt(comptime T: type, value: T) T</code></pre>
<p>
Expand Down Expand Up @@ -6810,7 +6831,7 @@ hljs.registerLanguage("zig", function(t) {
a = t.IR + "\\s*\\(",
c = {
keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong resume cancel await async orelse",
built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall",
built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bytesToSlice sliceToBytes errSetCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall",
literal: "true false null undefined"
},
n = [e, t.CLCM, t.CBCM, s, r];
Expand Down
28 changes: 28 additions & 0 deletions src/all_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,16 @@ enum RuntimeHintPtr {
RuntimeHintPtrNonStack,
};

enum RuntimeHintSliceId {
RuntimeHintSliceIdUnknown,
RuntimeHintSliceIdLen,
};

struct RuntimeHintSlice {
enum RuntimeHintSliceId id;
uint64_t len;
};

struct ConstGlobalRefs {
LLVMValueRef llvm_value;
LLVMValueRef llvm_global;
Expand Down Expand Up @@ -270,6 +280,7 @@ struct ConstExprValue {
RuntimeHintErrorUnion rh_error_union;
RuntimeHintOptional rh_maybe;
RuntimeHintPtr rh_ptr;
RuntimeHintSlice rh_slice;
} data;
};

Expand Down Expand Up @@ -1360,6 +1371,8 @@ enum BuiltinFnId {
BuiltinFnIdIntCast,
BuiltinFnIdFloatCast,
BuiltinFnIdErrSetCast,
BuiltinFnIdToBytes,
BuiltinFnIdFromBytes,
BuiltinFnIdIntToFloat,
BuiltinFnIdFloatToInt,
BuiltinFnIdBoolToInt,
Expand Down Expand Up @@ -2123,6 +2136,8 @@ enum IrInstructionId {
IrInstructionIdMarkErrRetTracePtr,
IrInstructionIdSqrt,
IrInstructionIdErrSetCast,
IrInstructionIdToBytes,
IrInstructionIdFromBytes,
};

struct IrInstruction {
Expand Down Expand Up @@ -2665,6 +2680,19 @@ struct IrInstructionErrSetCast {
IrInstruction *target;
};

struct IrInstructionToBytes {
IrInstruction base;

IrInstruction *target;
};

struct IrInstructionFromBytes {
IrInstruction base;

IrInstruction *dest_child_type;
IrInstruction *target;
};

struct IrInstructionIntToFloat {
IrInstruction base;

Expand Down
4 changes: 4 additions & 0 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4728,6 +4728,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdFloatToInt:
case IrInstructionIdBoolToInt:
case IrInstructionIdErrSetCast:
case IrInstructionIdFromBytes:
case IrInstructionIdToBytes:
zig_unreachable();

case IrInstructionIdReturn:
Expand Down Expand Up @@ -6358,6 +6360,8 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);
create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
}

static const char *bool_to_str(bool b) {
Expand Down

0 comments on commit 1aafbae

Please sign in to comment.