| author | |
| committer | |
| log | b883bc873df7f1a8fa3a13800402e1ec8da74328 |
| tree | cd53413c233c9e724332f1ce2cc5291a3d67a385 |
| parent | 634d11ab28839ebc3caae2bf18cbc028a7a1c3e9 |
| signature | Commit is signed but in an unrecognized format. |
* add `@bswap` builtin function. See #767
* comptime evaluation facilities are improved to be able to
handle a `@ptrCast` with a backing array.
* `@truncate` allows "truncating" a u0 value to any integer
type, and the result is always comptime known to be `0`.
* when specifying pointer alignment in a type expression,
the alignment value of pointers which do not have addresses
at runtime is ignored, and always has the default/ABI alignment
* threw in a fix to freebsd/x86_64.zig to update syntax from
language changes
* some improvements are pending #863
closes #638
closes #1733
std lib API changes
* io.InStream().readIntNe renamed to readIntNative
* io.InStream().readIntLe renamed to readIntLittle
* io.InStream().readIntBe renamed to readIntBig
* introduced io.InStream().readIntForeign
* io.InStream().readInt has parameter order changed
* io.InStream().readVarInt has parameter order changed
* io.InStream().writeIntNe renamed to writeIntNative
* introduced io.InStream().writeIntForeign
* io.InStream().writeIntLe renamed to writeIntLittle
* io.InStream().writeIntBe renamed to writeIntBig
* io.InStream().writeInt has parameter order changed
* mem.readInt has different parameters and semantics
* introduced mem.readIntNative
* introduced mem.readIntForeign
* mem.readIntBE renamed to mem.readIntBig and different API
* mem.readIntLE renamed to mem.readIntLittle and different API
* introduced mem.readIntSliceNative
* introduced mem.readIntSliceForeign
* introduced mem.readIntSliceLittle
* introduced mem.readIntSliceBig
* introduced mem.readIntSlice
* mem.writeInt has different parameters and semantics
* introduced mem.writeIntNative
* introduced mem.writeIntForeign
* mem.writeIntBE renamed to mem.readIntBig and different semantics
* mem.writeIntLE renamed to mem.readIntLittle and different semantics
* introduced mem.writeIntSliceForeign
* introduced mem.writeIntSliceNative
* introduced mem.writeIntSliceBig
* introduced mem.writeIntSliceLittle
* introduced mem.writeIntSlice
* removed mem.endianSwapIfLe
* removed mem.endianSwapIfBe
* removed mem.endianSwapIf
* added mem.littleToNative
* added mem.bigToNative
* added mem.toNative
* added mem.nativeTo
* added mem.nativeToLittle
* added mem.nativeToBig34 files changed, 797 insertions(+), 398 deletions(-)
doc/langref.html.in+9| ... | @@ -5312,6 +5312,15 @@ comptime { | ... | @@ -5312,6 +5312,15 @@ comptime { |
| 5312 | </p> | 5312 | </p> |
| 5313 | {#header_close#} | 5313 | {#header_close#} |
| 5314 | 5314 | ||
| 5315 | {#header_open|@bswap#} | ||
| 5316 | <pre>{#syntax#}@swap(comptime T: type, value: T) T{#endsyntax#}</pre> | ||
| 5317 | <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p> | ||
| 5318 | <p> | ||
| 5319 | Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, | ||
| 5320 | and converts a little endian integer to a big endian integer. | ||
| 5321 | </p> | ||
| 5322 | {#header_close#} | ||
| 5323 | |||
| 5315 | {#header_open|@bytesToSlice#} | 5324 | {#header_open|@bytesToSlice#} |
| 5316 | <pre>{#syntax#}@bytesToSlice(comptime Element: type, bytes: []u8) []Element{#endsyntax#}</pre> | 5325 | <pre>{#syntax#}@bytesToSlice(comptime Element: type, bytes: []u8) []Element{#endsyntax#}</pre> |
| 5317 | <p> | 5326 | <p> |
example/guess_number/main.zig+1-1| ... | @@ -15,7 +15,7 @@ pub fn main() !void { | ... | @@ -15,7 +15,7 @@ pub fn main() !void { |
| 15 | std.debug.warn("unable to seed random number generator: {}", err); | 15 | std.debug.warn("unable to seed random number generator: {}", err); |
| 16 | return err; | 16 | return err; |
| 17 | }; | 17 | }; |
| 18 | const seed = std.mem.readInt(seed_bytes, u64, builtin.Endian.Big); | 18 | const seed = std.mem.readIntNative(u64, &seed_bytes); |
| 19 | var prng = std.rand.DefaultPrng.init(seed); | 19 | var prng = std.rand.DefaultPrng.init(seed); |
| 20 | 20 | ||
| 21 | const answer = prng.random.range(u8, 0, 100) + 1; | 21 | const answer = prng.random.range(u8, 0, 100) + 1; |
src-self-hosted/compilation.zig+1-1| ... | @@ -55,7 +55,7 @@ pub const ZigCompiler = struct { | ... | @@ -55,7 +55,7 @@ pub const ZigCompiler = struct { |
| 55 | 55 | ||
| 56 | var seed_bytes: [@sizeOf(u64)]u8 = undefined; | 56 | var seed_bytes: [@sizeOf(u64)]u8 = undefined; |
| 57 | try std.os.getRandomBytes(seed_bytes[0..]); | 57 | try std.os.getRandomBytes(seed_bytes[0..]); |
| 58 | const seed = std.mem.readInt(seed_bytes, u64, builtin.Endian.Big); | 58 | const seed = mem.readIntNative(u64, &seed_bytes); |
| 59 | 59 | ||
| 60 | return ZigCompiler{ | 60 | return ZigCompiler{ |
| 61 | .loop = loop, | 61 | .loop = loop, |
src/all_types.hpp+13| ... | @@ -1415,6 +1415,7 @@ enum BuiltinFnId { | ... | @@ -1415,6 +1415,7 @@ enum BuiltinFnId { |
| 1415 | BuiltinFnIdErrorReturnTrace, | 1415 | BuiltinFnIdErrorReturnTrace, |
| 1416 | BuiltinFnIdAtomicRmw, | 1416 | BuiltinFnIdAtomicRmw, |
| 1417 | BuiltinFnIdAtomicLoad, | 1417 | BuiltinFnIdAtomicLoad, |
| 1418 | BuiltinFnIdBswap, | ||
| 1418 | }; | 1419 | }; |
| 1419 | 1420 | ||
| 1420 | struct BuiltinFnEntry { | 1421 | struct BuiltinFnEntry { |
| ... | @@ -1487,6 +1488,7 @@ enum ZigLLVMFnId { | ... | @@ -1487,6 +1488,7 @@ enum ZigLLVMFnId { |
| 1487 | ZigLLVMFnIdFloor, | 1488 | ZigLLVMFnIdFloor, |
| 1488 | ZigLLVMFnIdCeil, | 1489 | ZigLLVMFnIdCeil, |
| 1489 | ZigLLVMFnIdSqrt, | 1490 | ZigLLVMFnIdSqrt, |
| 1491 | ZigLLVMFnIdBswap, | ||
| 1490 | }; | 1492 | }; |
| 1491 | 1493 | ||
| 1492 | enum AddSubMul { | 1494 | enum AddSubMul { |
| ... | @@ -1516,6 +1518,9 @@ struct ZigLLVMFnKey { | ... | @@ -1516,6 +1518,9 @@ struct ZigLLVMFnKey { |
| 1516 | uint32_t bit_count; | 1518 | uint32_t bit_count; |
| 1517 | bool is_signed; | 1519 | bool is_signed; |
| 1518 | } overflow_arithmetic; | 1520 | } overflow_arithmetic; |
| 1521 | struct { | ||
| 1522 | uint32_t bit_count; | ||
| 1523 | } bswap; | ||
| 1519 | } data; | 1524 | } data; |
| 1520 | }; | 1525 | }; |
| 1521 | 1526 | ||
| ... | @@ -2158,6 +2163,7 @@ enum IrInstructionId { | ... | @@ -2158,6 +2163,7 @@ enum IrInstructionId { |
| 2158 | IrInstructionIdMergeErrRetTraces, | 2163 | IrInstructionIdMergeErrRetTraces, |
| 2159 | IrInstructionIdMarkErrRetTracePtr, | 2164 | IrInstructionIdMarkErrRetTracePtr, |
| 2160 | IrInstructionIdSqrt, | 2165 | IrInstructionIdSqrt, |
| 2166 | IrInstructionIdBswap, | ||
| 2161 | IrInstructionIdErrSetCast, | 2167 | IrInstructionIdErrSetCast, |
| 2162 | IrInstructionIdToBytes, | 2168 | IrInstructionIdToBytes, |
| 2163 | IrInstructionIdFromBytes, | 2169 | IrInstructionIdFromBytes, |
| ... | @@ -3251,6 +3257,13 @@ struct IrInstructionCheckRuntimeScope { | ... | @@ -3251,6 +3257,13 @@ struct IrInstructionCheckRuntimeScope { |
| 3251 | IrInstruction *is_comptime; | 3257 | IrInstruction *is_comptime; |
| 3252 | }; | 3258 | }; |
| 3253 | 3259 | ||
| 3260 | struct IrInstructionBswap { | ||
| 3261 | IrInstruction base; | ||
| 3262 | |||
| 3263 | IrInstruction *type; | ||
| 3264 | IrInstruction *op; | ||
| 3265 | }; | ||
| 3266 | |||
| 3254 | static const size_t slice_ptr_index = 0; | 3267 | static const size_t slice_ptr_index = 0; |
| 3255 | static const size_t slice_len_index = 1; | 3268 | static const size_t slice_len_index = 1; |
| 3256 | 3269 |
src/analyze.cpp+6-1| ... | @@ -401,7 +401,8 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) { | ... | @@ -401,7 +401,8 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) { |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const, | 403 | ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const, |
| 404 | bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset_in_host, uint32_t host_int_bytes) | 404 | bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, |
| 405 | uint32_t bit_offset_in_host, uint32_t host_int_bytes) | ||
| 405 | { | 406 | { |
| 406 | assert(!type_is_invalid(child_type)); | 407 | assert(!type_is_invalid(child_type)); |
| 407 | assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque); | 408 | assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque); |
| ... | @@ -6110,6 +6111,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) { | ... | @@ -6110,6 +6111,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) { |
| 6110 | return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1953839089; | 6111 | return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1953839089; |
| 6111 | case ZigLLVMFnIdSqrt: | 6112 | case ZigLLVMFnIdSqrt: |
| 6112 | return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385; | 6113 | return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385; |
| 6114 | case ZigLLVMFnIdBswap: | ||
| 6115 | return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335; | ||
| 6113 | case ZigLLVMFnIdOverflowArithmetic: | 6116 | case ZigLLVMFnIdOverflowArithmetic: |
| 6114 | return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) + | 6117 | return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) + |
| 6115 | ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) + | 6118 | ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) + |
| ... | @@ -6128,6 +6131,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { | ... | @@ -6128,6 +6131,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { |
| 6128 | return a.data.clz.bit_count == b.data.clz.bit_count; | 6131 | return a.data.clz.bit_count == b.data.clz.bit_count; |
| 6129 | case ZigLLVMFnIdPopCount: | 6132 | case ZigLLVMFnIdPopCount: |
| 6130 | return a.data.pop_count.bit_count == b.data.pop_count.bit_count; | 6133 | return a.data.pop_count.bit_count == b.data.pop_count.bit_count; |
| 6134 | case ZigLLVMFnIdBswap: | ||
| 6135 | return a.data.bswap.bit_count == b.data.bswap.bit_count; | ||
| 6131 | case ZigLLVMFnIdFloor: | 6136 | case ZigLLVMFnIdFloor: |
| 6132 | case ZigLLVMFnIdCeil: | 6137 | case ZigLLVMFnIdCeil: |
| 6133 | case ZigLLVMFnIdSqrt: | 6138 | case ZigLLVMFnIdSqrt: |
src/codegen.cpp+31| ... | @@ -3814,6 +3814,11 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI | ... | @@ -3814,6 +3814,11 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI |
| 3814 | n_args = 1; | 3814 | n_args = 1; |
| 3815 | key.id = ZigLLVMFnIdPopCount; | 3815 | key.id = ZigLLVMFnIdPopCount; |
| 3816 | key.data.pop_count.bit_count = (uint32_t)int_type->data.integral.bit_count; | 3816 | key.data.pop_count.bit_count = (uint32_t)int_type->data.integral.bit_count; |
| 3817 | } else if (fn_id == BuiltinFnIdBswap) { | ||
| 3818 | fn_name = "bswap"; | ||
| 3819 | n_args = 1; | ||
| 3820 | key.id = ZigLLVMFnIdBswap; | ||
| 3821 | key.data.bswap.bit_count = (uint32_t)int_type->data.integral.bit_count; | ||
| 3817 | } else { | 3822 | } else { |
| 3818 | zig_unreachable(); | 3823 | zig_unreachable(); |
| 3819 | } | 3824 | } |
| ... | @@ -5098,6 +5103,29 @@ static LLVMValueRef ir_render_sqrt(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -5098,6 +5103,29 @@ static LLVMValueRef ir_render_sqrt(CodeGen *g, IrExecutable *executable, IrInstr |
| 5098 | return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); | 5103 | return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); |
| 5099 | } | 5104 | } |
| 5100 | 5105 | ||
| 5106 | static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInstructionBswap *instruction) { | ||
| 5107 | LLVMValueRef op = ir_llvm_value(g, instruction->op); | ||
| 5108 | ZigType *int_type = instruction->base.value.type; | ||
| 5109 | assert(int_type->id == ZigTypeIdInt); | ||
| 5110 | if (int_type->data.integral.bit_count % 16 == 0) { | ||
| 5111 | LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value.type, BuiltinFnIdBswap); | ||
| 5112 | return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); | ||
| 5113 | } | ||
| 5114 | // Not an even number of bytes, so we zext 1 byte, then bswap, shift right 1 byte, truncate | ||
| 5115 | ZigType *extended_type = get_int_type(g, int_type->data.integral.is_signed, | ||
| 5116 | int_type->data.integral.bit_count + 8); | ||
| 5117 | // aabbcc | ||
| 5118 | LLVMValueRef extended = LLVMBuildZExt(g->builder, op, extended_type->type_ref, ""); | ||
| 5119 | // 00aabbcc | ||
| 5120 | LLVMValueRef fn_val = get_int_builtin_fn(g, extended_type, BuiltinFnIdBswap); | ||
| 5121 | LLVMValueRef swapped = LLVMBuildCall(g->builder, fn_val, &extended, 1, ""); | ||
| 5122 | // ccbbaa00 | ||
| 5123 | LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped, | ||
| 5124 | LLVMConstInt(extended_type->type_ref, 8, false), ""); | ||
| 5125 | // 00ccbbaa | ||
| 5126 | return LLVMBuildTrunc(g->builder, shifted, int_type->type_ref, ""); | ||
| 5127 | } | ||
| 5128 | |||
| 5101 | static void set_debug_location(CodeGen *g, IrInstruction *instruction) { | 5129 | static void set_debug_location(CodeGen *g, IrInstruction *instruction) { |
| 5102 | AstNode *source_node = instruction->source_node; | 5130 | AstNode *source_node = instruction->source_node; |
| 5103 | Scope *scope = instruction->scope; | 5131 | Scope *scope = instruction->scope; |
| ... | @@ -5335,6 +5363,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -5335,6 +5363,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5335 | return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction); | 5363 | return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 5336 | case IrInstructionIdSqrt: | 5364 | case IrInstructionIdSqrt: |
| 5337 | return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction); | 5365 | return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction); |
| 5366 | case IrInstructionIdBswap: | ||
| 5367 | return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction); | ||
| 5338 | } | 5368 | } |
| 5339 | zig_unreachable(); | 5369 | zig_unreachable(); |
| 5340 | } | 5370 | } |
| ... | @@ -6757,6 +6787,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -6757,6 +6787,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 6757 | create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); | 6787 | create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); |
| 6758 | create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); | 6788 | create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); |
| 6759 | create_builtin_fn(g, BuiltinFnIdThis, "This", 0); | 6789 | create_builtin_fn(g, BuiltinFnIdThis, "This", 0); |
| 6790 | create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2); | ||
| 6760 | } | 6791 | } |
| 6761 | 6792 | ||
| 6762 | static const char *bool_to_str(bool b) { | 6793 | static const char *bool_to_str(bool b) { |
src/ir.cpp+146-10| ... | @@ -856,6 +856,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { | ... | @@ -856,6 +856,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { |
| 856 | return IrInstructionIdSqrt; | 856 | return IrInstructionIdSqrt; |
| 857 | } | 857 | } |
| 858 | 858 | ||
| 859 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { | ||
| 860 | return IrInstructionIdBswap; | ||
| 861 | } | ||
| 862 | |||
| 859 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { | 863 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { |
| 860 | return IrInstructionIdCheckRuntimeScope; | 864 | return IrInstructionIdCheckRuntimeScope; |
| 861 | } | 865 | } |
| ... | @@ -2705,6 +2709,17 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc | ... | @@ -2705,6 +2709,17 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 2705 | return &instruction->base; | 2709 | return &instruction->base; |
| 2706 | } | 2710 | } |
| 2707 | 2711 | ||
| 2712 | static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | ||
| 2713 | IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); | ||
| 2714 | instruction->type = type; | ||
| 2715 | instruction->op = op; | ||
| 2716 | |||
| 2717 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | ||
| 2718 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 2719 | |||
| 2720 | return &instruction->base; | ||
| 2721 | } | ||
| 2722 | |||
| 2708 | static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { | 2723 | static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { |
| 2709 | IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); | 2724 | IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); |
| 2710 | instruction->scope_is_comptime = scope_is_comptime; | 2725 | instruction->scope_is_comptime = scope_is_comptime; |
| ... | @@ -4689,6 +4704,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4689,6 +4704,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4689 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); | 4704 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); |
| 4690 | return ir_lval_wrap(irb, scope, result, lval); | 4705 | return ir_lval_wrap(irb, scope, result, lval); |
| 4691 | } | 4706 | } |
| 4707 | case BuiltinFnIdBswap: | ||
| 4708 | { | ||
| 4709 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4710 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4711 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4712 | return arg0_value; | ||
| 4713 | |||
| 4714 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4715 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4716 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4717 | return arg1_value; | ||
| 4718 | |||
| 4719 | IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); | ||
| 4720 | return ir_lval_wrap(irb, scope, result, lval); | ||
| 4721 | } | ||
| 4692 | } | 4722 | } |
| 4693 | zig_unreachable(); | 4723 | zig_unreachable(); |
| 4694 | } | 4724 | } |
| ... | @@ -13674,18 +13704,55 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, | ... | @@ -13674,18 +13704,55 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, |
| 13674 | return ErrorNone; | 13704 | return ErrorNone; |
| 13675 | } | 13705 | } |
| 13676 | 13706 | ||
| 13677 | if (dst_size > src_size) { | 13707 | if (dst_size <= src_size) { |
| 13678 | ir_add_error_node(ira, source_node, | 13708 | Buf buf = BUF_INIT; |
| 13679 | buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes", | 13709 | buf_resize(&buf, src_size); |
| 13680 | dst_size, buf_ptr(&pointee->type->name), src_size)); | 13710 | buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee); |
| 13681 | return ErrorSemanticAnalyzeFail; | 13711 | buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); |
| 13712 | return ErrorNone; | ||
| 13682 | } | 13713 | } |
| 13683 | 13714 | ||
| 13684 | Buf buf = BUF_INIT; | 13715 | switch (ptr_val->data.x_ptr.special) { |
| 13685 | buf_resize(&buf, src_size); | 13716 | case ConstPtrSpecialInvalid: |
| 13686 | buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee); | 13717 | zig_unreachable(); |
| 13687 | buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); | 13718 | case ConstPtrSpecialRef: { |
| 13688 | return ErrorNone; | 13719 | ir_add_error_node(ira, source_node, |
| 13720 | buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes", | ||
| 13721 | dst_size, buf_ptr(&pointee->type->name), src_size)); | ||
| 13722 | return ErrorSemanticAnalyzeFail; | ||
| 13723 | } | ||
| 13724 | case ConstPtrSpecialBaseArray: { | ||
| 13725 | ConstExprValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; | ||
| 13726 | assert(array_val->type->id == ZigTypeIdArray); | ||
| 13727 | if (array_val->data.x_array.special != ConstArraySpecialNone) | ||
| 13728 | zig_panic("TODO"); | ||
| 13729 | size_t elem_size = src_size; | ||
| 13730 | src_size = elem_size * | ||
| 13731 | (array_val->type->data.array.len - ptr_val->data.x_ptr.data.base_array.elem_index); | ||
| 13732 | if (dst_size > src_size) { | ||
| 13733 | ir_add_error_node(ira, source_node, | ||
| 13734 | buf_sprintf("attempt to read %zu bytes from %s at index %" ZIG_PRI_usize " which is %zu bytes", | ||
| 13735 | dst_size, buf_ptr(&array_val->type->name), ptr_val->data.x_ptr.data.base_array.elem_index, | ||
| 13736 | src_size)); | ||
| 13737 | return ErrorSemanticAnalyzeFail; | ||
| 13738 | } | ||
| 13739 | size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); | ||
| 13740 | Buf buf = BUF_INIT; | ||
| 13741 | buf_resize(&buf, elem_count * elem_size); | ||
| 13742 | for (size_t i = 0; i < elem_count; i += 1) { | ||
| 13743 | ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[i]; | ||
| 13744 | buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); | ||
| 13745 | } | ||
| 13746 | buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); | ||
| 13747 | return ErrorNone; | ||
| 13748 | } | ||
| 13749 | case ConstPtrSpecialBaseStruct: | ||
| 13750 | case ConstPtrSpecialDiscard: | ||
| 13751 | case ConstPtrSpecialHardCodedAddr: | ||
| 13752 | case ConstPtrSpecialFunction: | ||
| 13753 | zig_panic("TODO"); | ||
| 13754 | } | ||
| 13755 | zig_unreachable(); | ||
| 13689 | } | 13756 | } |
| 13690 | 13757 | ||
| 13691 | static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { | 13758 | static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { |
| ... | @@ -18054,6 +18121,12 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct | ... | @@ -18054,6 +18121,12 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct |
| 18054 | return ira->codegen->invalid_instruction; | 18121 | return ira->codegen->invalid_instruction; |
| 18055 | } | 18122 | } |
| 18056 | 18123 | ||
| 18124 | if (src_type->data.integral.bit_count == 0) { | ||
| 18125 | IrInstruction *result = ir_const(ira, &instruction->base, dest_type); | ||
| 18126 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | ||
| 18127 | return result; | ||
| 18128 | } | ||
| 18129 | |||
| 18057 | if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { | 18130 | if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { |
| 18058 | const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; | 18131 | const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; |
| 18059 | ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); | 18132 | ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); |
| ... | @@ -20299,6 +20372,9 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct | ... | @@ -20299,6 +20372,9 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct |
| 20299 | return ira->codegen->invalid_instruction; | 20372 | return ira->codegen->invalid_instruction; |
| 20300 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) | 20373 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) |
| 20301 | return ira->codegen->invalid_instruction; | 20374 | return ira->codegen->invalid_instruction; |
| 20375 | if (!type_has_bits(child_type)) { | ||
| 20376 | align_bytes = 0; | ||
| 20377 | } | ||
| 20302 | } else { | 20378 | } else { |
| 20303 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) | 20379 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) |
| 20304 | return ira->codegen->invalid_instruction; | 20380 | return ira->codegen->invalid_instruction; |
| ... | @@ -20898,6 +20974,63 @@ static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionS | ... | @@ -20898,6 +20974,63 @@ static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionS |
| 20898 | return result; | 20974 | return result; |
| 20899 | } | 20975 | } |
| 20900 | 20976 | ||
| 20977 | static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) { | ||
| 20978 | ZigType *int_type = ir_resolve_type(ira, instruction->type->child); | ||
| 20979 | if (type_is_invalid(int_type)) | ||
| 20980 | return ira->codegen->invalid_instruction; | ||
| 20981 | |||
| 20982 | IrInstruction *op = instruction->op->child; | ||
| 20983 | if (type_is_invalid(op->value.type)) | ||
| 20984 | return ira->codegen->invalid_instruction; | ||
| 20985 | |||
| 20986 | if (int_type->id != ZigTypeIdInt) { | ||
| 20987 | ir_add_error(ira, instruction->type, | ||
| 20988 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); | ||
| 20989 | return ira->codegen->invalid_instruction; | ||
| 20990 | } | ||
| 20991 | |||
| 20992 | if (int_type->data.integral.bit_count % 8 != 0) { | ||
| 20993 | ir_add_error(ira, instruction->type, | ||
| 20994 | buf_sprintf("@bswap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", | ||
| 20995 | buf_ptr(&int_type->name), int_type->data.integral.bit_count)); | ||
| 20996 | return ira->codegen->invalid_instruction; | ||
| 20997 | } | ||
| 20998 | |||
| 20999 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | ||
| 21000 | if (type_is_invalid(casted_op->value.type)) | ||
| 21001 | return ira->codegen->invalid_instruction; | ||
| 21002 | |||
| 21003 | if (int_type->data.integral.bit_count == 0) { | ||
| 21004 | IrInstruction *result = ir_const(ira, &instruction->base, int_type); | ||
| 21005 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | ||
| 21006 | return result; | ||
| 21007 | } | ||
| 21008 | |||
| 21009 | if (int_type->data.integral.bit_count == 8) { | ||
| 21010 | return casted_op; | ||
| 21011 | } | ||
| 21012 | |||
| 21013 | if (instr_is_comptime(casted_op)) { | ||
| 21014 | ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); | ||
| 21015 | if (!val) | ||
| 21016 | return ira->codegen->invalid_instruction; | ||
| 21017 | |||
| 21018 | IrInstruction *result = ir_const(ira, &instruction->base, int_type); | ||
| 21019 | size_t buf_size = int_type->data.integral.bit_count / 8; | ||
| 21020 | uint8_t *buf = allocate_nonzero<uint8_t>(buf_size); | ||
| 21021 | bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true); | ||
| 21022 | bigint_read_twos_complement(&result->value.data.x_bigint, buf, int_type->data.integral.bit_count, false, | ||
| 21023 | int_type->data.integral.is_signed); | ||
| 21024 | return result; | ||
| 21025 | } | ||
| 21026 | |||
| 21027 | IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope, | ||
| 21028 | instruction->base.source_node, nullptr, casted_op); | ||
| 21029 | result->value.type = int_type; | ||
| 21030 | return result; | ||
| 21031 | } | ||
| 21032 | |||
| 21033 | |||
| 20901 | static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { | 21034 | static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { |
| 20902 | Error err; | 21035 | Error err; |
| 20903 | IrInstruction *target = instruction->target->child; | 21036 | IrInstruction *target = instruction->target->child; |
| ... | @@ -21233,6 +21366,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -21233,6 +21366,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 21233 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); | 21366 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 21234 | case IrInstructionIdSqrt: | 21367 | case IrInstructionIdSqrt: |
| 21235 | return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); | 21368 | return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); |
| 21369 | case IrInstructionIdBswap: | ||
| 21370 | return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); | ||
| 21236 | case IrInstructionIdIntToErr: | 21371 | case IrInstructionIdIntToErr: |
| 21237 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); | 21372 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); |
| 21238 | case IrInstructionIdErrToInt: | 21373 | case IrInstructionIdErrToInt: |
| ... | @@ -21454,6 +21589,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -21454,6 +21589,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 21454 | case IrInstructionIdCoroPromise: | 21589 | case IrInstructionIdCoroPromise: |
| 21455 | case IrInstructionIdPromiseResultType: | 21590 | case IrInstructionIdPromiseResultType: |
| 21456 | case IrInstructionIdSqrt: | 21591 | case IrInstructionIdSqrt: |
| 21592 | case IrInstructionIdBswap: | ||
| 21457 | case IrInstructionIdAtomicLoad: | 21593 | case IrInstructionIdAtomicLoad: |
| 21458 | case IrInstructionIdIntCast: | 21594 | case IrInstructionIdIntCast: |
| 21459 | case IrInstructionIdFloatCast: | 21595 | case IrInstructionIdFloatCast: |
src/ir_print.cpp+15| ... | @@ -1323,6 +1323,18 @@ static void ir_print_sqrt(IrPrint *irp, IrInstructionSqrt *instruction) { | ... | @@ -1323,6 +1323,18 @@ static void ir_print_sqrt(IrPrint *irp, IrInstructionSqrt *instruction) { |
| 1323 | fprintf(irp->f, ")"); | 1323 | fprintf(irp->f, ")"); |
| 1324 | } | 1324 | } |
| 1325 | 1325 | ||
| 1326 | static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) { | ||
| 1327 | fprintf(irp->f, "@bswap("); | ||
| 1328 | if (instruction->type != nullptr) { | ||
| 1329 | ir_print_other_instruction(irp, instruction->type); | ||
| 1330 | } else { | ||
| 1331 | fprintf(irp->f, "null"); | ||
| 1332 | } | ||
| 1333 | fprintf(irp->f, ","); | ||
| 1334 | ir_print_other_instruction(irp, instruction->op); | ||
| 1335 | fprintf(irp->f, ")"); | ||
| 1336 | } | ||
| 1337 | |||
| 1326 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 1338 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1327 | ir_print_prefix(irp, instruction); | 1339 | ir_print_prefix(irp, instruction); |
| 1328 | switch (instruction->id) { | 1340 | switch (instruction->id) { |
| ... | @@ -1736,6 +1748,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1736,6 +1748,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1736 | case IrInstructionIdSqrt: | 1748 | case IrInstructionIdSqrt: |
| 1737 | ir_print_sqrt(irp, (IrInstructionSqrt *)instruction); | 1749 | ir_print_sqrt(irp, (IrInstructionSqrt *)instruction); |
| 1738 | break; | 1750 | break; |
| 1751 | case IrInstructionIdBswap: | ||
| 1752 | ir_print_bswap(irp, (IrInstructionBswap *)instruction); | ||
| 1753 | break; | ||
| 1739 | case IrInstructionIdAtomicLoad: | 1754 | case IrInstructionIdAtomicLoad: |
| 1740 | ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction); | 1755 | ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction); |
| 1741 | break; | 1756 | break; |
std/coff.zig+22-22| ... | @@ -51,7 +51,7 @@ pub const Coff = struct { | ... | @@ -51,7 +51,7 @@ pub const Coff = struct { |
| 51 | 51 | ||
| 52 | // Seek to PE File Header (coff header) | 52 | // Seek to PE File Header (coff header) |
| 53 | try self.in_file.seekTo(pe_pointer_offset); | 53 | try self.in_file.seekTo(pe_pointer_offset); |
| 54 | const pe_magic_offset = try in.readIntLe(u32); | 54 | const pe_magic_offset = try in.readIntLittle(u32); |
| 55 | try self.in_file.seekTo(pe_magic_offset); | 55 | try self.in_file.seekTo(pe_magic_offset); |
| 56 | 56 | ||
| 57 | var pe_header_magic: [4]u8 = undefined; | 57 | var pe_header_magic: [4]u8 = undefined; |
| ... | @@ -60,13 +60,13 @@ pub const Coff = struct { | ... | @@ -60,13 +60,13 @@ pub const Coff = struct { |
| 60 | return error.InvalidPEHeader; | 60 | return error.InvalidPEHeader; |
| 61 | 61 | ||
| 62 | self.coff_header = CoffHeader{ | 62 | self.coff_header = CoffHeader{ |
| 63 | .machine = try in.readIntLe(u16), | 63 | .machine = try in.readIntLittle(u16), |
| 64 | .number_of_sections = try in.readIntLe(u16), | 64 | .number_of_sections = try in.readIntLittle(u16), |
| 65 | .timedate_stamp = try in.readIntLe(u32), | 65 | .timedate_stamp = try in.readIntLittle(u32), |
| 66 | .pointer_to_symbol_table = try in.readIntLe(u32), | 66 | .pointer_to_symbol_table = try in.readIntLittle(u32), |
| 67 | .number_of_symbols = try in.readIntLe(u32), | 67 | .number_of_symbols = try in.readIntLittle(u32), |
| 68 | .size_of_optional_header = try in.readIntLe(u16), | 68 | .size_of_optional_header = try in.readIntLittle(u16), |
| 69 | .characteristics = try in.readIntLe(u16), | 69 | .characteristics = try in.readIntLittle(u16), |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | switch (self.coff_header.machine) { | 72 | switch (self.coff_header.machine) { |
| ... | @@ -79,7 +79,7 @@ pub const Coff = struct { | ... | @@ -79,7 +79,7 @@ pub const Coff = struct { |
| 79 | 79 | ||
| 80 | fn loadOptionalHeader(self: *Coff, file_stream: *os.File.InStream) !void { | 80 | fn loadOptionalHeader(self: *Coff, file_stream: *os.File.InStream) !void { |
| 81 | const in = &file_stream.stream; | 81 | const in = &file_stream.stream; |
| 82 | self.pe_header.magic = try in.readIntLe(u16); | 82 | self.pe_header.magic = try in.readIntLittle(u16); |
| 83 | // For now we're only interested in finding the reference to the .pdb, | 83 | // For now we're only interested in finding the reference to the .pdb, |
| 84 | // so we'll skip most of this header, which size is different in 32 | 84 | // so we'll skip most of this header, which size is different in 32 |
| 85 | // 64 bits by the way. | 85 | // 64 bits by the way. |
| ... | @@ -93,14 +93,14 @@ pub const Coff = struct { | ... | @@ -93,14 +93,14 @@ pub const Coff = struct { |
| 93 | 93 | ||
| 94 | try self.in_file.seekForward(skip_size); | 94 | try self.in_file.seekForward(skip_size); |
| 95 | 95 | ||
| 96 | const number_of_rva_and_sizes = try in.readIntLe(u32); | 96 | const number_of_rva_and_sizes = try in.readIntLittle(u32); |
| 97 | if (number_of_rva_and_sizes != IMAGE_NUMBEROF_DIRECTORY_ENTRIES) | 97 | if (number_of_rva_and_sizes != IMAGE_NUMBEROF_DIRECTORY_ENTRIES) |
| 98 | return error.InvalidPEHeader; | 98 | return error.InvalidPEHeader; |
| 99 | 99 | ||
| 100 | for (self.pe_header.data_directory) |*data_dir| { | 100 | for (self.pe_header.data_directory) |*data_dir| { |
| 101 | data_dir.* = OptionalHeader.DataDirectory{ | 101 | data_dir.* = OptionalHeader.DataDirectory{ |
| 102 | .virtual_address = try in.readIntLe(u32), | 102 | .virtual_address = try in.readIntLittle(u32), |
| 103 | .size = try in.readIntLe(u32), | 103 | .size = try in.readIntLittle(u32), |
| 104 | }; | 104 | }; |
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| ... | @@ -124,7 +124,7 @@ pub const Coff = struct { | ... | @@ -124,7 +124,7 @@ pub const Coff = struct { |
| 124 | if (!mem.eql(u8, cv_signature, "RSDS")) | 124 | if (!mem.eql(u8, cv_signature, "RSDS")) |
| 125 | return error.InvalidPEMagic; | 125 | return error.InvalidPEMagic; |
| 126 | try in.readNoEof(self.guid[0..]); | 126 | try in.readNoEof(self.guid[0..]); |
| 127 | self.age = try in.readIntLe(u32); | 127 | self.age = try in.readIntLittle(u32); |
| 128 | 128 | ||
| 129 | // Finally read the null-terminated string. | 129 | // Finally read the null-terminated string. |
| 130 | var byte = try in.readByte(); | 130 | var byte = try in.readByte(); |
| ... | @@ -157,15 +157,15 @@ pub const Coff = struct { | ... | @@ -157,15 +157,15 @@ pub const Coff = struct { |
| 157 | try self.sections.append(Section{ | 157 | try self.sections.append(Section{ |
| 158 | .header = SectionHeader{ | 158 | .header = SectionHeader{ |
| 159 | .name = name, | 159 | .name = name, |
| 160 | .misc = SectionHeader.Misc{ .physical_address = try in.readIntLe(u32) }, | 160 | .misc = SectionHeader.Misc{ .physical_address = try in.readIntLittle(u32) }, |
| 161 | .virtual_address = try in.readIntLe(u32), | 161 | .virtual_address = try in.readIntLittle(u32), |
| 162 | .size_of_raw_data = try in.readIntLe(u32), | 162 | .size_of_raw_data = try in.readIntLittle(u32), |
| 163 | .pointer_to_raw_data = try in.readIntLe(u32), | 163 | .pointer_to_raw_data = try in.readIntLittle(u32), |
| 164 | .pointer_to_relocations = try in.readIntLe(u32), | 164 | .pointer_to_relocations = try in.readIntLittle(u32), |
| 165 | .pointer_to_line_numbers = try in.readIntLe(u32), | 165 | .pointer_to_line_numbers = try in.readIntLittle(u32), |
| 166 | .number_of_relocations = try in.readIntLe(u16), | 166 | .number_of_relocations = try in.readIntLittle(u16), |
| 167 | .number_of_line_numbers = try in.readIntLe(u16), | 167 | .number_of_line_numbers = try in.readIntLittle(u16), |
| 168 | .characteristics = try in.readIntLe(u32), | 168 | .characteristics = try in.readIntLittle(u32), |
| 169 | }, | 169 | }, |
| 170 | }); | 170 | }); |
| 171 | } | 171 | } |
std/crypto/blake2.zig+7-4| ... | @@ -123,7 +123,8 @@ fn Blake2s(comptime out_len: usize) type { | ... | @@ -123,7 +123,8 @@ fn Blake2s(comptime out_len: usize) type { |
| 123 | const rr = d.h[0 .. out_len / 32]; | 123 | const rr = d.h[0 .. out_len / 32]; |
| 124 | 124 | ||
| 125 | for (rr) |s, j| { | 125 | for (rr) |s, j| { |
| 126 | mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Little); | 126 | // TODO https://github.com/ziglang/zig/issues/863 |
| 127 | mem.writeIntSliceLittle(u32, out[4 * j .. 4 * j + 4], s); | ||
| 127 | } | 128 | } |
| 128 | } | 129 | } |
| 129 | 130 | ||
| ... | @@ -134,7 +135,8 @@ fn Blake2s(comptime out_len: usize) type { | ... | @@ -134,7 +135,8 @@ fn Blake2s(comptime out_len: usize) type { |
| 134 | var v: [16]u32 = undefined; | 135 | var v: [16]u32 = undefined; |
| 135 | 136 | ||
| 136 | for (m) |*r, i| { | 137 | for (m) |*r, i| { |
| 137 | r.* = mem.readIntLE(u32, b[4 * i .. 4 * i + 4]); | 138 | // TODO https://github.com/ziglang/zig/issues/863 |
| 139 | r.* = mem.readIntSliceLittle(u32, b[4 * i .. 4 * i + 4]); | ||
| 138 | } | 140 | } |
| 139 | 141 | ||
| 140 | var k: usize = 0; | 142 | var k: usize = 0; |
| ... | @@ -356,7 +358,8 @@ fn Blake2b(comptime out_len: usize) type { | ... | @@ -356,7 +358,8 @@ fn Blake2b(comptime out_len: usize) type { |
| 356 | const rr = d.h[0 .. out_len / 64]; | 358 | const rr = d.h[0 .. out_len / 64]; |
| 357 | 359 | ||
| 358 | for (rr) |s, j| { | 360 | for (rr) |s, j| { |
| 359 | mem.writeInt(out[8 * j .. 8 * j + 8], s, builtin.Endian.Little); | 361 | // TODO https://github.com/ziglang/zig/issues/863 |
| 362 | mem.writeIntSliceLittle(u64, out[8 * j .. 8 * j + 8], s); | ||
| 360 | } | 363 | } |
| 361 | } | 364 | } |
| 362 | 365 | ||
| ... | @@ -367,7 +370,7 @@ fn Blake2b(comptime out_len: usize) type { | ... | @@ -367,7 +370,7 @@ fn Blake2b(comptime out_len: usize) type { |
| 367 | var v: [16]u64 = undefined; | 370 | var v: [16]u64 = undefined; |
| 368 | 371 | ||
| 369 | for (m) |*r, i| { | 372 | for (m) |*r, i| { |
| 370 | r.* = mem.readIntLE(u64, b[8 * i .. 8 * i + 8]); | 373 | r.* = mem.readIntSliceLittle(u64, b[8 * i .. 8 * i + 8]); |
| 371 | } | 374 | } |
| 372 | 375 | ||
| 373 | var k: usize = 0; | 376 | var k: usize = 0; |
std/crypto/chacha20.zig+27-26| ... | @@ -59,7 +59,8 @@ fn salsa20_wordtobyte(out: []u8, input: [16]u32) void { | ... | @@ -59,7 +59,8 @@ fn salsa20_wordtobyte(out: []u8, input: [16]u32) void { |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | for (x) |_, i| { | 61 | for (x) |_, i| { |
| 62 | mem.writeInt(out[4 * i .. 4 * i + 4], x[i] +% input[i], builtin.Endian.Little); | 62 | // TODO https://github.com/ziglang/zig/issues/863 |
| 63 | mem.writeIntSliceLittle(u32, out[4 * i .. 4 * i + 4], x[i] +% input[i]); | ||
| 63 | } | 64 | } |
| 64 | } | 65 | } |
| 65 | 66 | ||
| ... | @@ -70,10 +71,10 @@ fn chaCha20_internal(out: []u8, in: []const u8, key: [8]u32, counter: [4]u32) vo | ... | @@ -70,10 +71,10 @@ fn chaCha20_internal(out: []u8, in: []const u8, key: [8]u32, counter: [4]u32) vo |
| 70 | 71 | ||
| 71 | const c = "expand 32-byte k"; | 72 | const c = "expand 32-byte k"; |
| 72 | const constant_le = []u32{ | 73 | const constant_le = []u32{ |
| 73 | mem.readIntLE(u32, c[0..4]), | 74 | mem.readIntSliceLittle(u32, c[0..4]), |
| 74 | mem.readIntLE(u32, c[4..8]), | 75 | mem.readIntSliceLittle(u32, c[4..8]), |
| 75 | mem.readIntLE(u32, c[8..12]), | 76 | mem.readIntSliceLittle(u32, c[8..12]), |
| 76 | mem.readIntLE(u32, c[12..16]), | 77 | mem.readIntSliceLittle(u32, c[12..16]), |
| 77 | }; | 78 | }; |
| 78 | 79 | ||
| 79 | mem.copy(u32, ctx[0..], constant_le[0..4]); | 80 | mem.copy(u32, ctx[0..], constant_le[0..4]); |
| ... | @@ -117,19 +118,19 @@ pub fn chaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: | ... | @@ -117,19 +118,19 @@ pub fn chaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: |
| 117 | var k: [8]u32 = undefined; | 118 | var k: [8]u32 = undefined; |
| 118 | var c: [4]u32 = undefined; | 119 | var c: [4]u32 = undefined; |
| 119 | 120 | ||
| 120 | k[0] = mem.readIntLE(u32, key[0..4]); | 121 | k[0] = mem.readIntSliceLittle(u32, key[0..4]); |
| 121 | k[1] = mem.readIntLE(u32, key[4..8]); | 122 | k[1] = mem.readIntSliceLittle(u32, key[4..8]); |
| 122 | k[2] = mem.readIntLE(u32, key[8..12]); | 123 | k[2] = mem.readIntSliceLittle(u32, key[8..12]); |
| 123 | k[3] = mem.readIntLE(u32, key[12..16]); | 124 | k[3] = mem.readIntSliceLittle(u32, key[12..16]); |
| 124 | k[4] = mem.readIntLE(u32, key[16..20]); | 125 | k[4] = mem.readIntSliceLittle(u32, key[16..20]); |
| 125 | k[5] = mem.readIntLE(u32, key[20..24]); | 126 | k[5] = mem.readIntSliceLittle(u32, key[20..24]); |
| 126 | k[6] = mem.readIntLE(u32, key[24..28]); | 127 | k[6] = mem.readIntSliceLittle(u32, key[24..28]); |
| 127 | k[7] = mem.readIntLE(u32, key[28..32]); | 128 | k[7] = mem.readIntSliceLittle(u32, key[28..32]); |
| 128 | 129 | ||
| 129 | c[0] = counter; | 130 | c[0] = counter; |
| 130 | c[1] = mem.readIntLE(u32, nonce[0..4]); | 131 | c[1] = mem.readIntSliceLittle(u32, nonce[0..4]); |
| 131 | c[2] = mem.readIntLE(u32, nonce[4..8]); | 132 | c[2] = mem.readIntSliceLittle(u32, nonce[4..8]); |
| 132 | c[3] = mem.readIntLE(u32, nonce[8..12]); | 133 | c[3] = mem.readIntSliceLittle(u32, nonce[8..12]); |
| 133 | chaCha20_internal(out, in, k, c); | 134 | chaCha20_internal(out, in, k, c); |
| 134 | } | 135 | } |
| 135 | 136 | ||
| ... | @@ -144,19 +145,19 @@ pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32] | ... | @@ -144,19 +145,19 @@ pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32] |
| 144 | var k: [8]u32 = undefined; | 145 | var k: [8]u32 = undefined; |
| 145 | var c: [4]u32 = undefined; | 146 | var c: [4]u32 = undefined; |
| 146 | 147 | ||
| 147 | k[0] = mem.readIntLE(u32, key[0..4]); | 148 | k[0] = mem.readIntSliceLittle(u32, key[0..4]); |
| 148 | k[1] = mem.readIntLE(u32, key[4..8]); | 149 | k[1] = mem.readIntSliceLittle(u32, key[4..8]); |
| 149 | k[2] = mem.readIntLE(u32, key[8..12]); | 150 | k[2] = mem.readIntSliceLittle(u32, key[8..12]); |
| 150 | k[3] = mem.readIntLE(u32, key[12..16]); | 151 | k[3] = mem.readIntSliceLittle(u32, key[12..16]); |
| 151 | k[4] = mem.readIntLE(u32, key[16..20]); | 152 | k[4] = mem.readIntSliceLittle(u32, key[16..20]); |
| 152 | k[5] = mem.readIntLE(u32, key[20..24]); | 153 | k[5] = mem.readIntSliceLittle(u32, key[20..24]); |
| 153 | k[6] = mem.readIntLE(u32, key[24..28]); | 154 | k[6] = mem.readIntSliceLittle(u32, key[24..28]); |
| 154 | k[7] = mem.readIntLE(u32, key[28..32]); | 155 | k[7] = mem.readIntSliceLittle(u32, key[28..32]); |
| 155 | 156 | ||
| 156 | c[0] = @truncate(u32, counter); | 157 | c[0] = @truncate(u32, counter); |
| 157 | c[1] = @truncate(u32, counter >> 32); | 158 | c[1] = @truncate(u32, counter >> 32); |
| 158 | c[2] = mem.readIntLE(u32, nonce[0..4]); | 159 | c[2] = mem.readIntSliceLittle(u32, nonce[0..4]); |
| 159 | c[3] = mem.readIntLE(u32, nonce[4..8]); | 160 | c[3] = mem.readIntSliceLittle(u32, nonce[4..8]); |
| 160 | 161 | ||
| 161 | const block_size = (1 << 6); | 162 | const block_size = (1 << 6); |
| 162 | const big_block = (block_size << 32); | 163 | const big_block = (block_size << 32); |
std/crypto/md5.zig+2-1| ... | @@ -112,7 +112,8 @@ pub const Md5 = struct { | ... | @@ -112,7 +112,8 @@ pub const Md5 = struct { |
| 112 | d.round(d.buf[0..]); | 112 | d.round(d.buf[0..]); |
| 113 | 113 | ||
| 114 | for (d.s) |s, j| { | 114 | for (d.s) |s, j| { |
| 115 | mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Little); | 115 | // TODO https://github.com/ziglang/zig/issues/863 |
| 116 | mem.writeIntSliceLittle(u32, out[4 * j .. 4 * j + 4], s); | ||
| 116 | } | 117 | } |
| 117 | } | 118 | } |
| 118 | 119 |
std/crypto/poly1305.zig+14-13| ... | @@ -6,8 +6,8 @@ const std = @import("../index.zig"); | ... | @@ -6,8 +6,8 @@ const std = @import("../index.zig"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | const Endian = builtin.Endian; | 8 | const Endian = builtin.Endian; |
| 9 | const readInt = std.mem.readInt; | 9 | const readIntSliceLittle = std.mem.readIntSliceLittle; |
| 10 | const writeInt = std.mem.writeInt; | 10 | const writeIntSliceLittle = std.mem.writeIntSliceLittle; |
| 11 | 11 | ||
| 12 | pub const Poly1305 = struct { | 12 | pub const Poly1305 = struct { |
| 13 | const Self = @This(); | 13 | const Self = @This(); |
| ... | @@ -59,19 +59,19 @@ pub const Poly1305 = struct { | ... | @@ -59,19 +59,19 @@ pub const Poly1305 = struct { |
| 59 | { | 59 | { |
| 60 | var i: usize = 0; | 60 | var i: usize = 0; |
| 61 | while (i < 1) : (i += 1) { | 61 | while (i < 1) : (i += 1) { |
| 62 | ctx.r[0] = readInt(key[0..4], u32, Endian.Little) & 0x0fffffff; | 62 | ctx.r[0] = readIntSliceLittle(u32, key[0..4]) & 0x0fffffff; |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| 65 | { | 65 | { |
| 66 | var i: usize = 1; | 66 | var i: usize = 1; |
| 67 | while (i < 4) : (i += 1) { | 67 | while (i < 4) : (i += 1) { |
| 68 | ctx.r[i] = readInt(key[i * 4 .. i * 4 + 4], u32, Endian.Little) & 0x0ffffffc; | 68 | ctx.r[i] = readIntSliceLittle(u32, key[i * 4 .. i * 4 + 4]) & 0x0ffffffc; |
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | { | 71 | { |
| 72 | var i: usize = 0; | 72 | var i: usize = 0; |
| 73 | while (i < 4) : (i += 1) { | 73 | while (i < 4) : (i += 1) { |
| 74 | ctx.pad[i] = readInt(key[i * 4 + 16 .. i * 4 + 16 + 4], u32, Endian.Little); | 74 | ctx.pad[i] = readIntSliceLittle(u32, key[i * 4 + 16 .. i * 4 + 16 + 4]); |
| 75 | } | 75 | } |
| 76 | } | 76 | } |
| 77 | 77 | ||
| ... | @@ -168,10 +168,10 @@ pub const Poly1305 = struct { | ... | @@ -168,10 +168,10 @@ pub const Poly1305 = struct { |
| 168 | const nb_blocks = nmsg.len >> 4; | 168 | const nb_blocks = nmsg.len >> 4; |
| 169 | var i: usize = 0; | 169 | var i: usize = 0; |
| 170 | while (i < nb_blocks) : (i += 1) { | 170 | while (i < nb_blocks) : (i += 1) { |
| 171 | ctx.c[0] = readInt(nmsg[0..4], u32, Endian.Little); | 171 | ctx.c[0] = readIntSliceLittle(u32, nmsg[0..4]); |
| 172 | ctx.c[1] = readInt(nmsg[4..8], u32, Endian.Little); | 172 | ctx.c[1] = readIntSliceLittle(u32, nmsg[4..8]); |
| 173 | ctx.c[2] = readInt(nmsg[8..12], u32, Endian.Little); | 173 | ctx.c[2] = readIntSliceLittle(u32, nmsg[8..12]); |
| 174 | ctx.c[3] = readInt(nmsg[12..16], u32, Endian.Little); | 174 | ctx.c[3] = readIntSliceLittle(u32, nmsg[12..16]); |
| 175 | polyBlock(ctx); | 175 | polyBlock(ctx); |
| 176 | nmsg = nmsg[16..]; | 176 | nmsg = nmsg[16..]; |
| 177 | } | 177 | } |
| ... | @@ -210,10 +210,11 @@ pub const Poly1305 = struct { | ... | @@ -210,10 +210,11 @@ pub const Poly1305 = struct { |
| 210 | const uu2 = (uu1 >> 32) + ctx.h[2] + ctx.pad[2]; // <= 2_00000000 | 210 | const uu2 = (uu1 >> 32) + ctx.h[2] + ctx.pad[2]; // <= 2_00000000 |
| 211 | const uu3 = (uu2 >> 32) + ctx.h[3] + ctx.pad[3]; // <= 2_00000000 | 211 | const uu3 = (uu2 >> 32) + ctx.h[3] + ctx.pad[3]; // <= 2_00000000 |
| 212 | 212 | ||
| 213 | writeInt(out[0..], @truncate(u32, uu0), Endian.Little); | 213 | // TODO https://github.com/ziglang/zig/issues/863 |
| 214 | writeInt(out[4..], @truncate(u32, uu1), Endian.Little); | 214 | writeIntSliceLittle(u32, out[0..], @truncate(u32, uu0)); |
| 215 | writeInt(out[8..], @truncate(u32, uu2), Endian.Little); | 215 | writeIntSliceLittle(u32, out[4..], @truncate(u32, uu1)); |
| 216 | writeInt(out[12..], @truncate(u32, uu3), Endian.Little); | 216 | writeIntSliceLittle(u32, out[8..], @truncate(u32, uu2)); |
| 217 | writeIntSliceLittle(u32, out[12..], @truncate(u32, uu3)); | ||
| 217 | 218 | ||
| 218 | ctx.secureZero(); | 219 | ctx.secureZero(); |
| 219 | } | 220 | } |
std/crypto/sha1.zig+2-1| ... | @@ -109,7 +109,8 @@ pub const Sha1 = struct { | ... | @@ -109,7 +109,8 @@ pub const Sha1 = struct { |
| 109 | d.round(d.buf[0..]); | 109 | d.round(d.buf[0..]); |
| 110 | 110 | ||
| 111 | for (d.s) |s, j| { | 111 | for (d.s) |s, j| { |
| 112 | mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Big); | 112 | // TODO https://github.com/ziglang/zig/issues/863 |
| 113 | mem.writeIntSliceBig(u32, out[4 * j .. 4 * j + 4], s); | ||
| 113 | } | 114 | } |
| 114 | } | 115 | } |
| 115 | 116 |
std/crypto/sha2.zig+4-2| ... | @@ -167,7 +167,8 @@ fn Sha2_32(comptime params: Sha2Params32) type { | ... | @@ -167,7 +167,8 @@ fn Sha2_32(comptime params: Sha2Params32) type { |
| 167 | const rr = d.s[0 .. params.out_len / 32]; | 167 | const rr = d.s[0 .. params.out_len / 32]; |
| 168 | 168 | ||
| 169 | for (rr) |s, j| { | 169 | for (rr) |s, j| { |
| 170 | mem.writeInt(out[4 * j .. 4 * j + 4], s, builtin.Endian.Big); | 170 | // TODO https://github.com/ziglang/zig/issues/863 |
| 171 | mem.writeIntSliceBig(u32, out[4 * j .. 4 * j + 4], s); | ||
| 171 | } | 172 | } |
| 172 | } | 173 | } |
| 173 | 174 | ||
| ... | @@ -508,7 +509,8 @@ fn Sha2_64(comptime params: Sha2Params64) type { | ... | @@ -508,7 +509,8 @@ fn Sha2_64(comptime params: Sha2Params64) type { |
| 508 | const rr = d.s[0 .. params.out_len / 64]; | 509 | const rr = d.s[0 .. params.out_len / 64]; |
| 509 | 510 | ||
| 510 | for (rr) |s, j| { | 511 | for (rr) |s, j| { |
| 511 | mem.writeInt(out[8 * j .. 8 * j + 8], s, builtin.Endian.Big); | 512 | // TODO https://github.com/ziglang/zig/issues/863 |
| 513 | mem.writeIntSliceBig(u64, out[8 * j .. 8 * j + 8], s); | ||
| 512 | } | 514 | } |
| 513 | } | 515 | } |
| 514 | 516 |
std/crypto/sha3.zig+3-2| ... | @@ -120,7 +120,7 @@ fn keccak_f(comptime F: usize, d: []u8) void { | ... | @@ -120,7 +120,7 @@ fn keccak_f(comptime F: usize, d: []u8) void { |
| 120 | var c = []const u64{0} ** 5; | 120 | var c = []const u64{0} ** 5; |
| 121 | 121 | ||
| 122 | for (s) |*r, i| { | 122 | for (s) |*r, i| { |
| 123 | r.* = mem.readIntLE(u64, d[8 * i .. 8 * i + 8]); | 123 | r.* = mem.readIntSliceLittle(u64, d[8 * i .. 8 * i + 8]); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | comptime var x: usize = 0; | 126 | comptime var x: usize = 0; |
| ... | @@ -167,7 +167,8 @@ fn keccak_f(comptime F: usize, d: []u8) void { | ... | @@ -167,7 +167,8 @@ fn keccak_f(comptime F: usize, d: []u8) void { |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | for (s) |r, i| { | 169 | for (s) |r, i| { |
| 170 | mem.writeInt(d[8 * i .. 8 * i + 8], r, builtin.Endian.Little); | 170 | // TODO https://github.com/ziglang/zig/issues/863 |
| 171 | mem.writeIntSliceLittle(u64, d[8 * i .. 8 * i + 8], r); | ||
| 171 | } | 172 | } |
| 172 | } | 173 | } |
| 173 | 174 |
std/crypto/x25519.zig+21-20| ... | @@ -7,8 +7,8 @@ const builtin = @import("builtin"); | ... | @@ -7,8 +7,8 @@ const builtin = @import("builtin"); |
| 7 | const fmt = std.fmt; | 7 | const fmt = std.fmt; |
| 8 | 8 | ||
| 9 | const Endian = builtin.Endian; | 9 | const Endian = builtin.Endian; |
| 10 | const readInt = std.mem.readInt; | 10 | const readIntSliceLittle = std.mem.readIntSliceLittle; |
| 11 | const writeInt = std.mem.writeInt; | 11 | const writeIntSliceLittle = std.mem.writeIntSliceLittle; |
| 12 | 12 | ||
| 13 | // Based on Supercop's ref10 implementation. | 13 | // Based on Supercop's ref10 implementation. |
| 14 | pub const X25519 = struct { | 14 | pub const X25519 = struct { |
| ... | @@ -255,16 +255,16 @@ const Fe = struct { | ... | @@ -255,16 +255,16 @@ const Fe = struct { |
| 255 | 255 | ||
| 256 | var t: [10]i64 = undefined; | 256 | var t: [10]i64 = undefined; |
| 257 | 257 | ||
| 258 | t[0] = readInt(s[0..4], u32, Endian.Little); | 258 | t[0] = readIntSliceLittle(u32, s[0..4]); |
| 259 | t[1] = readInt(s[4..7], u32, Endian.Little) << 6; | 259 | t[1] = u32(readIntSliceLittle(u24, s[4..7])) << 6; |
| 260 | t[2] = readInt(s[7..10], u32, Endian.Little) << 5; | 260 | t[2] = u32(readIntSliceLittle(u24, s[7..10])) << 5; |
| 261 | t[3] = readInt(s[10..13], u32, Endian.Little) << 3; | 261 | t[3] = u32(readIntSliceLittle(u24, s[10..13])) << 3; |
| 262 | t[4] = readInt(s[13..16], u32, Endian.Little) << 2; | 262 | t[4] = u32(readIntSliceLittle(u24, s[13..16])) << 2; |
| 263 | t[5] = readInt(s[16..20], u32, Endian.Little); | 263 | t[5] = readIntSliceLittle(u32, s[16..20]); |
| 264 | t[6] = readInt(s[20..23], u32, Endian.Little) << 7; | 264 | t[6] = u32(readIntSliceLittle(u24, s[20..23])) << 7; |
| 265 | t[7] = readInt(s[23..26], u32, Endian.Little) << 5; | 265 | t[7] = u32(readIntSliceLittle(u24, s[23..26])) << 5; |
| 266 | t[8] = readInt(s[26..29], u32, Endian.Little) << 4; | 266 | t[8] = u32(readIntSliceLittle(u24, s[26..29])) << 4; |
| 267 | t[9] = (readInt(s[29..32], u32, Endian.Little) & 0x7fffff) << 2; | 267 | t[9] = (u32(readIntSliceLittle(u24, s[29..32])) & 0x7fffff) << 2; |
| 268 | 268 | ||
| 269 | carry1(h, t[0..]); | 269 | carry1(h, t[0..]); |
| 270 | } | 270 | } |
| ... | @@ -544,14 +544,15 @@ const Fe = struct { | ... | @@ -544,14 +544,15 @@ const Fe = struct { |
| 544 | ut[i] = @bitCast(u32, @intCast(i32, t[i])); | 544 | ut[i] = @bitCast(u32, @intCast(i32, t[i])); |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | writeInt(s[0..], (ut[0] >> 0) | (ut[1] << 26), Endian.Little); | 547 | // TODO https://github.com/ziglang/zig/issues/863 |
| 548 | writeInt(s[4..], (ut[1] >> 6) | (ut[2] << 19), Endian.Little); | 548 | writeIntSliceLittle(u32, s[0..4], (ut[0] >> 0) | (ut[1] << 26)); |
| 549 | writeInt(s[8..], (ut[2] >> 13) | (ut[3] << 13), Endian.Little); | 549 | writeIntSliceLittle(u32, s[4..8], (ut[1] >> 6) | (ut[2] << 19)); |
| 550 | writeInt(s[12..], (ut[3] >> 19) | (ut[4] << 6), Endian.Little); | 550 | writeIntSliceLittle(u32, s[8..12], (ut[2] >> 13) | (ut[3] << 13)); |
| 551 | writeInt(s[16..], (ut[5] >> 0) | (ut[6] << 25), Endian.Little); | 551 | writeIntSliceLittle(u32, s[12..16], (ut[3] >> 19) | (ut[4] << 6)); |
| 552 | writeInt(s[20..], (ut[6] >> 7) | (ut[7] << 19), Endian.Little); | 552 | writeIntSliceLittle(u32, s[16..20], (ut[5] >> 0) | (ut[6] << 25)); |
| 553 | writeInt(s[24..], (ut[7] >> 13) | (ut[8] << 12), Endian.Little); | 553 | writeIntSliceLittle(u32, s[20..24], (ut[6] >> 7) | (ut[7] << 19)); |
| 554 | writeInt(s[28..], (ut[8] >> 20) | (ut[9] << 6), Endian.Little); | 554 | writeIntSliceLittle(u32, s[24..28], (ut[7] >> 13) | (ut[8] << 12)); |
| 555 | writeIntSliceLittle(u32, s[28..], (ut[8] >> 20) | (ut[9] << 6)); | ||
| 555 | 556 | ||
| 556 | std.mem.secureZero(i64, t[0..]); | 557 | std.mem.secureZero(i64, t[0..]); |
| 557 | } | 558 | } |
std/debug/index.zig+31-29| ... | @@ -523,7 +523,7 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void { | ... | @@ -523,7 +523,7 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void { |
| 523 | 523 | ||
| 524 | const modi = di.pdb.getStreamById(mod.mod_info.ModuleSymStream) orelse return error.MissingDebugInfo; | 524 | const modi = di.pdb.getStreamById(mod.mod_info.ModuleSymStream) orelse return error.MissingDebugInfo; |
| 525 | 525 | ||
| 526 | const signature = try modi.stream.readIntLe(u32); | 526 | const signature = try modi.stream.readIntLittle(u32); |
| 527 | if (signature != 4) | 527 | if (signature != 4) |
| 528 | return error.InvalidDebugInfo; | 528 | return error.InvalidDebugInfo; |
| 529 | 529 | ||
| ... | @@ -757,9 +757,9 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { | ... | @@ -757,9 +757,9 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { |
| 757 | try di.pdb.openFile(di.coff, path); | 757 | try di.pdb.openFile(di.coff, path); |
| 758 | 758 | ||
| 759 | var pdb_stream = di.pdb.getStream(pdb.StreamType.Pdb) orelse return error.InvalidDebugInfo; | 759 | var pdb_stream = di.pdb.getStream(pdb.StreamType.Pdb) orelse return error.InvalidDebugInfo; |
| 760 | const version = try pdb_stream.stream.readIntLe(u32); | 760 | const version = try pdb_stream.stream.readIntLittle(u32); |
| 761 | const signature = try pdb_stream.stream.readIntLe(u32); | 761 | const signature = try pdb_stream.stream.readIntLittle(u32); |
| 762 | const age = try pdb_stream.stream.readIntLe(u32); | 762 | const age = try pdb_stream.stream.readIntLittle(u32); |
| 763 | var guid: [16]u8 = undefined; | 763 | var guid: [16]u8 = undefined; |
| 764 | try pdb_stream.stream.readNoEof(guid[0..]); | 764 | try pdb_stream.stream.readNoEof(guid[0..]); |
| 765 | if (!mem.eql(u8, di.coff.guid, guid) or di.coff.age != age) | 765 | if (!mem.eql(u8, di.coff.guid, guid) or di.coff.age != age) |
| ... | @@ -767,7 +767,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { | ... | @@ -767,7 +767,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { |
| 767 | // We validated the executable and pdb match. | 767 | // We validated the executable and pdb match. |
| 768 | 768 | ||
| 769 | const string_table_index = str_tab_index: { | 769 | const string_table_index = str_tab_index: { |
| 770 | const name_bytes_len = try pdb_stream.stream.readIntLe(u32); | 770 | const name_bytes_len = try pdb_stream.stream.readIntLittle(u32); |
| 771 | const name_bytes = try allocator.alloc(u8, name_bytes_len); | 771 | const name_bytes = try allocator.alloc(u8, name_bytes_len); |
| 772 | try pdb_stream.stream.readNoEof(name_bytes); | 772 | try pdb_stream.stream.readNoEof(name_bytes); |
| 773 | 773 | ||
| ... | @@ -797,8 +797,8 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { | ... | @@ -797,8 +797,8 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { |
| 797 | }; | 797 | }; |
| 798 | const bucket_list = try allocator.alloc(Bucket, present.len); | 798 | const bucket_list = try allocator.alloc(Bucket, present.len); |
| 799 | for (present) |_| { | 799 | for (present) |_| { |
| 800 | const name_offset = try pdb_stream.stream.readIntLe(u32); | 800 | const name_offset = try pdb_stream.stream.readIntLittle(u32); |
| 801 | const name_index = try pdb_stream.stream.readIntLe(u32); | 801 | const name_index = try pdb_stream.stream.readIntLittle(u32); |
| 802 | const name = mem.toSlice(u8, name_bytes.ptr + name_offset); | 802 | const name = mem.toSlice(u8, name_bytes.ptr + name_offset); |
| 803 | if (mem.eql(u8, name, "/names")) { | 803 | if (mem.eql(u8, name, "/names")) { |
| 804 | break :str_tab_index name_index; | 804 | break :str_tab_index name_index; |
| ... | @@ -859,7 +859,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { | ... | @@ -859,7 +859,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { |
| 859 | var sect_contribs = ArrayList(pdb.SectionContribEntry).init(allocator); | 859 | var sect_contribs = ArrayList(pdb.SectionContribEntry).init(allocator); |
| 860 | var sect_cont_offset: usize = 0; | 860 | var sect_cont_offset: usize = 0; |
| 861 | if (section_contrib_size != 0) { | 861 | if (section_contrib_size != 0) { |
| 862 | const ver = @intToEnum(pdb.SectionContrSubstreamVersion, try dbi.stream.readIntLe(u32)); | 862 | const ver = @intToEnum(pdb.SectionContrSubstreamVersion, try dbi.stream.readIntLittle(u32)); |
| 863 | if (ver != pdb.SectionContrSubstreamVersion.Ver60) | 863 | if (ver != pdb.SectionContrSubstreamVersion.Ver60) |
| 864 | return error.InvalidDebugInfo; | 864 | return error.InvalidDebugInfo; |
| 865 | sect_cont_offset += @sizeOf(u32); | 865 | sect_cont_offset += @sizeOf(u32); |
| ... | @@ -879,11 +879,11 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { | ... | @@ -879,11 +879,11 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { |
| 879 | } | 879 | } |
| 880 | 880 | ||
| 881 | fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize { | 881 | fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize { |
| 882 | const num_words = try stream.readIntLe(u32); | 882 | const num_words = try stream.readIntLittle(u32); |
| 883 | var word_i: usize = 0; | 883 | var word_i: usize = 0; |
| 884 | var list = ArrayList(usize).init(allocator); | 884 | var list = ArrayList(usize).init(allocator); |
| 885 | while (word_i != num_words) : (word_i += 1) { | 885 | while (word_i != num_words) : (word_i += 1) { |
| 886 | const word = try stream.readIntLe(u32); | 886 | const word = try stream.readIntLittle(u32); |
| 887 | var bit_i: u5 = 0; | 887 | var bit_i: u5 = 0; |
| 888 | while (true) : (bit_i += 1) { | 888 | while (true) : (bit_i += 1) { |
| 889 | if (word & (u32(1) << bit_i) != 0) { | 889 | if (word & (u32(1) << bit_i) != 0) { |
| ... | @@ -1200,7 +1200,7 @@ const Constant = struct { | ... | @@ -1200,7 +1200,7 @@ const Constant = struct { |
| 1200 | fn asUnsignedLe(self: *const Constant) !u64 { | 1200 | fn asUnsignedLe(self: *const Constant) !u64 { |
| 1201 | if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo; | 1201 | if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo; |
| 1202 | if (self.signed) return error.InvalidDebugInfo; | 1202 | if (self.signed) return error.InvalidDebugInfo; |
| 1203 | return mem.readInt(self.payload, u64, builtin.Endian.Little); | 1203 | return mem.readIntSliceLittle(u64, self.payload); |
| 1204 | } | 1204 | } |
| 1205 | }; | 1205 | }; |
| 1206 | 1206 | ||
| ... | @@ -1381,7 +1381,7 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize | ... | @@ -1381,7 +1381,7 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize |
| 1381 | } | 1381 | } |
| 1382 | 1382 | ||
| 1383 | fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue { | 1383 | fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue { |
| 1384 | const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size); | 1384 | const block_len = try in_stream.readVarInt(usize, builtin.Endian.Little, size); |
| 1385 | return parseFormValueBlockLen(allocator, in_stream, block_len); | 1385 | return parseFormValueBlockLen(allocator, in_stream, block_len); |
| 1386 | } | 1386 | } |
| 1387 | 1387 | ||
| ... | @@ -1395,11 +1395,11 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo | ... | @@ -1395,11 +1395,11 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo |
| 1395 | } | 1395 | } |
| 1396 | 1396 | ||
| 1397 | fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 { | 1397 | fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 { |
| 1398 | return if (is_64) try in_stream.readIntLe(u64) else u64(try in_stream.readIntLe(u32)); | 1398 | return if (is_64) try in_stream.readIntLittle(u64) else u64(try in_stream.readIntLittle(u32)); |
| 1399 | } | 1399 | } |
| 1400 | 1400 | ||
| 1401 | fn parseFormValueTargetAddrSize(in_stream: var) !u64 { | 1401 | fn parseFormValueTargetAddrSize(in_stream: var) !u64 { |
| 1402 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) else unreachable; | 1402 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLittle(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLittle(u64) else unreachable; |
| 1403 | } | 1403 | } |
| 1404 | 1404 | ||
| 1405 | fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue { | 1405 | fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue { |
| ... | @@ -1408,7 +1408,7 @@ fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) | ... | @@ -1408,7 +1408,7 @@ fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) |
| 1408 | } | 1408 | } |
| 1409 | 1409 | ||
| 1410 | fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, comptime T: type) !FormValue { | 1410 | fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, comptime T: type) !FormValue { |
| 1411 | const block_len = try in_stream.readIntLe(T); | 1411 | const block_len = try in_stream.readIntLittle(T); |
| 1412 | return parseFormValueRefLen(allocator, in_stream, block_len); | 1412 | return parseFormValueRefLen(allocator, in_stream, block_len); |
| 1413 | } | 1413 | } |
| 1414 | 1414 | ||
| ... | @@ -1450,7 +1450,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 | ... | @@ -1450,7 +1450,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 |
| 1450 | }, | 1450 | }, |
| 1451 | 1451 | ||
| 1452 | DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 1452 | DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| 1453 | DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLe(u64) }, | 1453 | DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLittle(u64) }, |
| 1454 | 1454 | ||
| 1455 | DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) }, | 1455 | DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) }, |
| 1456 | DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 1456 | DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| ... | @@ -1747,11 +1747,11 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr | ... | @@ -1747,11 +1747,11 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr |
| 1747 | continue; | 1747 | continue; |
| 1748 | } | 1748 | } |
| 1749 | 1749 | ||
| 1750 | const version = try di.dwarf_in_stream.readInt(di.endian, u16); | 1750 | const version = try di.dwarf_in_stream.readInt(u16, di.endian); |
| 1751 | // TODO support 3 and 5 | 1751 | // TODO support 3 and 5 |
| 1752 | if (version != 2 and version != 4) return error.InvalidDebugInfo; | 1752 | if (version != 2 and version != 4) return error.InvalidDebugInfo; |
| 1753 | 1753 | ||
| 1754 | const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(di.endian, u64) else try di.dwarf_in_stream.readInt(di.endian, u32); | 1754 | const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian); |
| 1755 | const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length; | 1755 | const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length; |
| 1756 | 1756 | ||
| 1757 | const minimum_instruction_length = try di.dwarf_in_stream.readByte(); | 1757 | const minimum_instruction_length = try di.dwarf_in_stream.readByte(); |
| ... | @@ -1820,7 +1820,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr | ... | @@ -1820,7 +1820,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr |
| 1820 | return error.MissingDebugInfo; | 1820 | return error.MissingDebugInfo; |
| 1821 | }, | 1821 | }, |
| 1822 | DW.LNE_set_address => { | 1822 | DW.LNE_set_address => { |
| 1823 | const addr = try di.dwarf_in_stream.readInt(di.endian, usize); | 1823 | const addr = try di.dwarf_in_stream.readInt(usize, di.endian); |
| 1824 | prog.address = addr; | 1824 | prog.address = addr; |
| 1825 | }, | 1825 | }, |
| 1826 | DW.LNE_define_file => { | 1826 | DW.LNE_define_file => { |
| ... | @@ -1882,7 +1882,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr | ... | @@ -1882,7 +1882,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr |
| 1882 | prog.address += inc_addr; | 1882 | prog.address += inc_addr; |
| 1883 | }, | 1883 | }, |
| 1884 | DW.LNS_fixed_advance_pc => { | 1884 | DW.LNS_fixed_advance_pc => { |
| 1885 | const arg = try di.dwarf_in_stream.readInt(di.endian, u16); | 1885 | const arg = try di.dwarf_in_stream.readInt(u16, di.endian); |
| 1886 | prog.address += arg; | 1886 | prog.address += arg; |
| 1887 | }, | 1887 | }, |
| 1888 | DW.LNS_set_prologue_end => {}, | 1888 | DW.LNS_set_prologue_end => {}, |
| ... | @@ -1914,10 +1914,10 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void { | ... | @@ -1914,10 +1914,10 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void { |
| 1914 | if (unit_length == 0) return; | 1914 | if (unit_length == 0) return; |
| 1915 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); | 1915 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| 1916 | 1916 | ||
| 1917 | const version = try di.dwarf_in_stream.readInt(di.endian, u16); | 1917 | const version = try di.dwarf_in_stream.readInt(u16, di.endian); |
| 1918 | if (version < 2 or version > 5) return error.InvalidDebugInfo; | 1918 | if (version < 2 or version > 5) return error.InvalidDebugInfo; |
| 1919 | 1919 | ||
| 1920 | const debug_abbrev_offset = if (is_64) try di.dwarf_in_stream.readInt(di.endian, u64) else try di.dwarf_in_stream.readInt(di.endian, u32); | 1920 | const debug_abbrev_offset = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian); |
| 1921 | 1921 | ||
| 1922 | const address_size = try di.dwarf_in_stream.readByte(); | 1922 | const address_size = try di.dwarf_in_stream.readByte(); |
| 1923 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; | 1923 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; |
| ... | @@ -1978,8 +1978,8 @@ fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit { | ... | @@ -1978,8 +1978,8 @@ fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit { |
| 1978 | if (di.debug_ranges) |debug_ranges| { | 1978 | if (di.debug_ranges) |debug_ranges| { |
| 1979 | try di.dwarf_seekable_stream.seekTo(debug_ranges.offset + ranges_offset); | 1979 | try di.dwarf_seekable_stream.seekTo(debug_ranges.offset + ranges_offset); |
| 1980 | while (true) { | 1980 | while (true) { |
| 1981 | const begin_addr = try di.dwarf_in_stream.readIntLe(usize); | 1981 | const begin_addr = try di.dwarf_in_stream.readIntLittle(usize); |
| 1982 | const end_addr = try di.dwarf_in_stream.readIntLe(usize); | 1982 | const end_addr = try di.dwarf_in_stream.readIntLittle(usize); |
| 1983 | if (begin_addr == 0 and end_addr == 0) { | 1983 | if (begin_addr == 0 and end_addr == 0) { |
| 1984 | break; | 1984 | break; |
| 1985 | } | 1985 | } |
| ... | @@ -2001,7 +2001,8 @@ fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit { | ... | @@ -2001,7 +2001,8 @@ fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit { |
| 2001 | } | 2001 | } |
| 2002 | 2002 | ||
| 2003 | fn readIntMem(ptr: *[*]const u8, comptime T: type, endian: builtin.Endian) T { | 2003 | fn readIntMem(ptr: *[*]const u8, comptime T: type, endian: builtin.Endian) T { |
| 2004 | const result = mem.readInt(ptr.*[0..@sizeOf(T)], T, endian); | 2004 | // TODO https://github.com/ziglang/zig/issues/863 |
| 2005 | const result = mem.readIntSlice(T, ptr.*[0..@sizeOf(T)], endian); | ||
| 2005 | ptr.* += @sizeOf(T); | 2006 | ptr.* += @sizeOf(T); |
| 2006 | return result; | 2007 | return result; |
| 2007 | } | 2008 | } |
| ... | @@ -2017,11 +2018,12 @@ fn readByteSignedMem(ptr: *[*]const u8) i8 { | ... | @@ -2017,11 +2018,12 @@ fn readByteSignedMem(ptr: *[*]const u8) i8 { |
| 2017 | } | 2018 | } |
| 2018 | 2019 | ||
| 2019 | fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 { | 2020 | fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 { |
| 2020 | const first_32_bits = mem.readIntLE(u32, ptr.*[0..4]); | 2021 | // TODO this code can be improved with https://github.com/ziglang/zig/issues/863 |
| 2022 | const first_32_bits = mem.readIntSliceLittle(u32, ptr.*[0..4]); | ||
| 2021 | is_64.* = (first_32_bits == 0xffffffff); | 2023 | is_64.* = (first_32_bits == 0xffffffff); |
| 2022 | if (is_64.*) { | 2024 | if (is_64.*) { |
| 2023 | ptr.* += 4; | 2025 | ptr.* += 4; |
| 2024 | const result = mem.readIntLE(u64, ptr.*[0..8]); | 2026 | const result = mem.readIntSliceLittle(u64, ptr.*[0..8]); |
| 2025 | ptr.* += 8; | 2027 | ptr.* += 8; |
| 2026 | return result; | 2028 | return result; |
| 2027 | } else { | 2029 | } else { |
| ... | @@ -2084,10 +2086,10 @@ fn readILeb128Mem(ptr: *[*]const u8) !i64 { | ... | @@ -2084,10 +2086,10 @@ fn readILeb128Mem(ptr: *[*]const u8) !i64 { |
| 2084 | } | 2086 | } |
| 2085 | 2087 | ||
| 2086 | fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool) !u64 { | 2088 | fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool) !u64 { |
| 2087 | const first_32_bits = try in_stream.readIntLe(u32); | 2089 | const first_32_bits = try in_stream.readIntLittle(u32); |
| 2088 | is_64.* = (first_32_bits == 0xffffffff); | 2090 | is_64.* = (first_32_bits == 0xffffffff); |
| 2089 | if (is_64.*) { | 2091 | if (is_64.*) { |
| 2090 | return in_stream.readIntLe(u64); | 2092 | return in_stream.readIntLittle(u64); |
| 2091 | } else { | 2093 | } else { |
| 2092 | if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo; | 2094 | if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo; |
| 2093 | return u64(first_32_bits); | 2095 | return u64(first_32_bits); |
std/elf.zig+35-35| ... | @@ -412,7 +412,7 @@ pub const Elf = struct { | ... | @@ -412,7 +412,7 @@ pub const Elf = struct { |
| 412 | // skip over padding | 412 | // skip over padding |
| 413 | try seekable_stream.seekForward(9); | 413 | try seekable_stream.seekForward(9); |
| 414 | 414 | ||
| 415 | elf.file_type = switch (try in.readInt(elf.endian, u16)) { | 415 | elf.file_type = switch (try in.readInt(u16, elf.endian)) { |
| 416 | 1 => FileType.Relocatable, | 416 | 1 => FileType.Relocatable, |
| 417 | 2 => FileType.Executable, | 417 | 2 => FileType.Executable, |
| 418 | 3 => FileType.Shared, | 418 | 3 => FileType.Shared, |
| ... | @@ -420,7 +420,7 @@ pub const Elf = struct { | ... | @@ -420,7 +420,7 @@ pub const Elf = struct { |
| 420 | else => return error.InvalidFormat, | 420 | else => return error.InvalidFormat, |
| 421 | }; | 421 | }; |
| 422 | 422 | ||
| 423 | elf.arch = switch (try in.readInt(elf.endian, u16)) { | 423 | elf.arch = switch (try in.readInt(u16, elf.endian)) { |
| 424 | 0x02 => Arch.Sparc, | 424 | 0x02 => Arch.Sparc, |
| 425 | 0x03 => Arch.x86, | 425 | 0x03 => Arch.x86, |
| 426 | 0x08 => Arch.Mips, | 426 | 0x08 => Arch.Mips, |
| ... | @@ -433,32 +433,32 @@ pub const Elf = struct { | ... | @@ -433,32 +433,32 @@ pub const Elf = struct { |
| 433 | else => return error.InvalidFormat, | 433 | else => return error.InvalidFormat, |
| 434 | }; | 434 | }; |
| 435 | 435 | ||
| 436 | const elf_version = try in.readInt(elf.endian, u32); | 436 | const elf_version = try in.readInt(u32, elf.endian); |
| 437 | if (elf_version != 1) return error.InvalidFormat; | 437 | if (elf_version != 1) return error.InvalidFormat; |
| 438 | 438 | ||
| 439 | if (elf.is_64) { | 439 | if (elf.is_64) { |
| 440 | elf.entry_addr = try in.readInt(elf.endian, u64); | 440 | elf.entry_addr = try in.readInt(u64, elf.endian); |
| 441 | elf.program_header_offset = try in.readInt(elf.endian, u64); | 441 | elf.program_header_offset = try in.readInt(u64, elf.endian); |
| 442 | elf.section_header_offset = try in.readInt(elf.endian, u64); | 442 | elf.section_header_offset = try in.readInt(u64, elf.endian); |
| 443 | } else { | 443 | } else { |
| 444 | elf.entry_addr = u64(try in.readInt(elf.endian, u32)); | 444 | elf.entry_addr = u64(try in.readInt(u32, elf.endian)); |
| 445 | elf.program_header_offset = u64(try in.readInt(elf.endian, u32)); | 445 | elf.program_header_offset = u64(try in.readInt(u32, elf.endian)); |
| 446 | elf.section_header_offset = u64(try in.readInt(elf.endian, u32)); | 446 | elf.section_header_offset = u64(try in.readInt(u32, elf.endian)); |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | // skip over flags | 449 | // skip over flags |
| 450 | try seekable_stream.seekForward(4); | 450 | try seekable_stream.seekForward(4); |
| 451 | 451 | ||
| 452 | const header_size = try in.readInt(elf.endian, u16); | 452 | const header_size = try in.readInt(u16, elf.endian); |
| 453 | if ((elf.is_64 and header_size != 64) or (!elf.is_64 and header_size != 52)) { | 453 | if ((elf.is_64 and header_size != 64) or (!elf.is_64 and header_size != 52)) { |
| 454 | return error.InvalidFormat; | 454 | return error.InvalidFormat; |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | const ph_entry_size = try in.readInt(elf.endian, u16); | 457 | const ph_entry_size = try in.readInt(u16, elf.endian); |
| 458 | const ph_entry_count = try in.readInt(elf.endian, u16); | 458 | const ph_entry_count = try in.readInt(u16, elf.endian); |
| 459 | const sh_entry_size = try in.readInt(elf.endian, u16); | 459 | const sh_entry_size = try in.readInt(u16, elf.endian); |
| 460 | const sh_entry_count = try in.readInt(elf.endian, u16); | 460 | const sh_entry_count = try in.readInt(u16, elf.endian); |
| 461 | elf.string_section_index = u64(try in.readInt(elf.endian, u16)); | 461 | elf.string_section_index = u64(try in.readInt(u16, elf.endian)); |
| 462 | 462 | ||
| 463 | if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat; | 463 | if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat; |
| 464 | 464 | ||
| ... | @@ -481,32 +481,32 @@ pub const Elf = struct { | ... | @@ -481,32 +481,32 @@ pub const Elf = struct { |
| 481 | if (sh_entry_size != 64) return error.InvalidFormat; | 481 | if (sh_entry_size != 64) return error.InvalidFormat; |
| 482 | 482 | ||
| 483 | for (elf.section_headers) |*elf_section| { | 483 | for (elf.section_headers) |*elf_section| { |
| 484 | elf_section.name = try in.readInt(elf.endian, u32); | 484 | elf_section.name = try in.readInt(u32, elf.endian); |
| 485 | elf_section.sh_type = try in.readInt(elf.endian, u32); | 485 | elf_section.sh_type = try in.readInt(u32, elf.endian); |
| 486 | elf_section.flags = try in.readInt(elf.endian, u64); | 486 | elf_section.flags = try in.readInt(u64, elf.endian); |
| 487 | elf_section.addr = try in.readInt(elf.endian, u64); | 487 | elf_section.addr = try in.readInt(u64, elf.endian); |
| 488 | elf_section.offset = try in.readInt(elf.endian, u64); | 488 | elf_section.offset = try in.readInt(u64, elf.endian); |
| 489 | elf_section.size = try in.readInt(elf.endian, u64); | 489 | elf_section.size = try in.readInt(u64, elf.endian); |
| 490 | elf_section.link = try in.readInt(elf.endian, u32); | 490 | elf_section.link = try in.readInt(u32, elf.endian); |
| 491 | elf_section.info = try in.readInt(elf.endian, u32); | 491 | elf_section.info = try in.readInt(u32, elf.endian); |
| 492 | elf_section.addr_align = try in.readInt(elf.endian, u64); | 492 | elf_section.addr_align = try in.readInt(u64, elf.endian); |
| 493 | elf_section.ent_size = try in.readInt(elf.endian, u64); | 493 | elf_section.ent_size = try in.readInt(u64, elf.endian); |
| 494 | } | 494 | } |
| 495 | } else { | 495 | } else { |
| 496 | if (sh_entry_size != 40) return error.InvalidFormat; | 496 | if (sh_entry_size != 40) return error.InvalidFormat; |
| 497 | 497 | ||
| 498 | for (elf.section_headers) |*elf_section| { | 498 | for (elf.section_headers) |*elf_section| { |
| 499 | // TODO (multiple occurrences) allow implicit cast from %u32 -> %u64 ? | 499 | // TODO (multiple occurrences) allow implicit cast from %u32 -> %u64 ? |
| 500 | elf_section.name = try in.readInt(elf.endian, u32); | 500 | elf_section.name = try in.readInt(u32, elf.endian); |
| 501 | elf_section.sh_type = try in.readInt(elf.endian, u32); | 501 | elf_section.sh_type = try in.readInt(u32, elf.endian); |
| 502 | elf_section.flags = u64(try in.readInt(elf.endian, u32)); | 502 | elf_section.flags = u64(try in.readInt(u32, elf.endian)); |
| 503 | elf_section.addr = u64(try in.readInt(elf.endian, u32)); | 503 | elf_section.addr = u64(try in.readInt(u32, elf.endian)); |
| 504 | elf_section.offset = u64(try in.readInt(elf.endian, u32)); | 504 | elf_section.offset = u64(try in.readInt(u32, elf.endian)); |
| 505 | elf_section.size = u64(try in.readInt(elf.endian, u32)); | 505 | elf_section.size = u64(try in.readInt(u32, elf.endian)); |
| 506 | elf_section.link = try in.readInt(elf.endian, u32); | 506 | elf_section.link = try in.readInt(u32, elf.endian); |
| 507 | elf_section.info = try in.readInt(elf.endian, u32); | 507 | elf_section.info = try in.readInt(u32, elf.endian); |
| 508 | elf_section.addr_align = u64(try in.readInt(elf.endian, u32)); | 508 | elf_section.addr_align = u64(try in.readInt(u32, elf.endian)); |
| 509 | elf_section.ent_size = u64(try in.readInt(elf.endian, u32)); | 509 | elf_section.ent_size = u64(try in.readInt(u32, elf.endian)); |
| 510 | } | 510 | } |
| 511 | } | 511 | } |
| 512 | 512 |
std/event/io.zig+9-5| ... | @@ -39,18 +39,22 @@ pub fn InStream(comptime ReadError: type) type { | ... | @@ -39,18 +39,22 @@ pub fn InStream(comptime ReadError: type) type { |
| 39 | if (amt_read < buf.len) return error.EndOfStream; | 39 | if (amt_read < buf.len) return error.EndOfStream; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | pub async fn readIntLe(self: *Self, comptime T: type) !T { | 42 | pub async fn readIntLittle(self: *Self, comptime T: type) !T { |
| 43 | return await (async self.readInt(builtin.Endian.Little, T) catch unreachable); | 43 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 44 | try await (async self.readNoEof(bytes[0..]) catch unreachable); | ||
| 45 | return mem.readIntLittle(T, &bytes); | ||
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | pub async fn readIntBe(self: *Self, comptime T: type) !T { | 48 | pub async fn readIntBe(self: *Self, comptime T: type) !T { |
| 47 | return await (async self.readInt(builtin.Endian.Big, T) catch unreachable); | 49 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 50 | try await (async self.readNoEof(bytes[0..]) catch unreachable); | ||
| 51 | return mem.readIntBig(T, &bytes); | ||
| 48 | } | 52 | } |
| 49 | 53 | ||
| 50 | pub async fn readInt(self: *Self, endian: builtin.Endian, comptime T: type) !T { | 54 | pub async fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T { |
| 51 | var bytes: [@sizeOf(T)]u8 = undefined; | 55 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 52 | try await (async self.readNoEof(bytes[0..]) catch unreachable); | 56 | try await (async self.readNoEof(bytes[0..]) catch unreachable); |
| 53 | return mem.readInt(bytes, T, endian); | 57 | return mem.readInt(T, &bytes, endian); |
| 54 | } | 58 | } |
| 55 | 59 | ||
| 56 | pub async fn readStruct(self: *Self, comptime T: type) !T { | 60 | pub async fn readStruct(self: *Self, comptime T: type) !T { |
std/hash/siphash.zig+7-7| ... | @@ -42,8 +42,8 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) | ... | @@ -42,8 +42,8 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) |
| 42 | pub fn init(key: []const u8) Self { | 42 | pub fn init(key: []const u8) Self { |
| 43 | debug.assert(key.len >= 16); | 43 | debug.assert(key.len >= 16); |
| 44 | 44 | ||
| 45 | const k0 = mem.readInt(key[0..8], u64, Endian.Little); | 45 | const k0 = mem.readIntSliceLittle(u64, key[0..8]); |
| 46 | const k1 = mem.readInt(key[8..16], u64, Endian.Little); | 46 | const k1 = mem.readIntSliceLittle(u64, key[8..16]); |
| 47 | 47 | ||
| 48 | var d = Self{ | 48 | var d = Self{ |
| 49 | .v0 = k0 ^ 0x736f6d6570736575, | 49 | .v0 = k0 ^ 0x736f6d6570736575, |
| ... | @@ -121,7 +121,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) | ... | @@ -121,7 +121,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) |
| 121 | fn round(d: *Self, b: []const u8) void { | 121 | fn round(d: *Self, b: []const u8) void { |
| 122 | debug.assert(b.len == 8); | 122 | debug.assert(b.len == 8); |
| 123 | 123 | ||
| 124 | const m = mem.readInt(b[0..], u64, Endian.Little); | 124 | const m = mem.readIntSliceLittle(u64, b[0..]); |
| 125 | d.v3 ^= m; | 125 | d.v3 ^= m; |
| 126 | 126 | ||
| 127 | comptime var i: usize = 0; | 127 | comptime var i: usize = 0; |
| ... | @@ -162,7 +162,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) | ... | @@ -162,7 +162,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) |
| 162 | const test_key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"; | 162 | const test_key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"; |
| 163 | 163 | ||
| 164 | test "siphash64-2-4 sanity" { | 164 | test "siphash64-2-4 sanity" { |
| 165 | const vectors = [][]const u8{ | 165 | const vectors = [][8]u8{ |
| 166 | "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72", // "" | 166 | "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72", // "" |
| 167 | "\xfd\x67\xdc\x93\xc5\x39\xf8\x74", // "\x00" | 167 | "\xfd\x67\xdc\x93\xc5\x39\xf8\x74", // "\x00" |
| 168 | "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d", // "\x00\x01" ... etc | 168 | "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d", // "\x00\x01" ... etc |
| ... | @@ -235,13 +235,13 @@ test "siphash64-2-4 sanity" { | ... | @@ -235,13 +235,13 @@ test "siphash64-2-4 sanity" { |
| 235 | for (vectors) |vector, i| { | 235 | for (vectors) |vector, i| { |
| 236 | buffer[i] = @intCast(u8, i); | 236 | buffer[i] = @intCast(u8, i); |
| 237 | 237 | ||
| 238 | const expected = mem.readInt(vector, u64, Endian.Little); | 238 | const expected = mem.readIntLittle(u64, &vector); |
| 239 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); | 239 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); |
| 240 | } | 240 | } |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | test "siphash128-2-4 sanity" { | 243 | test "siphash128-2-4 sanity" { |
| 244 | const vectors = [][]const u8{ | 244 | const vectors = [][16]u8{ |
| 245 | "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93", | 245 | "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93", |
| 246 | "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45", | 246 | "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45", |
| 247 | "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4", | 247 | "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4", |
| ... | @@ -314,7 +314,7 @@ test "siphash128-2-4 sanity" { | ... | @@ -314,7 +314,7 @@ test "siphash128-2-4 sanity" { |
| 314 | for (vectors) |vector, i| { | 314 | for (vectors) |vector, i| { |
| 315 | buffer[i] = @intCast(u8, i); | 315 | buffer[i] = @intCast(u8, i); |
| 316 | 316 | ||
| 317 | const expected = mem.readInt(vector, u128, Endian.Little); | 317 | const expected = mem.readIntLittle(u128, &vector); |
| 318 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); | 318 | debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); |
| 319 | } | 319 | } |
| 320 | } | 320 | } |
std/heap.zig+1-1| ... | @@ -66,7 +66,7 @@ pub const DirectAllocator = struct { | ... | @@ -66,7 +66,7 @@ pub const DirectAllocator = struct { |
| 66 | } | 66 | } |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | fn alloc(allocator: *Allocator, n: usize, alignment: u29) ![]u8 { | 69 | fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 { |
| 70 | const self = @fieldParentPtr(DirectAllocator, "allocator", allocator); | 70 | const self = @fieldParentPtr(DirectAllocator, "allocator", allocator); |
| 71 | 71 | ||
| 72 | switch (builtin.os) { | 72 | switch (builtin.os) { |
std/io.zig+38-22| ... | @@ -152,35 +152,42 @@ pub fn InStream(comptime ReadError: type) type { | ... | @@ -152,35 +152,42 @@ pub fn InStream(comptime ReadError: type) type { |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | /// Reads a native-endian integer | 154 | /// Reads a native-endian integer |
| 155 | pub fn readIntNe(self: *Self, comptime T: type) !T { | 155 | pub fn readIntNative(self: *Self, comptime T: type) !T { |
| 156 | return self.readInt(builtin.endian, T); | 156 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 157 | try self.readNoEof(bytes[0..]); | ||
| 158 | return mem.readIntSliceNative(T, bytes); | ||
| 157 | } | 159 | } |
| 158 | 160 | ||
| 159 | pub fn readIntLe(self: *Self, comptime T: type) !T { | 161 | /// Reads a foreign-endian integer |
| 162 | pub fn readIntForeign(self: *Self, comptime T: type) !T { | ||
| 160 | var bytes: [@sizeOf(T)]u8 = undefined; | 163 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 161 | try self.readNoEof(bytes[0..]); | 164 | try self.readNoEof(bytes[0..]); |
| 162 | return mem.readIntLE(T, bytes); | 165 | return mem.readIntSliceForeign(T, bytes); |
| 163 | } | 166 | } |
| 164 | 167 | ||
| 165 | pub fn readIntBe(self: *Self, comptime T: type) !T { | 168 | pub fn readIntLittle(self: *Self, comptime T: type) !T { |
| 166 | var bytes: [@sizeOf(T)]u8 = undefined; | 169 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 167 | try self.readNoEof(bytes[0..]); | 170 | try self.readNoEof(bytes[0..]); |
| 168 | return mem.readIntBE(T, bytes); | 171 | return mem.readIntSliceLittle(T, bytes); |
| 169 | } | 172 | } |
| 170 | 173 | ||
| 171 | pub fn readInt(self: *Self, endian: builtin.Endian, comptime T: type) !T { | 174 | pub fn readIntBig(self: *Self, comptime T: type) !T { |
| 172 | var bytes: [@sizeOf(T)]u8 = undefined; | 175 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 173 | try self.readNoEof(bytes[0..]); | 176 | try self.readNoEof(bytes[0..]); |
| 174 | return mem.readInt(bytes, T, endian); | 177 | return mem.readIntSliceBig(T, bytes); |
| 175 | } | 178 | } |
| 176 | 179 | ||
| 177 | pub fn readVarInt(self: *Self, endian: builtin.Endian, comptime T: type, size: usize) !T { | 180 | pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T { |
| 181 | var bytes: [@sizeOf(T)]u8 = undefined; | ||
| 182 | try self.readNoEof(bytes[0..]); | ||
| 183 | return mem.readIntSlice(T, bytes, endian); | ||
| 184 | } | ||
| 185 | |||
| 186 | pub fn readVarInt(self: *Self, comptime T: type, endian: builtin.Endian, size: usize) !T { | ||
| 178 | assert(size <= @sizeOf(T)); | 187 | assert(size <= @sizeOf(T)); |
| 179 | assert(size <= 8); | 188 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 180 | var input_buf: [8]u8 = undefined; | 189 | try self.readNoEof(bytes[0..]); |
| 181 | const input_slice = input_buf[0..size]; | 190 | return mem.readIntSlice(T, bytes, endian); |
| 182 | try self.readNoEof(input_slice); | ||
| 183 | return mem.readInt(input_slice, T, endian); | ||
| 184 | } | 191 | } |
| 185 | 192 | ||
| 186 | pub fn skipBytes(self: *Self, num_bytes: usize) !void { | 193 | pub fn skipBytes(self: *Self, num_bytes: usize) !void { |
| ... | @@ -229,25 +236,34 @@ pub fn OutStream(comptime WriteError: type) type { | ... | @@ -229,25 +236,34 @@ pub fn OutStream(comptime WriteError: type) type { |
| 229 | } | 236 | } |
| 230 | 237 | ||
| 231 | /// Write a native-endian integer. | 238 | /// Write a native-endian integer. |
| 232 | pub fn writeIntNe(self: *Self, comptime T: type, value: T) Error!void { | 239 | pub fn writeIntNative(self: *Self, comptime T: type, value: T) Error!void { |
| 233 | return self.writeInt(builtin.endian, T, value); | 240 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 241 | mem.writeIntNative(T, &bytes, value); | ||
| 242 | return self.writeFn(self, bytes); | ||
| 243 | } | ||
| 244 | |||
| 245 | /// Write a foreign-endian integer. | ||
| 246 | pub fn writeIntForeign(self: *Self, comptime T: type, value: T) Error!void { | ||
| 247 | var bytes: [@sizeOf(T)]u8 = undefined; | ||
| 248 | mem.writeIntForeign(T, &bytes, value); | ||
| 249 | return self.writeFn(self, bytes); | ||
| 234 | } | 250 | } |
| 235 | 251 | ||
| 236 | pub fn writeIntLe(self: *Self, comptime T: type, value: T) Error!void { | 252 | pub fn writeIntLittle(self: *Self, comptime T: type, value: T) Error!void { |
| 237 | var bytes: [@sizeOf(T)]u8 = undefined; | 253 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 238 | mem.writeIntLE(T, &bytes, value); | 254 | mem.writeIntLittle(T, &bytes, value); |
| 239 | return self.writeFn(self, bytes); | 255 | return self.writeFn(self, bytes); |
| 240 | } | 256 | } |
| 241 | 257 | ||
| 242 | pub fn writeIntBe(self: *Self, comptime T: type, value: T) Error!void { | 258 | pub fn writeIntBig(self: *Self, comptime T: type, value: T) Error!void { |
| 243 | var bytes: [@sizeOf(T)]u8 = undefined; | 259 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 244 | mem.writeIntBE(T, &bytes, value); | 260 | mem.writeIntBig(T, &bytes, value); |
| 245 | return self.writeFn(self, bytes); | 261 | return self.writeFn(self, bytes); |
| 246 | } | 262 | } |
| 247 | 263 | ||
| 248 | pub fn writeInt(self: *Self, endian: builtin.Endian, comptime T: type, value: T) Error!void { | 264 | pub fn writeInt(self: *Self, comptime T: type, value: T, endian: builtin.Endian) Error!void { |
| 249 | var bytes: [@sizeOf(T)]u8 = undefined; | 265 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 250 | mem.writeInt(bytes[0..], value, endian); | 266 | mem.writeInt(T, &bytes, value, endian); |
| 251 | return self.writeFn(self, bytes); | 267 | return self.writeFn(self, bytes); |
| 252 | } | 268 | } |
| 253 | }; | 269 | }; |
std/mem.zig+263-164| ... | @@ -407,186 +407,250 @@ test "mem.indexOf" { | ... | @@ -407,186 +407,250 @@ test "mem.indexOf" { |
| 407 | assert(lastIndexOfScalar(u8, "boo", 'o').? == 2); | 407 | assert(lastIndexOfScalar(u8, "boo", 'o').? == 2); |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | /// Reads an integer from memory with size equal to bytes.len. | 410 | /// Reads an integer from memory with bit count specified by T. |
| 411 | /// T specifies the return type, which must be large enough to store | 411 | /// The bit count of T must be evenly divisible by 8. |
| 412 | /// the result. | 412 | /// This function cannot fail and cannot cause undefined behavior. |
| 413 | /// See also ::readIntBE or ::readIntLE. | 413 | /// Assumes the endianness of memory is native. This means the function can |
| 414 | pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T { | 414 | /// simply pointer cast memory. |
| 415 | if (T.bit_count == 8) { | 415 | pub fn readIntNative(comptime T: type, bytes: *const [@sizeOf(T)]u8) T { |
| 416 | return bytes[0]; | 416 | comptime assert(T.bit_count % 8 == 0); |
| 417 | } | 417 | return @ptrCast(*align(1) const T, bytes).*; |
| 418 | var result: T = 0; | 418 | } |
| 419 | switch (endian) { | 419 | |
| 420 | builtin.Endian.Big => { | 420 | /// Reads an integer from memory with bit count specified by T. |
| 421 | for (bytes) |b| { | 421 | /// The bit count of T must be evenly divisible by 8. |
| 422 | result = (result << 8) | b; | 422 | /// This function cannot fail and cannot cause undefined behavior. |
| 423 | } | 423 | /// Assumes the endianness of memory is foreign, so it must byte-swap. |
| 424 | }, | 424 | pub fn readIntForeign(comptime T: type, bytes: *const [@sizeOf(T)]u8) T { |
| 425 | builtin.Endian.Little => { | 425 | comptime assert(T.bit_count % 8 == 0); |
| 426 | const ShiftType = math.Log2Int(T); | 426 | return @bswap(T, @ptrCast(*align(1) const T, bytes).*); |
| 427 | for (bytes) |b, index| { | 427 | } |
| 428 | result = result | (T(b) << @intCast(ShiftType, index * 8)); | 428 | |
| 429 | } | 429 | pub const readIntLittle = switch (builtin.endian) { |
| 430 | }, | 430 | builtin.Endian.Little => readIntNative, |
| 431 | } | 431 | builtin.Endian.Big => readIntForeign, |
| 432 | return result; | 432 | }; |
| 433 | } | ||
| 434 | 433 | ||
| 435 | /// Reads a big-endian int of type T from bytes. | 434 | pub const readIntBig = switch (builtin.endian) { |
| 436 | /// bytes.len must be exactly @sizeOf(T). | 435 | builtin.Endian.Little => readIntForeign, |
| 437 | pub fn readIntBE(comptime T: type, bytes: []const u8) T { | 436 | builtin.Endian.Big => readIntNative, |
| 438 | if (T.is_signed) { | 437 | }; |
| 439 | return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes)); | 438 | |
| 440 | } | 439 | /// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0 |
| 441 | assert(bytes.len == @sizeOf(T)); | 440 | /// and ignores extra bytes. |
| 442 | if (T == u8) return bytes[0]; | 441 | /// Note that @sizeOf(u24) is 3. |
| 443 | var result: T = 0; | 442 | /// The bit count of T must be evenly divisible by 8. |
| 444 | { | 443 | /// Assumes the endianness of memory is native. This means the function can |
| 445 | comptime var i = 0; | 444 | /// simply pointer cast memory. |
| 446 | inline while (i < @sizeOf(T)) : (i += 1) { | 445 | pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T { |
| 447 | result = (result << 8) | T(bytes[i]); | 446 | assert(@sizeOf(u24) == 3); |
| 448 | } | 447 | assert(bytes.len >= @sizeOf(T)); |
| 448 | // TODO https://github.com/ziglang/zig/issues/863 | ||
| 449 | return readIntNative(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr)); | ||
| 450 | } | ||
| 451 | |||
| 452 | /// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0 | ||
| 453 | /// and ignores extra bytes. | ||
| 454 | /// Note that @sizeOf(u24) is 3. | ||
| 455 | /// The bit count of T must be evenly divisible by 8. | ||
| 456 | /// Assumes the endianness of memory is foreign, so it must byte-swap. | ||
| 457 | pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T { | ||
| 458 | assert(@sizeOf(u24) == 3); | ||
| 459 | assert(bytes.len >= @sizeOf(T)); | ||
| 460 | // TODO https://github.com/ziglang/zig/issues/863 | ||
| 461 | return readIntForeign(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr)); | ||
| 462 | } | ||
| 463 | |||
| 464 | pub const readIntSliceLittle = switch (builtin.endian) { | ||
| 465 | builtin.Endian.Little => readIntSliceNative, | ||
| 466 | builtin.Endian.Big => readIntSliceForeign, | ||
| 467 | }; | ||
| 468 | |||
| 469 | pub const readIntSliceBig = switch (builtin.endian) { | ||
| 470 | builtin.Endian.Little => readIntSliceForeign, | ||
| 471 | builtin.Endian.Big => readIntSliceNative, | ||
| 472 | }; | ||
| 473 | |||
| 474 | /// Reads an integer from memory with bit count specified by T. | ||
| 475 | /// The bit count of T must be evenly divisible by 8. | ||
| 476 | /// This function cannot fail and cannot cause undefined behavior. | ||
| 477 | pub fn readInt(comptime T: type, bytes: *const [@sizeOf(T)]u8, endian: builtin.Endian) T { | ||
| 478 | if (endian == builtin.endian) { | ||
| 479 | return readIntNative(T, bytes); | ||
| 480 | } else { | ||
| 481 | return readIntForeign(T, bytes); | ||
| 449 | } | 482 | } |
| 450 | return result; | ||
| 451 | } | 483 | } |
| 452 | 484 | ||
| 453 | /// Reads a little-endian int of type T from bytes. | 485 | /// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0 |
| 454 | /// bytes.len must be exactly @sizeOf(T). | 486 | /// and ignores extra bytes. |
| 455 | pub fn readIntLE(comptime T: type, bytes: []const u8) T { | 487 | /// Note that @sizeOf(u24) is 3. |
| 456 | if (T.is_signed) { | 488 | /// The bit count of T must be evenly divisible by 8. |
| 457 | return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes)); | 489 | pub fn readIntSlice(comptime T: type, bytes: []const u8, endian: builtin.Endian) T { |
| 458 | } | 490 | assert(@sizeOf(u24) == 3); |
| 459 | assert(bytes.len == @sizeOf(T)); | 491 | assert(bytes.len >= @sizeOf(T)); |
| 460 | if (T == u8) return bytes[0]; | 492 | // TODO https://github.com/ziglang/zig/issues/863 |
| 461 | var result: T = 0; | 493 | return readInt(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr), endian); |
| 462 | { | ||
| 463 | comptime var i = 0; | ||
| 464 | inline while (i < @sizeOf(T)) : (i += 1) { | ||
| 465 | result |= T(bytes[i]) << i * 8; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | return result; | ||
| 469 | } | 494 | } |
| 470 | 495 | ||
| 471 | test "readIntBE/LE" { | 496 | test "readIntBig and readIntLittle" { |
| 472 | assert(readIntBE(u0, []u8{}) == 0x0); | 497 | assert(readIntSliceBig(u0, []u8{}) == 0x0); |
| 473 | assert(readIntLE(u0, []u8{}) == 0x0); | 498 | assert(readIntSliceLittle(u0, []u8{}) == 0x0); |
| 474 | 499 | ||
| 475 | assert(readIntBE(u8, []u8{0x32}) == 0x32); | 500 | assert(readIntSliceBig(u8, []u8{0x32}) == 0x32); |
| 476 | assert(readIntLE(u8, []u8{0x12}) == 0x12); | 501 | assert(readIntSliceLittle(u8, []u8{0x12}) == 0x12); |
| 477 | 502 | ||
| 478 | assert(readIntBE(u16, []u8{ 0x12, 0x34 }) == 0x1234); | 503 | assert(readIntSliceBig(u16, []u8{ 0x12, 0x34 }) == 0x1234); |
| 479 | assert(readIntLE(u16, []u8{ 0x12, 0x34 }) == 0x3412); | 504 | assert(readIntSliceLittle(u16, []u8{ 0x12, 0x34 }) == 0x3412); |
| 480 | 505 | ||
| 481 | assert(readIntBE(u72, []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024); | 506 | assert(readIntSliceBig(u72, []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024); |
| 482 | assert(readIntLE(u72, []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec); | 507 | assert(readIntSliceLittle(u72, []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec); |
| 483 | 508 | ||
| 484 | assert(readIntBE(i8, []u8{0xff}) == -1); | 509 | assert(readIntSliceBig(i8, []u8{0xff}) == -1); |
| 485 | assert(readIntLE(i8, []u8{0xfe}) == -2); | 510 | assert(readIntSliceLittle(i8, []u8{0xfe}) == -2); |
| 486 | 511 | ||
| 487 | assert(readIntBE(i16, []u8{ 0xff, 0xfd }) == -3); | 512 | assert(readIntSliceBig(i16, []u8{ 0xff, 0xfd }) == -3); |
| 488 | assert(readIntLE(i16, []u8{ 0xfc, 0xff }) == -4); | 513 | assert(readIntSliceLittle(i16, []u8{ 0xfc, 0xff }) == -4); |
| 489 | } | 514 | } |
| 490 | 515 | ||
| 491 | /// Writes an integer to memory with size equal to bytes.len. Pads with zeroes | 516 | /// Writes an integer to memory, storing it in twos-complement. |
| 492 | /// to fill the entire buffer provided. | 517 | /// This function always succeeds, has defined behavior for all inputs, and |
| 493 | /// value must be an integer. | 518 | /// accepts any integer bit width. |
| 494 | pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void { | 519 | /// This function stores in native endian, which means it is implemented as a simple |
| 495 | const uint = @IntType(false, @typeOf(value).bit_count); | 520 | /// memory store. |
| 496 | var bits = @truncate(uint, value); | 521 | pub fn writeIntNative(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void { |
| 497 | switch (endian) { | 522 | @ptrCast(*align(1) T, buf).* = value; |
| 498 | builtin.Endian.Big => { | 523 | } |
| 499 | var index: usize = buf.len; | ||
| 500 | while (index != 0) { | ||
| 501 | index -= 1; | ||
| 502 | 524 | ||
| 503 | buf[index] = @truncate(u8, bits); | 525 | /// Writes an integer to memory, storing it in twos-complement. |
| 504 | bits >>= 8; | 526 | /// This function always succeeds, has defined behavior for all inputs, but |
| 505 | } | 527 | /// the integer bit width must be divisible by 8. |
| 506 | }, | 528 | /// This function stores in foreign endian, which means it does a @bswap first. |
| 507 | builtin.Endian.Little => { | 529 | pub fn writeIntForeign(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void { |
| 508 | for (buf) |*b| { | 530 | @ptrCast(*align(1) T, buf).* = @bswap(T, value); |
| 509 | b.* = @truncate(u8, bits); | 531 | } |
| 510 | bits >>= 8; | 532 | |
| 511 | } | 533 | pub const writeIntLittle = switch (builtin.endian) { |
| 512 | }, | 534 | builtin.Endian.Little => writeIntNative, |
| 535 | builtin.Endian.Big => writeIntForeign, | ||
| 536 | }; | ||
| 537 | |||
| 538 | pub const writeIntBig = switch (builtin.endian) { | ||
| 539 | builtin.Endian.Little => writeIntForeign, | ||
| 540 | builtin.Endian.Big => writeIntNative, | ||
| 541 | }; | ||
| 542 | |||
| 543 | /// Writes an integer to memory, storing it in twos-complement. | ||
| 544 | /// This function always succeeds, has defined behavior for all inputs, but | ||
| 545 | /// the integer bit width must be divisible by 8. | ||
| 546 | pub fn writeInt(comptime T: type, buffer: *[@sizeOf(T)]u8, value: T, endian: builtin.Endian) void { | ||
| 547 | comptime assert(T.bit_count % 8 == 0); | ||
| 548 | if (endian == builtin.endian) { | ||
| 549 | return writeIntNative(T, buffer, value); | ||
| 550 | } else { | ||
| 551 | return writeIntForeign(T, buffer, value); | ||
| 513 | } | 552 | } |
| 514 | assert(bits == 0); | ||
| 515 | } | 553 | } |
| 516 | 554 | ||
| 517 | pub fn writeIntBE(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void { | 555 | /// Writes a twos-complement little-endian integer to memory. |
| 518 | assert(T.bit_count % 8 == 0); | 556 | /// Asserts that buf.len >= @sizeOf(T). Note that @sizeOf(u24) is 3. |
| 557 | /// The bit count of T must be divisible by 8. | ||
| 558 | /// Any extra bytes in buffer after writing the integer are set to zero. To | ||
| 559 | /// avoid the branch to check for extra buffer bytes, use writeIntLittle | ||
| 560 | /// instead. | ||
| 561 | pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void { | ||
| 562 | comptime assert(@sizeOf(u24) == 3); | ||
| 563 | comptime assert(T.bit_count % 8 == 0); | ||
| 564 | assert(buffer.len >= @sizeOf(T)); | ||
| 565 | |||
| 566 | // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough | ||
| 519 | const uint = @IntType(false, T.bit_count); | 567 | const uint = @IntType(false, T.bit_count); |
| 520 | if (uint == u0) { | 568 | var bits = @truncate(uint, value); |
| 521 | return; | 569 | for (buffer) |*b| { |
| 522 | } | 570 | b.* = @truncate(u8, bits); |
| 523 | var bits = @bitCast(uint, value); | 571 | bits >>= 8; |
| 524 | if (uint == u8) { | ||
| 525 | buf[0] = bits; | ||
| 526 | return; | ||
| 527 | } | 572 | } |
| 528 | var index: usize = buf.len; | 573 | } |
| 574 | |||
| 575 | /// Writes a twos-complement big-endian integer to memory. | ||
| 576 | /// Asserts that buffer.len >= @sizeOf(T). Note that @sizeOf(u24) is 3. | ||
| 577 | /// The bit count of T must be divisible by 8. | ||
| 578 | /// Any extra bytes in buffer before writing the integer are set to zero. To | ||
| 579 | /// avoid the branch to check for extra buffer bytes, use writeIntBig instead. | ||
| 580 | pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void { | ||
| 581 | comptime assert(@sizeOf(u24) == 3); | ||
| 582 | comptime assert(T.bit_count % 8 == 0); | ||
| 583 | assert(buffer.len >= @sizeOf(T)); | ||
| 584 | |||
| 585 | // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough | ||
| 586 | const uint = @IntType(false, T.bit_count); | ||
| 587 | var bits = @truncate(uint, value); | ||
| 588 | var index: usize = buffer.len; | ||
| 529 | while (index != 0) { | 589 | while (index != 0) { |
| 530 | index -= 1; | 590 | index -= 1; |
| 531 | 591 | buffer[index] = @truncate(u8, bits); | |
| 532 | buf[index] = @truncate(u8, bits); | ||
| 533 | bits >>= 8; | 592 | bits >>= 8; |
| 534 | } | 593 | } |
| 535 | assert(bits == 0); | ||
| 536 | } | 594 | } |
| 537 | 595 | ||
| 538 | pub fn writeIntLE(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void { | 596 | pub const writeIntSliceNative = switch (builtin.endian) { |
| 539 | assert(T.bit_count % 8 == 0); | 597 | builtin.Endian.Little => writeIntSliceLittle, |
| 540 | const uint = @IntType(false, T.bit_count); | 598 | builtin.Endian.Big => writeIntSliceBig, |
| 541 | if (uint == u0) { | 599 | }; |
| 542 | return; | 600 | |
| 543 | } | 601 | pub const writeIntSliceForeign = switch (builtin.endian) { |
| 544 | var bits = @bitCast(uint, value); | 602 | builtin.Endian.Little => writeIntSliceBig, |
| 545 | if (uint == u8) { | 603 | builtin.Endian.Big => writeIntSliceLittle, |
| 546 | buf[0] = bits; | 604 | }; |
| 547 | return; | 605 | |
| 548 | } | 606 | /// Writes a twos-complement integer to memory, with the specified endianness. |
| 549 | for (buf) |*b| { | 607 | /// Asserts that buf.len >= @sizeOf(T). Note that @sizeOf(u24) is 3. |
| 550 | b.* = @truncate(u8, bits); | 608 | /// The bit count of T must be evenly divisible by 8. |
| 551 | bits >>= 8; | 609 | /// Any extra bytes in buffer not part of the integer are set to zero, with |
| 610 | /// respect to endianness. To avoid the branch to check for extra buffer bytes, | ||
| 611 | /// use writeInt instead. | ||
| 612 | pub fn writeIntSlice(comptime T: type, buffer: []u8, value: T, endian: builtin.Endian) void { | ||
| 613 | comptime assert(T.bit_count % 8 == 0); | ||
| 614 | switch (endian) { | ||
| 615 | builtin.Endian.Little => return writeIntSliceLittle(T, buffer, value), | ||
| 616 | builtin.Endian.Big => return writeIntSliceBig(T, buffer, value), | ||
| 552 | } | 617 | } |
| 553 | assert(bits == 0); | ||
| 554 | } | 618 | } |
| 555 | 619 | ||
| 556 | test "writeIntBE/LE" { | 620 | test "writeIntBig and writeIntLittle" { |
| 557 | var buf0: [0]u8 = undefined; | 621 | var buf0: [0]u8 = undefined; |
| 558 | var buf1: [1]u8 = undefined; | 622 | var buf1: [1]u8 = undefined; |
| 559 | var buf2: [2]u8 = undefined; | 623 | var buf2: [2]u8 = undefined; |
| 560 | var buf9: [9]u8 = undefined; | 624 | var buf9: [9]u8 = undefined; |
| 561 | 625 | ||
| 562 | writeIntBE(u0, &buf0, 0x0); | 626 | writeIntBig(u0, &buf0, 0x0); |
| 563 | assert(eql_slice_u8(buf0[0..], []u8{})); | 627 | assert(eql_slice_u8(buf0[0..], []u8{})); |
| 564 | writeIntLE(u0, &buf0, 0x0); | 628 | writeIntLittle(u0, &buf0, 0x0); |
| 565 | assert(eql_slice_u8(buf0[0..], []u8{})); | 629 | assert(eql_slice_u8(buf0[0..], []u8{})); |
| 566 | 630 | ||
| 567 | writeIntBE(u8, &buf1, 0x12); | 631 | writeIntBig(u8, &buf1, 0x12); |
| 568 | assert(eql_slice_u8(buf1[0..], []u8{0x12})); | 632 | assert(eql_slice_u8(buf1[0..], []u8{0x12})); |
| 569 | writeIntLE(u8, &buf1, 0x34); | 633 | writeIntLittle(u8, &buf1, 0x34); |
| 570 | assert(eql_slice_u8(buf1[0..], []u8{0x34})); | 634 | assert(eql_slice_u8(buf1[0..], []u8{0x34})); |
| 571 | 635 | ||
| 572 | writeIntBE(u16, &buf2, 0x1234); | 636 | writeIntBig(u16, &buf2, 0x1234); |
| 573 | assert(eql_slice_u8(buf2[0..], []u8{ 0x12, 0x34 })); | 637 | assert(eql_slice_u8(buf2[0..], []u8{ 0x12, 0x34 })); |
| 574 | writeIntLE(u16, &buf2, 0x5678); | 638 | writeIntLittle(u16, &buf2, 0x5678); |
| 575 | assert(eql_slice_u8(buf2[0..], []u8{ 0x78, 0x56 })); | 639 | assert(eql_slice_u8(buf2[0..], []u8{ 0x78, 0x56 })); |
| 576 | 640 | ||
| 577 | writeIntBE(u72, &buf9, 0x123456789abcdef024); | 641 | writeIntBig(u72, &buf9, 0x123456789abcdef024); |
| 578 | assert(eql_slice_u8(buf9[0..], []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 })); | 642 | assert(eql_slice_u8(buf9[0..], []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 })); |
| 579 | writeIntLE(u72, &buf9, 0xfedcba9876543210ec); | 643 | writeIntLittle(u72, &buf9, 0xfedcba9876543210ec); |
| 580 | assert(eql_slice_u8(buf9[0..], []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe })); | 644 | assert(eql_slice_u8(buf9[0..], []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe })); |
| 581 | 645 | ||
| 582 | writeIntBE(i8, &buf1, -1); | 646 | writeIntBig(i8, &buf1, -1); |
| 583 | assert(eql_slice_u8(buf1[0..], []u8{0xff})); | 647 | assert(eql_slice_u8(buf1[0..], []u8{0xff})); |
| 584 | writeIntLE(i8, &buf1, -2); | 648 | writeIntLittle(i8, &buf1, -2); |
| 585 | assert(eql_slice_u8(buf1[0..], []u8{0xfe})); | 649 | assert(eql_slice_u8(buf1[0..], []u8{0xfe})); |
| 586 | 650 | ||
| 587 | writeIntBE(i16, &buf2, -3); | 651 | writeIntBig(i16, &buf2, -3); |
| 588 | assert(eql_slice_u8(buf2[0..], []u8{ 0xff, 0xfd })); | 652 | assert(eql_slice_u8(buf2[0..], []u8{ 0xff, 0xfd })); |
| 589 | writeIntLE(i16, &buf2, -4); | 653 | writeIntLittle(i16, &buf2, -4); |
| 590 | assert(eql_slice_u8(buf2[0..], []u8{ 0xfc, 0xff })); | 654 | assert(eql_slice_u8(buf2[0..], []u8{ 0xfc, 0xff })); |
| 591 | } | 655 | } |
| 592 | 656 | ||
| ... | @@ -735,12 +799,12 @@ fn testReadIntImpl() void { | ... | @@ -735,12 +799,12 @@ fn testReadIntImpl() void { |
| 735 | 0x56, | 799 | 0x56, |
| 736 | 0x78, | 800 | 0x78, |
| 737 | }; | 801 | }; |
| 738 | assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678); | 802 | assert(readInt(u32, &bytes, builtin.Endian.Big) == 0x12345678); |
| 739 | assert(readIntBE(u32, bytes) == 0x12345678); | 803 | assert(readIntBig(u32, &bytes) == 0x12345678); |
| 740 | assert(readIntBE(i32, bytes) == 0x12345678); | 804 | assert(readIntBig(i32, &bytes) == 0x12345678); |
| 741 | assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412); | 805 | assert(readInt(u32, &bytes, builtin.Endian.Little) == 0x78563412); |
| 742 | assert(readIntLE(u32, bytes) == 0x78563412); | 806 | assert(readIntLittle(u32, &bytes) == 0x78563412); |
| 743 | assert(readIntLE(i32, bytes) == 0x78563412); | 807 | assert(readIntLittle(i32, &bytes) == 0x78563412); |
| 744 | } | 808 | } |
| 745 | { | 809 | { |
| 746 | const buf = []u8{ | 810 | const buf = []u8{ |
| ... | @@ -749,7 +813,7 @@ fn testReadIntImpl() void { | ... | @@ -749,7 +813,7 @@ fn testReadIntImpl() void { |
| 749 | 0x12, | 813 | 0x12, |
| 750 | 0x34, | 814 | 0x34, |
| 751 | }; | 815 | }; |
| 752 | const answer = readInt(buf, u64, builtin.Endian.Big); | 816 | const answer = readInt(u32, &buf, builtin.Endian.Big); |
| 753 | assert(answer == 0x00001234); | 817 | assert(answer == 0x00001234); |
| 754 | } | 818 | } |
| 755 | { | 819 | { |
| ... | @@ -759,7 +823,7 @@ fn testReadIntImpl() void { | ... | @@ -759,7 +823,7 @@ fn testReadIntImpl() void { |
| 759 | 0x00, | 823 | 0x00, |
| 760 | 0x00, | 824 | 0x00, |
| 761 | }; | 825 | }; |
| 762 | const answer = readInt(buf, u64, builtin.Endian.Little); | 826 | const answer = readInt(u32, &buf, builtin.Endian.Little); |
| 763 | assert(answer == 0x00003412); | 827 | assert(answer == 0x00003412); |
| 764 | } | 828 | } |
| 765 | { | 829 | { |
| ... | @@ -767,21 +831,33 @@ fn testReadIntImpl() void { | ... | @@ -767,21 +831,33 @@ fn testReadIntImpl() void { |
| 767 | 0xff, | 831 | 0xff, |
| 768 | 0xfe, | 832 | 0xfe, |
| 769 | }; | 833 | }; |
| 770 | assert(readIntBE(u16, bytes) == 0xfffe); | 834 | assert(readIntBig(u16, &bytes) == 0xfffe); |
| 771 | assert(readIntBE(i16, bytes) == -0x0002); | 835 | assert(readIntBig(i16, &bytes) == -0x0002); |
| 772 | assert(readIntLE(u16, bytes) == 0xfeff); | 836 | assert(readIntLittle(u16, &bytes) == 0xfeff); |
| 773 | assert(readIntLE(i16, bytes) == -0x0101); | 837 | assert(readIntLittle(i16, &bytes) == -0x0101); |
| 774 | } | 838 | } |
| 775 | } | 839 | } |
| 776 | 840 | ||
| 777 | test "testWriteInt" { | 841 | test "std.mem.writeIntSlice" { |
| 778 | testWriteIntImpl(); | 842 | testWriteIntImpl(); |
| 779 | comptime testWriteIntImpl(); | 843 | comptime testWriteIntImpl(); |
| 780 | } | 844 | } |
| 781 | fn testWriteIntImpl() void { | 845 | fn testWriteIntImpl() void { |
| 782 | var bytes: [8]u8 = undefined; | 846 | var bytes: [8]u8 = undefined; |
| 783 | 847 | ||
| 784 | writeInt(bytes[0..], u64(0x12345678CAFEBABE), builtin.Endian.Big); | 848 | writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Big); |
| 849 | assert(eql(u8, bytes, []u8{ | ||
| 850 | 0x00, 0x00, 0x00, 0x00, | ||
| 851 | 0x00, 0x00, 0x00, 0x00, | ||
| 852 | })); | ||
| 853 | |||
| 854 | writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Little); | ||
| 855 | assert(eql(u8, bytes, []u8{ | ||
| 856 | 0x00, 0x00, 0x00, 0x00, | ||
| 857 | 0x00, 0x00, 0x00, 0x00, | ||
| 858 | })); | ||
| 859 | |||
| 860 | writeIntSlice(u64, bytes[0..], 0x12345678CAFEBABE, builtin.Endian.Big); | ||
| 785 | assert(eql(u8, bytes, []u8{ | 861 | assert(eql(u8, bytes, []u8{ |
| 786 | 0x12, | 862 | 0x12, |
| 787 | 0x34, | 863 | 0x34, |
| ... | @@ -793,7 +869,7 @@ fn testWriteIntImpl() void { | ... | @@ -793,7 +869,7 @@ fn testWriteIntImpl() void { |
| 793 | 0xBE, | 869 | 0xBE, |
| 794 | })); | 870 | })); |
| 795 | 871 | ||
| 796 | writeInt(bytes[0..], u64(0xBEBAFECA78563412), builtin.Endian.Little); | 872 | writeIntSlice(u64, bytes[0..], 0xBEBAFECA78563412, builtin.Endian.Little); |
| 797 | assert(eql(u8, bytes, []u8{ | 873 | assert(eql(u8, bytes, []u8{ |
| 798 | 0x12, | 874 | 0x12, |
| 799 | 0x34, | 875 | 0x34, |
| ... | @@ -805,7 +881,7 @@ fn testWriteIntImpl() void { | ... | @@ -805,7 +881,7 @@ fn testWriteIntImpl() void { |
| 805 | 0xBE, | 881 | 0xBE, |
| 806 | })); | 882 | })); |
| 807 | 883 | ||
| 808 | writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big); | 884 | writeIntSlice(u32, bytes[0..], 0x12345678, builtin.Endian.Big); |
| 809 | assert(eql(u8, bytes, []u8{ | 885 | assert(eql(u8, bytes, []u8{ |
| 810 | 0x00, | 886 | 0x00, |
| 811 | 0x00, | 887 | 0x00, |
| ... | @@ -817,7 +893,7 @@ fn testWriteIntImpl() void { | ... | @@ -817,7 +893,7 @@ fn testWriteIntImpl() void { |
| 817 | 0x78, | 893 | 0x78, |
| 818 | })); | 894 | })); |
| 819 | 895 | ||
| 820 | writeInt(bytes[0..], u32(0x78563412), builtin.Endian.Little); | 896 | writeIntSlice(u32, bytes[0..], 0x78563412, builtin.Endian.Little); |
| 821 | assert(eql(u8, bytes, []u8{ | 897 | assert(eql(u8, bytes, []u8{ |
| 822 | 0x12, | 898 | 0x12, |
| 823 | 0x34, | 899 | 0x34, |
| ... | @@ -829,7 +905,7 @@ fn testWriteIntImpl() void { | ... | @@ -829,7 +905,7 @@ fn testWriteIntImpl() void { |
| 829 | 0x00, | 905 | 0x00, |
| 830 | })); | 906 | })); |
| 831 | 907 | ||
| 832 | writeInt(bytes[0..], u16(0x1234), builtin.Endian.Big); | 908 | writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Big); |
| 833 | assert(eql(u8, bytes, []u8{ | 909 | assert(eql(u8, bytes, []u8{ |
| 834 | 0x00, | 910 | 0x00, |
| 835 | 0x00, | 911 | 0x00, |
| ... | @@ -841,7 +917,7 @@ fn testWriteIntImpl() void { | ... | @@ -841,7 +917,7 @@ fn testWriteIntImpl() void { |
| 841 | 0x34, | 917 | 0x34, |
| 842 | })); | 918 | })); |
| 843 | 919 | ||
| 844 | writeInt(bytes[0..], u16(0x1234), builtin.Endian.Little); | 920 | writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Little); |
| 845 | assert(eql(u8, bytes, []u8{ | 921 | assert(eql(u8, bytes, []u8{ |
| 846 | 0x34, | 922 | 0x34, |
| 847 | 0x12, | 923 | 0x12, |
| ... | @@ -939,29 +1015,52 @@ test "std.mem.rotate" { | ... | @@ -939,29 +1015,52 @@ test "std.mem.rotate" { |
| 939 | })); | 1015 | })); |
| 940 | } | 1016 | } |
| 941 | 1017 | ||
| 942 | // TODO: When https://github.com/ziglang/zig/issues/649 is solved these can be done by | 1018 | /// Converts a little-endian integer to host endianness. |
| 943 | // endian-casting the pointer and then dereferencing | 1019 | pub fn littleToNative(comptime T: type, x: T) T { |
| 1020 | return switch (builtin.endian) { | ||
| 1021 | builtin.Endian.Little => x, | ||
| 1022 | builtin.Endian.Big => @bswap(T, x), | ||
| 1023 | }; | ||
| 1024 | } | ||
| 944 | 1025 | ||
| 945 | pub fn endianSwapIfLe(comptime T: type, x: T) T { | 1026 | /// Converts a big-endian integer to host endianness. |
| 946 | return endianSwapIf(builtin.Endian.Little, T, x); | 1027 | pub fn bigToNative(comptime T: type, x: T) T { |
| 1028 | return switch (builtin.endian) { | ||
| 1029 | builtin.Endian.Little => @bswap(T, x), | ||
| 1030 | builtin.Endian.Big => x, | ||
| 1031 | }; | ||
| 947 | } | 1032 | } |
| 948 | 1033 | ||
| 949 | pub fn endianSwapIfBe(comptime T: type, x: T) T { | 1034 | /// Converts an integer from specified endianness to host endianness. |
| 950 | return endianSwapIf(builtin.Endian.Big, T, x); | 1035 | pub fn toNative(comptime T: type, x: T, endianness_of_x: builtin.Endian) T { |
| 1036 | return switch (endianness_of_x) { | ||
| 1037 | builtin.Endian.Little => littleToNative(T, x), | ||
| 1038 | builtin.Endian.Big => bigToNative(T, x), | ||
| 1039 | }; | ||
| 951 | } | 1040 | } |
| 952 | 1041 | ||
| 953 | pub fn endianSwapIf(endian: builtin.Endian, comptime T: type, x: T) T { | 1042 | /// Converts an integer which has host endianness to the desired endianness. |
| 954 | return if (builtin.endian == endian) endianSwap(T, x) else x; | 1043 | pub fn nativeTo(comptime T: type, x: T, desired_endianness: builtin.Endian) T { |
| 1044 | return switch (desired_endianness) { | ||
| 1045 | builtin.Endian.Little => nativeToLittle(T, x), | ||
| 1046 | builtin.Endian.Big => nativeToBig(T, x), | ||
| 1047 | }; | ||
| 955 | } | 1048 | } |
| 956 | 1049 | ||
| 957 | pub fn endianSwap(comptime T: type, x: T) T { | 1050 | /// Converts an integer which has host endianness to little endian. |
| 958 | var buf: [@sizeOf(T)]u8 = undefined; | 1051 | pub fn nativeToLittle(comptime T: type, x: T) T { |
| 959 | mem.writeInt(buf[0..], x, builtin.Endian.Little); | 1052 | return switch (builtin.endian) { |
| 960 | return mem.readInt(buf, T, builtin.Endian.Big); | 1053 | builtin.Endian.Little => x, |
| 1054 | builtin.Endian.Big => @bswap(T, x), | ||
| 1055 | }; | ||
| 961 | } | 1056 | } |
| 962 | 1057 | ||
| 963 | test "std.mem.endianSwap" { | 1058 | /// Converts an integer which has host endianness to big endian. |
| 964 | assert(endianSwap(u32, 0xDEADBEEF) == 0xEFBEADDE); | 1059 | pub fn nativeToBig(comptime T: type, x: T) T { |
| 1060 | return switch (builtin.endian) { | ||
| 1061 | builtin.Endian.Little => @bswap(T, x), | ||
| 1062 | builtin.Endian.Big => x, | ||
| 1063 | }; | ||
| 965 | } | 1064 | } |
| 966 | 1065 | ||
| 967 | fn AsBytesReturnType(comptime P: type) type { | 1066 | fn AsBytesReturnType(comptime P: type) type { |
std/net.zig+6-6| ... | @@ -23,7 +23,7 @@ pub const Address = struct { | ... | @@ -23,7 +23,7 @@ pub const Address = struct { |
| 23 | .os_addr = posix.sockaddr{ | 23 | .os_addr = posix.sockaddr{ |
| 24 | .in = posix.sockaddr_in{ | 24 | .in = posix.sockaddr_in{ |
| 25 | .family = posix.AF_INET, | 25 | .family = posix.AF_INET, |
| 26 | .port = std.mem.endianSwapIfLe(u16, _port), | 26 | .port = mem.nativeToBig(u16, _port), |
| 27 | .addr = ip4, | 27 | .addr = ip4, |
| 28 | .zero = []u8{0} ** 8, | 28 | .zero = []u8{0} ** 8, |
| 29 | }, | 29 | }, |
| ... | @@ -37,7 +37,7 @@ pub const Address = struct { | ... | @@ -37,7 +37,7 @@ pub const Address = struct { |
| 37 | .os_addr = posix.sockaddr{ | 37 | .os_addr = posix.sockaddr{ |
| 38 | .in6 = posix.sockaddr_in6{ | 38 | .in6 = posix.sockaddr_in6{ |
| 39 | .family = posix.AF_INET6, | 39 | .family = posix.AF_INET6, |
| 40 | .port = std.mem.endianSwapIfLe(u16, _port), | 40 | .port = mem.nativeToBig(u16, _port), |
| 41 | .flowinfo = 0, | 41 | .flowinfo = 0, |
| 42 | .addr = ip6.addr, | 42 | .addr = ip6.addr, |
| 43 | .scope_id = ip6.scope_id, | 43 | .scope_id = ip6.scope_id, |
| ... | @@ -47,7 +47,7 @@ pub const Address = struct { | ... | @@ -47,7 +47,7 @@ pub const Address = struct { |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | pub fn port(self: Address) u16 { | 49 | pub fn port(self: Address) u16 { |
| 50 | return std.mem.endianSwapIfLe(u16, self.os_addr.in.port); | 50 | return mem.bigToNative(u16, self.os_addr.in.port); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | pub fn initPosix(addr: posix.sockaddr) Address { | 53 | pub fn initPosix(addr: posix.sockaddr) Address { |
| ... | @@ -57,12 +57,12 @@ pub const Address = struct { | ... | @@ -57,12 +57,12 @@ pub const Address = struct { |
| 57 | pub fn format(self: *const Address, out_stream: var) !void { | 57 | pub fn format(self: *const Address, out_stream: var) !void { |
| 58 | switch (self.os_addr.in.family) { | 58 | switch (self.os_addr.in.family) { |
| 59 | posix.AF_INET => { | 59 | posix.AF_INET => { |
| 60 | const native_endian_port = std.mem.endianSwapIfLe(u16, self.os_addr.in.port); | 60 | const native_endian_port = mem.bigToNative(u16, self.os_addr.in.port); |
| 61 | const bytes = ([]const u8)((*self.os_addr.in.addr)[0..1]); | 61 | const bytes = ([]const u8)((*self.os_addr.in.addr)[0..1]); |
| 62 | try out_stream.print("{}.{}.{}.{}:{}", bytes[0], bytes[1], bytes[2], bytes[3], native_endian_port); | 62 | try out_stream.print("{}.{}.{}.{}:{}", bytes[0], bytes[1], bytes[2], bytes[3], native_endian_port); |
| 63 | }, | 63 | }, |
| 64 | posix.AF_INET6 => { | 64 | posix.AF_INET6 => { |
| 65 | const native_endian_port = std.mem.endianSwapIfLe(u16, self.os_addr.in6.port); | 65 | const native_endian_port = mem.bigToNative(u16, self.os_addr.in6.port); |
| 66 | try out_stream.print("[TODO render ip6 address]:{}", native_endian_port); | 66 | try out_stream.print("[TODO render ip6 address]:{}", native_endian_port); |
| 67 | }, | 67 | }, |
| 68 | else => try out_stream.write("(unrecognized address family)"), | 68 | else => try out_stream.write("(unrecognized address family)"), |
| ... | @@ -193,7 +193,7 @@ pub fn parseIp6(buf: []const u8) !Ip6Addr { | ... | @@ -193,7 +193,7 @@ pub fn parseIp6(buf: []const u8) !Ip6Addr { |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | test "std.net.parseIp4" { | 195 | test "std.net.parseIp4" { |
| 196 | assert((try parseIp4("127.0.0.1")) == std.mem.endianSwapIfLe(u32, 0x7f000001)); | 196 | assert((try parseIp4("127.0.0.1")) == mem.bigToNative(u32, 0x7f000001)); |
| 197 | 197 | ||
| 198 | testParseIp4Fail("256.0.0.1", error.Overflow); | 198 | testParseIp4Fail("256.0.0.1", error.Overflow); |
| 199 | testParseIp4Fail("x.0.0.1", error.InvalidCharacter); | 199 | testParseIp4Fail("x.0.0.1", error.InvalidCharacter); |
std/os/child_process.zig+2-2| ... | @@ -807,10 +807,10 @@ const ErrInt = @IntType(false, @sizeOf(anyerror) * 8); | ... | @@ -807,10 +807,10 @@ const ErrInt = @IntType(false, @sizeOf(anyerror) * 8); |
| 807 | 807 | ||
| 808 | fn writeIntFd(fd: i32, value: ErrInt) !void { | 808 | fn writeIntFd(fd: i32, value: ErrInt) !void { |
| 809 | const stream = &os.File.openHandle(fd).outStream().stream; | 809 | const stream = &os.File.openHandle(fd).outStream().stream; |
| 810 | stream.writeIntNe(ErrInt, value) catch return error.SystemResources; | 810 | stream.writeIntNative(ErrInt, value) catch return error.SystemResources; |
| 811 | } | 811 | } |
| 812 | 812 | ||
| 813 | fn readIntFd(fd: i32) !ErrInt { | 813 | fn readIntFd(fd: i32) !ErrInt { |
| 814 | const stream = &os.File.openHandle(fd).inStream().stream; | 814 | const stream = &os.File.openHandle(fd).inStream().stream; |
| 815 | return stream.readIntNe(ErrInt) catch return error.SystemResources; | 815 | return stream.readIntNative(ErrInt) catch return error.SystemResources; |
| 816 | } | 816 | } |
std/os/freebsd/x86_64.zig+3-3| ... | @@ -98,12 +98,12 @@ pub nakedcc fn restore_rt() void { | ... | @@ -98,12 +98,12 @@ pub nakedcc fn restore_rt() void { |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | pub const msghdr = extern struct { | 100 | pub const msghdr = extern struct { |
| 101 | msg_name: &u8, | 101 | msg_name: *u8, |
| 102 | msg_namelen: socklen_t, | 102 | msg_namelen: socklen_t, |
| 103 | msg_iov: &iovec, | 103 | msg_iov: *iovec, |
| 104 | msg_iovlen: i32, | 104 | msg_iovlen: i32, |
| 105 | __pad1: i32, | 105 | __pad1: i32, |
| 106 | msg_control: &u8, | 106 | msg_control: *u8, |
| 107 | msg_controllen: socklen_t, | 107 | msg_controllen: socklen_t, |
| 108 | __pad2: socklen_t, | 108 | __pad2: socklen_t, |
| 109 | msg_flags: i32, | 109 | msg_flags: i32, |
std/pdb.zig+3-3| ... | @@ -508,11 +508,11 @@ const Msf = struct { | ... | @@ -508,11 +508,11 @@ const Msf = struct { |
| 508 | allocator, | 508 | allocator, |
| 509 | ); | 509 | ); |
| 510 | 510 | ||
| 511 | const stream_count = try self.directory.stream.readIntLe(u32); | 511 | const stream_count = try self.directory.stream.readIntLittle(u32); |
| 512 | 512 | ||
| 513 | const stream_sizes = try allocator.alloc(u32, stream_count); | 513 | const stream_sizes = try allocator.alloc(u32, stream_count); |
| 514 | for (stream_sizes) |*s| { | 514 | for (stream_sizes) |*s| { |
| 515 | const size = try self.directory.stream.readIntLe(u32); | 515 | const size = try self.directory.stream.readIntLittle(u32); |
| 516 | s.* = blockCountFromSize(size, superblock.BlockSize); | 516 | s.* = blockCountFromSize(size, superblock.BlockSize); |
| 517 | } | 517 | } |
| 518 | 518 | ||
| ... | @@ -603,7 +603,7 @@ const MsfStream = struct { | ... | @@ -603,7 +603,7 @@ const MsfStream = struct { |
| 603 | 603 | ||
| 604 | var i: u32 = 0; | 604 | var i: u32 = 0; |
| 605 | while (i < block_count) : (i += 1) { | 605 | while (i < block_count) : (i += 1) { |
| 606 | stream.blocks[i] = try in.readIntLe(u32); | 606 | stream.blocks[i] = try in.readIntLittle(u32); |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | return stream; | 609 | return stream; |
std/rand/index.zig+6-2| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | // ``` | 5 | // ``` |
| 6 | // var buf: [8]u8 = undefined; | 6 | // var buf: [8]u8 = undefined; |
| 7 | // try std.os.getRandomBytes(buf[0..]); | 7 | // try std.os.getRandomBytes(buf[0..]); |
| 8 | // const seed = mem.readIntLE(u64, buf[0..8]); | 8 | // const seed = mem.readIntSliceLittle(u64, buf[0..8]); |
| 9 | // | 9 | // |
| 10 | // var r = DefaultPrng.init(seed); | 10 | // var r = DefaultPrng.init(seed); |
| 11 | // | 11 | // |
| ... | @@ -52,7 +52,7 @@ pub const Random = struct { | ... | @@ -52,7 +52,7 @@ pub const Random = struct { |
| 52 | // use LE instead of native endian for better portability maybe? | 52 | // use LE instead of native endian for better portability maybe? |
| 53 | // TODO: endian portability is pointless if the underlying prng isn't endian portable. | 53 | // TODO: endian portability is pointless if the underlying prng isn't endian portable. |
| 54 | // TODO: document the endian portability of this library. | 54 | // TODO: document the endian portability of this library. |
| 55 | const byte_aligned_result = mem.readIntLE(ByteAlignedT, rand_bytes); | 55 | const byte_aligned_result = mem.readIntSliceLittle(ByteAlignedT, rand_bytes); |
| 56 | const unsigned_result = @truncate(UnsignedT, byte_aligned_result); | 56 | const unsigned_result = @truncate(UnsignedT, byte_aligned_result); |
| 57 | return @bitCast(T, unsigned_result); | 57 | return @bitCast(T, unsigned_result); |
| 58 | } | 58 | } |
| ... | @@ -69,6 +69,7 @@ pub const Random = struct { | ... | @@ -69,6 +69,7 @@ pub const Random = struct { |
| 69 | return @intCast(T, limitRangeBiased(u64, r.int(u64), less_than)); | 69 | return @intCast(T, limitRangeBiased(u64, r.int(u64), less_than)); |
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | |||
| 72 | /// Returns an evenly distributed random unsigned integer `0 <= i < less_than`. | 73 | /// Returns an evenly distributed random unsigned integer `0 <= i < less_than`. |
| 73 | /// This function assumes that the underlying ::fillFn produces evenly distributed values. | 74 | /// This function assumes that the underlying ::fillFn produces evenly distributed values. |
| 74 | /// Within this assumption, the runtime of this function is exponentially distributed. | 75 | /// Within this assumption, the runtime of this function is exponentially distributed. |
| ... | @@ -123,6 +124,7 @@ pub const Random = struct { | ... | @@ -123,6 +124,7 @@ pub const Random = struct { |
| 123 | } | 124 | } |
| 124 | return r.uintLessThanBiased(T, at_most + 1); | 125 | return r.uintLessThanBiased(T, at_most + 1); |
| 125 | } | 126 | } |
| 127 | |||
| 126 | /// Returns an evenly distributed random unsigned integer `0 <= i <= at_most`. | 128 | /// Returns an evenly distributed random unsigned integer `0 <= i <= at_most`. |
| 127 | /// See ::uintLessThan, which this function uses in most cases, | 129 | /// See ::uintLessThan, which this function uses in most cases, |
| 128 | /// for commentary on the runtime of this function. | 130 | /// for commentary on the runtime of this function. |
| ... | @@ -151,6 +153,7 @@ pub const Random = struct { | ... | @@ -151,6 +153,7 @@ pub const Random = struct { |
| 151 | return at_least + r.uintLessThanBiased(T, less_than - at_least); | 153 | return at_least + r.uintLessThanBiased(T, less_than - at_least); |
| 152 | } | 154 | } |
| 153 | } | 155 | } |
| 156 | |||
| 154 | /// Returns an evenly distributed random integer `at_least <= i < less_than`. | 157 | /// Returns an evenly distributed random integer `at_least <= i < less_than`. |
| 155 | /// See ::uintLessThan, which this function uses in most cases, | 158 | /// See ::uintLessThan, which this function uses in most cases, |
| 156 | /// for commentary on the runtime of this function. | 159 | /// for commentary on the runtime of this function. |
| ... | @@ -185,6 +188,7 @@ pub const Random = struct { | ... | @@ -185,6 +188,7 @@ pub const Random = struct { |
| 185 | return at_least + r.uintAtMostBiased(T, at_most - at_least); | 188 | return at_least + r.uintAtMostBiased(T, at_most - at_least); |
| 186 | } | 189 | } |
| 187 | } | 190 | } |
| 191 | |||
| 188 | /// Returns an evenly distributed random integer `at_least <= i <= at_most`. | 192 | /// Returns an evenly distributed random integer `at_least <= i <= at_most`. |
| 189 | /// See ::uintLessThan, which this function uses in most cases, | 193 | /// See ::uintLessThan, which this function uses in most cases, |
| 190 | /// for commentary on the runtime of this function. | 194 | /// for commentary on the runtime of this function. |
std/unicode.zig+15-15| ... | @@ -249,12 +249,12 @@ pub const Utf16LeIterator = struct { | ... | @@ -249,12 +249,12 @@ pub const Utf16LeIterator = struct { |
| 249 | pub fn nextCodepoint(it: *Utf16LeIterator) !?u32 { | 249 | pub fn nextCodepoint(it: *Utf16LeIterator) !?u32 { |
| 250 | assert(it.i <= it.bytes.len); | 250 | assert(it.i <= it.bytes.len); |
| 251 | if (it.i == it.bytes.len) return null; | 251 | if (it.i == it.bytes.len) return null; |
| 252 | const c0: u32 = mem.readIntLE(u16, it.bytes[it.i .. it.i + 2]); | 252 | const c0: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]); |
| 253 | if (c0 & ~u32(0x03ff) == 0xd800) { | 253 | if (c0 & ~u32(0x03ff) == 0xd800) { |
| 254 | // surrogate pair | 254 | // surrogate pair |
| 255 | it.i += 2; | 255 | it.i += 2; |
| 256 | if (it.i >= it.bytes.len) return error.DanglingSurrogateHalf; | 256 | if (it.i >= it.bytes.len) return error.DanglingSurrogateHalf; |
| 257 | const c1: u32 = mem.readIntLE(u16, it.bytes[it.i .. it.i + 2]); | 257 | const c1: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]); |
| 258 | if (c1 & ~u32(0x03ff) != 0xdc00) return error.ExpectedSecondSurrogateHalf; | 258 | if (c1 & ~u32(0x03ff) != 0xdc00) return error.ExpectedSecondSurrogateHalf; |
| 259 | it.i += 2; | 259 | it.i += 2; |
| 260 | return 0x10000 + (((c0 & 0x03ff) << 10) | (c1 & 0x03ff)); | 260 | return 0x10000 + (((c0 & 0x03ff) << 10) | (c1 & 0x03ff)); |
| ... | @@ -510,46 +510,46 @@ test "utf16leToUtf8" { | ... | @@ -510,46 +510,46 @@ test "utf16leToUtf8" { |
| 510 | const utf16le_as_bytes = @sliceToBytes(utf16le[0..]); | 510 | const utf16le_as_bytes = @sliceToBytes(utf16le[0..]); |
| 511 | 511 | ||
| 512 | { | 512 | { |
| 513 | mem.writeInt(utf16le_as_bytes[0..], u16('A'), builtin.Endian.Little); | 513 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A'); |
| 514 | mem.writeInt(utf16le_as_bytes[2..], u16('a'), builtin.Endian.Little); | 514 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 'a'); |
| 515 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); | 515 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); |
| 516 | assert(mem.eql(u8, utf8, "Aa")); | 516 | assert(mem.eql(u8, utf8, "Aa")); |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | { | 519 | { |
| 520 | mem.writeInt(utf16le_as_bytes[0..], u16(0x80), builtin.Endian.Little); | 520 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0x80); |
| 521 | mem.writeInt(utf16le_as_bytes[2..], u16(0xffff), builtin.Endian.Little); | 521 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xffff); |
| 522 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); | 522 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); |
| 523 | assert(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf")); | 523 | assert(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf")); |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | { | 526 | { |
| 527 | // the values just outside the surrogate half range | 527 | // the values just outside the surrogate half range |
| 528 | mem.writeInt(utf16le_as_bytes[0..], u16(0xd7ff), builtin.Endian.Little); | 528 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd7ff); |
| 529 | mem.writeInt(utf16le_as_bytes[2..], u16(0xe000), builtin.Endian.Little); | 529 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xe000); |
| 530 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); | 530 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); |
| 531 | assert(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80")); | 531 | assert(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80")); |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | { | 534 | { |
| 535 | // smallest surrogate pair | 535 | // smallest surrogate pair |
| 536 | mem.writeInt(utf16le_as_bytes[0..], u16(0xd800), builtin.Endian.Little); | 536 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd800); |
| 537 | mem.writeInt(utf16le_as_bytes[2..], u16(0xdc00), builtin.Endian.Little); | 537 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00); |
| 538 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); | 538 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); |
| 539 | assert(mem.eql(u8, utf8, "\xf0\x90\x80\x80")); | 539 | assert(mem.eql(u8, utf8, "\xf0\x90\x80\x80")); |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | { | 542 | { |
| 543 | // largest surrogate pair | 543 | // largest surrogate pair |
| 544 | mem.writeInt(utf16le_as_bytes[0..], u16(0xdbff), builtin.Endian.Little); | 544 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff); |
| 545 | mem.writeInt(utf16le_as_bytes[2..], u16(0xdfff), builtin.Endian.Little); | 545 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdfff); |
| 546 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); | 546 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); |
| 547 | assert(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf")); | 547 | assert(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf")); |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | { | 550 | { |
| 551 | mem.writeInt(utf16le_as_bytes[0..], u16(0xdbff), builtin.Endian.Little); | 551 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff); |
| 552 | mem.writeInt(utf16le_as_bytes[2..], u16(0xdc00), builtin.Endian.Little); | 552 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00); |
| 553 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); | 553 | const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); |
| 554 | assert(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80")); | 554 | assert(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80")); |
| 555 | } | 555 | } |
| ... | @@ -583,7 +583,7 @@ pub fn utf8ToUtf16Le(utf16le: []u16, utf8: []const u8) !usize { | ... | @@ -583,7 +583,7 @@ pub fn utf8ToUtf16Le(utf16le: []u16, utf8: []const u8) !usize { |
| 583 | while (it.nextCodepoint()) |codepoint| { | 583 | while (it.nextCodepoint()) |codepoint| { |
| 584 | if (end_index == utf16le_as_bytes.len) return (end_index / 2) + 1; | 584 | if (end_index == utf16le_as_bytes.len) return (end_index / 2) + 1; |
| 585 | // TODO surrogate pairs | 585 | // TODO surrogate pairs |
| 586 | mem.writeInt(utf16le_as_bytes[end_index..], @intCast(u16, codepoint), builtin.Endian.Little); | 586 | mem.writeIntSliceLittle(u16, utf16le_as_bytes[end_index..], @intCast(u16, codepoint)); |
| 587 | end_index += 2; | 587 | end_index += 2; |
| 588 | } | 588 | } |
| 589 | return end_index / 2; | 589 | return end_index / 2; |
test/behavior.zig+2| ... | @@ -8,6 +8,7 @@ comptime { | ... | @@ -8,6 +8,7 @@ comptime { |
| 8 | _ = @import("cases/atomics.zig"); | 8 | _ = @import("cases/atomics.zig"); |
| 9 | _ = @import("cases/bitcast.zig"); | 9 | _ = @import("cases/bitcast.zig"); |
| 10 | _ = @import("cases/bool.zig"); | 10 | _ = @import("cases/bool.zig"); |
| 11 | _ = @import("cases/bswap.zig"); | ||
| 11 | _ = @import("cases/bugs/1076.zig"); | 12 | _ = @import("cases/bugs/1076.zig"); |
| 12 | _ = @import("cases/bugs/1111.zig"); | 13 | _ = @import("cases/bugs/1111.zig"); |
| 13 | _ = @import("cases/bugs/1277.zig"); | 14 | _ = @import("cases/bugs/1277.zig"); |
| ... | @@ -64,6 +65,7 @@ comptime { | ... | @@ -64,6 +65,7 @@ comptime { |
| 64 | _ = @import("cases/switch_prong_implicit_cast.zig"); | 65 | _ = @import("cases/switch_prong_implicit_cast.zig"); |
| 65 | _ = @import("cases/syntax.zig"); | 66 | _ = @import("cases/syntax.zig"); |
| 66 | _ = @import("cases/this.zig"); | 67 | _ = @import("cases/this.zig"); |
| 68 | _ = @import("cases/truncate.zig"); | ||
| 67 | _ = @import("cases/try.zig"); | 69 | _ = @import("cases/try.zig"); |
| 68 | _ = @import("cases/type_info.zig"); | 70 | _ = @import("cases/type_info.zig"); |
| 69 | _ = @import("cases/undefined.zig"); | 71 | _ = @import("cases/undefined.zig"); |
test/cases/bswap.zig created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const assert = std.debug.assert; | ||
| 3 | |||
| 4 | test "@bswap" { | ||
| 5 | comptime testByteSwap(); | ||
| 6 | testByteSwap(); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn testByteSwap() void { | ||
| 10 | assert(@bswap(u0, 0) == 0); | ||
| 11 | assert(@bswap(u8, 0x12) == 0x12); | ||
| 12 | assert(@bswap(u16, 0x1234) == 0x3412); | ||
| 13 | assert(@bswap(u24, 0x123456) == 0x563412); | ||
| 14 | assert(@bswap(u32, 0x12345678) == 0x78563412); | ||
| 15 | assert(@bswap(u40, 0x123456789a) == 0x9a78563412); | ||
| 16 | assert(@bswap(u48, 0x123456789abc) == 0xbc9a78563412); | ||
| 17 | assert(@bswap(u56, 0x123456789abcde) == 0xdebc9a78563412); | ||
| 18 | assert(@bswap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412); | ||
| 19 | assert(@bswap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412); | ||
| 20 | |||
| 21 | assert(@bswap(i0, 0) == 0); | ||
| 22 | assert(@bswap(i8, -50) == -50); | ||
| 23 | assert(@bswap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412))); | ||
| 24 | assert(@bswap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412))); | ||
| 25 | assert(@bswap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412))); | ||
| 26 | assert(@bswap(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x9a78563412))); | ||
| 27 | assert(@bswap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412))); | ||
| 28 | assert(@bswap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412))); | ||
| 29 | assert(@bswap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412))); | ||
| 30 | assert(@bswap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == | ||
| 31 | @bitCast(i128, u128(0x8171615141312111f1debc9a78563412))); | ||
| 32 | } | ||
test/cases/truncate.zig created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const assert = std.debug.assert; | ||
| 3 | |||
| 4 | test "truncate u0 to larger integer allowed and has comptime known result" { | ||
| 5 | var x: u0 = 0; | ||
| 6 | const y = @truncate(u8, x); | ||
| 7 | comptime assert(y == 0); | ||
| 8 | } | ||
test/compile_errors.zig+12| ... | @@ -1,6 +1,18 @@ | ... | @@ -1,6 +1,18 @@ |
| 1 | const tests = @import("tests.zig"); | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | ||
| 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4 | cases.add( | ||
| 5 | "reading past end of pointer casted array", | ||
| 6 | \\comptime { | ||
| 7 | \\ const array = "aoeu"; | ||
| 8 | \\ const slice = array[2..]; | ||
| 9 | \\ const int_ptr = @ptrCast(*const u24, slice.ptr); | ||
| 10 | \\ const deref = int_ptr.*; | ||
| 11 | \\} | ||
| 12 | , | ||
| 13 | ".tmp_source.zig:5:26: error: attempt to read 3 bytes from [4]u8 at index 2 which is 2 bytes", | ||
| 14 | ); | ||
| 15 | |||
| 4 | cases.add( | 16 | cases.add( |
| 5 | "error note for function parameter incompatibility", | 17 | "error note for function parameter incompatibility", |
| 6 | \\fn do_the_thing(func: fn (arg: i32) void) void {} | 18 | \\fn do_the_thing(func: fn (arg: i32) void) void {} |