authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-15 13:49:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-16 19:37:00-04:00
loge311cd562b47529bdcd2423658915539ddb6bc36
tree5b3d735831183076d83a405042eabebaf8c9c91e
parent59b3dc8907f76b93caa689732e878a5bfa2f65c2

don't automatically take pointer when passing by non-copying value

this commit does not have all tests passing

11 files changed, 249 insertions(+), 272 deletions(-)

src/ir.cpp+34-23
...@@ -10463,13 +10463,6 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ...@@ -10463,13 +10463,6 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
10463 zig_unreachable();10463 zig_unreachable();
10464}10464}
1046510465
10466static IrInstruction *ir_implicit_byval_const_ref_cast(IrAnalyze *ira, IrInstruction *inst) {
10467 if (type_is_copyable(ira->codegen, inst->value.type))
10468 return inst;
10469 TypeTableEntry *const_ref_type = get_pointer_to_type(ira->codegen, inst->value.type, true);
10470 return ir_implicit_cast(ira, inst, const_ref_type);
10471}
10472
10473static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {10466static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {
10474 TypeTableEntry *type_entry = ptr->value.type;10467 TypeTableEntry *type_entry = ptr->value.type;
10475 if (type_is_invalid(type_entry)) {10468 if (type_is_invalid(type_entry)) {
...@@ -12283,7 +12276,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -12283,7 +12276,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
12283 IrInstruction *casted_arg;12276 IrInstruction *casted_arg;
12284 if (is_var_args) {12277 if (is_var_args) {
12285 arg_part_of_generic_id = true;12278 arg_part_of_generic_id = true;
12286 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);12279 casted_arg = arg;
12287 } else {12280 } else {
12288 if (param_decl_node->data.param_decl.var_token == nullptr) {12281 if (param_decl_node->data.param_decl.var_token == nullptr) {
12289 AstNode *param_type_node = param_decl_node->data.param_decl.type;12282 AstNode *param_type_node = param_decl_node->data.param_decl.type;
...@@ -12296,7 +12289,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -12296,7 +12289,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
12296 return false;12289 return false;
12297 } else {12290 } else {
12298 arg_part_of_generic_id = true;12291 arg_part_of_generic_id = true;
12299 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);12292 casted_arg = arg;
12300 }12293 }
12301 }12294 }
1230212295
...@@ -12515,9 +12508,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12515,9 +12508,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1251512508
12516 size_t next_proto_i = 0;12509 size_t next_proto_i = 0;
12517 if (first_arg_ptr) {12510 if (first_arg_ptr) {
12518 IrInstruction *first_arg;
12519 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);12511 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12520 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {12512
12513 bool first_arg_known_bare = false;
12514 if (fn_type_id->next_param_index >= 1) {
12515 TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
12516 if (type_is_invalid(param_type))
12517 return ira->codegen->builtin_types.entry_invalid;
12518 first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
12519 }
12520
12521 IrInstruction *first_arg;
12522 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
12521 first_arg = first_arg_ptr;12523 first_arg = first_arg_ptr;
12522 } else {12524 } else {
12523 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);12525 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
...@@ -12667,9 +12669,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12667,9 +12669,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12667 size_t next_proto_i = 0;12669 size_t next_proto_i = 0;
1266812670
12669 if (first_arg_ptr) {12671 if (first_arg_ptr) {
12670 IrInstruction *first_arg;
12671 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);12672 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12672 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {12673
12674 bool first_arg_known_bare = false;
12675 if (fn_type_id->next_param_index >= 1) {
12676 TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
12677 if (type_is_invalid(param_type))
12678 return ira->codegen->builtin_types.entry_invalid;
12679 first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
12680 }
12681
12682 IrInstruction *first_arg;
12683 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
12673 first_arg = first_arg_ptr;12684 first_arg = first_arg_ptr;
12674 } else {12685 } else {
12675 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);12686 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
...@@ -12802,10 +12813,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12802,10 +12813,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12802 return ira->codegen->builtin_types.entry_invalid;12813 return ira->codegen->builtin_types.entry_invalid;
12803 }12814 }
12804 if (inst_fn_type_id.async_allocator_type == nullptr) {12815 if (inst_fn_type_id.async_allocator_type == nullptr) {
12805 IrInstruction *casted_inst = ir_implicit_byval_const_ref_cast(ira, uncasted_async_allocator_inst);12816 inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type;
12806 if (type_is_invalid(casted_inst->value.type))
12807 return ira->codegen->builtin_types.entry_invalid;
12808 inst_fn_type_id.async_allocator_type = casted_inst->value.type;
12809 }12817 }
12810 async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type);12818 async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type);
12811 if (type_is_invalid(async_allocator_inst->value.type))12819 if (type_is_invalid(async_allocator_inst->value.type))
...@@ -12866,9 +12874,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12866,9 +12874,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12866 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count);12874 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count);
12867 size_t next_arg_index = 0;12875 size_t next_arg_index = 0;
12868 if (first_arg_ptr) {12876 if (first_arg_ptr) {
12869 IrInstruction *first_arg;
12870 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);12877 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12871 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {12878
12879 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
12880 if (type_is_invalid(param_type))
12881 return ira->codegen->builtin_types.entry_invalid;
12882
12883 IrInstruction *first_arg;
12884 if (param_type->id == TypeTableEntryIdPointer &&
12885 handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type))
12886 {
12872 first_arg = first_arg_ptr;12887 first_arg = first_arg_ptr;
12873 } else {12888 } else {
12874 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);12889 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
...@@ -12876,10 +12891,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -12876,10 +12891,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
12876 return ira->codegen->builtin_types.entry_invalid;12891 return ira->codegen->builtin_types.entry_invalid;
12877 }12892 }
1287812893
12879 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
12880 if (type_is_invalid(param_type))
12881 return ira->codegen->builtin_types.entry_invalid;
12882
12883 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type);12894 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type);
12884 if (type_is_invalid(casted_arg->value.type))12895 if (type_is_invalid(casted_arg->value.type))
12885 return ira->codegen->builtin_types.entry_invalid;12896 return ira->codegen->builtin_types.entry_invalid;
std/array_list.zig+13-13
...@@ -29,36 +29,36 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {...@@ -29,36 +29,36 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
29 };29 };
30 }30 }
3131
32 pub fn deinit(self: *const Self) void {32 pub fn deinit(self: Self) void {
33 self.allocator.free(self.items);33 self.allocator.free(self.items);
34 }34 }
3535
36 pub fn toSlice(self: *const Self) []align(A) T {36 pub fn toSlice(self: Self) []align(A) T {
37 return self.items[0..self.len];37 return self.items[0..self.len];
38 }38 }
3939
40 pub fn toSliceConst(self: *const Self) []align(A) const T {40 pub fn toSliceConst(self: Self) []align(A) const T {
41 return self.items[0..self.len];41 return self.items[0..self.len];
42 }42 }
4343
44 pub fn at(self: *const Self, n: usize) T {44 pub fn at(self: Self, n: usize) T {
45 return self.toSliceConst()[n];45 return self.toSliceConst()[n];
46 }46 }
4747
48 /// Sets the value at index `i`, or returns `error.OutOfBounds` if48 /// Sets the value at index `i`, or returns `error.OutOfBounds` if
49 /// the index is not in range.49 /// the index is not in range.
50 pub fn setOrError(self: *const Self, i: usize, item: *const T) !void {50 pub fn setOrError(self: Self, i: usize, item: T) !void {
51 if (i >= self.len) return error.OutOfBounds;51 if (i >= self.len) return error.OutOfBounds;
52 self.items[i] = item.*;52 self.items[i] = item;
53 }53 }
5454
55 /// Sets the value at index `i`, asserting that the value is in range.55 /// Sets the value at index `i`, asserting that the value is in range.
56 pub fn set(self: *const Self, i: usize, item: *const T) void {56 pub fn set(self: *Self, i: usize, item: T) void {
57 assert(i < self.len);57 assert(i < self.len);
58 self.items[i] = item.*;58 self.items[i] = item;
59 }59 }
6060
61 pub fn count(self: *const Self) usize {61 pub fn count(self: Self) usize {
62 return self.len;62 return self.len;
63 }63 }
6464
...@@ -81,12 +81,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {...@@ -81,12 +81,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
81 return result;81 return result;
82 }82 }
8383
84 pub fn insert(self: *Self, n: usize, item: *const T) !void {84 pub fn insert(self: *Self, n: usize, item: T) !void {
85 try self.ensureCapacity(self.len + 1);85 try self.ensureCapacity(self.len + 1);
86 self.len += 1;86 self.len += 1;
8787
88 mem.copy(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]);88 mem.copy(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]);
89 self.items[n] = item.*;89 self.items[n] = item;
90 }90 }
9191
92 pub fn insertSlice(self: *Self, n: usize, items: []align(A) const T) !void {92 pub fn insertSlice(self: *Self, n: usize, items: []align(A) const T) !void {
...@@ -97,9 +97,9 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {...@@ -97,9 +97,9 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
97 mem.copy(T, self.items[n .. n + items.len], items);97 mem.copy(T, self.items[n .. n + items.len], items);
98 }98 }
9999
100 pub fn append(self: *Self, item: *const T) !void {100 pub fn append(self: *Self, item: T) !void {
101 const new_item_ptr = try self.addOne();101 const new_item_ptr = try self.addOne();
102 new_item_ptr.* = item.*;102 new_item_ptr.* = item;
103 }103 }
104104
105 pub fn appendSlice(self: *Self, items: []align(A) const T) !void {105 pub fn appendSlice(self: *Self, items: []align(A) const T) !void {
std/build.zig+1-1
...@@ -234,7 +234,7 @@ pub const Builder = struct {...@@ -234,7 +234,7 @@ pub const Builder = struct {
234 defer wanted_steps.deinit();234 defer wanted_steps.deinit();
235235
236 if (step_names.len == 0) {236 if (step_names.len == 0) {
237 try wanted_steps.append(&self.default_step);237 try wanted_steps.append(self.default_step);
238 } else {238 } else {
239 for (step_names) |step_name| {239 for (step_names) |step_name| {
240 const s = try self.getTopLevelStepByName(step_name);240 const s = try self.getTopLevelStepByName(step_name);
std/fmt/index.zig+6-2
...@@ -162,8 +162,6 @@ pub fn formatType(...@@ -162,8 +162,6 @@ pub fn formatType(
162 },162 },
163 builtin.TypeInfo.Pointer.Size.Many => {163 builtin.TypeInfo.Pointer.Size.Many => {
164 if (ptr_info.child == u8) {164 if (ptr_info.child == u8) {
165 //This is a bit of a hack, but it made more sense to
166 // do this check here than have formatText do it
167 if (fmt[0] == 's') {165 if (fmt[0] == 's') {
168 const len = std.cstr.len(value);166 const len = std.cstr.len(value);
169 return formatText(value[0..len], fmt, context, Errors, output);167 return formatText(value[0..len], fmt, context, Errors, output);
...@@ -176,6 +174,12 @@ pub fn formatType(...@@ -176,6 +174,12 @@ pub fn formatType(
176 return output(context, casted_value);174 return output(context, casted_value);
177 },175 },
178 },176 },
177 builtin.TypeId.Array => |info| {
178 if (info.child == u8) {
179 return formatText(value, fmt, context, Errors, output);
180 }
181 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
182 },
179 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),183 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
180 }184 }
181}185}
std/json.zig+1-1
...@@ -1326,7 +1326,7 @@ pub const Parser = struct {...@@ -1326,7 +1326,7 @@ pub const Parser = struct {
1326 },1326 },
1327 // Array Parent -> [ ..., <array>, value ]1327 // Array Parent -> [ ..., <array>, value ]
1328 Value.Array => |*array| {1328 Value.Array => |*array| {
1329 try array.append(value);1329 try array.append(value.*);
1330 p.state = State.ArrayValue;1330 p.state = State.ArrayValue;
1331 },1331 },
1332 else => {1332 else => {
std/math/big/int.zig+144-202
...@@ -18,39 +18,6 @@ comptime {...@@ -18,39 +18,6 @@ comptime {
18 debug.assert(Limb.is_signed == false);18 debug.assert(Limb.is_signed == false);
19}19}
2020
21const wrapped_buffer_size = 512;
22
23// Converts primitive integer values onto a stack-based big integer, or passes through existing
24// Int types with no modifications. This can fail at runtime if using a very large dynamic
25// integer but it is very unlikely and is considered a user error.
26fn wrapInt(allocator: *Allocator, bn: var) *const Int {
27 const T = @typeOf(bn);
28 switch (@typeInfo(T)) {
29 TypeId.Pointer => |info| {
30 if (info.child == Int) {
31 return bn;
32 } else {
33 @compileError("cannot set Int using type " ++ @typeName(T));
34 }
35 },
36 else => {
37 var s = allocator.create(Int) catch unreachable;
38 s.* = Int{
39 .allocator = allocator,
40 .positive = false,
41 .limbs = block: {
42 var limbs = allocator.alloc(Limb, Int.default_capacity) catch unreachable;
43 limbs[0] = 0;
44 break :block limbs;
45 },
46 .len = 1,
47 };
48 s.set(bn) catch unreachable;
49 return s;
50 },
51 }
52}
53
54pub const Int = struct {21pub const Int = struct {
55 allocator: *Allocator,22 allocator: *Allocator,
56 positive: bool,23 positive: bool,
...@@ -93,11 +60,11 @@ pub const Int = struct {...@@ -93,11 +60,11 @@ pub const Int = struct {
93 self.limbs = try self.allocator.realloc(Limb, self.limbs, capacity);60 self.limbs = try self.allocator.realloc(Limb, self.limbs, capacity);
94 }61 }
9562
96 pub fn deinit(self: *const Int) void {63 pub fn deinit(self: Int) void {
97 self.allocator.free(self.limbs);64 self.allocator.free(self.limbs);
98 }65 }
9966
100 pub fn clone(other: *const Int) !Int {67 pub fn clone(other: Int) !Int {
101 return Int{68 return Int{
102 .allocator = other.allocator,69 .allocator = other.allocator,
103 .positive = other.positive,70 .positive = other.positive,
...@@ -110,8 +77,8 @@ pub const Int = struct {...@@ -110,8 +77,8 @@ pub const Int = struct {
110 };77 };
111 }78 }
11279
113 pub fn copy(self: *Int, other: *const Int) !void {80 pub fn copy(self: *Int, other: Int) !void {
114 if (self == other) {81 if (self == &other) {
115 return;82 return;
116 }83 }
11784
...@@ -125,7 +92,7 @@ pub const Int = struct {...@@ -125,7 +92,7 @@ pub const Int = struct {
125 mem.swap(Int, self, other);92 mem.swap(Int, self, other);
126 }93 }
12794
128 pub fn dump(self: *const Int) void {95 pub fn dump(self: Int) void {
129 for (self.limbs) |limb| {96 for (self.limbs) |limb| {
130 debug.warn("{x} ", limb);97 debug.warn("{x} ", limb);
131 }98 }
...@@ -140,20 +107,20 @@ pub const Int = struct {...@@ -140,20 +107,20 @@ pub const Int = struct {
140 r.positive = true;107 r.positive = true;
141 }108 }
142109
143 pub fn isOdd(r: *const Int) bool {110 pub fn isOdd(r: Int) bool {
144 return r.limbs[0] & 1 != 0;111 return r.limbs[0] & 1 != 0;
145 }112 }
146113
147 pub fn isEven(r: *const Int) bool {114 pub fn isEven(r: Int) bool {
148 return !r.isOdd();115 return !r.isOdd();
149 }116 }
150117
151 fn bitcount(self: *const Int) usize {118 fn bitcount(self: Int) usize {
152 const u_bit_count = (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1]));119 const u_bit_count = (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1]));
153 return usize(!self.positive) + u_bit_count;120 return usize(!self.positive) + u_bit_count;
154 }121 }
155122
156 pub fn sizeInBase(self: *const Int, base: usize) usize {123 pub fn sizeInBase(self: Int, base: usize) usize {
157 return (self.bitcount() / math.log2(base)) + 1;124 return (self.bitcount() / math.log2(base)) + 1;
158 }125 }
159126
...@@ -219,7 +186,7 @@ pub const Int = struct {...@@ -219,7 +186,7 @@ pub const Int = struct {
219 TargetTooSmall,186 TargetTooSmall,
220 };187 };
221188
222 pub fn to(self: *const Int, comptime T: type) ConvertError!T {189 pub fn to(self: Int, comptime T: type) ConvertError!T {
223 switch (@typeId(T)) {190 switch (@typeId(T)) {
224 TypeId.Int => {191 TypeId.Int => {
225 const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;192 const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;
...@@ -286,16 +253,28 @@ pub const Int = struct {...@@ -286,16 +253,28 @@ pub const Int = struct {
286 i += 1;253 i += 1;
287 }254 }
288255
256 // TODO values less than limb size should guarantee non allocating
257 var base_buffer: [512]u8 = undefined;
258 const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator;
259 const base_ap = try Int.initSet(base_al, base);
260
261 var d_buffer: [512]u8 = undefined;
262 var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]);
263 const d_al = &d_fba.allocator;
264
289 try self.set(0);265 try self.set(0);
290 for (value[i..]) |ch| {266 for (value[i..]) |ch| {
291 const d = try charToDigit(ch, base);267 const d = try charToDigit(ch, base);
292 try self.mul(self, base);268 d_fba.end_index = 0;
293 try self.add(self, d);269 const d_ap = try Int.initSet(d_al, d);
270
271 try self.mul(self.*, base_ap);
272 try self.add(self.*, d_ap);
294 }273 }
295 self.positive = positive;274 self.positive = positive;
296 }275 }
297276
298 pub fn toString(self: *const Int, allocator: *Allocator, base: u8) ![]const u8 {277 pub fn toString(self: Int, allocator: *Allocator, base: u8) ![]const u8 {
299 if (base < 2 or base > 16) {278 if (base < 2 or base > 16) {
300 return error.InvalidBase;279 return error.InvalidBase;
301 }280 }
...@@ -345,7 +324,7 @@ pub const Int = struct {...@@ -345,7 +324,7 @@ pub const Int = struct {
345 var b = try Int.initSet(allocator, limb_base);324 var b = try Int.initSet(allocator, limb_base);
346325
347 while (q.len >= 2) {326 while (q.len >= 2) {
348 try Int.divTrunc(&q, &r, &q, &b);327 try Int.divTrunc(&q, &r, q, b);
349328
350 var r_word = r.limbs[0];329 var r_word = r.limbs[0];
351 var i: usize = 0;330 var i: usize = 0;
...@@ -378,12 +357,7 @@ pub const Int = struct {...@@ -378,12 +357,7 @@ pub const Int = struct {
378 }357 }
379358
380 // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.359 // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
381 pub fn cmpAbs(a: *const Int, bv: var) i8 {360 pub fn cmpAbs(a: Int, b: Int) i8 {
382 // TODO: Thread-local buffer.
383 var buffer: [wrapped_buffer_size]u8 = undefined;
384 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
385 var b = wrapInt(&stack.allocator, bv);
386
387 if (a.len < b.len) {361 if (a.len < b.len) {
388 return -1;362 return -1;
389 }363 }
...@@ -408,11 +382,7 @@ pub const Int = struct {...@@ -408,11 +382,7 @@ pub const Int = struct {
408 }382 }
409383
410 // returns -1, 0, 1 if a < b, a == b or a > b respectively.384 // returns -1, 0, 1 if a < b, a == b or a > b respectively.
411 pub fn cmp(a: *const Int, bv: var) i8 {385 pub fn cmp(a: Int, b: Int) i8 {
412 var buffer: [wrapped_buffer_size]u8 = undefined;
413 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
414 var b = wrapInt(&stack.allocator, bv);
415
416 if (a.positive != b.positive) {386 if (a.positive != b.positive) {
417 return if (a.positive) i8(1) else -1;387 return if (a.positive) i8(1) else -1;
418 } else {388 } else {
...@@ -422,17 +392,17 @@ pub const Int = struct {...@@ -422,17 +392,17 @@ pub const Int = struct {
422 }392 }
423393
424 // if a == 0394 // if a == 0
425 pub fn eqZero(a: *const Int) bool {395 pub fn eqZero(a: Int) bool {
426 return a.len == 1 and a.limbs[0] == 0;396 return a.len == 1 and a.limbs[0] == 0;
427 }397 }
428398
429 // if |a| == |b|399 // if |a| == |b|
430 pub fn eqAbs(a: *const Int, b: var) bool {400 pub fn eqAbs(a: Int, b: Int) bool {
431 return cmpAbs(a, b) == 0;401 return cmpAbs(a, b) == 0;
432 }402 }
433403
434 // if a == b404 // if a == b
435 pub fn eq(a: *const Int, b: var) bool {405 pub fn eq(a: Int, b: Int) bool {
436 return cmp(a, b) == 0;406 return cmp(a, b) == 0;
437 }407 }
438408
...@@ -473,12 +443,7 @@ pub const Int = struct {...@@ -473,12 +443,7 @@ pub const Int = struct {
473 }443 }
474444
475 // r = a + b445 // r = a + b
476 pub fn add(r: *Int, av: var, bv: var) Allocator.Error!void {446 pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void {
477 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
478 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
479 var a = wrapInt(&stack.allocator, av);
480 var b = wrapInt(&stack.allocator, bv);
481
482 if (a.eqZero()) {447 if (a.eqZero()) {
483 try r.copy(b);448 try r.copy(b);
484 return;449 return;
...@@ -547,12 +512,7 @@ pub const Int = struct {...@@ -547,12 +512,7 @@ pub const Int = struct {
547 }512 }
548513
549 // r = a - b514 // r = a - b
550 pub fn sub(r: *Int, av: var, bv: var) !void {515 pub fn sub(r: *Int, a: Int, b: Int) !void {
551 var buffer: [wrapped_buffer_size]u8 = undefined;
552 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
553 var a = wrapInt(&stack.allocator, av);
554 var b = wrapInt(&stack.allocator, bv);
555
556 if (a.positive != b.positive) {516 if (a.positive != b.positive) {
557 if (a.positive) {517 if (a.positive) {
558 // (a) - (-b) => a + b518 // (a) - (-b) => a + b
...@@ -632,14 +592,9 @@ pub const Int = struct {...@@ -632,14 +592,9 @@ pub const Int = struct {
632 // rma = a * b592 // rma = a * b
633 //593 //
634 // For greatest efficiency, ensure rma does not alias a or b.594 // For greatest efficiency, ensure rma does not alias a or b.
635 pub fn mul(rma: *Int, av: var, bv: var) !void {595 pub fn mul(rma: *Int, a: Int, b: Int) !void {
636 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
637 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
638 var a = wrapInt(&stack.allocator, av);
639 var b = wrapInt(&stack.allocator, bv);
640
641 var r = rma;596 var r = rma;
642 var aliased = rma == a or rma == b;597 var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr;
643598
644 var sr: Int = undefined;599 var sr: Int = undefined;
645 if (aliased) {600 if (aliased) {
...@@ -714,29 +669,29 @@ pub const Int = struct {...@@ -714,29 +669,29 @@ pub const Int = struct {
714 }669 }
715 }670 }
716671
717 pub fn divFloor(q: *Int, r: *Int, a: var, b: var) !void {672 pub fn divFloor(q: *Int, r: *Int, a: Int, b: Int) !void {
718 try div(q, r, a, b);673 try div(q, r, a, b);
719674
720 // Trunc -> Floor.675 // Trunc -> Floor.
721 if (!q.positive) {676 if (!q.positive) {
722 try q.sub(q, 1);677 // TODO values less than limb size should guarantee non allocating
723 try r.add(q, 1);678 var one_buffer: [512]u8 = undefined;
679 const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator;
680 const one_ap = try Int.initSet(one_al, 1);
681
682 try q.sub(q.*, one_ap);
683 try r.add(q.*, one_ap);
724 }684 }
725 r.positive = b.positive;685 r.positive = b.positive;
726 }686 }
727687
728 pub fn divTrunc(q: *Int, r: *Int, a: var, b: var) !void {688 pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void {
729 try div(q, r, a, b);689 try div(q, r, a, b);
730 r.positive = a.positive;690 r.positive = a.positive;
731 }691 }
732692
733 // Truncates by default.693 // Truncates by default.
734 fn div(quo: *Int, rem: *Int, av: var, bv: var) !void {694 fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void {
735 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
736 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
737 var a = wrapInt(&stack.allocator, av);
738 var b = wrapInt(&stack.allocator, bv);
739
740 if (b.eqZero()) {695 if (b.eqZero()) {
741 @panic("division by zero");696 @panic("division by zero");
742 }697 }
...@@ -821,8 +776,8 @@ pub const Int = struct {...@@ -821,8 +776,8 @@ pub const Int = struct {
821776
822 // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set)777 // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set)
823 const norm_shift = @clz(y.limbs[y.len - 1]);778 const norm_shift = @clz(y.limbs[y.len - 1]);
824 try x.shiftLeft(x, norm_shift);779 try x.shiftLeft(x.*, norm_shift);
825 try y.shiftLeft(y, norm_shift);780 try y.shiftLeft(y.*, norm_shift);
826781
827 const n = x.len - 1;782 const n = x.len - 1;
828 const t = y.len - 1;783 const t = y.len - 1;
...@@ -832,10 +787,10 @@ pub const Int = struct {...@@ -832,10 +787,10 @@ pub const Int = struct {
832 mem.set(Limb, q.limbs[0..q.len], 0);787 mem.set(Limb, q.limbs[0..q.len], 0);
833788
834 // 2.789 // 2.
835 try tmp.shiftLeft(y, Limb.bit_count * (n - t));790 try tmp.shiftLeft(y.*, Limb.bit_count * (n - t));
836 while (x.cmp(&tmp) >= 0) {791 while (x.cmp(tmp) >= 0) {
837 q.limbs[n - t] += 1;792 q.limbs[n - t] += 1;
838 try x.sub(x, tmp);793 try x.sub(x.*, tmp);
839 }794 }
840795
841 // 3.796 // 3.
...@@ -864,7 +819,7 @@ pub const Int = struct {...@@ -864,7 +819,7 @@ pub const Int = struct {
864 r.limbs[2] = carry;819 r.limbs[2] = carry;
865 r.normN(3);820 r.normN(3);
866821
867 if (r.cmpAbs(&tmp) <= 0) {822 if (r.cmpAbs(tmp) <= 0) {
868 break;823 break;
869 }824 }
870825
...@@ -873,13 +828,13 @@ pub const Int = struct {...@@ -873,13 +828,13 @@ pub const Int = struct {
873828
874 // 3.3829 // 3.3
875 try tmp.set(q.limbs[i - t - 1]);830 try tmp.set(q.limbs[i - t - 1]);
876 try tmp.mul(&tmp, y);831 try tmp.mul(tmp, y.*);
877 try tmp.shiftLeft(&tmp, Limb.bit_count * (i - t - 1));832 try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1));
878 try x.sub(x, &tmp);833 try x.sub(x.*, tmp);
879834
880 if (!x.positive) {835 if (!x.positive) {
881 try tmp.shiftLeft(y, Limb.bit_count * (i - t - 1));836 try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1));
882 try x.add(x, &tmp);837 try x.add(x.*, tmp);
883 q.limbs[i - t - 1] -= 1;838 q.limbs[i - t - 1] -= 1;
884 }839 }
885 }840 }
...@@ -887,16 +842,12 @@ pub const Int = struct {...@@ -887,16 +842,12 @@ pub const Int = struct {
887 // Denormalize842 // Denormalize
888 q.normN(q.len);843 q.normN(q.len);
889844
890 try r.shiftRight(x, norm_shift);845 try r.shiftRight(x.*, norm_shift);
891 r.normN(r.len);846 r.normN(r.len);
892 }847 }
893848
894 // r = a << shift, in other words, r = a * 2^shift849 // r = a << shift, in other words, r = a * 2^shift
895 pub fn shiftLeft(r: *Int, av: var, shift: usize) !void {850 pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void {
896 var buffer: [wrapped_buffer_size]u8 = undefined;
897 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
898 var a = wrapInt(&stack.allocator, av);
899
900 try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1);851 try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1);
901 llshl(r.limbs[0..], a.limbs[0..a.len], shift);852 llshl(r.limbs[0..], a.limbs[0..a.len], shift);
902 r.norm1(a.len + (shift / Limb.bit_count) + 1);853 r.norm1(a.len + (shift / Limb.bit_count) + 1);
...@@ -927,11 +878,7 @@ pub const Int = struct {...@@ -927,11 +878,7 @@ pub const Int = struct {
927 }878 }
928879
929 // r = a >> shift880 // r = a >> shift
930 pub fn shiftRight(r: *Int, av: var, shift: usize) !void {881 pub fn shiftRight(r: *Int, a: Int, shift: usize) !void {
931 var buffer: [wrapped_buffer_size]u8 = undefined;
932 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
933 var a = wrapInt(&stack.allocator, av);
934
935 if (a.len <= shift / Limb.bit_count) {882 if (a.len <= shift / Limb.bit_count) {
936 r.len = 1;883 r.len = 1;
937 r.limbs[0] = 0;884 r.limbs[0] = 0;
...@@ -966,12 +913,7 @@ pub const Int = struct {...@@ -966,12 +913,7 @@ pub const Int = struct {
966 }913 }
967914
968 // r = a | b915 // r = a | b
969 pub fn bitOr(r: *Int, av: var, bv: var) !void {916 pub fn bitOr(r: *Int, a: Int, b: Int) !void {
970 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
971 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
972 var a = wrapInt(&stack.allocator, av);
973 var b = wrapInt(&stack.allocator, bv);
974
975 if (a.len > b.len) {917 if (a.len > b.len) {
976 try r.ensureCapacity(a.len);918 try r.ensureCapacity(a.len);
977 llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);919 llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
...@@ -998,12 +940,7 @@ pub const Int = struct {...@@ -998,12 +940,7 @@ pub const Int = struct {
998 }940 }
999941
1000 // r = a & b942 // r = a & b
1001 pub fn bitAnd(r: *Int, av: var, bv: var) !void {943 pub fn bitAnd(r: *Int, a: Int, b: Int) !void {
1002 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
1003 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
1004 var a = wrapInt(&stack.allocator, av);
1005 var b = wrapInt(&stack.allocator, bv);
1006
1007 if (a.len > b.len) {944 if (a.len > b.len) {
1008 try r.ensureCapacity(b.len);945 try r.ensureCapacity(b.len);
1009 lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);946 lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
...@@ -1027,12 +964,7 @@ pub const Int = struct {...@@ -1027,12 +964,7 @@ pub const Int = struct {
1027 }964 }
1028965
1029 // r = a ^ b966 // r = a ^ b
1030 pub fn bitXor(r: *Int, av: var, bv: var) !void {967 pub fn bitXor(r: *Int, a: Int, b: Int) !void {
1031 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
1032 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
1033 var a = wrapInt(&stack.allocator, av);
1034 var b = wrapInt(&stack.allocator, bv);
1035
1036 if (a.len > b.len) {968 if (a.len > b.len) {
1037 try r.ensureCapacity(a.len);969 try r.ensureCapacity(a.len);
1038 llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);970 llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
...@@ -1065,7 +997,7 @@ pub const Int = struct {...@@ -1065,7 +997,7 @@ pub const Int = struct {
1065// may be untested in some cases.997// may be untested in some cases.
1066998
1067const u256 = @IntType(false, 256);999const u256 = @IntType(false, 256);
1068var al = debug.global_allocator;1000const al = debug.global_allocator;
10691001
1070test "big.int comptime_int set" {1002test "big.int comptime_int set" {
1071 comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;1003 comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;
...@@ -1198,7 +1130,7 @@ test "big.int bitcount + sizeInBase" {...@@ -1198,7 +1130,7 @@ test "big.int bitcount + sizeInBase" {
1198 debug.assert(a.sizeInBase(2) >= 32);1130 debug.assert(a.sizeInBase(2) >= 32);
1199 debug.assert(a.sizeInBase(10) >= 10);1131 debug.assert(a.sizeInBase(10) >= 10);
12001132
1201 try a.shiftLeft(&a, 5000);1133 try a.shiftLeft(a, 5000);
1202 debug.assert(a.bitcount() == 5032);1134 debug.assert(a.bitcount() == 5032);
1203 debug.assert(a.sizeInBase(2) >= 5032);1135 debug.assert(a.sizeInBase(2) >= 5032);
1204 a.positive = false;1136 a.positive = false;
...@@ -1320,40 +1252,40 @@ test "big.int compare" {...@@ -1320,40 +1252,40 @@ test "big.int compare" {
1320 var a = try Int.initSet(al, -11);1252 var a = try Int.initSet(al, -11);
1321 var b = try Int.initSet(al, 10);1253 var b = try Int.initSet(al, 10);
13221254
1323 debug.assert(a.cmpAbs(&b) == 1);1255 debug.assert(a.cmpAbs(b) == 1);
1324 debug.assert(a.cmp(&b) == -1);1256 debug.assert(a.cmp(b) == -1);
1325}1257}
13261258
1327test "big.int compare similar" {1259test "big.int compare similar" {
1328 var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee);1260 var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee);
1329 var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef);1261 var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef);
13301262
1331 debug.assert(a.cmpAbs(&b) == -1);1263 debug.assert(a.cmpAbs(b) == -1);
1332 debug.assert(b.cmpAbs(&a) == 1);1264 debug.assert(b.cmpAbs(a) == 1);
1333}1265}
13341266
1335test "big.int compare different limb size" {1267test "big.int compare different limb size" {
1336 var a = try Int.initSet(al, @maxValue(Limb) + 1);1268 var a = try Int.initSet(al, @maxValue(Limb) + 1);
1337 var b = try Int.initSet(al, 1);1269 var b = try Int.initSet(al, 1);
13381270
1339 debug.assert(a.cmpAbs(&b) == 1);1271 debug.assert(a.cmpAbs(b) == 1);
1340 debug.assert(b.cmpAbs(&a) == -1);1272 debug.assert(b.cmpAbs(a) == -1);
1341}1273}
13421274
1343test "big.int compare multi-limb" {1275test "big.int compare multi-limb" {
1344 var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);1276 var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);
1345 var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);1277 var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);
13461278
1347 debug.assert(a.cmpAbs(&b) == 1);1279 debug.assert(a.cmpAbs(b) == 1);
1348 debug.assert(a.cmp(&b) == -1);1280 debug.assert(a.cmp(b) == -1);
1349}1281}
13501282
1351test "big.int equality" {1283test "big.int equality" {
1352 var a = try Int.initSet(al, 0xffffffff1);1284 var a = try Int.initSet(al, 0xffffffff1);
1353 var b = try Int.initSet(al, -0xffffffff1);1285 var b = try Int.initSet(al, -0xffffffff1);
13541286
1355 debug.assert(a.eqAbs(&b));1287 debug.assert(a.eqAbs(b));
1356 debug.assert(!a.eq(&b));1288 debug.assert(!a.eq(b));
1357}1289}
13581290
1359test "big.int abs" {1291test "big.int abs" {
...@@ -1381,7 +1313,7 @@ test "big.int add single-single" {...@@ -1381,7 +1313,7 @@ test "big.int add single-single" {
1381 var b = try Int.initSet(al, 5);1313 var b = try Int.initSet(al, 5);
13821314
1383 var c = try Int.init(al);1315 var c = try Int.init(al);
1384 try c.add(&a, &b);1316 try c.add(a, b);
13851317
1386 debug.assert((try c.to(u32)) == 55);1318 debug.assert((try c.to(u32)) == 55);
1387}1319}
...@@ -1392,10 +1324,10 @@ test "big.int add multi-single" {...@@ -1392,10 +1324,10 @@ test "big.int add multi-single" {
13921324
1393 var c = try Int.init(al);1325 var c = try Int.init(al);
13941326
1395 try c.add(&a, &b);1327 try c.add(a, b);
1396 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);1328 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);
13971329
1398 try c.add(&b, &a);1330 try c.add(b, a);
1399 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);1331 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);
1400}1332}
14011333
...@@ -1406,7 +1338,7 @@ test "big.int add multi-multi" {...@@ -1406,7 +1338,7 @@ test "big.int add multi-multi" {
1406 var b = try Int.initSet(al, op2);1338 var b = try Int.initSet(al, op2);
14071339
1408 var c = try Int.init(al);1340 var c = try Int.init(al);
1409 try c.add(&a, &b);1341 try c.add(a, b);
14101342
1411 debug.assert((try c.to(u128)) == op1 + op2);1343 debug.assert((try c.to(u128)) == op1 + op2);
1412}1344}
...@@ -1416,7 +1348,7 @@ test "big.int add zero-zero" {...@@ -1416,7 +1348,7 @@ test "big.int add zero-zero" {
1416 var b = try Int.initSet(al, 0);1348 var b = try Int.initSet(al, 0);
14171349
1418 var c = try Int.init(al);1350 var c = try Int.init(al);
1419 try c.add(&a, &b);1351 try c.add(a, b);
14201352
1421 debug.assert((try c.to(u32)) == 0);1353 debug.assert((try c.to(u32)) == 0);
1422}1354}
...@@ -1426,7 +1358,7 @@ test "big.int add alias multi-limb nonzero-zero" {...@@ -1426,7 +1358,7 @@ test "big.int add alias multi-limb nonzero-zero" {
1426 var a = try Int.initSet(al, op1);1358 var a = try Int.initSet(al, op1);
1427 var b = try Int.initSet(al, 0);1359 var b = try Int.initSet(al, 0);
14281360
1429 try a.add(&a, &b);1361 try a.add(a, b);
14301362
1431 debug.assert((try a.to(u128)) == op1);1363 debug.assert((try a.to(u128)) == op1);
1432}1364}
...@@ -1434,16 +1366,21 @@ test "big.int add alias multi-limb nonzero-zero" {...@@ -1434,16 +1366,21 @@ test "big.int add alias multi-limb nonzero-zero" {
1434test "big.int add sign" {1366test "big.int add sign" {
1435 var a = try Int.init(al);1367 var a = try Int.init(al);
14361368
1437 try a.add(1, 2);1369 const one = try Int.initSet(al, 1);
1370 const two = try Int.initSet(al, 2);
1371 const neg_one = try Int.initSet(al, -1);
1372 const neg_two = try Int.initSet(al, -2);
1373
1374 try a.add(one, two);
1438 debug.assert((try a.to(i32)) == 3);1375 debug.assert((try a.to(i32)) == 3);
14391376
1440 try a.add(-1, 2);1377 try a.add(neg_one, two);
1441 debug.assert((try a.to(i32)) == 1);1378 debug.assert((try a.to(i32)) == 1);
14421379
1443 try a.add(1, -2);1380 try a.add(one, neg_two);
1444 debug.assert((try a.to(i32)) == -1);1381 debug.assert((try a.to(i32)) == -1);
14451382
1446 try a.add(-1, -2);1383 try a.add(neg_one, neg_two);
1447 debug.assert((try a.to(i32)) == -3);1384 debug.assert((try a.to(i32)) == -3);
1448}1385}
14491386
...@@ -1452,7 +1389,7 @@ test "big.int sub single-single" {...@@ -1452,7 +1389,7 @@ test "big.int sub single-single" {
1452 var b = try Int.initSet(al, 5);1389 var b = try Int.initSet(al, 5);
14531390
1454 var c = try Int.init(al);1391 var c = try Int.init(al);
1455 try c.sub(&a, &b);1392 try c.sub(a, b);
14561393
1457 debug.assert((try c.to(u32)) == 45);1394 debug.assert((try c.to(u32)) == 45);
1458}1395}
...@@ -1462,7 +1399,7 @@ test "big.int sub multi-single" {...@@ -1462,7 +1399,7 @@ test "big.int sub multi-single" {
1462 var b = try Int.initSet(al, 1);1399 var b = try Int.initSet(al, 1);
14631400
1464 var c = try Int.init(al);1401 var c = try Int.init(al);
1465 try c.sub(&a, &b);1402 try c.sub(a, b);
14661403
1467 debug.assert((try c.to(Limb)) == @maxValue(Limb));1404 debug.assert((try c.to(Limb)) == @maxValue(Limb));
1468}1405}
...@@ -1475,7 +1412,7 @@ test "big.int sub multi-multi" {...@@ -1475,7 +1412,7 @@ test "big.int sub multi-multi" {
1475 var b = try Int.initSet(al, op2);1412 var b = try Int.initSet(al, op2);
14761413
1477 var c = try Int.init(al);1414 var c = try Int.init(al);
1478 try c.sub(&a, &b);1415 try c.sub(a, b);
14791416
1480 debug.assert((try c.to(u128)) == op1 - op2);1417 debug.assert((try c.to(u128)) == op1 - op2);
1481}1418}
...@@ -1485,7 +1422,7 @@ test "big.int sub equal" {...@@ -1485,7 +1422,7 @@ test "big.int sub equal" {
1485 var b = try Int.initSet(al, 0x11efefefefefefefefefefefef);1422 var b = try Int.initSet(al, 0x11efefefefefefefefefefefef);
14861423
1487 var c = try Int.init(al);1424 var c = try Int.init(al);
1488 try c.sub(&a, &b);1425 try c.sub(a, b);
14891426
1490 debug.assert((try c.to(u32)) == 0);1427 debug.assert((try c.to(u32)) == 0);
1491}1428}
...@@ -1493,19 +1430,24 @@ test "big.int sub equal" {...@@ -1493,19 +1430,24 @@ test "big.int sub equal" {
1493test "big.int sub sign" {1430test "big.int sub sign" {
1494 var a = try Int.init(al);1431 var a = try Int.init(al);
14951432
1496 try a.sub(1, 2);1433 const one = try Int.initSet(al, 1);
1434 const two = try Int.initSet(al, 2);
1435 const neg_one = try Int.initSet(al, -1);
1436 const neg_two = try Int.initSet(al, -2);
1437
1438 try a.sub(one, two);
1497 debug.assert((try a.to(i32)) == -1);1439 debug.assert((try a.to(i32)) == -1);
14981440
1499 try a.sub(-1, 2);1441 try a.sub(neg_one, two);
1500 debug.assert((try a.to(i32)) == -3);1442 debug.assert((try a.to(i32)) == -3);
15011443
1502 try a.sub(1, -2);1444 try a.sub(one, neg_two);
1503 debug.assert((try a.to(i32)) == 3);1445 debug.assert((try a.to(i32)) == 3);
15041446
1505 try a.sub(-1, -2);1447 try a.sub(neg_one, neg_two);
1506 debug.assert((try a.to(i32)) == 1);1448 debug.assert((try a.to(i32)) == 1);
15071449
1508 try a.sub(-2, -1);1450 try a.sub(neg_two, neg_one);
1509 debug.assert((try a.to(i32)) == -1);1451 debug.assert((try a.to(i32)) == -1);
1510}1452}
15111453
...@@ -1514,7 +1456,7 @@ test "big.int mul single-single" {...@@ -1514,7 +1456,7 @@ test "big.int mul single-single" {
1514 var b = try Int.initSet(al, 5);1456 var b = try Int.initSet(al, 5);
15151457
1516 var c = try Int.init(al);1458 var c = try Int.init(al);
1517 try c.mul(&a, &b);1459 try c.mul(a, b);
15181460
1519 debug.assert((try c.to(u64)) == 250);1461 debug.assert((try c.to(u64)) == 250);
1520}1462}
...@@ -1524,7 +1466,7 @@ test "big.int mul multi-single" {...@@ -1524,7 +1466,7 @@ test "big.int mul multi-single" {
1524 var b = try Int.initSet(al, 2);1466 var b = try Int.initSet(al, 2);
15251467
1526 var c = try Int.init(al);1468 var c = try Int.init(al);
1527 try c.mul(&a, &b);1469 try c.mul(a, b);
15281470
1529 debug.assert((try c.to(DoubleLimb)) == 2 * @maxValue(Limb));1471 debug.assert((try c.to(DoubleLimb)) == 2 * @maxValue(Limb));
1530}1472}
...@@ -1536,7 +1478,7 @@ test "big.int mul multi-multi" {...@@ -1536,7 +1478,7 @@ test "big.int mul multi-multi" {
1536 var b = try Int.initSet(al, op2);1478 var b = try Int.initSet(al, op2);
15371479
1538 var c = try Int.init(al);1480 var c = try Int.init(al);
1539 try c.mul(&a, &b);1481 try c.mul(a, b);
15401482
1541 debug.assert((try c.to(u256)) == op1 * op2);1483 debug.assert((try c.to(u256)) == op1 * op2);
1542}1484}
...@@ -1545,7 +1487,7 @@ test "big.int mul alias r with a" {...@@ -1545,7 +1487,7 @@ test "big.int mul alias r with a" {
1545 var a = try Int.initSet(al, @maxValue(Limb));1487 var a = try Int.initSet(al, @maxValue(Limb));
1546 var b = try Int.initSet(al, 2);1488 var b = try Int.initSet(al, 2);
15471489
1548 try a.mul(&a, &b);1490 try a.mul(a, b);
15491491
1550 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));1492 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));
1551}1493}
...@@ -1554,7 +1496,7 @@ test "big.int mul alias r with b" {...@@ -1554,7 +1496,7 @@ test "big.int mul alias r with b" {
1554 var a = try Int.initSet(al, @maxValue(Limb));1496 var a = try Int.initSet(al, @maxValue(Limb));
1555 var b = try Int.initSet(al, 2);1497 var b = try Int.initSet(al, 2);
15561498
1557 try a.mul(&b, &a);1499 try a.mul(b, a);
15581500
1559 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));1501 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));
1560}1502}
...@@ -1562,7 +1504,7 @@ test "big.int mul alias r with b" {...@@ -1562,7 +1504,7 @@ test "big.int mul alias r with b" {
1562test "big.int mul alias r with a and b" {1504test "big.int mul alias r with a and b" {
1563 var a = try Int.initSet(al, @maxValue(Limb));1505 var a = try Int.initSet(al, @maxValue(Limb));
15641506
1565 try a.mul(&a, &a);1507 try a.mul(a, a);
15661508
1567 debug.assert((try a.to(DoubleLimb)) == @maxValue(Limb) * @maxValue(Limb));1509 debug.assert((try a.to(DoubleLimb)) == @maxValue(Limb) * @maxValue(Limb));
1568}1510}
...@@ -1572,7 +1514,7 @@ test "big.int mul a*0" {...@@ -1572,7 +1514,7 @@ test "big.int mul a*0" {
1572 var b = try Int.initSet(al, 0);1514 var b = try Int.initSet(al, 0);
15731515
1574 var c = try Int.init(al);1516 var c = try Int.init(al);
1575 try c.mul(&a, &b);1517 try c.mul(a, b);
15761518
1577 debug.assert((try c.to(u32)) == 0);1519 debug.assert((try c.to(u32)) == 0);
1578}1520}
...@@ -1582,7 +1524,7 @@ test "big.int mul 0*0" {...@@ -1582,7 +1524,7 @@ test "big.int mul 0*0" {
1582 var b = try Int.initSet(al, 0);1524 var b = try Int.initSet(al, 0);
15831525
1584 var c = try Int.init(al);1526 var c = try Int.init(al);
1585 try c.mul(&a, &b);1527 try c.mul(a, b);
15861528
1587 debug.assert((try c.to(u32)) == 0);1529 debug.assert((try c.to(u32)) == 0);
1588}1530}
...@@ -1593,7 +1535,7 @@ test "big.int div single-single no rem" {...@@ -1593,7 +1535,7 @@ test "big.int div single-single no rem" {
15931535
1594 var q = try Int.init(al);1536 var q = try Int.init(al);
1595 var r = try Int.init(al);1537 var r = try Int.init(al);
1596 try Int.divTrunc(&q, &r, &a, &b);1538 try Int.divTrunc(&q, &r, a, b);
15971539
1598 debug.assert((try q.to(u32)) == 10);1540 debug.assert((try q.to(u32)) == 10);
1599 debug.assert((try r.to(u32)) == 0);1541 debug.assert((try r.to(u32)) == 0);
...@@ -1605,7 +1547,7 @@ test "big.int div single-single with rem" {...@@ -1605,7 +1547,7 @@ test "big.int div single-single with rem" {
16051547
1606 var q = try Int.init(al);1548 var q = try Int.init(al);
1607 var r = try Int.init(al);1549 var r = try Int.init(al);
1608 try Int.divTrunc(&q, &r, &a, &b);1550 try Int.divTrunc(&q, &r, a, b);
16091551
1610 debug.assert((try q.to(u32)) == 9);1552 debug.assert((try q.to(u32)) == 9);
1611 debug.assert((try r.to(u32)) == 4);1553 debug.assert((try r.to(u32)) == 4);
...@@ -1620,7 +1562,7 @@ test "big.int div multi-single no rem" {...@@ -1620,7 +1562,7 @@ test "big.int div multi-single no rem" {
16201562
1621 var q = try Int.init(al);1563 var q = try Int.init(al);
1622 var r = try Int.init(al);1564 var r = try Int.init(al);
1623 try Int.divTrunc(&q, &r, &a, &b);1565 try Int.divTrunc(&q, &r, a, b);
16241566
1625 debug.assert((try q.to(u64)) == op1 / op2);1567 debug.assert((try q.to(u64)) == op1 / op2);
1626 debug.assert((try r.to(u64)) == 0);1568 debug.assert((try r.to(u64)) == 0);
...@@ -1635,7 +1577,7 @@ test "big.int div multi-single with rem" {...@@ -1635,7 +1577,7 @@ test "big.int div multi-single with rem" {
16351577
1636 var q = try Int.init(al);1578 var q = try Int.init(al);
1637 var r = try Int.init(al);1579 var r = try Int.init(al);
1638 try Int.divTrunc(&q, &r, &a, &b);1580 try Int.divTrunc(&q, &r, a, b);
16391581
1640 debug.assert((try q.to(u64)) == op1 / op2);1582 debug.assert((try q.to(u64)) == op1 / op2);
1641 debug.assert((try r.to(u64)) == 3);1583 debug.assert((try r.to(u64)) == 3);
...@@ -1650,7 +1592,7 @@ test "big.int div multi>2-single" {...@@ -1650,7 +1592,7 @@ test "big.int div multi>2-single" {
16501592
1651 var q = try Int.init(al);1593 var q = try Int.init(al);
1652 var r = try Int.init(al);1594 var r = try Int.init(al);
1653 try Int.divTrunc(&q, &r, &a, &b);1595 try Int.divTrunc(&q, &r, a, b);
16541596
1655 debug.assert((try q.to(u128)) == op1 / op2);1597 debug.assert((try q.to(u128)) == op1 / op2);
1656 debug.assert((try r.to(u32)) == 0x3e4e);1598 debug.assert((try r.to(u32)) == 0x3e4e);
...@@ -1662,7 +1604,7 @@ test "big.int div single-single q < r" {...@@ -1662,7 +1604,7 @@ test "big.int div single-single q < r" {
16621604
1663 var q = try Int.init(al);1605 var q = try Int.init(al);
1664 var r = try Int.init(al);1606 var r = try Int.init(al);
1665 try Int.divTrunc(&q, &r, &a, &b);1607 try Int.divTrunc(&q, &r, a, b);
16661608
1667 debug.assert((try q.to(u64)) == 0);1609 debug.assert((try q.to(u64)) == 0);
1668 debug.assert((try r.to(u64)) == 0x0078f432);1610 debug.assert((try r.to(u64)) == 0x0078f432);
...@@ -1674,7 +1616,7 @@ test "big.int div single-single q == r" {...@@ -1674,7 +1616,7 @@ test "big.int div single-single q == r" {
16741616
1675 var q = try Int.init(al);1617 var q = try Int.init(al);
1676 var r = try Int.init(al);1618 var r = try Int.init(al);
1677 try Int.divTrunc(&q, &r, &a, &b);1619 try Int.divTrunc(&q, &r, a, b);
16781620
1679 debug.assert((try q.to(u64)) == 1);1621 debug.assert((try q.to(u64)) == 1);
1680 debug.assert((try r.to(u64)) == 0);1622 debug.assert((try r.to(u64)) == 0);
...@@ -1684,7 +1626,7 @@ test "big.int div q=0 alias" {...@@ -1684,7 +1626,7 @@ test "big.int div q=0 alias" {
1684 var a = try Int.initSet(al, 3);1626 var a = try Int.initSet(al, 3);
1685 var b = try Int.initSet(al, 10);1627 var b = try Int.initSet(al, 10);
16861628
1687 try Int.divTrunc(&a, &b, &a, &b);1629 try Int.divTrunc(&a, &b, a, b);
16881630
1689 debug.assert((try a.to(u64)) == 0);1631 debug.assert((try a.to(u64)) == 0);
1690 debug.assert((try b.to(u64)) == 3);1632 debug.assert((try b.to(u64)) == 3);
...@@ -1698,7 +1640,7 @@ test "big.int div multi-multi q < r" {...@@ -1698,7 +1640,7 @@ test "big.int div multi-multi q < r" {
16981640
1699 var q = try Int.init(al);1641 var q = try Int.init(al);
1700 var r = try Int.init(al);1642 var r = try Int.init(al);
1701 try Int.divTrunc(&q, &r, &a, &b);1643 try Int.divTrunc(&q, &r, a, b);
17021644
1703 debug.assert((try q.to(u128)) == 0);1645 debug.assert((try q.to(u128)) == 0);
1704 debug.assert((try r.to(u128)) == op1);1646 debug.assert((try r.to(u128)) == op1);
...@@ -1713,7 +1655,7 @@ test "big.int div trunc single-single +/+" {...@@ -1713,7 +1655,7 @@ test "big.int div trunc single-single +/+" {
17131655
1714 var q = try Int.init(al);1656 var q = try Int.init(al);
1715 var r = try Int.init(al);1657 var r = try Int.init(al);
1716 try Int.divTrunc(&q, &r, &a, &b);1658 try Int.divTrunc(&q, &r, a, b);
17171659
1718 // n = q * d + r1660 // n = q * d + r
1719 // 5 = 1 * 3 + 21661 // 5 = 1 * 3 + 2
...@@ -1733,7 +1675,7 @@ test "big.int div trunc single-single -/+" {...@@ -1733,7 +1675,7 @@ test "big.int div trunc single-single -/+" {
17331675
1734 var q = try Int.init(al);1676 var q = try Int.init(al);
1735 var r = try Int.init(al);1677 var r = try Int.init(al);
1736 try Int.divTrunc(&q, &r, &a, &b);1678 try Int.divTrunc(&q, &r, a, b);
17371679
1738 // n = q * d + r1680 // n = q * d + r
1739 // -5 = 1 * -3 - 21681 // -5 = 1 * -3 - 2
...@@ -1753,7 +1695,7 @@ test "big.int div trunc single-single +/-" {...@@ -1753,7 +1695,7 @@ test "big.int div trunc single-single +/-" {
17531695
1754 var q = try Int.init(al);1696 var q = try Int.init(al);
1755 var r = try Int.init(al);1697 var r = try Int.init(al);
1756 try Int.divTrunc(&q, &r, &a, &b);1698 try Int.divTrunc(&q, &r, a, b);
17571699
1758 // n = q * d + r1700 // n = q * d + r
1759 // 5 = -1 * -3 + 21701 // 5 = -1 * -3 + 2
...@@ -1773,7 +1715,7 @@ test "big.int div trunc single-single -/-" {...@@ -1773,7 +1715,7 @@ test "big.int div trunc single-single -/-" {
17731715
1774 var q = try Int.init(al);1716 var q = try Int.init(al);
1775 var r = try Int.init(al);1717 var r = try Int.init(al);
1776 try Int.divTrunc(&q, &r, &a, &b);1718 try Int.divTrunc(&q, &r, a, b);
17771719
1778 // n = q * d + r1720 // n = q * d + r
1779 // -5 = 1 * -3 - 21721 // -5 = 1 * -3 - 2
...@@ -1793,7 +1735,7 @@ test "big.int div floor single-single +/+" {...@@ -1793,7 +1735,7 @@ test "big.int div floor single-single +/+" {
17931735
1794 var q = try Int.init(al);1736 var q = try Int.init(al);
1795 var r = try Int.init(al);1737 var r = try Int.init(al);
1796 try Int.divFloor(&q, &r, &a, &b);1738 try Int.divFloor(&q, &r, a, b);
17971739
1798 // n = q * d + r1740 // n = q * d + r
1799 // 5 = 1 * 3 + 21741 // 5 = 1 * 3 + 2
...@@ -1813,7 +1755,7 @@ test "big.int div floor single-single -/+" {...@@ -1813,7 +1755,7 @@ test "big.int div floor single-single -/+" {
18131755
1814 var q = try Int.init(al);1756 var q = try Int.init(al);
1815 var r = try Int.init(al);1757 var r = try Int.init(al);
1816 try Int.divFloor(&q, &r, &a, &b);1758 try Int.divFloor(&q, &r, a, b);
18171759
1818 // n = q * d + r1760 // n = q * d + r
1819 // -5 = -2 * 3 + 11761 // -5 = -2 * 3 + 1
...@@ -1833,7 +1775,7 @@ test "big.int div floor single-single +/-" {...@@ -1833,7 +1775,7 @@ test "big.int div floor single-single +/-" {
18331775
1834 var q = try Int.init(al);1776 var q = try Int.init(al);
1835 var r = try Int.init(al);1777 var r = try Int.init(al);
1836 try Int.divFloor(&q, &r, &a, &b);1778 try Int.divFloor(&q, &r, a, b);
18371779
1838 // n = q * d + r1780 // n = q * d + r
1839 // 5 = -2 * -3 - 11781 // 5 = -2 * -3 - 1
...@@ -1853,7 +1795,7 @@ test "big.int div floor single-single -/-" {...@@ -1853,7 +1795,7 @@ test "big.int div floor single-single -/-" {
18531795
1854 var q = try Int.init(al);1796 var q = try Int.init(al);
1855 var r = try Int.init(al);1797 var r = try Int.init(al);
1856 try Int.divFloor(&q, &r, &a, &b);1798 try Int.divFloor(&q, &r, a, b);
18571799
1858 // n = q * d + r1800 // n = q * d + r
1859 // -5 = 2 * -3 + 11801 // -5 = 2 * -3 + 1
...@@ -1870,7 +1812,7 @@ test "big.int div multi-multi with rem" {...@@ -1870,7 +1812,7 @@ test "big.int div multi-multi with rem" {
18701812
1871 var q = try Int.init(al);1813 var q = try Int.init(al);
1872 var r = try Int.init(al);1814 var r = try Int.init(al);
1873 try Int.divTrunc(&q, &r, &a, &b);1815 try Int.divTrunc(&q, &r, a, b);
18741816
1875 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);1817 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
1876 debug.assert((try r.to(u128)) == 0x28de0acacd806823638);1818 debug.assert((try r.to(u128)) == 0x28de0acacd806823638);
...@@ -1882,7 +1824,7 @@ test "big.int div multi-multi no rem" {...@@ -1882,7 +1824,7 @@ test "big.int div multi-multi no rem" {
18821824
1883 var q = try Int.init(al);1825 var q = try Int.init(al);
1884 var r = try Int.init(al);1826 var r = try Int.init(al);
1885 try Int.divTrunc(&q, &r, &a, &b);1827 try Int.divTrunc(&q, &r, a, b);
18861828
1887 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);1829 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
1888 debug.assert((try r.to(u128)) == 0);1830 debug.assert((try r.to(u128)) == 0);
...@@ -1894,7 +1836,7 @@ test "big.int div multi-multi (2 branch)" {...@@ -1894,7 +1836,7 @@ test "big.int div multi-multi (2 branch)" {
18941836
1895 var q = try Int.init(al);1837 var q = try Int.init(al);
1896 var r = try Int.init(al);1838 var r = try Int.init(al);
1897 try Int.divTrunc(&q, &r, &a, &b);1839 try Int.divTrunc(&q, &r, a, b);
18981840
1899 debug.assert((try q.to(u128)) == 0x10000000000000000);1841 debug.assert((try q.to(u128)) == 0x10000000000000000);
1900 debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111);1842 debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111);
...@@ -1906,7 +1848,7 @@ test "big.int div multi-multi (3.1/3.3 branch)" {...@@ -1906,7 +1848,7 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
19061848
1907 var q = try Int.init(al);1849 var q = try Int.init(al);
1908 var r = try Int.init(al);1850 var r = try Int.init(al);
1909 try Int.divTrunc(&q, &r, &a, &b);1851 try Int.divTrunc(&q, &r, a, b);
19101852
1911 debug.assert((try q.to(u128)) == 0xfffffffffffffffffff);1853 debug.assert((try q.to(u128)) == 0xfffffffffffffffffff);
1912 debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);1854 debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
...@@ -1943,17 +1885,17 @@ test "big.int shift-left multi" {...@@ -1943,17 +1885,17 @@ test "big.int shift-left multi" {
1943test "big.int shift-right negative" {1885test "big.int shift-right negative" {
1944 var a = try Int.init(al);1886 var a = try Int.init(al);
19451887
1946 try a.shiftRight(-20, 2);1888 try a.shiftRight(try Int.initSet(al, -20), 2);
1947 debug.assert((try a.to(i32)) == -20 >> 2);1889 debug.assert((try a.to(i32)) == -20 >> 2);
19481890
1949 try a.shiftRight(-5, 10);1891 try a.shiftRight(try Int.initSet(al, -5), 10);
1950 debug.assert((try a.to(i32)) == -5 >> 10);1892 debug.assert((try a.to(i32)) == -5 >> 10);
1951}1893}
19521894
1953test "big.int shift-left negative" {1895test "big.int shift-left negative" {
1954 var a = try Int.init(al);1896 var a = try Int.init(al);
19551897
1956 try a.shiftRight(-10, 1232);1898 try a.shiftRight(try Int.initSet(al, -10), 1232);
1957 debug.assert((try a.to(i32)) == -10 >> 1232);1899 debug.assert((try a.to(i32)) == -10 >> 1232);
1958}1900}
19591901
...@@ -1961,7 +1903,7 @@ test "big.int bitwise and simple" {...@@ -1961,7 +1903,7 @@ test "big.int bitwise and simple" {
1961 var a = try Int.initSet(al, 0xffffffff11111111);1903 var a = try Int.initSet(al, 0xffffffff11111111);
1962 var b = try Int.initSet(al, 0xeeeeeeee22222222);1904 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19631905
1964 try a.bitAnd(&a, &b);1906 try a.bitAnd(a, b);
19651907
1966 debug.assert((try a.to(u64)) == 0xeeeeeeee00000000);1908 debug.assert((try a.to(u64)) == 0xeeeeeeee00000000);
1967}1909}
...@@ -1970,7 +1912,7 @@ test "big.int bitwise and multi-limb" {...@@ -1970,7 +1912,7 @@ test "big.int bitwise and multi-limb" {
1970 var a = try Int.initSet(al, @maxValue(Limb) + 1);1912 var a = try Int.initSet(al, @maxValue(Limb) + 1);
1971 var b = try Int.initSet(al, @maxValue(Limb));1913 var b = try Int.initSet(al, @maxValue(Limb));
19721914
1973 try a.bitAnd(&a, &b);1915 try a.bitAnd(a, b);
19741916
1975 debug.assert((try a.to(u128)) == 0);1917 debug.assert((try a.to(u128)) == 0);
1976}1918}
...@@ -1979,7 +1921,7 @@ test "big.int bitwise xor simple" {...@@ -1979,7 +1921,7 @@ test "big.int bitwise xor simple" {
1979 var a = try Int.initSet(al, 0xffffffff11111111);1921 var a = try Int.initSet(al, 0xffffffff11111111);
1980 var b = try Int.initSet(al, 0xeeeeeeee22222222);1922 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19811923
1982 try a.bitXor(&a, &b);1924 try a.bitXor(a, b);
19831925
1984 debug.assert((try a.to(u64)) == 0x1111111133333333);1926 debug.assert((try a.to(u64)) == 0x1111111133333333);
1985}1927}
...@@ -1988,7 +1930,7 @@ test "big.int bitwise xor multi-limb" {...@@ -1988,7 +1930,7 @@ test "big.int bitwise xor multi-limb" {
1988 var a = try Int.initSet(al, @maxValue(Limb) + 1);1930 var a = try Int.initSet(al, @maxValue(Limb) + 1);
1989 var b = try Int.initSet(al, @maxValue(Limb));1931 var b = try Int.initSet(al, @maxValue(Limb));
19901932
1991 try a.bitXor(&a, &b);1933 try a.bitXor(a, b);
19921934
1993 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) ^ @maxValue(Limb));1935 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) ^ @maxValue(Limb));
1994}1936}
...@@ -1997,7 +1939,7 @@ test "big.int bitwise or simple" {...@@ -1997,7 +1939,7 @@ test "big.int bitwise or simple" {
1997 var a = try Int.initSet(al, 0xffffffff11111111);1939 var a = try Int.initSet(al, 0xffffffff11111111);
1998 var b = try Int.initSet(al, 0xeeeeeeee22222222);1940 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19991941
2000 try a.bitOr(&a, &b);1942 try a.bitOr(a, b);
20011943
2002 debug.assert((try a.to(u64)) == 0xffffffff33333333);1944 debug.assert((try a.to(u64)) == 0xffffffff33333333);
2003}1945}
...@@ -2006,7 +1948,7 @@ test "big.int bitwise or multi-limb" {...@@ -2006,7 +1948,7 @@ test "big.int bitwise or multi-limb" {
2006 var a = try Int.initSet(al, @maxValue(Limb) + 1);1948 var a = try Int.initSet(al, @maxValue(Limb) + 1);
2007 var b = try Int.initSet(al, @maxValue(Limb));1949 var b = try Int.initSet(al, @maxValue(Limb));
20081950
2009 try a.bitOr(&a, &b);1951 try a.bitOr(a, b);
20101952
2011 // TODO: big.int.cpp or is wrong on multi-limb.1953 // TODO: big.int.cpp or is wrong on multi-limb.
2012 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) + @maxValue(Limb));1954 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) + @maxValue(Limb));
...@@ -2015,9 +1957,9 @@ test "big.int bitwise or multi-limb" {...@@ -2015,9 +1957,9 @@ test "big.int bitwise or multi-limb" {
2015test "big.int var args" {1957test "big.int var args" {
2016 var a = try Int.initSet(al, 5);1958 var a = try Int.initSet(al, 5);
20171959
2018 try a.add(&a, 6);1960 try a.add(a, try Int.initSet(al, 6));
2019 debug.assert((try a.to(u64)) == 11);1961 debug.assert((try a.to(u64)) == 11);
20201962
2021 debug.assert(a.cmp(11) == 0);1963 debug.assert(a.cmp(try Int.initSet(al, 11)) == 0);
2022 debug.assert(a.cmp(14) <= 0);1964 debug.assert(a.cmp(try Int.initSet(al, 14)) <= 0);
2023}1965}
std/mem.zig+3-7
...@@ -40,16 +40,12 @@ pub const Allocator = struct {...@@ -40,16 +40,12 @@ pub const Allocator = struct {
4040
41 /// Call destroy with the result41 /// Call destroy with the result
42 /// TODO once #733 is solved, this will replace create42 /// TODO once #733 is solved, this will replace create
43 pub fn construct(self: *Allocator, init: var) t: {43 pub fn construct(self: *Allocator, init: var) Error!*@typeOf(init) {
44 // TODO this is a workaround for type getting parsed as Error!&const T44 const T = @typeOf(init);
45 const T = @typeOf(init).Child;
46 break :t Error!*T;
47 } {
48 const T = @typeOf(init).Child;
49 if (@sizeOf(T) == 0) return &{};45 if (@sizeOf(T) == 0) return &{};
50 const slice = try self.alloc(T, 1);46 const slice = try self.alloc(T, 1);
51 const ptr = &slice[0];47 const ptr = &slice[0];
52 ptr.* = init.*;48 ptr.* = init;
53 return ptr;49 return ptr;
54 }50 }
5551
test/cases/cast.zig-8
...@@ -318,14 +318,6 @@ fn testCastConstArrayRefToConstSlice() void {...@@ -318,14 +318,6 @@ fn testCastConstArrayRefToConstSlice() void {
318 assert(mem.eql(u8, slice, "aoeu"));318 assert(mem.eql(u8, slice, "aoeu"));
319}319}
320320
321test "var args implicitly casts by value arg to const ref" {
322 foo("hello");
323}
324
325fn foo(args: ...) void {
326 assert(@typeOf(args[0]) == *const [5]u8);
327}
328
329test "peer type resolution: error and [N]T" {321test "peer type resolution: error and [N]T" {
330 // TODO: implicit error!T to error!U where T can implicitly cast to U322 // TODO: implicit error!T to error!U where T can implicitly cast to U
331 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));323 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
test/cases/fn.zig+46-2
...@@ -121,7 +121,7 @@ test "assign inline fn to const variable" {...@@ -121,7 +121,7 @@ test "assign inline fn to const variable" {
121inline fn inlineFn() void {}121inline fn inlineFn() void {}
122122
123test "pass by non-copying value" {123test "pass by non-copying value" {
124 assert(bar(Point{ .x = 1, .y = 2 }) == 3);124 assert(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
125}125}
126126
127const Point = struct {127const Point = struct {
...@@ -129,6 +129,50 @@ const Point = struct {...@@ -129,6 +129,50 @@ const Point = struct {
129 y: i32,129 y: i32,
130};130};
131131
132fn bar(pt: Point) i32 {132fn addPointCoords(pt: Point) i32 {
133 return pt.x + pt.y;133 return pt.x + pt.y;
134}134}
135
136test "pass by non-copying value through var arg" {
137 assert(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3);
138}
139
140fn addPointCoordsVar(pt: var) i32 {
141 comptime assert(@typeOf(pt) == Point);
142 return pt.x + pt.y;
143}
144
145test "pass by non-copying value as method" {
146 var pt = Point2{ .x = 1, .y = 2 };
147 assert(pt.addPointCoords() == 3);
148}
149
150const Point2 = struct {
151 x: i32,
152 y: i32,
153
154 fn addPointCoords(self: Point2) i32 {
155 return self.x + self.y;
156 }
157};
158
159test "pass by non-copying value as method, which is generic" {
160 var pt = Point3{ .x = 1, .y = 2 };
161 assert(pt.addPointCoords(i32) == 3);
162}
163
164const Point3 = struct {
165 x: i32,
166 y: i32,
167
168 fn addPointCoords(self: Point3, comptime T: type) i32 {
169 return self.x + self.y;
170 }
171};
172
173test "pass by non-copying value as method, at comptime" {
174 comptime {
175 var pt = Point2{ .x = 1, .y = 2 };
176 assert(pt.addPointCoords() == 3);
177 }
178}
test/cases/var_args.zig-12
...@@ -75,18 +75,6 @@ test "array of var args functions" {...@@ -75,18 +75,6 @@ test "array of var args functions" {
75 assert(!foos[1]());75 assert(!foos[1]());
76}76}
7777
78test "pass array and slice of same array to var args should have same pointers" {
79 const array = "hi";
80 const slice: []const u8 = array;
81 return assertSlicePtrsEql(array, slice);
82}
83
84fn assertSlicePtrsEql(args: ...) void {
85 const s1 = ([]const u8)(args[0]);
86 const s2 = args[1];
87 assert(s1.ptr == s2.ptr);
88}
89
90test "pass zero length array to var args param" {78test "pass zero length array to var args param" {
91 doNothingWithFirstArg("");79 doNothingWithFirstArg("");
92}80}
test/compile_errors.zig+1-1
...@@ -2215,7 +2215,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2215,7 +2215,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2215 \\ derp.init();2215 \\ derp.init();
2216 \\}2216 \\}
2217 ,2217 ,
2218 ".tmp_source.zig:14:5: error: expected type 'i32', found '*const Foo'",2218 ".tmp_source.zig:14:5: error: expected type 'i32', found 'Foo'",
2219 );2219 );
22202220
2221 cases.add(2221 cases.add(