mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
update zig to 0.11 and update build script
Also update memcpy to avoid recursive memcpy due to optimizations.
This commit is contained in:
parent
0aaf8ebf8a
commit
2e2e609547
18 changed files with 535 additions and 507 deletions
|
@ -44,7 +44,7 @@ pub fn __divti3(a: i128, b: i128) callconv(.C) i128 {
|
|||
}
|
||||
|
||||
fn __divti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
|
||||
return @bitCast(v2u64, div(@bitCast(i128, a), @bitCast(i128, b)));
|
||||
return @as(v2u64, @bitCast(div(@as(i128, @bitCast(a)), @as(i128, @bitCast(b)))));
|
||||
}
|
||||
|
||||
inline fn div(a: i128, b: i128) i128 {
|
||||
|
@ -54,9 +54,9 @@ inline fn div(a: i128, b: i128) i128 {
|
|||
const an = (a ^ s_a) -% s_a;
|
||||
const bn = (b ^ s_b) -% s_b;
|
||||
|
||||
const r = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), null);
|
||||
const r = udivmod(u128, @as(u128, @bitCast(an)), @as(u128, @bitCast(bn)), null);
|
||||
const s = s_a ^ s_b;
|
||||
return (@bitCast(i128, r) ^ s) -% s;
|
||||
return (@as(i128, @bitCast(r)) ^ s) -% s;
|
||||
}
|
||||
|
||||
pub fn __udivti3(a: u128, b: u128) callconv(.C) u128 {
|
||||
|
@ -64,7 +64,7 @@ pub fn __udivti3(a: u128, b: u128) callconv(.C) u128 {
|
|||
}
|
||||
|
||||
fn __udivti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
|
||||
return @bitCast(v2u64, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), null));
|
||||
return @as(v2u64, @bitCast(udivmod(u128, @as(u128, @bitCast(a)), @as(u128, @bitCast(b)), null)));
|
||||
}
|
||||
|
||||
pub fn __umodti3(a: u128, b: u128) callconv(.C) u128 {
|
||||
|
@ -75,8 +75,8 @@ pub fn __umodti3(a: u128, b: u128) callconv(.C) u128 {
|
|||
|
||||
fn __umodti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
|
||||
var r: u128 = undefined;
|
||||
_ = udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), &r);
|
||||
return @bitCast(v2u64, r);
|
||||
_ = udivmod(u128, @as(u128, @bitCast(a)), @as(u128, @bitCast(b)), &r);
|
||||
return @as(v2u64, @bitCast(r));
|
||||
}
|
||||
|
||||
pub fn __modti3(a: i128, b: i128) callconv(.C) i128 {
|
||||
|
@ -84,7 +84,7 @@ pub fn __modti3(a: i128, b: i128) callconv(.C) i128 {
|
|||
}
|
||||
|
||||
fn __modti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
|
||||
return @bitCast(v2u64, mod(@bitCast(i128, a), @bitCast(i128, b)));
|
||||
return @as(v2u64, @bitCast(mod(@as(i128, @bitCast(a)), @as(i128, @bitCast(b)))));
|
||||
}
|
||||
|
||||
inline fn mod(a: i128, b: i128) i128 {
|
||||
|
@ -95,8 +95,8 @@ inline fn mod(a: i128, b: i128) i128 {
|
|||
const bn = (b ^ s_b) -% s_b; // negate if s == -1
|
||||
|
||||
var r: u128 = undefined;
|
||||
_ = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), &r);
|
||||
return (@bitCast(i128, r) ^ s_a) -% s_a; // negate if s == -1
|
||||
_ = udivmod(u128, @as(u128, @bitCast(an)), @as(u128, @bitCast(bn)), &r);
|
||||
return (@as(i128, @bitCast(r)) ^ s_a) -% s_a; // negate if s == -1
|
||||
}
|
||||
|
||||
pub fn __fixdfti(a: f64) callconv(.C) i128 {
|
||||
|
@ -104,7 +104,7 @@ pub fn __fixdfti(a: f64) callconv(.C) i128 {
|
|||
}
|
||||
|
||||
fn __fixdfti_windows_x86_64(a: f64) callconv(.C) v2u64 {
|
||||
return @bitCast(v2u64, floatToInt(i128, a));
|
||||
return @as(v2u64, @bitCast(floatToInt(i128, a)));
|
||||
}
|
||||
|
||||
pub fn __fixsfti(a: f32) callconv(.C) i128 {
|
||||
|
@ -112,7 +112,7 @@ pub fn __fixsfti(a: f32) callconv(.C) i128 {
|
|||
}
|
||||
|
||||
fn __fixsfti_windows_x86_64(a: f32) callconv(.C) v2u64 {
|
||||
return @bitCast(v2u64, floatToInt(i128, a));
|
||||
return @as(v2u64, @bitCast(floatToInt(i128, a)));
|
||||
}
|
||||
|
||||
pub fn __fixunsdfti(a: f64) callconv(.C) u128 {
|
||||
|
@ -120,7 +120,7 @@ pub fn __fixunsdfti(a: f64) callconv(.C) u128 {
|
|||
}
|
||||
|
||||
fn __fixunsdfti_windows_x86_64(a: f64) callconv(.C) v2u64 {
|
||||
return @bitCast(v2u64, floatToInt(u128, a));
|
||||
return @as(v2u64, @bitCast(floatToInt(u128, a)));
|
||||
}
|
||||
|
||||
pub fn __fixunssfti(a: f32) callconv(.C) u128 {
|
||||
|
@ -128,7 +128,7 @@ pub fn __fixunssfti(a: f32) callconv(.C) u128 {
|
|||
}
|
||||
|
||||
fn __fixunssfti_windows_x86_64(a: f32) callconv(.C) v2u64 {
|
||||
return @bitCast(v2u64, floatToInt(u128, a));
|
||||
return @as(v2u64, @bitCast(floatToInt(u128, a)));
|
||||
}
|
||||
// mulo - multiplication overflow
|
||||
// * return a*%b.
|
||||
|
@ -164,7 +164,7 @@ inline fn muloXi4_genericFast(comptime ST: type, a: ST, b: ST, overflow: *c_int)
|
|||
//invariant: -2^{bitwidth(EST)} < res < 2^{bitwidth(EST)-1}
|
||||
if (res < min or max < res)
|
||||
overflow.* = 1;
|
||||
return @truncate(ST, res);
|
||||
return @as(ST, @truncate(res));
|
||||
}
|
||||
|
||||
const native_endian = builtin.cpu.arch.endian();
|
||||
|
@ -183,8 +183,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
const SignedDoubleInt = std.meta.Int(.signed, double_int_bits);
|
||||
const Log2SingleInt = std.math.Log2Int(SingleInt);
|
||||
|
||||
const n = @bitCast([2]SingleInt, a);
|
||||
const d = @bitCast([2]SingleInt, b);
|
||||
const n = @as([2]SingleInt, @bitCast(a));
|
||||
const d = @as([2]SingleInt, @bitCast(b));
|
||||
var q: [2]SingleInt = undefined;
|
||||
var r: [2]SingleInt = undefined;
|
||||
var sr: c_uint = undefined;
|
||||
|
@ -226,7 +226,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
if (maybe_rem) |rem| {
|
||||
r[high] = n[high] % d[high];
|
||||
r[low] = 0;
|
||||
rem.* = @bitCast(DoubleInt, r);
|
||||
rem.* = @as(DoubleInt, @bitCast(r));
|
||||
}
|
||||
return n[high] / d[high];
|
||||
}
|
||||
|
@ -238,14 +238,14 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
if (maybe_rem) |rem| {
|
||||
r[low] = n[low];
|
||||
r[high] = n[high] & (d[high] - 1);
|
||||
rem.* = @bitCast(DoubleInt, r);
|
||||
rem.* = @as(DoubleInt, @bitCast(r));
|
||||
}
|
||||
return n[high] >> @intCast(Log2SingleInt, @ctz(SingleInt, d[high]));
|
||||
return n[high] >> @as(Log2SingleInt, @intCast(@ctz(d[high])));
|
||||
}
|
||||
// K K
|
||||
// ---
|
||||
// K 0
|
||||
sr = @bitCast(c_uint, @as(c_int, @clz(SingleInt, d[high])) - @as(c_int, @clz(SingleInt, n[high])));
|
||||
sr = @as(c_uint, @bitCast(@as(c_int, @clz(d[high])) - @as(c_int, @clz(n[high]))));
|
||||
// 0 <= sr <= single_int_bits - 2 or sr large
|
||||
if (sr > single_int_bits - 2) {
|
||||
if (maybe_rem) |rem| {
|
||||
|
@ -257,10 +257,10 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
// 1 <= sr <= single_int_bits - 1
|
||||
// q.all = a << (double_int_bits - sr);
|
||||
q[low] = 0;
|
||||
q[high] = n[low] << @intCast(Log2SingleInt, single_int_bits - sr);
|
||||
q[high] = n[low] << @as(Log2SingleInt, @intCast(single_int_bits - sr));
|
||||
// r.all = a >> sr;
|
||||
r[high] = n[high] >> @intCast(Log2SingleInt, sr);
|
||||
r[low] = (n[high] << @intCast(Log2SingleInt, single_int_bits - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
|
||||
r[high] = n[high] >> @as(Log2SingleInt, @intCast(sr));
|
||||
r[low] = (n[high] << @as(Log2SingleInt, @intCast(single_int_bits - sr))) | (n[low] >> @as(Log2SingleInt, @intCast(sr)));
|
||||
} else {
|
||||
// d[low] != 0
|
||||
if (d[high] == 0) {
|
||||
|
@ -275,15 +275,15 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
if (d[low] == 1) {
|
||||
return a;
|
||||
}
|
||||
sr = @ctz(SingleInt, d[low]);
|
||||
q[high] = n[high] >> @intCast(Log2SingleInt, sr);
|
||||
q[low] = (n[high] << @intCast(Log2SingleInt, single_int_bits - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
|
||||
return @bitCast(DoubleInt, q);
|
||||
sr = @ctz(d[low]);
|
||||
q[high] = n[high] >> @as(Log2SingleInt, @intCast(sr));
|
||||
q[low] = (n[high] << @as(Log2SingleInt, @intCast(single_int_bits - sr))) | (n[low] >> @as(Log2SingleInt, @intCast(sr)));
|
||||
return @as(DoubleInt, @bitCast(q));
|
||||
}
|
||||
// K X
|
||||
// ---
|
||||
// 0 K
|
||||
sr = 1 + single_int_bits + @as(c_uint, @clz(SingleInt, d[low])) - @as(c_uint, @clz(SingleInt, n[high]));
|
||||
sr = 1 + single_int_bits + @as(c_uint, @clz(d[low])) - @as(c_uint, @clz(n[high]));
|
||||
// 2 <= sr <= double_int_bits - 1
|
||||
// q.all = a << (double_int_bits - sr);
|
||||
// r.all = a >> sr;
|
||||
|
@ -295,21 +295,21 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
} else if (sr < single_int_bits) {
|
||||
// 2 <= sr <= single_int_bits - 1
|
||||
q[low] = 0;
|
||||
q[high] = n[low] << @intCast(Log2SingleInt, single_int_bits - sr);
|
||||
r[high] = n[high] >> @intCast(Log2SingleInt, sr);
|
||||
r[low] = (n[high] << @intCast(Log2SingleInt, single_int_bits - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
|
||||
q[high] = n[low] << @as(Log2SingleInt, @intCast(single_int_bits - sr));
|
||||
r[high] = n[high] >> @as(Log2SingleInt, @intCast(sr));
|
||||
r[low] = (n[high] << @as(Log2SingleInt, @intCast(single_int_bits - sr))) | (n[low] >> @as(Log2SingleInt, @intCast(sr)));
|
||||
} else {
|
||||
// single_int_bits + 1 <= sr <= double_int_bits - 1
|
||||
q[low] = n[low] << @intCast(Log2SingleInt, double_int_bits - sr);
|
||||
q[high] = (n[high] << @intCast(Log2SingleInt, double_int_bits - sr)) | (n[low] >> @intCast(Log2SingleInt, sr - single_int_bits));
|
||||
q[low] = n[low] << @as(Log2SingleInt, @intCast(double_int_bits - sr));
|
||||
q[high] = (n[high] << @as(Log2SingleInt, @intCast(double_int_bits - sr))) | (n[low] >> @as(Log2SingleInt, @intCast(sr - single_int_bits)));
|
||||
r[high] = 0;
|
||||
r[low] = n[high] >> @intCast(Log2SingleInt, sr - single_int_bits);
|
||||
r[low] = n[high] >> @as(Log2SingleInt, @intCast(sr - single_int_bits));
|
||||
}
|
||||
} else {
|
||||
// K X
|
||||
// ---
|
||||
// K K
|
||||
sr = @bitCast(c_uint, @as(c_int, @clz(SingleInt, d[high])) - @as(c_int, @clz(SingleInt, n[high])));
|
||||
sr = @as(c_uint, @bitCast(@as(c_int, @clz(d[high])) - @as(c_int, @clz(n[high]))));
|
||||
// 0 <= sr <= single_int_bits - 1 or sr large
|
||||
if (sr > single_int_bits - 1) {
|
||||
if (maybe_rem) |rem| {
|
||||
|
@ -327,9 +327,9 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
r[high] = 0;
|
||||
r[low] = n[high];
|
||||
} else {
|
||||
r[high] = n[high] >> @intCast(Log2SingleInt, sr);
|
||||
r[low] = (n[high] << @intCast(Log2SingleInt, single_int_bits - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
|
||||
q[high] = n[low] << @intCast(Log2SingleInt, single_int_bits - sr);
|
||||
r[high] = n[high] >> @as(Log2SingleInt, @intCast(sr));
|
||||
r[low] = (n[high] << @as(Log2SingleInt, @intCast(single_int_bits - sr))) | (n[low] >> @as(Log2SingleInt, @intCast(sr)));
|
||||
q[high] = n[low] << @as(Log2SingleInt, @intCast(single_int_bits - sr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,13 +352,13 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
|
|||
// r.all -= b;
|
||||
// carry = 1;
|
||||
// }
|
||||
r_all = @bitCast(DoubleInt, r);
|
||||
const s: SignedDoubleInt = @bitCast(SignedDoubleInt, b -% r_all -% 1) >> (double_int_bits - 1);
|
||||
carry = @intCast(u32, s & 1);
|
||||
r_all -= b & @bitCast(DoubleInt, s);
|
||||
r = @bitCast([2]SingleInt, r_all);
|
||||
r_all = @as(DoubleInt, @bitCast(r));
|
||||
const s: SignedDoubleInt = @as(SignedDoubleInt, @bitCast(b -% r_all -% 1)) >> (double_int_bits - 1);
|
||||
carry = @as(u32, @intCast(s & 1));
|
||||
r_all -= b & @as(DoubleInt, @bitCast(s));
|
||||
r = @as([2]SingleInt, @bitCast(r_all));
|
||||
}
|
||||
const q_all = (@bitCast(DoubleInt, q) << 1) | carry;
|
||||
const q_all = (@as(DoubleInt, @bitCast(q)) << 1) | carry;
|
||||
if (maybe_rem) |rem| {
|
||||
rem.* = r_all;
|
||||
}
|
||||
|
@ -383,9 +383,9 @@ pub inline fn floatToInt(comptime I: type, a: anytype) I {
|
|||
const sig_mask = (@as(rep_t, 1) << sig_bits) - 1;
|
||||
|
||||
// Break a into sign, exponent, significand
|
||||
const a_rep: rep_t = @bitCast(rep_t, a);
|
||||
const a_rep: rep_t = @as(rep_t, @bitCast(a));
|
||||
const negative = (a_rep >> (float_bits - 1)) != 0;
|
||||
const exponent = @intCast(i32, (a_rep << 1) >> (sig_bits + 1)) - exp_bias;
|
||||
const exponent = @as(i32, @intCast((a_rep << 1) >> (sig_bits + 1))) - exp_bias;
|
||||
const significand: rep_t = (a_rep & sig_mask) | implicit_bit;
|
||||
|
||||
// If the exponent is negative, the result rounds to zero.
|
||||
|
@ -395,9 +395,9 @@ pub inline fn floatToInt(comptime I: type, a: anytype) I {
|
|||
switch (@typeInfo(I).Int.signedness) {
|
||||
.unsigned => {
|
||||
if (negative) return 0;
|
||||
if (@intCast(c_uint, exponent) >= @minimum(int_bits, max_exp)) return math.maxInt(I);
|
||||
if (@as(c_uint, @intCast(exponent)) >= @min(int_bits, max_exp)) return math.maxInt(I);
|
||||
},
|
||||
.signed => if (@intCast(c_uint, exponent) >= @minimum(int_bits - 1, max_exp)) {
|
||||
.signed => if (@as(c_uint, @intCast(exponent)) >= @min(int_bits - 1, max_exp)) {
|
||||
return if (negative) math.minInt(I) else math.maxInt(I);
|
||||
},
|
||||
}
|
||||
|
@ -406,9 +406,9 @@ pub inline fn floatToInt(comptime I: type, a: anytype) I {
|
|||
// Otherwise, shift left.
|
||||
var result: I = undefined;
|
||||
if (exponent < fractional_bits) {
|
||||
result = @intCast(I, significand >> @intCast(Log2Int(rep_t), fractional_bits - exponent));
|
||||
result = @as(I, @intCast(significand >> @as(Log2Int(rep_t), @intCast(fractional_bits - exponent))));
|
||||
} else {
|
||||
result = @intCast(I, significand) << @intCast(Log2Int(I), exponent - fractional_bits);
|
||||
result = @as(I, @intCast(significand)) << @as(Log2Int(I), @intCast(exponent - fractional_bits));
|
||||
}
|
||||
|
||||
if ((@typeInfo(I).Int.signedness == .signed) and negative)
|
||||
|
@ -448,13 +448,13 @@ inline fn lshrXi3(comptime T: type, a: T, b: i32) T {
|
|||
|
||||
if (b >= word_t.bits) {
|
||||
output.s.high = 0;
|
||||
output.s.low = input.s.high >> @intCast(S, b - word_t.bits);
|
||||
output.s.low = input.s.high >> @as(S, @intCast(b - word_t.bits));
|
||||
} else if (b == 0) {
|
||||
return a;
|
||||
} else {
|
||||
output.s.high = input.s.high >> @intCast(S, b);
|
||||
output.s.low = input.s.high << @intCast(S, word_t.bits - b);
|
||||
output.s.low |= input.s.low >> @intCast(S, b);
|
||||
output.s.high = input.s.high >> @as(S, @intCast(b));
|
||||
output.s.low = input.s.high << @as(S, @intCast(word_t.bits - b));
|
||||
output.s.low |= input.s.low >> @as(S, @intCast(b));
|
||||
}
|
||||
|
||||
return output.all;
|
||||
|
|
|
@ -4,7 +4,6 @@ const num_ = @import("num.zig");
|
|||
const utils = @import("utils.zig");
|
||||
|
||||
const math = std.math;
|
||||
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
|
||||
const RocStr = str.RocStr;
|
||||
const WithOverflow = utils.WithOverflow;
|
||||
const roc_panic = @import("panic.zig").panic_help;
|
||||
|
@ -30,22 +29,22 @@ pub const RocDec = extern struct {
|
|||
}
|
||||
|
||||
pub fn fromF64(num: f64) ?RocDec {
|
||||
var result: f64 = num * comptime @intToFloat(f64, one_point_zero_i128);
|
||||
var result: f64 = num * comptime @as(f64, @floatFromInt(one_point_zero_i128));
|
||||
|
||||
if (result > comptime @intToFloat(f64, math.maxInt(i128))) {
|
||||
if (result > comptime @as(f64, @floatFromInt(math.maxInt(i128)))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (result < comptime @intToFloat(f64, math.minInt(i128))) {
|
||||
if (result < comptime @as(f64, @floatFromInt(math.minInt(i128)))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var ret: RocDec = .{ .num = @floatToInt(i128, result) };
|
||||
var ret: RocDec = .{ .num = @as(i128, @intFromFloat(result)) };
|
||||
return ret;
|
||||
}
|
||||
|
||||
pub fn toF64(dec: RocDec) f64 {
|
||||
return @intToFloat(f64, dec.num) / comptime @intToFloat(f64, one_point_zero_i128);
|
||||
return @as(f64, @floatFromInt(dec.num)) / comptime @as(f64, @floatFromInt(one_point_zero_i128));
|
||||
}
|
||||
|
||||
// TODO: If Str.toDec eventually supports more error types, return errors here.
|
||||
|
@ -92,7 +91,7 @@ pub const RocDec = extern struct {
|
|||
|
||||
var after_str = roc_str_slice[pi + 1 .. length];
|
||||
var after_u64 = std.fmt.parseUnsigned(u64, after_str, 10) catch null;
|
||||
after_val_i128 = if (after_u64) |f| @intCast(i128, f) * math.pow(i128, 10, diff_decimal_places) else null;
|
||||
after_val_i128 = if (after_u64) |f| @as(i128, @intCast(f)) * math.pow(i128, 10, diff_decimal_places) else null;
|
||||
}
|
||||
|
||||
var before_str = roc_str_slice[initial_index..before_str_length];
|
||||
|
@ -100,9 +99,10 @@ pub const RocDec = extern struct {
|
|||
|
||||
var before_val_i128: ?i128 = null;
|
||||
if (before_val_not_adjusted) |before| {
|
||||
var result: i128 = undefined;
|
||||
var overflowed = @mulWithOverflow(i128, before, one_point_zero_i128, &result);
|
||||
if (overflowed) {
|
||||
const answer = @mulWithOverflow(before, one_point_zero_i128);
|
||||
const result = answer[0];
|
||||
const overflowed = answer[1];
|
||||
if (overflowed == 1) {
|
||||
// TODO: runtime exception for overflow!
|
||||
return null;
|
||||
}
|
||||
|
@ -112,9 +112,10 @@ pub const RocDec = extern struct {
|
|||
const dec: RocDec = blk: {
|
||||
if (before_val_i128) |before| {
|
||||
if (after_val_i128) |after| {
|
||||
var result: i128 = undefined;
|
||||
var overflowed = @addWithOverflow(i128, before, after, &result);
|
||||
if (overflowed) {
|
||||
var answer = @addWithOverflow(before, after);
|
||||
const result = answer[0];
|
||||
const overflowed = answer[1];
|
||||
if (overflowed == 1) {
|
||||
// TODO: runtime exception for overflow!
|
||||
return null;
|
||||
}
|
||||
|
@ -241,10 +242,9 @@ pub const RocDec = extern struct {
|
|||
}
|
||||
|
||||
pub fn addWithOverflow(self: RocDec, other: RocDec) WithOverflow(RocDec) {
|
||||
var answer: i128 = undefined;
|
||||
const overflowed = @addWithOverflow(i128, self.num, other.num, &answer);
|
||||
const answer = @addWithOverflow(self.num, other.num);
|
||||
|
||||
return .{ .value = RocDec{ .num = answer }, .has_overflowed = overflowed };
|
||||
return .{ .value = RocDec{ .num = answer[0] }, .has_overflowed = answer[1] == 1 };
|
||||
}
|
||||
|
||||
pub fn add(self: RocDec, other: RocDec) RocDec {
|
||||
|
@ -273,10 +273,9 @@ pub const RocDec = extern struct {
|
|||
}
|
||||
|
||||
pub fn subWithOverflow(self: RocDec, other: RocDec) WithOverflow(RocDec) {
|
||||
var answer: i128 = undefined;
|
||||
const overflowed = @subWithOverflow(i128, self.num, other.num, &answer);
|
||||
const answer = @subWithOverflow(self.num, other.num);
|
||||
|
||||
return .{ .value = RocDec{ .num = answer }, .has_overflowed = overflowed };
|
||||
return .{ .value = RocDec{ .num = answer[0] }, .has_overflowed = answer[1] == 1 };
|
||||
}
|
||||
|
||||
pub fn sub(self: RocDec, other: RocDec) RocDec {
|
||||
|
@ -310,7 +309,7 @@ pub const RocDec = extern struct {
|
|||
|
||||
const is_answer_negative = (self_i128 < 0) != (other_i128 < 0);
|
||||
|
||||
const self_u128 = @intCast(u128, math.absInt(self_i128) catch {
|
||||
const self_u128 = @as(u128, @intCast(math.absInt(self_i128) catch {
|
||||
if (other_i128 == 0) {
|
||||
return .{ .value = RocDec{ .num = 0 }, .has_overflowed = false };
|
||||
} else if (other_i128 == RocDec.one_point_zero.num) {
|
||||
|
@ -320,9 +319,9 @@ pub const RocDec = extern struct {
|
|||
} else {
|
||||
return .{ .value = RocDec.max, .has_overflowed = true };
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
const other_u128 = @intCast(u128, math.absInt(other_i128) catch {
|
||||
const other_u128 = @as(u128, @intCast(math.absInt(other_i128) catch {
|
||||
if (self_i128 == 0) {
|
||||
return .{ .value = RocDec{ .num = 0 }, .has_overflowed = false };
|
||||
} else if (self_i128 == RocDec.one_point_zero.num) {
|
||||
|
@ -332,7 +331,7 @@ pub const RocDec = extern struct {
|
|||
} else {
|
||||
return .{ .value = RocDec.max, .has_overflowed = true };
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
const unsigned_answer: i128 = mul_and_decimalize(self_u128, other_u128);
|
||||
|
||||
|
@ -401,7 +400,7 @@ pub const RocDec = extern struct {
|
|||
@panic("TODO runtime exception for overflow when dividing!");
|
||||
}
|
||||
};
|
||||
const numerator_u128 = @intCast(u128, numerator_abs_i128);
|
||||
const numerator_u128 = @as(u128, @intCast(numerator_abs_i128));
|
||||
|
||||
const denominator_abs_i128 = math.absInt(denominator_i128) catch {
|
||||
// Currently, if you try to do multiplication on i64::MIN, panic
|
||||
|
@ -414,14 +413,14 @@ pub const RocDec = extern struct {
|
|||
@panic("TODO runtime exception for overflow when dividing!");
|
||||
}
|
||||
};
|
||||
const denominator_u128 = @intCast(u128, denominator_abs_i128);
|
||||
const denominator_u128 = @as(u128, @intCast(denominator_abs_i128));
|
||||
|
||||
const numerator_u256: U256 = mul_u128(numerator_u128, math.pow(u128, 10, decimal_places));
|
||||
const answer = div_u256_by_u128(numerator_u256, denominator_u128);
|
||||
|
||||
var unsigned_answer: i128 = undefined;
|
||||
if (answer.hi == 0 and answer.lo <= math.maxInt(i128)) {
|
||||
unsigned_answer = @intCast(i128, answer.lo);
|
||||
unsigned_answer = @as(i128, @intCast(answer.lo));
|
||||
} else {
|
||||
@panic("TODO runtime exception for overflow when dividing!");
|
||||
}
|
||||
|
@ -442,18 +441,19 @@ pub const RocDec = extern struct {
|
|||
// This is dec/(b0+1), but as a multiplication.
|
||||
// So dec * (1/(b0+1)). This is way faster.
|
||||
const dec = self.num;
|
||||
const tmp = @intCast(i128, num_.mul_u128(math.absCast(dec), 249757942369376157886101012127821356963).hi >> (190 - 128));
|
||||
const tmp = @as(i128, @intCast(num_.mul_u128(math.absCast(dec), 249757942369376157886101012127821356963).hi >> (190 - 128)));
|
||||
const q0 = if (dec < 0) -tmp else tmp;
|
||||
|
||||
const upper = q0 * b0;
|
||||
var lower: i128 = undefined;
|
||||
const overflow = @mulWithOverflow(i128, q0, b1, &lower);
|
||||
const answer = @mulWithOverflow(q0, b1);
|
||||
const lower = answer[0];
|
||||
const overflowed = answer[1];
|
||||
// TODO: maybe write this out branchlessly.
|
||||
// Currently is is probably cmovs, but could be just math?
|
||||
const q0_sign: i128 =
|
||||
if (q0 > 0) 1 else -1;
|
||||
const overflow_val: i128 = if (overflow) q0_sign << 64 else 0;
|
||||
const full = upper + @intCast(i128, lower >> 64) + overflow_val;
|
||||
const overflowed_val: i128 = if (overflowed == 1) q0_sign << 64 else 0;
|
||||
const full = upper + @as(i128, @intCast(lower >> 64)) + overflowed_val;
|
||||
|
||||
var out = dec - full;
|
||||
if (out < 0) {
|
||||
|
@ -524,9 +524,11 @@ fn mul_and_decimalize(a: u128, b: u128) i128 {
|
|||
|
||||
// Add 1.
|
||||
// This can't overflow because the initial numbers are only 127bit due to removing the sign bit.
|
||||
var overflowed = @addWithOverflow(u128, lhs_lo, 1, &lhs_lo);
|
||||
var answer = @addWithOverflow(lhs_lo, 1);
|
||||
lhs_lo = answer[0];
|
||||
var overflowed = answer[1];
|
||||
lhs_hi = blk: {
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
break :blk lhs_hi + 1;
|
||||
} else {
|
||||
break :blk lhs_hi + 0;
|
||||
|
@ -558,76 +560,85 @@ fn mul_and_decimalize(a: u128, b: u128) i128 {
|
|||
const k = lk.lo;
|
||||
|
||||
// b = e + f + h
|
||||
var e_plus_f: u128 = undefined;
|
||||
overflowed = @addWithOverflow(u128, e, f, &e_plus_f);
|
||||
answer = @addWithOverflow(e, f);
|
||||
const e_plus_f = answer[0];
|
||||
overflowed = answer[1];
|
||||
var b_carry1: u128 = undefined;
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
b_carry1 = 1;
|
||||
} else {
|
||||
b_carry1 = 0;
|
||||
}
|
||||
|
||||
var idk: u128 = undefined;
|
||||
overflowed = @addWithOverflow(u128, e_plus_f, h, &idk);
|
||||
answer = @addWithOverflow(e_plus_f, h);
|
||||
overflowed = answer[1];
|
||||
var b_carry2: u128 = undefined;
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
b_carry2 = 1;
|
||||
} else {
|
||||
b_carry2 = 0;
|
||||
}
|
||||
|
||||
// c = carry + g + j + k // it doesn't say +k but I think it should be?
|
||||
var g_plus_j: u128 = undefined;
|
||||
overflowed = @addWithOverflow(u128, g, j, &g_plus_j);
|
||||
answer = @addWithOverflow(g, j);
|
||||
const g_plus_j = answer[0];
|
||||
overflowed = answer[1];
|
||||
var c_carry1: u128 = undefined;
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
c_carry1 = 1;
|
||||
} else {
|
||||
c_carry1 = 0;
|
||||
}
|
||||
|
||||
var g_plus_j_plus_k: u128 = undefined;
|
||||
overflowed = @addWithOverflow(u128, g_plus_j, k, &g_plus_j_plus_k);
|
||||
answer = @addWithOverflow(g_plus_j, k);
|
||||
const g_plus_j_plus_k = answer[0];
|
||||
overflowed = answer[1];
|
||||
var c_carry2: u128 = undefined;
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
c_carry2 = 1;
|
||||
} else {
|
||||
c_carry2 = 0;
|
||||
}
|
||||
|
||||
var c_without_bcarry2: u128 = undefined;
|
||||
overflowed = @addWithOverflow(u128, g_plus_j_plus_k, b_carry1, &c_without_bcarry2);
|
||||
answer = @addWithOverflow(g_plus_j_plus_k, b_carry1);
|
||||
const c_without_bcarry2 = answer[0];
|
||||
overflowed = answer[1];
|
||||
var c_carry3: u128 = undefined;
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
c_carry3 = 1;
|
||||
} else {
|
||||
c_carry3 = 0;
|
||||
}
|
||||
|
||||
var c: u128 = undefined;
|
||||
overflowed = @addWithOverflow(u128, c_without_bcarry2, b_carry2, &c);
|
||||
answer = @addWithOverflow(c_without_bcarry2, b_carry2);
|
||||
const c = answer[0];
|
||||
overflowed = answer[1];
|
||||
var c_carry4: u128 = undefined;
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
c_carry4 = 1;
|
||||
} else {
|
||||
c_carry4 = 0;
|
||||
}
|
||||
|
||||
// d = carry + l
|
||||
var d: u128 = undefined;
|
||||
overflowed = @addWithOverflow(u128, l, c_carry1, &d);
|
||||
overflowed = overflowed or @addWithOverflow(u128, d, c_carry2, &d);
|
||||
overflowed = overflowed or @addWithOverflow(u128, d, c_carry3, &d);
|
||||
overflowed = overflowed or @addWithOverflow(u128, d, c_carry4, &d);
|
||||
answer = @addWithOverflow(l, c_carry1);
|
||||
overflowed = answer[1];
|
||||
answer = @addWithOverflow(answer[0], c_carry2);
|
||||
overflowed = overflowed | answer[1];
|
||||
answer = @addWithOverflow(answer[0], c_carry3);
|
||||
overflowed = overflowed | answer[1];
|
||||
answer = @addWithOverflow(answer[0], c_carry4);
|
||||
overflowed = overflowed | answer[1];
|
||||
const d = answer[0];
|
||||
|
||||
if (overflowed) {
|
||||
if (overflowed == 1) {
|
||||
@panic("TODO runtime exception for overflow!");
|
||||
}
|
||||
|
||||
// Final 512bit value is d, c, b, a
|
||||
// need to left shift 321 times
|
||||
// 315 - 256 is 59. So left shift d, c 59 times.
|
||||
return @intCast(i128, c >> 59 | (d << (128 - 59)));
|
||||
return @as(i128, @intCast(c >> 59 | (d << (128 - 59))));
|
||||
}
|
||||
|
||||
// Multiply two 128-bit ints and divide the result by 10^DECIMAL_PLACES
|
||||
|
@ -678,7 +689,7 @@ fn div_u256_by_u128(numer: U256, denom: u128) U256 {
|
|||
return numer;
|
||||
}
|
||||
|
||||
sr = @ctz(u128, denom);
|
||||
sr = @ctz(denom);
|
||||
|
||||
return .{
|
||||
.hi = math.shr(u128, numer.hi, sr),
|
||||
|
@ -689,8 +700,8 @@ fn div_u256_by_u128(numer: U256, denom: u128) U256 {
|
|||
// K X
|
||||
// ---
|
||||
// 0 K
|
||||
var denom_leading_zeros = @clz(u128, denom);
|
||||
var numer_hi_leading_zeros = @clz(u128, numer.hi);
|
||||
var denom_leading_zeros = @clz(denom);
|
||||
var numer_hi_leading_zeros = @clz(numer.hi);
|
||||
sr = 1 + N_UDWORD_BITS + denom_leading_zeros - numer_hi_leading_zeros;
|
||||
// 2 <= sr <= N_UTWORD_BITS - 1
|
||||
// q.all = n.all << (N_UTWORD_BITS - sr);
|
||||
|
@ -751,15 +762,15 @@ fn div_u256_by_u128(numer: U256, denom: u128) U256 {
|
|||
// NOTE: Modified from `(d - r - 1) >> (N_UTWORD_BITS - 1)` to be an
|
||||
// **arithmetic** shift.
|
||||
|
||||
var lo: u128 = undefined;
|
||||
var lo_overflowed: bool = undefined;
|
||||
var hi: u128 = undefined;
|
||||
var answer = @subWithOverflow(denom, r.lo);
|
||||
var lo = answer[0];
|
||||
var lo_overflowed = answer[1];
|
||||
var hi = 0 -% @as(u128, @intCast(@as(u1, @bitCast(lo_overflowed)))) -% r.hi;
|
||||
|
||||
lo_overflowed = @subWithOverflow(u128, denom, r.lo, &lo);
|
||||
hi = 0 -% @intCast(u128, @bitCast(u1, lo_overflowed)) -% r.hi;
|
||||
|
||||
lo_overflowed = @subWithOverflow(u128, lo, 1, &lo);
|
||||
hi = hi -% @intCast(u128, @bitCast(u1, lo_overflowed));
|
||||
answer = @subWithOverflow(lo, 1);
|
||||
lo = answer[0];
|
||||
lo_overflowed = answer[1];
|
||||
hi = hi -% @as(u128, @intCast(@as(u1, @bitCast(lo_overflowed))));
|
||||
|
||||
// NOTE: this U256 was originally created by:
|
||||
//
|
||||
|
@ -785,8 +796,10 @@ fn div_u256_by_u128(numer: U256, denom: u128) U256 {
|
|||
carry = s.lo & 1;
|
||||
|
||||
// var (lo, carry) = r.lo.overflowing_sub(denom & s.lo);
|
||||
lo_overflowed = @subWithOverflow(u128, r.lo, (denom & s.lo), &lo);
|
||||
hi = r.hi -% @intCast(u128, @bitCast(u1, lo_overflowed));
|
||||
answer = @subWithOverflow(r.lo, (denom & s.lo));
|
||||
lo = answer[0];
|
||||
lo_overflowed = answer[1];
|
||||
hi = r.hi -% @as(u128, @intCast(@as(u1, @bitCast(lo_overflowed))));
|
||||
|
||||
r = .{ .hi = hi, .lo = lo };
|
||||
|
||||
|
@ -983,7 +996,7 @@ test "toStr: -0.45" {
|
|||
}
|
||||
|
||||
test "toStr: 0.00045" {
|
||||
var dec: RocDec = .{ .num = 000450000000000000 };
|
||||
var dec: RocDec = .{ .num = 450000000000000 };
|
||||
var res_roc_str = dec.toStr();
|
||||
|
||||
const res_slice: []const u8 = "0.00045"[0..];
|
||||
|
@ -991,7 +1004,7 @@ test "toStr: 0.00045" {
|
|||
}
|
||||
|
||||
test "toStr: -0.00045" {
|
||||
var dec: RocDec = .{ .num = -000450000000000000 };
|
||||
var dec: RocDec = .{ .num = -450000000000000 };
|
||||
var res_roc_str = dec.toStr();
|
||||
|
||||
const res_slice: []const u8 = "-0.00045"[0..];
|
||||
|
@ -1180,7 +1193,7 @@ test "div: 500 / 1000" {
|
|||
// exports
|
||||
|
||||
pub fn fromStr(arg: RocStr) callconv(.C) num_.NumParseResult(i128) {
|
||||
if (@call(.{ .modifier = always_inline }, RocDec.fromStr, .{arg})) |dec| {
|
||||
if (@call(.always_inline, RocDec.fromStr, .{arg})) |dec| {
|
||||
return .{ .errorcode = 0, .value = dec.num };
|
||||
} else {
|
||||
return .{ .errorcode = 1, .value = 0 };
|
||||
|
@ -1188,11 +1201,11 @@ pub fn fromStr(arg: RocStr) callconv(.C) num_.NumParseResult(i128) {
|
|||
}
|
||||
|
||||
pub fn toStr(arg: RocDec) callconv(.C) RocStr {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.toStr, .{arg});
|
||||
return @call(.always_inline, RocDec.toStr, .{arg});
|
||||
}
|
||||
|
||||
pub fn fromF64C(arg: f64) callconv(.C) i128 {
|
||||
if (@call(.{ .modifier = always_inline }, RocDec.fromF64, .{arg})) |dec| {
|
||||
if (@call(.always_inline, RocDec.fromF64, .{arg})) |dec| {
|
||||
return dec.num;
|
||||
} else {
|
||||
@panic("TODO runtime exception failing convert f64 to RocDec");
|
||||
|
@ -1201,7 +1214,7 @@ pub fn fromF64C(arg: f64) callconv(.C) i128 {
|
|||
|
||||
pub fn fromF32C(arg_f32: f32) callconv(.C) i128 {
|
||||
const arg_f64 = arg_f32;
|
||||
if (@call(.{ .modifier = always_inline }, RocDec.fromF64, .{arg_f64})) |dec| {
|
||||
if (@call(.always_inline, RocDec.fromF64, .{arg_f64})) |dec| {
|
||||
return dec.num;
|
||||
} else {
|
||||
@panic("TODO runtime exception failing convert f64 to RocDec");
|
||||
|
@ -1209,20 +1222,19 @@ pub fn fromF32C(arg_f32: f32) callconv(.C) i128 {
|
|||
}
|
||||
|
||||
pub fn toF64(arg: RocDec) callconv(.C) f64 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.toF64, .{arg});
|
||||
return @call(.always_inline, RocDec.toF64, .{arg});
|
||||
}
|
||||
|
||||
pub fn exportFromInt(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T) callconv(.C) i128 {
|
||||
const this = @intCast(i128, self);
|
||||
const this = @as(i128, @intCast(self));
|
||||
|
||||
var result: i128 = undefined;
|
||||
|
||||
if (@mulWithOverflow(i128, this, RocDec.one_point_zero_i128, &result)) {
|
||||
const answer = @mulWithOverflow(this, RocDec.one_point_zero_i128);
|
||||
if (answer[1] == 1) {
|
||||
@panic("TODO runtime exception failing convert integer to RocDec");
|
||||
} else {
|
||||
return result;
|
||||
return answer[0];
|
||||
}
|
||||
}
|
||||
}.func;
|
||||
|
@ -1230,23 +1242,23 @@ pub fn exportFromInt(comptime T: type, comptime name: []const u8) void {
|
|||
}
|
||||
|
||||
pub fn fromU64C(arg: u64) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.fromU64, .{arg}).toI128();
|
||||
return @call(.always_inline, RocDec.fromU64, .{arg}).toI128();
|
||||
}
|
||||
|
||||
pub fn toI128(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.toI128, .{arg});
|
||||
return @call(.always_inline, RocDec.toI128, .{arg});
|
||||
}
|
||||
|
||||
pub fn eqC(arg1: RocDec, arg2: RocDec) callconv(.C) bool {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.eq, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.eq, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn neqC(arg1: RocDec, arg2: RocDec) callconv(.C) bool {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.neq, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.neq, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn negateC(arg: RocDec) callconv(.C) i128 {
|
||||
return if (@call(.{ .modifier = always_inline }, RocDec.negate, .{arg})) |dec| dec.num else @panic("TODO overflow for negating RocDec");
|
||||
return if (@call(.always_inline, RocDec.negate, .{arg})) |dec| dec.num else @panic("TODO overflow for negating RocDec");
|
||||
}
|
||||
|
||||
pub fn absC(arg: RocDec) callconv(.C) i128 {
|
||||
|
@ -1255,65 +1267,65 @@ pub fn absC(arg: RocDec) callconv(.C) i128 {
|
|||
}
|
||||
|
||||
pub fn addC(arg1: RocDec, arg2: RocDec) callconv(.C) WithOverflow(RocDec) {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.addWithOverflow, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.addWithOverflow, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn subC(arg1: RocDec, arg2: RocDec) callconv(.C) WithOverflow(RocDec) {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.subWithOverflow, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.subWithOverflow, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn mulC(arg1: RocDec, arg2: RocDec) callconv(.C) WithOverflow(RocDec) {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.mulWithOverflow, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.mulWithOverflow, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn divC(arg1: RocDec, arg2: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.div, .{ arg1, arg2 }).num;
|
||||
return @call(.always_inline, RocDec.div, .{ arg1, arg2 }).num;
|
||||
}
|
||||
|
||||
pub fn sinC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.sin, .{arg}).num;
|
||||
return @call(.always_inline, RocDec.sin, .{arg}).num;
|
||||
}
|
||||
|
||||
pub fn cosC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.cos, .{arg}).num;
|
||||
return @call(.always_inline, RocDec.cos, .{arg}).num;
|
||||
}
|
||||
|
||||
pub fn tanC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.tan, .{arg}).num;
|
||||
return @call(.always_inline, RocDec.tan, .{arg}).num;
|
||||
}
|
||||
|
||||
pub fn asinC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.asin, .{arg}).num;
|
||||
return @call(.always_inline, RocDec.asin, .{arg}).num;
|
||||
}
|
||||
|
||||
pub fn acosC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.acos, .{arg}).num;
|
||||
return @call(.always_inline, RocDec.acos, .{arg}).num;
|
||||
}
|
||||
|
||||
pub fn atanC(arg: RocDec) callconv(.C) i128 {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.atan, .{arg}).num;
|
||||
return @call(.always_inline, RocDec.atan, .{arg}).num;
|
||||
}
|
||||
|
||||
pub fn addOrPanicC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.add, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.add, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn addSaturatedC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.addSaturated, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.addSaturated, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn subOrPanicC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.sub, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.sub, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn subSaturatedC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.subSaturated, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.subSaturated, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn mulOrPanicC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.mul, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.mul, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
pub fn mulSaturatedC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
|
||||
return @call(.{ .modifier = always_inline }, RocDec.mulSaturated, .{ arg1, arg2 });
|
||||
return @call(.always_inline, RocDec.mulSaturated, .{ arg1, arg2 });
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ pub fn expectFailedStartSharedFile() callconv(.C) [*]u8 {
|
|||
_ = std.fmt.bufPrint(name[0..100], "/roc_expect_buffer_{}\x00", .{roc_getppid()}) catch unreachable;
|
||||
|
||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||
const shared_fd = roc_shm_open(@ptrCast(*const i8, &name), O_RDWR | O_CREAT, 0o666);
|
||||
const shared_fd = roc_shm_open(@as(*const i8, @ptrCast(&name)), O_RDWR | O_CREAT, 0o666);
|
||||
|
||||
const length = 4096;
|
||||
|
||||
|
@ -42,7 +42,7 @@ pub fn expectFailedStartSharedFile() callconv(.C) [*]u8 {
|
|||
0,
|
||||
);
|
||||
|
||||
const ptr = @ptrCast([*]u8, shared_ptr);
|
||||
const ptr = @as([*]u8, @ptrCast(shared_ptr));
|
||||
|
||||
return ptr;
|
||||
} else {
|
||||
|
@ -61,7 +61,7 @@ pub fn readSharedBufferEnv() callconv(.C) void {
|
|||
var name: [100]u8 = undefined;
|
||||
_ = std.fmt.bufPrint(name[0..100], "/roc_expect_buffer_{}\x00", .{roc_getppid()}) catch unreachable;
|
||||
|
||||
const shared_fd = roc_shm_open(@ptrCast(*const i8, &name), O_RDWR | O_CREAT, 0o666);
|
||||
const shared_fd = roc_shm_open(@as(*const i8, @ptrCast(&name)), O_RDWR | O_CREAT, 0o666);
|
||||
const length = 4096;
|
||||
|
||||
const shared_ptr = roc_mmap(
|
||||
|
@ -73,7 +73,7 @@ pub fn readSharedBufferEnv() callconv(.C) void {
|
|||
0,
|
||||
);
|
||||
|
||||
const ptr = @ptrCast([*]u8, shared_ptr);
|
||||
const ptr = @as([*]u8, @ptrCast(shared_ptr));
|
||||
|
||||
SHARED_BUFFER = ptr[0..length];
|
||||
}
|
||||
|
@ -81,8 +81,8 @@ pub fn readSharedBufferEnv() callconv(.C) void {
|
|||
|
||||
pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
|
||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||
const usize_ptr = @ptrCast([*]u32, @alignCast(@alignOf(usize), shared_buffer));
|
||||
const atomic_ptr = @ptrCast(*Atomic(u32), &usize_ptr[5]);
|
||||
const usize_ptr = @as([*]u32, @ptrCast(@alignCast(shared_buffer)));
|
||||
const atomic_ptr = @as(*Atomic(u32), @ptrCast(&usize_ptr[5]));
|
||||
atomic_ptr.storeUnchecked(tag);
|
||||
|
||||
// wait till the parent is done before proceeding
|
||||
|
|
|
@ -42,32 +42,32 @@ pub const BoundClass = enum(u8) {
|
|||
};
|
||||
|
||||
test "Bound Class" {
|
||||
try expectEqual(0, @enumToInt(BoundClass.START));
|
||||
try expectEqual(0, @intFromEnum(BoundClass.START));
|
||||
}
|
||||
|
||||
// https://github.com/JuliaStrings/utf8proc/blob/master/utf8proc.c#L261
|
||||
fn graphemeBreakSimple(lbc: BoundClass, tbc: BoundClass) bool {
|
||||
const lbc_u8 = @enumToInt(lbc);
|
||||
const tbc_u8 = @enumToInt(tbc);
|
||||
return (if (lbc_u8 == @enumToInt(BoundClass.START)) // GB1
|
||||
const lbc_u8 = @intFromEnum(lbc);
|
||||
const tbc_u8 = @intFromEnum(tbc);
|
||||
return (if (lbc_u8 == @intFromEnum(BoundClass.START)) // GB1
|
||||
true
|
||||
else if (lbc_u8 == @enumToInt(BoundClass.CR) and tbc_u8 == @enumToInt(BoundClass.LF)) // GB3
|
||||
else if (lbc_u8 == @intFromEnum(BoundClass.CR) and tbc_u8 == @intFromEnum(BoundClass.LF)) // GB3
|
||||
false
|
||||
else if (lbc_u8 >= @enumToInt(BoundClass.CR) and lbc_u8 <= @enumToInt(BoundClass.CONTROL)) // GB4
|
||||
else if (lbc_u8 >= @intFromEnum(BoundClass.CR) and lbc_u8 <= @intFromEnum(BoundClass.CONTROL)) // GB4
|
||||
true
|
||||
else if (tbc_u8 >= @enumToInt(BoundClass.CR) and tbc_u8 <= @enumToInt(BoundClass.CONTROL)) // GB5
|
||||
else if (tbc_u8 >= @intFromEnum(BoundClass.CR) and tbc_u8 <= @intFromEnum(BoundClass.CONTROL)) // GB5
|
||||
true
|
||||
else if (lbc_u8 == @enumToInt(BoundClass.L) and (tbc_u8 == @enumToInt(BoundClass.L) or tbc_u8 == @enumToInt(BoundClass.V) or tbc_u8 == @enumToInt(BoundClass.LV) or tbc_u8 == @enumToInt(BoundClass.LVT))) // GB6
|
||||
else if (lbc_u8 == @intFromEnum(BoundClass.L) and (tbc_u8 == @intFromEnum(BoundClass.L) or tbc_u8 == @intFromEnum(BoundClass.V) or tbc_u8 == @intFromEnum(BoundClass.LV) or tbc_u8 == @intFromEnum(BoundClass.LVT))) // GB6
|
||||
false
|
||||
else if ((lbc_u8 == @enumToInt(BoundClass.LV) or lbc_u8 == @enumToInt(BoundClass.V)) and (tbc_u8 == @enumToInt(BoundClass.V) or tbc_u8 == @enumToInt(BoundClass.T))) // GB7
|
||||
else if ((lbc_u8 == @intFromEnum(BoundClass.LV) or lbc_u8 == @intFromEnum(BoundClass.V)) and (tbc_u8 == @intFromEnum(BoundClass.V) or tbc_u8 == @intFromEnum(BoundClass.T))) // GB7
|
||||
false
|
||||
else if ((lbc_u8 == @enumToInt(BoundClass.LVT) or lbc_u8 == @enumToInt(BoundClass.T)) and tbc_u8 == @enumToInt(BoundClass.T)) // GB8
|
||||
else if ((lbc_u8 == @intFromEnum(BoundClass.LVT) or lbc_u8 == @intFromEnum(BoundClass.T)) and tbc_u8 == @intFromEnum(BoundClass.T)) // GB8
|
||||
false
|
||||
else if (tbc_u8 == @enumToInt(BoundClass.EXTEND) or tbc_u8 == @enumToInt(BoundClass.ZWJ) or tbc_u8 == @enumToInt(BoundClass.SPACINGMARK) or lbc_u8 == @enumToInt(BoundClass.PREPEND)) // GB9a
|
||||
else if (tbc_u8 == @intFromEnum(BoundClass.EXTEND) or tbc_u8 == @intFromEnum(BoundClass.ZWJ) or tbc_u8 == @intFromEnum(BoundClass.SPACINGMARK) or lbc_u8 == @intFromEnum(BoundClass.PREPEND)) // GB9a
|
||||
false
|
||||
else if (lbc_u8 == @enumToInt(BoundClass.E_ZWG) and tbc_u8 == @enumToInt(BoundClass.EXTENDED_PICTOGRAPHIC)) // GB11 (requires additional handling below)
|
||||
else if (lbc_u8 == @intFromEnum(BoundClass.E_ZWG) and tbc_u8 == @intFromEnum(BoundClass.EXTENDED_PICTOGRAPHIC)) // GB11 (requires additional handling below)
|
||||
false
|
||||
else if (lbc_u8 == @enumToInt(BoundClass.REGIONAL_INDICATOR) and tbc_u8 == @enumToInt(BoundClass.REGIONAL_INDICATOR)) // GB12/13 (requires additional handling below)
|
||||
else if (lbc_u8 == @intFromEnum(BoundClass.REGIONAL_INDICATOR) and tbc_u8 == @intFromEnum(BoundClass.REGIONAL_INDICATOR)) // GB12/13 (requires additional handling below)
|
||||
false
|
||||
else // GB999
|
||||
true);
|
||||
|
|
|
@ -9,15 +9,14 @@ comptime {
|
|||
// TODO: remove this workaround.
|
||||
// Our wasm llvm pipeline always links in memcpy.
|
||||
// As such, our impl will conflict.
|
||||
if (builtin.is_test and builtin.os.tag == .windows) {
|
||||
// We don't need memcpy on Windows for tests because the tests are built with -lc
|
||||
// lld-link: error: duplicate symbol: memcpy
|
||||
if (builtin.is_test) {
|
||||
// We don't need memcpy for tests because the tests are built with -lc
|
||||
} else if (arch != .wasm32) {
|
||||
@export(memcpy, .{ .name = "memcpy", .linkage = .Strong });
|
||||
}
|
||||
}
|
||||
|
||||
const Memcpy = fn (noalias [*]u8, noalias [*]const u8, len: usize) callconv(.C) [*]u8;
|
||||
const Memcpy = *const fn (noalias [*]u8, noalias [*]const u8, len: usize) callconv(.C) [*]u8;
|
||||
|
||||
pub var memcpy_target: Memcpy = switch (arch) {
|
||||
.x86_64 => dispatch_memcpy,
|
||||
|
|
|
@ -8,8 +8,8 @@ comptime {
|
|||
.x86_64 => {
|
||||
asm (std.fmt.comptimePrint(@embedFile("memcpy-x86_64.S"), .{ .function_prefix = function_prefix }));
|
||||
},
|
||||
.i386 => {
|
||||
asm (std.fmt.comptimePrint(@embedFile("memcpy-i386.S"), .{ .function_prefix = function_prefix }));
|
||||
.x86 => {
|
||||
asm (std.fmt.comptimePrint(@embedFile("memcpy-x86.S"), .{ .function_prefix = function_prefix }));
|
||||
},
|
||||
// TODO: add assembly implementations for other platforms.
|
||||
else => {},
|
||||
|
@ -18,7 +18,7 @@ comptime {
|
|||
|
||||
pub const memcpy =
|
||||
switch (arch) {
|
||||
.x86_64, .i386 => musl_memcpy,
|
||||
.x86_64, .x86 => musl_memcpy,
|
||||
else => fallback_memcpy,
|
||||
};
|
||||
|
||||
|
@ -30,18 +30,37 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
var d = dest;
|
||||
var s = src;
|
||||
var n = len;
|
||||
while (@ptrToInt(s) % 4 != 0 and n != 0) : (n -= 1) {
|
||||
d[0] = s[0];
|
||||
d += 1;
|
||||
s += 1;
|
||||
switch (@min(n, @intFromPtr(s) % 4)) {
|
||||
1 => {
|
||||
d[0] = s[0];
|
||||
d += 1;
|
||||
s += 1;
|
||||
n -= 1;
|
||||
},
|
||||
2 => {
|
||||
d[0] = s[0];
|
||||
d[1] = s[1];
|
||||
d += 2;
|
||||
s += 2;
|
||||
n -= 2;
|
||||
},
|
||||
3 => {
|
||||
d[0] = s[0];
|
||||
d[1] = s[1];
|
||||
d[2] = s[2];
|
||||
d += 3;
|
||||
s += 3;
|
||||
n -= 3;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
if (@ptrToInt(d) % 4 == 0) {
|
||||
var d4 = @alignCast(4, d);
|
||||
var s4 = @alignCast(4, s);
|
||||
if (@intFromPtr(d) % 4 == 0) {
|
||||
var d4 = @as([*]align(4) u8, @alignCast(d));
|
||||
var s4 = @as([*]align(4) const u8, @alignCast(s));
|
||||
while (n >= 16) : (n -= 16) {
|
||||
var d_u32 = @ptrCast([*]u32, d4);
|
||||
var s_u32 = @ptrCast([*]const u32, s4);
|
||||
var d_u32 = @as([*]u32, @ptrCast(d4));
|
||||
var s_u32 = @as([*]const u32, @ptrCast(s4));
|
||||
d_u32[0] = s_u32[0];
|
||||
d_u32[1] = s_u32[1];
|
||||
d_u32[2] = s_u32[2];
|
||||
|
@ -51,8 +70,8 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
s4 += 16;
|
||||
}
|
||||
if (n & 8 != 0) {
|
||||
var d_u32 = @ptrCast([*]u32, d4);
|
||||
var s_u32 = @ptrCast([*]const u32, s4);
|
||||
var d_u32 = @as([*]u32, @ptrCast(d4));
|
||||
var s_u32 = @as([*]const u32, @ptrCast(s4));
|
||||
d_u32[0] = s_u32[0];
|
||||
d_u32[1] = s_u32[1];
|
||||
|
||||
|
@ -60,8 +79,8 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
s4 += 8;
|
||||
}
|
||||
if (n & 4 != 0) {
|
||||
var d_u32 = @ptrCast([*]u32, d4);
|
||||
var s_u32 = @ptrCast([*]const u32, s4);
|
||||
var d_u32 = @as([*]u32, @ptrCast(d4));
|
||||
var s_u32 = @as([*]const u32, @ptrCast(s4));
|
||||
d_u32[0] = s_u32[0];
|
||||
|
||||
d4 += 4;
|
||||
|
@ -83,9 +102,9 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
return dest;
|
||||
}
|
||||
if (n >= 32) {
|
||||
switch (@ptrToInt(d) % 4) {
|
||||
switch (@intFromPtr(d) % 4) {
|
||||
1 => {
|
||||
var w = @ptrCast([*]const u32, @alignCast(4, s))[0];
|
||||
var w = @as([*]const u32, @ptrCast(@alignCast(s)))[0];
|
||||
d[0] = s[0];
|
||||
d += 1;
|
||||
s += 1;
|
||||
|
@ -97,8 +116,8 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
s += 1;
|
||||
n -= 3;
|
||||
while (n >= 17) : (n -= 16) {
|
||||
var d_u32 = @ptrCast([*]u32, @alignCast(4, d));
|
||||
var s_u32 = @ptrCast([*]const u32, @alignCast(4, s + 1));
|
||||
var d_u32 = @as([*]u32, @ptrCast(@alignCast(d)));
|
||||
var s_u32 = @as([*]const u32, @ptrCast(@alignCast(s + 1)));
|
||||
var x = s_u32[0];
|
||||
d_u32[0] = (w >> 24) | (x << 8);
|
||||
w = s_u32[1];
|
||||
|
@ -113,7 +132,7 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
}
|
||||
},
|
||||
2 => {
|
||||
var w = @ptrCast([*]const u32, @alignCast(4, s))[0];
|
||||
var w = @as([*]const u32, @ptrCast(@alignCast(s)))[0];
|
||||
d[0] = s[0];
|
||||
d += 1;
|
||||
s += 1;
|
||||
|
@ -122,8 +141,8 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
s += 1;
|
||||
n -= 2;
|
||||
while (n >= 18) : (n -= 16) {
|
||||
var d_u32 = @ptrCast([*]u32, @alignCast(4, d));
|
||||
var s_u32 = @ptrCast([*]const u32, @alignCast(4, s + 2));
|
||||
var d_u32 = @as([*]u32, @ptrCast(@alignCast(d)));
|
||||
var s_u32 = @as([*]const u32, @ptrCast(@alignCast(s + 2)));
|
||||
var x = s_u32[0];
|
||||
d_u32[0] = (w >> 16) | (x << 16);
|
||||
w = s_u32[1];
|
||||
|
@ -138,14 +157,14 @@ pub fn fallback_memcpy(noalias dest: [*]u8, noalias src: [*]const u8, len: usize
|
|||
}
|
||||
},
|
||||
3 => {
|
||||
var w = @ptrCast([*]const u32, @alignCast(4, s))[0];
|
||||
var w = @as([*]const u32, @ptrCast(@alignCast(s)))[0];
|
||||
d[0] = s[0];
|
||||
d += 1;
|
||||
s += 1;
|
||||
n -= 1;
|
||||
while (n >= 19) : (n -= 16) {
|
||||
var d_u32 = @ptrCast([*]u32, @alignCast(4, d));
|
||||
var s_u32 = @ptrCast([*]const u32, @alignCast(4, s + 3));
|
||||
var d_u32 = @as([*]u32, @ptrCast(@alignCast(d)));
|
||||
var s_u32 = @as([*]const u32, @ptrCast(@alignCast(s + 3)));
|
||||
var x = s_u32[0];
|
||||
d_u32[0] = (w >> 8) | (x << 24);
|
||||
w = s_u32[1];
|
||||
|
|
|
@ -6,17 +6,17 @@ const math = std.math;
|
|||
|
||||
const expect = std.testing.expect;
|
||||
|
||||
const EqFn = fn (?[*]u8, ?[*]u8) callconv(.C) bool;
|
||||
const CompareFn = fn (?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) u8;
|
||||
const EqFn = *const fn (?[*]u8, ?[*]u8) callconv(.C) bool;
|
||||
const CompareFn = *const fn (?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) u8;
|
||||
const Opaque = ?[*]u8;
|
||||
|
||||
const Inc = fn (?[*]u8) callconv(.C) void;
|
||||
const IncN = fn (?[*]u8, usize) callconv(.C) void;
|
||||
const Dec = fn (?[*]u8) callconv(.C) void;
|
||||
const HasTagId = fn (u16, ?[*]u8) callconv(.C) extern struct { matched: bool, data: ?[*]u8 };
|
||||
const Inc = *const fn (?[*]u8) callconv(.C) void;
|
||||
const IncN = *const fn (?[*]u8, usize) callconv(.C) void;
|
||||
const Dec = *const fn (?[*]u8) callconv(.C) void;
|
||||
const HasTagId = *const fn (u16, ?[*]u8) callconv(.C) extern struct { matched: bool, data: ?[*]u8 };
|
||||
|
||||
const SEAMLESS_SLICE_BIT: usize =
|
||||
@bitCast(usize, @as(isize, std.math.minInt(isize)));
|
||||
@as(usize, @bitCast(@as(isize, std.math.minInt(isize))));
|
||||
|
||||
pub const RocList = extern struct {
|
||||
bytes: ?[*]u8,
|
||||
|
@ -38,14 +38,14 @@ pub const RocList = extern struct {
|
|||
}
|
||||
|
||||
pub fn isSeamlessSlice(self: RocList) bool {
|
||||
return @bitCast(isize, self.capacity_or_ref_ptr) < 0;
|
||||
return @as(isize, @bitCast(self.capacity_or_ref_ptr)) < 0;
|
||||
}
|
||||
|
||||
// This returns all ones if the list is a seamless slice.
|
||||
// Otherwise, it returns all zeros.
|
||||
// This is done without branching for optimization purposes.
|
||||
pub fn seamlessSliceMask(self: RocList) usize {
|
||||
return @bitCast(usize, @bitCast(isize, self.capacity_or_ref_ptr) >> (@bitSizeOf(isize) - 1));
|
||||
return @as(usize, @bitCast(@as(isize, @bitCast(self.capacity_or_ref_ptr)) >> (@bitSizeOf(isize) - 1)));
|
||||
}
|
||||
|
||||
pub fn isEmpty(self: RocList) bool {
|
||||
|
@ -90,10 +90,10 @@ pub const RocList = extern struct {
|
|||
|
||||
if (slice.len > 0) {
|
||||
const dest = list.bytes orelse unreachable;
|
||||
const src = @ptrCast([*]const u8, slice.ptr);
|
||||
const src = @as([*]const u8, @ptrCast(slice.ptr));
|
||||
const num_bytes = slice.len * @sizeOf(T);
|
||||
|
||||
@memcpy(dest, src, num_bytes);
|
||||
@memcpy(dest[0..num_bytes], src[0..num_bytes]);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -104,11 +104,11 @@ pub const RocList = extern struct {
|
|||
// For regular list, it just returns their bytes pointer.
|
||||
// For seamless slices, it returns the pointer stored in capacity_or_ref_ptr.
|
||||
pub fn getRefcountPtr(self: RocList) ?[*]u8 {
|
||||
const list_ref_ptr = @ptrToInt(self.bytes);
|
||||
const list_ref_ptr = @intFromPtr(self.bytes);
|
||||
const slice_ref_ptr = self.capacity_or_ref_ptr << 1;
|
||||
const slice_mask = self.seamlessSliceMask();
|
||||
const ref_ptr = (list_ref_ptr & ~slice_mask) | (slice_ref_ptr & slice_mask);
|
||||
return @intToPtr(?[*]u8, ref_ptr);
|
||||
return @as(?[*]u8, @ptrFromInt(ref_ptr));
|
||||
}
|
||||
|
||||
pub fn decref(self: RocList, alignment: u32) void {
|
||||
|
@ -117,7 +117,7 @@ pub const RocList = extern struct {
|
|||
}
|
||||
|
||||
pub fn elements(self: RocList, comptime T: type) ?[*]T {
|
||||
return @ptrCast(?[*]T, @alignCast(@alignOf(T), self.bytes));
|
||||
return @as(?[*]T, @ptrCast(@alignCast(self.bytes)));
|
||||
}
|
||||
|
||||
pub fn isUnique(self: RocList) bool {
|
||||
|
@ -130,7 +130,7 @@ pub const RocList = extern struct {
|
|||
return utils.REFCOUNT_ONE;
|
||||
}
|
||||
|
||||
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(@alignOf(usize), self.bytes));
|
||||
const ptr: [*]usize = @as([*]usize, @ptrCast(@alignCast(self.bytes)));
|
||||
return (ptr - 1)[0];
|
||||
}
|
||||
|
||||
|
@ -161,11 +161,11 @@ pub const RocList = extern struct {
|
|||
// unfortunately, we have to clone
|
||||
var new_list = RocList.allocate(alignment, self.length, element_width);
|
||||
|
||||
var old_bytes: [*]u8 = @ptrCast([*]u8, self.bytes);
|
||||
var new_bytes: [*]u8 = @ptrCast([*]u8, new_list.bytes);
|
||||
var old_bytes: [*]u8 = @as([*]u8, @ptrCast(self.bytes));
|
||||
var new_bytes: [*]u8 = @as([*]u8, @ptrCast(new_list.bytes));
|
||||
|
||||
const number_of_bytes = self.len() * element_width;
|
||||
@memcpy(new_bytes, old_bytes, number_of_bytes);
|
||||
@memcpy(new_bytes[0..number_of_bytes], old_bytes[0..number_of_bytes]);
|
||||
|
||||
// NOTE we fuse an increment of all keys/values with a decrement of the input list.
|
||||
self.decref(alignment);
|
||||
|
@ -238,7 +238,6 @@ pub const RocList = extern struct {
|
|||
element_width: usize,
|
||||
) RocList {
|
||||
const old_length = self.length;
|
||||
const delta_length = new_length - old_length;
|
||||
|
||||
const result = RocList.allocate(alignment, new_length, element_width);
|
||||
|
||||
|
@ -246,8 +245,8 @@ pub const RocList = extern struct {
|
|||
if (self.bytes) |source_ptr| {
|
||||
const dest_ptr = result.bytes orelse unreachable;
|
||||
|
||||
@memcpy(dest_ptr, source_ptr, old_length * element_width);
|
||||
@memset(dest_ptr + old_length * element_width, 0, delta_length * element_width);
|
||||
@memcpy(dest_ptr[0..(old_length * element_width)], source_ptr[0..(old_length * element_width)]);
|
||||
@memset(dest_ptr[(old_length * element_width)..(new_length * element_width)], 0);
|
||||
}
|
||||
|
||||
self.decref(alignment);
|
||||
|
@ -256,11 +255,11 @@ pub const RocList = extern struct {
|
|||
}
|
||||
};
|
||||
|
||||
const Caller0 = fn (?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller1 = fn (?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller2 = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller3 = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller4 = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller0 = *const fn (?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller1 = *const fn (?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller2 = *const fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller3 = *const fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
const Caller4 = *const fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
|
||||
pub fn listMap(
|
||||
list: RocList,
|
||||
|
@ -316,7 +315,7 @@ pub fn listMap2(
|
|||
dec_a: Dec,
|
||||
dec_b: Dec,
|
||||
) callconv(.C) RocList {
|
||||
const output_length = std.math.min(list1.len(), list2.len());
|
||||
const output_length = @min(list1.len(), list2.len());
|
||||
|
||||
// if the lists don't have equal length, we must consume the remaining elements
|
||||
// In this case we consume by (recursively) decrementing the elements
|
||||
|
@ -366,8 +365,8 @@ pub fn listMap3(
|
|||
dec_b: Dec,
|
||||
dec_c: Dec,
|
||||
) callconv(.C) RocList {
|
||||
const smaller_length = std.math.min(list1.len(), list2.len());
|
||||
const output_length = std.math.min(smaller_length, list3.len());
|
||||
const smaller_length = @min(list1.len(), list2.len());
|
||||
const output_length = @min(smaller_length, list3.len());
|
||||
|
||||
decrementTail(list1, output_length, a_width, dec_a);
|
||||
decrementTail(list2, output_length, b_width, dec_b);
|
||||
|
@ -425,7 +424,7 @@ pub fn listMap4(
|
|||
dec_c: Dec,
|
||||
dec_d: Dec,
|
||||
) callconv(.C) RocList {
|
||||
const output_length = std.math.min(std.math.min(list1.len(), list2.len()), std.math.min(list3.len(), list4.len()));
|
||||
const output_length = @min(@min(list1.len(), list2.len()), @min(list3.len(), list4.len()));
|
||||
|
||||
decrementTail(list1, output_length, a_width, dec_a);
|
||||
decrementTail(list2, output_length, b_width, dec_b);
|
||||
|
@ -512,7 +511,7 @@ pub fn listReleaseExcessCapacity(
|
|||
if (list.bytes) |source_ptr| {
|
||||
const dest_ptr = output.bytes orelse unreachable;
|
||||
|
||||
@memcpy(dest_ptr, source_ptr, old_length * element_width);
|
||||
@memcpy(dest_ptr[0..(old_length * element_width)], source_ptr[0..(old_length * element_width)]);
|
||||
}
|
||||
list.decref(alignment);
|
||||
return output;
|
||||
|
@ -528,9 +527,10 @@ pub fn listAppendUnsafe(
|
|||
var output = list;
|
||||
output.length += 1;
|
||||
|
||||
if (output.bytes) |target| {
|
||||
if (output.bytes) |bytes| {
|
||||
if (element) |source| {
|
||||
@memcpy(target + old_length * element_width, source, element_width);
|
||||
const target = bytes + old_length * element_width;
|
||||
@memcpy(target[0..element_width], source[0..element_width]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -556,12 +556,14 @@ pub fn listPrepend(list: RocList, alignment: u32, element: Opaque, element_width
|
|||
i -= 1;
|
||||
|
||||
// move the ith element to the (i + 1)th position
|
||||
@memcpy(target + (i + 1) * element_width, target + i * element_width, element_width);
|
||||
const to = target + (i + 1) * element_width;
|
||||
const from = target + i * element_width;
|
||||
@memcpy(to[0..element_width], from[0..element_width]);
|
||||
}
|
||||
|
||||
// finally copy in the new first element
|
||||
if (element) |source| {
|
||||
@memcpy(target, source, element_width);
|
||||
@memcpy(target[0..element_width], source[0..element_width]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,7 +592,7 @@ pub fn listSwap(
|
|||
}
|
||||
};
|
||||
|
||||
const source_ptr = @ptrCast([*]u8, newList.bytes);
|
||||
const source_ptr = @as([*]u8, @ptrCast(newList.bytes));
|
||||
swapElements(source_ptr, element_width, index_1, index_2);
|
||||
|
||||
return newList;
|
||||
|
@ -624,7 +626,7 @@ pub fn listSublist(
|
|||
}
|
||||
|
||||
if (list.bytes) |source_ptr| {
|
||||
const keep_len = std.math.min(len, size - start);
|
||||
const keep_len = @min(len, size - start);
|
||||
const drop_start_len = start;
|
||||
const drop_end_len = size - (start + keep_len);
|
||||
|
||||
|
@ -647,7 +649,7 @@ pub fn listSublist(
|
|||
output.length = keep_len;
|
||||
return output;
|
||||
} else {
|
||||
const list_ref_ptr = (@ptrToInt(source_ptr) >> 1) | SEAMLESS_SLICE_BIT;
|
||||
const list_ref_ptr = (@intFromPtr(source_ptr) >> 1) | SEAMLESS_SLICE_BIT;
|
||||
const slice_ref_ptr = list.capacity_or_ref_ptr;
|
||||
const slice_mask = list.seamlessSliceMask();
|
||||
const ref_ptr = (list_ref_ptr & ~slice_mask) | (slice_ref_ptr & slice_mask);
|
||||
|
@ -704,7 +706,7 @@ pub fn listDropAt(
|
|||
const copy_target = source_ptr + i * element_width;
|
||||
const copy_source = copy_target + element_width;
|
||||
|
||||
@memcpy(copy_target, copy_source, element_width);
|
||||
@memcpy(copy_target[0..element_width], copy_source[0..element_width]);
|
||||
}
|
||||
|
||||
var new_list = list;
|
||||
|
@ -717,12 +719,12 @@ pub fn listDropAt(
|
|||
const target_ptr = output.bytes orelse unreachable;
|
||||
|
||||
const head_size = drop_index * element_width;
|
||||
@memcpy(target_ptr, source_ptr, head_size);
|
||||
@memcpy(target_ptr[0..head_size], source_ptr[0..head_size]);
|
||||
|
||||
const tail_target = target_ptr + drop_index * element_width;
|
||||
const tail_source = source_ptr + (drop_index + 1) * element_width;
|
||||
const tail_size = (size - drop_index - 1) * element_width;
|
||||
@memcpy(tail_target, tail_source, tail_size);
|
||||
@memcpy(tail_target[0..tail_size], tail_source[0..tail_size]);
|
||||
|
||||
list.decref(alignment);
|
||||
|
||||
|
@ -733,26 +735,26 @@ pub fn listDropAt(
|
|||
}
|
||||
|
||||
fn partition(source_ptr: [*]u8, transform: Opaque, wrapper: CompareFn, element_width: usize, low: isize, high: isize) isize {
|
||||
const pivot = source_ptr + (@intCast(usize, high) * element_width);
|
||||
const pivot = source_ptr + (@as(usize, @intCast(high)) * element_width);
|
||||
var i = (low - 1); // Index of smaller element and indicates the right position of pivot found so far
|
||||
var j = low;
|
||||
|
||||
while (j <= high - 1) : (j += 1) {
|
||||
const current_elem = source_ptr + (@intCast(usize, j) * element_width);
|
||||
const current_elem = source_ptr + (@as(usize, @intCast(j)) * element_width);
|
||||
|
||||
const ordering = wrapper(transform, current_elem, pivot);
|
||||
const order = @intToEnum(utils.Ordering, ordering);
|
||||
const order = @as(utils.Ordering, @enumFromInt(ordering));
|
||||
|
||||
switch (order) {
|
||||
utils.Ordering.LT => {
|
||||
// the current element is smaller than the pivot; swap it
|
||||
i += 1;
|
||||
swapElements(source_ptr, element_width, @intCast(usize, i), @intCast(usize, j));
|
||||
swapElements(source_ptr, element_width, @as(usize, @intCast(i)), @as(usize, @intCast(j)));
|
||||
},
|
||||
utils.Ordering.EQ, utils.Ordering.GT => {},
|
||||
}
|
||||
}
|
||||
swapElements(source_ptr, element_width, @intCast(usize, i + 1), @intCast(usize, high));
|
||||
swapElements(source_ptr, element_width, @as(usize, @intCast(i + 1)), @as(usize, @intCast(high)));
|
||||
return (i + 1);
|
||||
}
|
||||
|
||||
|
@ -783,7 +785,7 @@ pub fn listSortWith(
|
|||
|
||||
if (list.bytes) |source_ptr| {
|
||||
const low = 0;
|
||||
const high: isize = @intCast(isize, list.len()) - 1;
|
||||
const high: isize = @as(isize, @intCast(list.len())) - 1;
|
||||
quicksort(source_ptr, data, caller, element_width, low, high);
|
||||
}
|
||||
|
||||
|
@ -793,9 +795,9 @@ pub fn listSortWith(
|
|||
// SWAP ELEMENTS
|
||||
|
||||
inline fn swapHelp(width: usize, temporary: [*]u8, ptr1: [*]u8, ptr2: [*]u8) void {
|
||||
@memcpy(temporary, ptr1, width);
|
||||
@memcpy(ptr1, ptr2, width);
|
||||
@memcpy(ptr2, temporary, width);
|
||||
@memcpy(temporary[0..width], ptr1[0..width]);
|
||||
@memcpy(ptr1[0..width], ptr2[0..width]);
|
||||
@memcpy(ptr2[0..width], temporary[0..width]);
|
||||
}
|
||||
|
||||
fn swap(width_initial: usize, p1: [*]u8, p2: [*]u8) void {
|
||||
|
@ -852,7 +854,7 @@ pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_widt
|
|||
// These must exist, otherwise, the lists would have been empty.
|
||||
const source_a = resized_list_a.bytes orelse unreachable;
|
||||
const source_b = list_b.bytes orelse unreachable;
|
||||
@memcpy(source_a + list_a.len() * element_width, source_b, list_b.len() * element_width);
|
||||
@memcpy(source_a[(list_a.len() * element_width)..(total_length * element_width)], source_b[0..(list_b.len() * element_width)]);
|
||||
|
||||
// decrement list b.
|
||||
list_b.decref(alignment);
|
||||
|
@ -873,7 +875,7 @@ pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_widt
|
|||
const byte_count_a = list_a.len() * element_width;
|
||||
const byte_count_b = list_b.len() * element_width;
|
||||
mem.copyBackwards(u8, source_b[byte_count_a .. byte_count_a + byte_count_b], source_b[0..byte_count_b]);
|
||||
@memcpy(source_b, source_a, byte_count_a);
|
||||
@memcpy(source_b[0..byte_count_a], source_a[0..byte_count_a]);
|
||||
|
||||
// decrement list a.
|
||||
list_a.decref(alignment);
|
||||
|
@ -889,8 +891,8 @@ pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_widt
|
|||
const source_a = list_a.bytes orelse unreachable;
|
||||
const source_b = list_b.bytes orelse unreachable;
|
||||
|
||||
@memcpy(target, source_a, list_a.len() * element_width);
|
||||
@memcpy(target + list_a.len() * element_width, source_b, list_b.len() * element_width);
|
||||
@memcpy(target[0..(list_a.len() * element_width)], source_a[0..(list_a.len() * element_width)]);
|
||||
@memcpy(target[(list_a.len() * element_width)..(total_length * element_width)], source_b[0..(list_b.len() * element_width)]);
|
||||
|
||||
// decrement list a and b.
|
||||
list_a.decref(alignment);
|
||||
|
@ -940,13 +942,13 @@ inline fn listReplaceInPlaceHelp(
|
|||
out_element: ?[*]u8,
|
||||
) RocList {
|
||||
// the element we will replace
|
||||
var element_at_index = (list.bytes orelse undefined) + (index * element_width);
|
||||
var element_at_index = (list.bytes orelse unreachable) + (index * element_width);
|
||||
|
||||
// copy out the old element
|
||||
@memcpy(out_element orelse undefined, element_at_index, element_width);
|
||||
@memcpy((out_element orelse unreachable)[0..element_width], element_at_index[0..element_width]);
|
||||
|
||||
// copy in the new element
|
||||
@memcpy(element_at_index, element orelse undefined, element_width);
|
||||
@memcpy(element_at_index[0..element_width], (element orelse unreachable)[0..element_width]);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -971,9 +973,9 @@ pub fn listRefcountPtr(
|
|||
|
||||
test "listConcat: non-unique with unique overlapping" {
|
||||
var nonUnique = RocList.fromSlice(u8, ([_]u8{1})[0..]);
|
||||
var bytes: [*]u8 = @ptrCast([*]u8, nonUnique.bytes);
|
||||
var bytes: [*]u8 = @as([*]u8, @ptrCast(nonUnique.bytes));
|
||||
const ptr_width = @sizeOf(usize);
|
||||
const refcount_ptr = @ptrCast([*]isize, @alignCast(ptr_width, bytes) - ptr_width);
|
||||
const refcount_ptr = @as([*]isize, @ptrCast(@as([*]align(ptr_width) u8, @alignCast(bytes)) - ptr_width));
|
||||
utils.increfRcPtrC(&refcount_ptr[0], 1);
|
||||
defer nonUnique.decref(@sizeOf(u8)); // listConcat will dec the other refcount
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ comptime {
|
|||
exportNumFn(num.greaterThanU128, "greater_than.u128");
|
||||
exportNumFn(num.greaterThanOrEqualU128, "greater_than_or_equal.u128");
|
||||
|
||||
inline for (INTEGERS) |T, i| {
|
||||
inline for (INTEGERS, 0..) |T, i| {
|
||||
num.exportPow(T, ROC_BUILTINS ++ "." ++ NUM ++ ".pow_int.");
|
||||
num.exportDivCeil(T, ROC_BUILTINS ++ "." ++ NUM ++ ".div_ceil.");
|
||||
|
||||
|
@ -307,12 +307,9 @@ fn exportUtilsFn(comptime func: anytype, comptime func_name: []const u8) void {
|
|||
}
|
||||
|
||||
// Custom panic function, as builtin Zig version errors during LLVM verification
|
||||
pub fn panic(message: []const u8, stacktrace: ?*std.builtin.StackTrace) noreturn {
|
||||
pub fn panic(message: []const u8, stacktrace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||
if (builtin.is_test) {
|
||||
std.debug.print("{s}: {?}", .{ message, stacktrace });
|
||||
} else {
|
||||
_ = message;
|
||||
_ = stacktrace;
|
||||
}
|
||||
|
||||
unreachable;
|
||||
|
@ -320,7 +317,7 @@ pub fn panic(message: []const u8, stacktrace: ?*std.builtin.StackTrace) noreturn
|
|||
|
||||
// Run all tests in imported modules
|
||||
// https://github.com/ziglang/zig/blob/master/lib/std/std.zig#L94
|
||||
test "" {
|
||||
test {
|
||||
const testing = std.testing;
|
||||
|
||||
testing.refAllDecls(@This());
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
|
||||
const math = std.math;
|
||||
const RocList = @import("list.zig").RocList;
|
||||
const RocStr = @import("str.zig").RocStr;
|
||||
|
@ -180,7 +179,7 @@ pub fn exportTan(comptime T: type, comptime name: []const u8) void {
|
|||
pub fn exportLog(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(input: T) callconv(.C) T {
|
||||
return math.ln(input);
|
||||
return @log(input);
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -189,7 +188,7 @@ pub fn exportLog(comptime T: type, comptime name: []const u8) void {
|
|||
pub fn exportFAbs(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(input: T) callconv(.C) T {
|
||||
return math.absFloat(input);
|
||||
return @fabs(input);
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -207,7 +206,7 @@ pub fn exportSqrt(comptime T: type, comptime name: []const u8) void {
|
|||
pub fn exportRound(comptime F: type, comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(input: F) callconv(.C) T {
|
||||
return @floatToInt(T, (math.round(input)));
|
||||
return @as(T, @intFromFloat((math.round(input))));
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -216,7 +215,7 @@ pub fn exportRound(comptime F: type, comptime T: type, comptime name: []const u8
|
|||
pub fn exportFloor(comptime F: type, comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(input: F) callconv(.C) T {
|
||||
return @floatToInt(T, (math.floor(input)));
|
||||
return @as(T, @intFromFloat((math.floor(input))));
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -225,7 +224,7 @@ pub fn exportFloor(comptime F: type, comptime T: type, comptime name: []const u8
|
|||
pub fn exportCeiling(comptime F: type, comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(input: F) callconv(.C) T {
|
||||
return @floatToInt(T, (math.ceil(input)));
|
||||
return @as(T, @intFromFloat((math.ceil(input))));
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -255,7 +254,7 @@ pub fn exportToIntCheckingMax(comptime From: type, comptime To: type, comptime n
|
|||
if (input > std.math.maxInt(To)) {
|
||||
return .{ .out_of_bounds = true, .value = 0 };
|
||||
}
|
||||
return .{ .out_of_bounds = false, .value = @intCast(To, input) };
|
||||
return .{ .out_of_bounds = false, .value = @as(To, @intCast(input)) };
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(From), .linkage = .Strong });
|
||||
|
@ -267,46 +266,46 @@ pub fn exportToIntCheckingMaxAndMin(comptime From: type, comptime To: type, comp
|
|||
if (input > std.math.maxInt(To) or input < std.math.minInt(To)) {
|
||||
return .{ .out_of_bounds = true, .value = 0 };
|
||||
}
|
||||
return .{ .out_of_bounds = false, .value = @intCast(To, input) };
|
||||
return .{ .out_of_bounds = false, .value = @as(To, @intCast(input)) };
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(From), .linkage = .Strong });
|
||||
}
|
||||
|
||||
pub fn bytesToU16C(arg: RocList, position: usize) callconv(.C) u16 {
|
||||
return @call(.{ .modifier = always_inline }, bytesToU16, .{ arg, position });
|
||||
return @call(.always_inline, bytesToU16, .{ arg, position });
|
||||
}
|
||||
|
||||
fn bytesToU16(arg: RocList, position: usize) u16 {
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes);
|
||||
return @bitCast(u16, [_]u8{ bytes[position], bytes[position + 1] });
|
||||
const bytes = @as([*]const u8, @ptrCast(arg.bytes));
|
||||
return @as(u16, @bitCast([_]u8{ bytes[position], bytes[position + 1] }));
|
||||
}
|
||||
|
||||
pub fn bytesToU32C(arg: RocList, position: usize) callconv(.C) u32 {
|
||||
return @call(.{ .modifier = always_inline }, bytesToU32, .{ arg, position });
|
||||
return @call(.always_inline, bytesToU32, .{ arg, position });
|
||||
}
|
||||
|
||||
fn bytesToU32(arg: RocList, position: usize) u32 {
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes);
|
||||
return @bitCast(u32, [_]u8{ bytes[position], bytes[position + 1], bytes[position + 2], bytes[position + 3] });
|
||||
const bytes = @as([*]const u8, @ptrCast(arg.bytes));
|
||||
return @as(u32, @bitCast([_]u8{ bytes[position], bytes[position + 1], bytes[position + 2], bytes[position + 3] }));
|
||||
}
|
||||
|
||||
pub fn bytesToU64C(arg: RocList, position: usize) callconv(.C) u64 {
|
||||
return @call(.{ .modifier = always_inline }, bytesToU64, .{ arg, position });
|
||||
return @call(.always_inline, bytesToU64, .{ arg, position });
|
||||
}
|
||||
|
||||
fn bytesToU64(arg: RocList, position: usize) u64 {
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes);
|
||||
return @bitCast(u64, [_]u8{ bytes[position], bytes[position + 1], bytes[position + 2], bytes[position + 3], bytes[position + 4], bytes[position + 5], bytes[position + 6], bytes[position + 7] });
|
||||
const bytes = @as([*]const u8, @ptrCast(arg.bytes));
|
||||
return @as(u64, @bitCast([_]u8{ bytes[position], bytes[position + 1], bytes[position + 2], bytes[position + 3], bytes[position + 4], bytes[position + 5], bytes[position + 6], bytes[position + 7] }));
|
||||
}
|
||||
|
||||
pub fn bytesToU128C(arg: RocList, position: usize) callconv(.C) u128 {
|
||||
return @call(.{ .modifier = always_inline }, bytesToU128, .{ arg, position });
|
||||
return @call(.always_inline, bytesToU128, .{ arg, position });
|
||||
}
|
||||
|
||||
fn bytesToU128(arg: RocList, position: usize) u128 {
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes);
|
||||
return @bitCast(u128, [_]u8{ bytes[position], bytes[position + 1], bytes[position + 2], bytes[position + 3], bytes[position + 4], bytes[position + 5], bytes[position + 6], bytes[position + 7], bytes[position + 8], bytes[position + 9], bytes[position + 10], bytes[position + 11], bytes[position + 12], bytes[position + 13], bytes[position + 14], bytes[position + 15] });
|
||||
const bytes = @as([*]const u8, @ptrCast(arg.bytes));
|
||||
return @as(u128, @bitCast([_]u8{ bytes[position], bytes[position + 1], bytes[position + 2], bytes[position + 3], bytes[position + 4], bytes[position + 5], bytes[position + 6], bytes[position + 7], bytes[position + 8], bytes[position + 9], bytes[position + 10], bytes[position + 11], bytes[position + 12], bytes[position + 13], bytes[position + 14], bytes[position + 15] }));
|
||||
}
|
||||
|
||||
fn isMultipleOf(comptime T: type, lhs: T, rhs: T) bool {
|
||||
|
@ -327,7 +326,7 @@ fn isMultipleOf(comptime T: type, lhs: T, rhs: T) bool {
|
|||
pub fn exportIsMultipleOf(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T, other: T) callconv(.C) bool {
|
||||
return @call(.{ .modifier = always_inline }, isMultipleOf, .{ T, self, other });
|
||||
return @call(.always_inline, isMultipleOf, .{ T, self, other });
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -336,9 +335,8 @@ pub fn exportIsMultipleOf(comptime T: type, comptime name: []const u8) void {
|
|||
fn addWithOverflow(comptime T: type, self: T, other: T) WithOverflow(T) {
|
||||
switch (@typeInfo(T)) {
|
||||
.Int => {
|
||||
var answer: T = undefined;
|
||||
const overflowed = @addWithOverflow(T, self, other, &answer);
|
||||
return .{ .value = answer, .has_overflowed = overflowed };
|
||||
const answer = @addWithOverflow(self, other);
|
||||
return .{ .value = answer[0], .has_overflowed = answer[1] == 1 };
|
||||
},
|
||||
else => {
|
||||
const answer = self + other;
|
||||
|
@ -351,7 +349,7 @@ fn addWithOverflow(comptime T: type, self: T, other: T) WithOverflow(T) {
|
|||
pub fn exportAddWithOverflow(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T, other: T) callconv(.C) WithOverflow(T) {
|
||||
return @call(.{ .modifier = always_inline }, addWithOverflow, .{ T, self, other });
|
||||
return @call(.always_inline, addWithOverflow, .{ T, self, other });
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -394,9 +392,8 @@ pub fn exportAddOrPanic(comptime T: type, comptime name: []const u8) void {
|
|||
fn subWithOverflow(comptime T: type, self: T, other: T) WithOverflow(T) {
|
||||
switch (@typeInfo(T)) {
|
||||
.Int => {
|
||||
var answer: T = undefined;
|
||||
const overflowed = @subWithOverflow(T, self, other, &answer);
|
||||
return .{ .value = answer, .has_overflowed = overflowed };
|
||||
const answer = @subWithOverflow(self, other);
|
||||
return .{ .value = answer[0], .has_overflowed = answer[1] == 1 };
|
||||
},
|
||||
else => {
|
||||
const answer = self - other;
|
||||
|
@ -409,7 +406,7 @@ fn subWithOverflow(comptime T: type, self: T, other: T) WithOverflow(T) {
|
|||
pub fn exportSubWithOverflow(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T, other: T) callconv(.C) WithOverflow(T) {
|
||||
return @call(.{ .modifier = always_inline }, subWithOverflow, .{ T, self, other });
|
||||
return @call(.always_inline, subWithOverflow, .{ T, self, other });
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -458,7 +455,7 @@ fn mulWithOverflow(comptime T: type, comptime W: type, self: T, other: T) WithOv
|
|||
const max = std.math.maxInt(i128);
|
||||
const min = std.math.minInt(i128);
|
||||
|
||||
const self_u128 = @intCast(u128, math.absInt(self) catch {
|
||||
const self_u128 = @as(u128, @intCast(math.absInt(self) catch {
|
||||
if (other == 0) {
|
||||
return .{ .value = 0, .has_overflowed = false };
|
||||
} else if (other == 1) {
|
||||
|
@ -468,9 +465,9 @@ fn mulWithOverflow(comptime T: type, comptime W: type, self: T, other: T) WithOv
|
|||
} else {
|
||||
return .{ .value = max, .has_overflowed = true };
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
const other_u128 = @intCast(u128, math.absInt(other) catch {
|
||||
const other_u128 = @as(u128, @intCast(math.absInt(other) catch {
|
||||
if (self == 0) {
|
||||
return .{ .value = 0, .has_overflowed = false };
|
||||
} else if (self == 1) {
|
||||
|
@ -480,7 +477,7 @@ fn mulWithOverflow(comptime T: type, comptime W: type, self: T, other: T) WithOv
|
|||
} else {
|
||||
return .{ .value = max, .has_overflowed = true };
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
const answer256: U256 = mul_u128(self_u128, other_u128);
|
||||
|
||||
|
@ -490,13 +487,13 @@ fn mulWithOverflow(comptime T: type, comptime W: type, self: T, other: T) WithOv
|
|||
} else if (answer256.lo == (1 << 127)) {
|
||||
return .{ .value = min, .has_overflowed = false };
|
||||
} else {
|
||||
return .{ .value = -@intCast(i128, answer256.lo), .has_overflowed = false };
|
||||
return .{ .value = -@as(i128, @intCast(answer256.lo)), .has_overflowed = false };
|
||||
}
|
||||
} else {
|
||||
if (answer256.hi != 0 or answer256.lo > @intCast(u128, max)) {
|
||||
if (answer256.hi != 0 or answer256.lo > @as(u128, @intCast(max))) {
|
||||
return .{ .value = max, .has_overflowed = true };
|
||||
} else {
|
||||
return .{ .value = @intCast(i128, answer256.lo), .has_overflowed = false };
|
||||
return .{ .value = @as(i128, @intCast(answer256.lo)), .has_overflowed = false };
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -512,7 +509,7 @@ fn mulWithOverflow(comptime T: type, comptime W: type, self: T, other: T) WithOv
|
|||
} else if (answer < min) {
|
||||
return .{ .value = min, .has_overflowed = true };
|
||||
} else {
|
||||
return .{ .value = @intCast(T, answer), .has_overflowed = false };
|
||||
return .{ .value = @as(T, @intCast(answer)), .has_overflowed = false };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -527,7 +524,7 @@ fn mulWithOverflow(comptime T: type, comptime W: type, self: T, other: T) WithOv
|
|||
pub fn exportMulWithOverflow(comptime T: type, comptime W: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T, other: T) callconv(.C) WithOverflow(T) {
|
||||
return @call(.{ .modifier = always_inline }, mulWithOverflow, .{ T, W, self, other });
|
||||
return @call(.always_inline, mulWithOverflow, .{ T, W, self, other });
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -536,7 +533,7 @@ pub fn exportMulWithOverflow(comptime T: type, comptime W: type, comptime name:
|
|||
pub fn exportMulSaturatedInt(comptime T: type, comptime W: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T, other: T) callconv(.C) T {
|
||||
const result = @call(.{ .modifier = always_inline }, mulWithOverflow, .{ T, W, self, other });
|
||||
const result = @call(.always_inline, mulWithOverflow, .{ T, W, self, other });
|
||||
return result.value;
|
||||
}
|
||||
}.func;
|
||||
|
@ -556,7 +553,7 @@ pub fn shiftRightZeroFillI128(self: i128, other: u8) callconv(.C) i128 {
|
|||
if (other & 0b1000_0000 > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return self >> @intCast(u7, other);
|
||||
return self >> @as(u7, @intCast(other));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,7 +561,7 @@ pub fn shiftRightZeroFillU128(self: u128, other: u8) callconv(.C) u128 {
|
|||
if (other & 0b1000_0000 > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return self >> @intCast(u7, other);
|
||||
return self >> @as(u7, @intCast(other));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,7 +620,7 @@ pub fn greaterThanOrEqualU128(self: u128, other: u128) callconv(.C) bool {
|
|||
pub fn exportMulOrPanic(comptime T: type, comptime W: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T, other: T) callconv(.C) T {
|
||||
const result = @call(.{ .modifier = always_inline }, mulWithOverflow, .{ T, W, self, other });
|
||||
const result = @call(.always_inline, mulWithOverflow, .{ T, W, self, other });
|
||||
if (result.has_overflowed) {
|
||||
roc_panic("integer multiplication overflowed!", 0);
|
||||
unreachable;
|
||||
|
@ -638,7 +635,7 @@ pub fn exportMulOrPanic(comptime T: type, comptime W: type, comptime name: []con
|
|||
pub fn exportCountLeadingZeroBits(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T) callconv(.C) usize {
|
||||
return @as(usize, @clz(T, self));
|
||||
return @as(usize, @clz(self));
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -647,7 +644,7 @@ pub fn exportCountLeadingZeroBits(comptime T: type, comptime name: []const u8) v
|
|||
pub fn exportCountTrailingZeroBits(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T) callconv(.C) usize {
|
||||
return @as(usize, @ctz(T, self));
|
||||
return @as(usize, @ctz(self));
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -656,7 +653,7 @@ pub fn exportCountTrailingZeroBits(comptime T: type, comptime name: []const u8)
|
|||
pub fn exportCountOneBits(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(self: T) callconv(.C) usize {
|
||||
return @as(usize, @popCount(T, self));
|
||||
return @as(usize, @popCount(self));
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const std = @import("std");
|
||||
const RocStr = @import("str.zig").RocStr;
|
||||
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
|
||||
|
||||
// Signals to the host that the program has panicked
|
||||
extern fn roc_panic(msg: *const RocStr, tag_id: u32) callconv(.C) void;
|
||||
|
@ -12,5 +11,5 @@ pub fn panic_help(msg: []const u8, tag_id: u32) void {
|
|||
|
||||
// must export this explicitly because right now it is not used from zig code
|
||||
pub fn panic(msg: *const RocStr, alignment: u32) callconv(.C) void {
|
||||
return @call(.{ .modifier = always_inline }, roc_panic, .{ msg, alignment });
|
||||
return roc_panic(msg, alignment);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ const grapheme = @import("helpers/grapheme.zig");
|
|||
const UpdateMode = utils.UpdateMode;
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
|
||||
const unicode = std.unicode;
|
||||
const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
|
@ -17,7 +16,7 @@ const InPlace = enum(u8) {
|
|||
};
|
||||
|
||||
const MASK_ISIZE: isize = std.math.minInt(isize);
|
||||
const MASK: usize = @bitCast(usize, MASK_ISIZE);
|
||||
const MASK: usize = @as(usize, @bitCast(MASK_ISIZE));
|
||||
const SEAMLESS_SLICE_BIT: usize = MASK;
|
||||
|
||||
const SMALL_STR_MAX_LENGTH = SMALL_STRING_SIZE - 1;
|
||||
|
@ -53,7 +52,7 @@ pub const RocStr = extern struct {
|
|||
// small string, and returns a (pointer, len) tuple which points to them.
|
||||
pub fn init(bytes_ptr: [*]const u8, length: usize) RocStr {
|
||||
var result = RocStr.allocate(length);
|
||||
@memcpy(result.asU8ptrMut(), bytes_ptr, length);
|
||||
@memcpy(result.asU8ptrMut()[0..length], bytes_ptr[0..length]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -61,7 +60,7 @@ pub const RocStr = extern struct {
|
|||
// This requires that the list is non-null.
|
||||
// It also requires that start and count define a slice that does not go outside the bounds of the list.
|
||||
pub fn fromSubListUnsafe(list: RocList, start: usize, count: usize, update_mode: UpdateMode) RocStr {
|
||||
const start_byte = @ptrCast([*]u8, list.bytes) + start;
|
||||
const start_byte = @as([*]u8, @ptrCast(list.bytes)) + start;
|
||||
if (list.isSeamlessSlice()) {
|
||||
return RocStr{
|
||||
.str_bytes = start_byte,
|
||||
|
@ -80,13 +79,13 @@ pub const RocStr = extern struct {
|
|||
return RocStr{
|
||||
.str_bytes = start_byte,
|
||||
.str_len = count | SEAMLESS_SLICE_BIT,
|
||||
.str_capacity = @ptrToInt(list.bytes) >> 1,
|
||||
.str_capacity = @intFromPtr(list.bytes) >> 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isSeamlessSlice(self: RocStr) bool {
|
||||
return !self.isSmallStr() and @bitCast(isize, self.str_len) < 0;
|
||||
return !self.isSmallStr() and @as(isize, @bitCast(self.str_len)) < 0;
|
||||
}
|
||||
|
||||
pub fn fromSlice(slice: []const u8) RocStr {
|
||||
|
@ -115,7 +114,7 @@ pub const RocStr = extern struct {
|
|||
} else {
|
||||
var string = RocStr.empty();
|
||||
|
||||
string.asU8ptrMut()[@sizeOf(RocStr) - 1] = @intCast(u8, length) | 0b1000_0000;
|
||||
string.asU8ptrMut()[@sizeOf(RocStr) - 1] = @as(u8, @intCast(length)) | 0b1000_0000;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
@ -131,7 +130,7 @@ pub const RocStr = extern struct {
|
|||
} else {
|
||||
var string = RocStr.empty();
|
||||
|
||||
string.asU8ptrMut()[@sizeOf(RocStr) - 1] = @intCast(u8, length) | 0b1000_0000;
|
||||
string.asU8ptrMut()[@sizeOf(RocStr) - 1] = @as(u8, @intCast(length)) | 0b1000_0000;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
@ -141,7 +140,7 @@ pub const RocStr = extern struct {
|
|||
// Otherwise, it returns all zeros.
|
||||
// This is done without branching for optimization purposes.
|
||||
pub fn seamlessSliceMask(self: RocStr) usize {
|
||||
return @bitCast(usize, @bitCast(isize, self.str_len) >> (@bitSizeOf(isize) - 1));
|
||||
return @as(usize, @bitCast(@as(isize, @bitCast(self.str_len)) >> (@bitSizeOf(isize) - 1)));
|
||||
}
|
||||
|
||||
// returns a pointer to just after the refcount.
|
||||
|
@ -150,19 +149,19 @@ pub const RocStr = extern struct {
|
|||
// For seamless slices, it returns the pointer stored in capacity_or_ref_ptr.
|
||||
// This does not return a valid value if the input is a small string.
|
||||
pub fn getRefcountPtr(self: RocStr) ?[*]u8 {
|
||||
const str_ref_ptr = @ptrToInt(self.str_bytes);
|
||||
const str_ref_ptr = @intFromPtr(self.str_bytes);
|
||||
const slice_ref_ptr = self.str_capacity << 1;
|
||||
const slice_mask = self.seamlessSliceMask();
|
||||
const ref_ptr = (str_ref_ptr & ~slice_mask) | (slice_ref_ptr & slice_mask);
|
||||
return @intToPtr(?[*]u8, ref_ptr);
|
||||
return @as(?[*]u8, @ptrFromInt(ref_ptr));
|
||||
}
|
||||
|
||||
pub fn incref(self: RocStr, n: usize) void {
|
||||
if (!self.isSmallStr()) {
|
||||
const ref_ptr = self.getRefcountPtr();
|
||||
if (ref_ptr != null) {
|
||||
const isizes: [*]isize = @ptrCast([*]isize, @alignCast(@alignOf(isize), ref_ptr));
|
||||
utils.increfRcPtrC(@ptrCast(*isize, isizes - 1), @intCast(isize, n));
|
||||
const isizes: [*]isize = @as([*]isize, @ptrCast(@alignCast(ref_ptr)));
|
||||
utils.increfRcPtrC(@as(*isize, @ptrCast(isizes - 1)), @as(isize, @intCast(n)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,10 +210,10 @@ pub const RocStr = extern struct {
|
|||
} else {
|
||||
var new_str = RocStr.allocateBig(str.str_len, str.str_len);
|
||||
|
||||
var old_bytes: [*]u8 = @ptrCast([*]u8, str.str_bytes);
|
||||
var new_bytes: [*]u8 = @ptrCast([*]u8, new_str.str_bytes);
|
||||
var old_bytes: [*]u8 = @as([*]u8, @ptrCast(str.str_bytes));
|
||||
var new_bytes: [*]u8 = @as([*]u8, @ptrCast(new_str.str_bytes));
|
||||
|
||||
@memcpy(new_bytes, old_bytes, str.str_len);
|
||||
@memcpy(new_bytes[0..str.str_len], old_bytes[0..str.str_len]);
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
@ -257,7 +256,6 @@ pub const RocStr = extern struct {
|
|||
new_length: usize,
|
||||
) RocStr {
|
||||
const old_length = self.len();
|
||||
const delta_length = new_length - old_length;
|
||||
|
||||
const element_width = 1;
|
||||
const result_is_big = new_length >= SMALL_STRING_SIZE;
|
||||
|
@ -272,7 +270,7 @@ pub const RocStr = extern struct {
|
|||
const dest_ptr = result.asU8ptrMut();
|
||||
|
||||
std.mem.copy(u8, dest_ptr[0..old_length], source_ptr[0..old_length]);
|
||||
std.mem.set(u8, dest_ptr[old_length .. old_length + delta_length], 0);
|
||||
@memset(dest_ptr[old_length..new_length], 0);
|
||||
|
||||
self.decref();
|
||||
|
||||
|
@ -282,13 +280,13 @@ pub const RocStr = extern struct {
|
|||
|
||||
// I believe taking this reference on the stack here is important for correctness.
|
||||
// Doing it via a method call seemed to cause issues
|
||||
const dest_ptr = @ptrCast([*]u8, &string);
|
||||
dest_ptr[@sizeOf(RocStr) - 1] = @intCast(u8, new_length) | 0b1000_0000;
|
||||
const dest_ptr = @as([*]u8, @ptrCast(&string));
|
||||
dest_ptr[@sizeOf(RocStr) - 1] = @as(u8, @intCast(new_length)) | 0b1000_0000;
|
||||
|
||||
const source_ptr = self.asU8ptr();
|
||||
|
||||
std.mem.copy(u8, dest_ptr[0..old_length], source_ptr[0..old_length]);
|
||||
std.mem.set(u8, dest_ptr[old_length .. old_length + delta_length], 0);
|
||||
@memset(dest_ptr[old_length..new_length], 0);
|
||||
|
||||
self.decref();
|
||||
|
||||
|
@ -297,7 +295,7 @@ pub const RocStr = extern struct {
|
|||
}
|
||||
|
||||
pub fn isSmallStr(self: RocStr) bool {
|
||||
return @bitCast(isize, self.str_capacity) < 0;
|
||||
return @as(isize, @bitCast(self.str_capacity)) < 0;
|
||||
}
|
||||
|
||||
test "isSmallStr: returns true for empty string" {
|
||||
|
@ -305,7 +303,7 @@ pub const RocStr = extern struct {
|
|||
}
|
||||
|
||||
fn asArray(self: RocStr) [@sizeOf(RocStr)]u8 {
|
||||
const as_ptr = @ptrCast([*]const u8, &self);
|
||||
const as_ptr = @as([*]const u8, @ptrCast(&self));
|
||||
const slice = as_ptr[0..@sizeOf(RocStr)];
|
||||
|
||||
return slice.*;
|
||||
|
@ -321,7 +319,7 @@ pub const RocStr = extern struct {
|
|||
|
||||
pub fn setLen(self: *RocStr, length: usize) void {
|
||||
if (self.isSmallStr()) {
|
||||
self.asU8ptrMut()[@sizeOf(RocStr) - 1] = @intCast(u8, length) | 0b1000_0000;
|
||||
self.asU8ptrMut()[@sizeOf(RocStr) - 1] = @as(u8, @intCast(length)) | 0b1000_0000;
|
||||
} else {
|
||||
self.str_len = length | (SEAMLESS_SLICE_BIT & self.str_len);
|
||||
}
|
||||
|
@ -359,7 +357,7 @@ pub const RocStr = extern struct {
|
|||
}
|
||||
|
||||
// otherwise, check if the refcount is one
|
||||
return @call(.{ .modifier = always_inline }, RocStr.isRefcountOne, .{self});
|
||||
return @call(.always_inline, RocStr.isRefcountOne, .{self});
|
||||
}
|
||||
|
||||
fn isRefcountOne(self: RocStr) bool {
|
||||
|
@ -371,7 +369,7 @@ pub const RocStr = extern struct {
|
|||
return utils.REFCOUNT_ONE;
|
||||
}
|
||||
|
||||
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(@alignOf(usize), self.str_bytes));
|
||||
const ptr: [*]usize = @as([*]usize, @ptrCast(@alignCast(self.str_bytes)));
|
||||
return (ptr - 1)[0];
|
||||
}
|
||||
|
||||
|
@ -393,17 +391,17 @@ pub const RocStr = extern struct {
|
|||
|
||||
pub fn asU8ptr(self: *const RocStr) [*]const u8 {
|
||||
if (self.isSmallStr()) {
|
||||
return @ptrCast([*]const u8, self);
|
||||
return @as([*]const u8, @ptrCast(self));
|
||||
} else {
|
||||
return @ptrCast([*]const u8, self.str_bytes);
|
||||
return @as([*]const u8, @ptrCast(self.str_bytes));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn asU8ptrMut(self: *RocStr) [*]u8 {
|
||||
if (self.isSmallStr()) {
|
||||
return @ptrCast([*]u8, self);
|
||||
return @as([*]u8, @ptrCast(self));
|
||||
} else {
|
||||
return @ptrCast([*]u8, self.str_bytes);
|
||||
return @as([*]u8, @ptrCast(self.str_bytes));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,7 +413,7 @@ pub const RocStr = extern struct {
|
|||
// a C function - like the file path argument to `fopen`.
|
||||
pub fn memcpy(self: RocStr, dest: [*]u8) void {
|
||||
const src = self.asU8ptr();
|
||||
@memcpy(dest, src, self.len());
|
||||
@memcpy(dest[0..self.len()], src[0..self.len()]);
|
||||
}
|
||||
|
||||
test "RocStr.eq: small, equal" {
|
||||
|
@ -536,7 +534,7 @@ pub const RocStr = extern struct {
|
|||
};
|
||||
|
||||
pub fn init(bytes_ptr: [*]const u8, length: usize) callconv(.C) RocStr {
|
||||
return @call(.{ .modifier = always_inline }, RocStr.init, .{ bytes_ptr, length });
|
||||
return @call(.always_inline, RocStr.init, .{ bytes_ptr, length });
|
||||
}
|
||||
|
||||
// Str.equal
|
||||
|
@ -551,7 +549,7 @@ pub fn strNumberOfBytes(string: RocStr) callconv(.C) usize {
|
|||
|
||||
// Str.toScalars
|
||||
pub fn strToScalarsC(str: RocStr) callconv(.C) RocList {
|
||||
return @call(.{ .modifier = always_inline }, strToScalars, .{str});
|
||||
return @call(.always_inline, strToScalars, .{str});
|
||||
}
|
||||
|
||||
fn strToScalars(string: RocStr) callconv(.C) RocList {
|
||||
|
@ -599,7 +597,7 @@ inline fn writeNextScalar(non_empty_string: RocStr, src_index: usize, dest: [*]u
|
|||
// https://docs.teradata.com/r/Teradata-Database-International-Character-Set-Support/June-2017/Client-Character-Set-Options/UTF8-Client-Character-Set-Support/UTF8-Multibyte-Sequences
|
||||
if (utf8_byte <= 127) {
|
||||
// It's an ASCII character. Copy it over directly.
|
||||
dest[dest_index] = @intCast(u32, utf8_byte);
|
||||
dest[dest_index] = @as(u32, @intCast(utf8_byte));
|
||||
|
||||
return 1;
|
||||
} else if (utf8_byte >> 5 == 0b0000_0110) {
|
||||
|
@ -610,7 +608,7 @@ inline fn writeNextScalar(non_empty_string: RocStr, src_index: usize, dest: [*]u
|
|||
// code pt: 0000 0011 1111 0001 (decimal: 1009)
|
||||
|
||||
// Discard the first byte's high order bits of 110.
|
||||
var code_pt = @intCast(u32, utf8_byte & 0b0001_1111);
|
||||
var code_pt = @as(u32, @intCast(utf8_byte & 0b0001_1111));
|
||||
|
||||
// Discard the second byte's high order bits of 10.
|
||||
code_pt <<= 6;
|
||||
|
@ -623,7 +621,7 @@ inline fn writeNextScalar(non_empty_string: RocStr, src_index: usize, dest: [*]u
|
|||
// Its four high order bits are 1110, so this is a three-byte sequence.
|
||||
|
||||
// Discard the first byte's high order bits of 1110.
|
||||
var code_pt = @intCast(u32, utf8_byte & 0b0000_1111);
|
||||
var code_pt = @as(u32, @intCast(utf8_byte & 0b0000_1111));
|
||||
|
||||
// Discard the second byte's high order bits of 10.
|
||||
code_pt <<= 6;
|
||||
|
@ -640,7 +638,7 @@ inline fn writeNextScalar(non_empty_string: RocStr, src_index: usize, dest: [*]u
|
|||
// This must be a four-byte sequence, so the five high order bits should be 11110.
|
||||
|
||||
// Discard the first byte's high order bits of 11110.
|
||||
var code_pt = @intCast(u32, utf8_byte & 0b0000_0111);
|
||||
var code_pt = @as(u32, @intCast(utf8_byte & 0b0000_0111));
|
||||
|
||||
// Discard the second byte's high order bits of 10.
|
||||
code_pt <<= 6;
|
||||
|
@ -789,7 +787,7 @@ test "strToScalars: Multiple 4-byte UTF-8 characters" {
|
|||
pub fn exportFromInt(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(int: T) callconv(.C) RocStr {
|
||||
return @call(.{ .modifier = always_inline }, strFromIntHelp, .{ T, int });
|
||||
return @call(.always_inline, strFromIntHelp, .{ T, int });
|
||||
}
|
||||
}.func;
|
||||
|
||||
|
@ -817,7 +815,7 @@ fn strFromIntHelp(comptime T: type, int: T) RocStr {
|
|||
pub fn exportFromFloat(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(float: T) callconv(.C) RocStr {
|
||||
return @call(.{ .modifier = always_inline }, strFromFloatHelp, .{ T, float });
|
||||
return @call(.always_inline, strFromFloatHelp, .{ T, float });
|
||||
}
|
||||
}.func;
|
||||
|
||||
|
@ -837,7 +835,7 @@ pub fn strSplit(string: RocStr, delimiter: RocStr) callconv(.C) RocList {
|
|||
const list = RocList.allocate(@alignOf(RocStr), segment_count, @sizeOf(RocStr));
|
||||
|
||||
if (list.bytes) |bytes| {
|
||||
const strings = @ptrCast([*]RocStr, @alignCast(@alignOf(RocStr), bytes));
|
||||
const strings = @as([*]RocStr, @ptrCast(@alignCast(bytes)));
|
||||
strSplitHelp(strings, string, delimiter);
|
||||
}
|
||||
|
||||
|
@ -858,13 +856,6 @@ fn initFromBigStr(slice_bytes: [*]u8, len: usize, ref_ptr: usize) RocStr {
|
|||
};
|
||||
}
|
||||
|
||||
// TODO: relpace this with @qualCast or @constCast in future version of zig
|
||||
fn constCast(ptr: [*]const u8) [*]u8 {
|
||||
var result: [*]u8 = undefined;
|
||||
@memcpy(@ptrCast([*]u8, &result), @ptrCast([*]const u8, &ptr), @sizeOf([*]u8));
|
||||
return result;
|
||||
}
|
||||
|
||||
fn strSplitHelp(array: [*]RocStr, string: RocStr, delimiter: RocStr) void {
|
||||
var ret_array_index: usize = 0;
|
||||
var slice_start_index: usize = 0;
|
||||
|
@ -872,11 +863,11 @@ fn strSplitHelp(array: [*]RocStr, string: RocStr, delimiter: RocStr) void {
|
|||
|
||||
const str_bytes = string.asU8ptr();
|
||||
const str_len = string.len();
|
||||
const ref_ptr = @ptrToInt(string.getRefcountPtr()) >> 1;
|
||||
const ref_ptr = @intFromPtr(string.getRefcountPtr()) >> 1;
|
||||
const init_fn = if (string.isSmallStr())
|
||||
initFromSmallStr
|
||||
&initFromSmallStr
|
||||
else
|
||||
initFromBigStr;
|
||||
&initFromBigStr;
|
||||
|
||||
const delimiter_bytes_ptrs = delimiter.asU8ptr();
|
||||
const delimiter_len = delimiter.len();
|
||||
|
@ -908,7 +899,7 @@ fn strSplitHelp(array: [*]RocStr, string: RocStr, delimiter: RocStr) void {
|
|||
if (matches_delimiter) {
|
||||
const segment_len: usize = str_index - slice_start_index;
|
||||
|
||||
array[ret_array_index] = init_fn(constCast(str_bytes) + slice_start_index, segment_len, ref_ptr);
|
||||
array[ret_array_index] = init_fn(@constCast(str_bytes) + slice_start_index, segment_len, ref_ptr);
|
||||
slice_start_index = str_index + delimiter_len;
|
||||
ret_array_index += 1;
|
||||
str_index += delimiter_len;
|
||||
|
@ -918,7 +909,7 @@ fn strSplitHelp(array: [*]RocStr, string: RocStr, delimiter: RocStr) void {
|
|||
}
|
||||
}
|
||||
|
||||
array[ret_array_index] = init_fn(constCast(str_bytes) + slice_start_index, str_len - slice_start_index, ref_ptr);
|
||||
array[ret_array_index] = init_fn(@constCast(str_bytes) + slice_start_index, str_len - slice_start_index, ref_ptr);
|
||||
|
||||
if (!string.isSmallStr()) {
|
||||
// Correct refcount for all of the splits made.
|
||||
|
@ -1418,11 +1409,11 @@ pub fn strGraphemes(roc_str: RocStr) callconv(.C) RocList {
|
|||
var index: usize = 0;
|
||||
var last_codepoint_len: u8 = 0;
|
||||
|
||||
const ref_ptr = @ptrToInt(roc_str.getRefcountPtr()) >> 1;
|
||||
const ref_ptr = @intFromPtr(roc_str.getRefcountPtr()) >> 1;
|
||||
const init_fn = if (roc_str.isSmallStr())
|
||||
initFromSmallStr
|
||||
&initFromSmallStr
|
||||
else
|
||||
initFromBigStr;
|
||||
&initFromBigStr;
|
||||
|
||||
var result = RocList.allocate(@alignOf(RocStr), countGraphemeClusters(roc_str), @sizeOf(RocStr));
|
||||
const graphemes = result.elements(RocStr) orelse return result;
|
||||
|
@ -1434,7 +1425,7 @@ pub fn strGraphemes(roc_str: RocStr) callconv(.C) RocList {
|
|||
if (opt_last_codepoint) |last_codepoint| {
|
||||
var did_break = grapheme.isGraphemeBreak(last_codepoint, cur_codepoint, &break_state);
|
||||
if (did_break) {
|
||||
graphemes[index] = init_fn(constCast(slice.ptr), last_codepoint_len, ref_ptr);
|
||||
graphemes[index] = init_fn(@constCast(slice.ptr), last_codepoint_len, ref_ptr);
|
||||
slice = slice[last_codepoint_len..];
|
||||
index += 1;
|
||||
break_state = null;
|
||||
|
@ -1445,7 +1436,7 @@ pub fn strGraphemes(roc_str: RocStr) callconv(.C) RocList {
|
|||
opt_last_codepoint = cur_codepoint;
|
||||
}
|
||||
// Append last grapheme
|
||||
graphemes[index] = init_fn(constCast(slice.ptr), slice.len, ref_ptr);
|
||||
graphemes[index] = init_fn(@constCast(slice.ptr), slice.len, ref_ptr);
|
||||
|
||||
if (!roc_str.isSmallStr()) {
|
||||
// Correct refcount for all of the splits made.
|
||||
|
@ -1465,7 +1456,7 @@ fn graphemesTest(input: []const u8, expected: []const []const u8) !void {
|
|||
defer graphemes.decref(@sizeOf(u8));
|
||||
if (input.len == 0) return; // empty string
|
||||
const elems = graphemes.elements(RocStr) orelse unreachable;
|
||||
for (expected) |g, i| {
|
||||
for (expected, 0..) |g, i| {
|
||||
try std.testing.expectEqualStrings(g, elems[i].asSlice());
|
||||
}
|
||||
}
|
||||
|
@ -1584,7 +1575,8 @@ pub fn repeat(string: RocStr, count: usize) callconv(.C) RocStr {
|
|||
|
||||
var i: usize = 0;
|
||||
while (i < count) : (i += 1) {
|
||||
@memcpy(ret_string_ptr + (i * bytes_len), bytes_ptr, bytes_len);
|
||||
@memcpy(ret_string_ptr[0..bytes_len], bytes_ptr[0..bytes_len]);
|
||||
ret_string_ptr += bytes_len;
|
||||
}
|
||||
|
||||
return ret_string;
|
||||
|
@ -1604,7 +1596,7 @@ pub fn startsWithScalar(string: RocStr, prefix: u32) callconv(.C) bool {
|
|||
_ = writeNextScalar(string, 0, &first_scalar, 0);
|
||||
|
||||
// Return whether `first_scalar` equals `prefix`
|
||||
return @ptrCast(*u32, &first_scalar).* == prefix;
|
||||
return @as(*u32, @ptrCast(&first_scalar)).* == prefix;
|
||||
}
|
||||
|
||||
test "startsWithScalar: empty string" {
|
||||
|
@ -1707,7 +1699,7 @@ test "endsWith: hello world ends with world" {
|
|||
|
||||
// Str.concat
|
||||
pub fn strConcatC(arg1: RocStr, arg2: RocStr) callconv(.C) RocStr {
|
||||
return @call(.{ .modifier = always_inline }, strConcat, .{ arg1, arg2 });
|
||||
return @call(.always_inline, strConcat, .{ arg1, arg2 });
|
||||
}
|
||||
|
||||
fn strConcat(arg1: RocStr, arg2: RocStr) RocStr {
|
||||
|
@ -1720,7 +1712,7 @@ fn strConcat(arg1: RocStr, arg2: RocStr) RocStr {
|
|||
const combined_length = arg1.len() + arg2.len();
|
||||
|
||||
var result = arg1.reallocate(combined_length);
|
||||
@memcpy(result.asU8ptrMut() + arg1.len(), arg2.asU8ptr(), arg2.len());
|
||||
@memcpy(result.asU8ptrMut()[arg1.len()..combined_length], arg2.asU8ptr()[0..arg2.len()]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1764,12 +1756,12 @@ pub const RocListStr = extern struct {
|
|||
// Str.joinWith
|
||||
pub fn strJoinWithC(list: RocList, separator: RocStr) callconv(.C) RocStr {
|
||||
const roc_list_str = RocListStr{
|
||||
.list_elements = @ptrCast(?[*]RocStr, @alignCast(@alignOf(usize), list.bytes)),
|
||||
.list_elements = @as(?[*]RocStr, @ptrCast(@alignCast(list.bytes))),
|
||||
.list_length = list.length,
|
||||
.list_capacity_or_ref_ptr = list.capacity_or_ref_ptr,
|
||||
};
|
||||
|
||||
return @call(.{ .modifier = always_inline }, strJoinWith, .{ roc_list_str, separator });
|
||||
return @call(.always_inline, strJoinWith, .{ roc_list_str, separator });
|
||||
}
|
||||
|
||||
fn strJoinWith(list: RocListStr, separator: RocStr) RocStr {
|
||||
|
@ -1778,7 +1770,7 @@ fn strJoinWith(list: RocListStr, separator: RocStr) RocStr {
|
|||
if (len == 0) {
|
||||
return RocStr.empty();
|
||||
} else {
|
||||
const ptr = @ptrCast([*]RocStr, list.list_elements);
|
||||
const ptr = @as([*]RocStr, @ptrCast(list.list_elements));
|
||||
const slice: []RocStr = ptr[0..len];
|
||||
|
||||
// determine the size of the result
|
||||
|
@ -1829,7 +1821,7 @@ test "RocStr.joinWith: result is big" {
|
|||
const list = RocListStr{
|
||||
.list_length = 3,
|
||||
.list_capacity_or_ref_ptr = 3,
|
||||
.list_elements = @ptrCast([*]RocStr, &elements),
|
||||
.list_elements = @as([*]RocStr, @ptrCast(&elements)),
|
||||
};
|
||||
|
||||
defer {
|
||||
|
@ -1857,7 +1849,7 @@ inline fn strToBytes(arg: RocStr) RocList {
|
|||
} else if (arg.isSmallStr()) {
|
||||
const ptr = utils.allocateWithRefcount(length, RocStr.alignment);
|
||||
|
||||
@memcpy(ptr, arg.asU8ptr(), length);
|
||||
@memcpy(ptr[0..length], arg.asU8ptr()[0..length]);
|
||||
|
||||
return RocList{ .length = length, .bytes = ptr, .capacity_or_ref_ptr = length };
|
||||
} else {
|
||||
|
@ -1897,7 +1889,7 @@ pub fn fromUtf8Range(arg: RocList, start: usize, count: usize, update_mode: Upda
|
|||
.problem_code = Utf8ByteProblem.InvalidStartByte,
|
||||
};
|
||||
}
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes)[start .. start + count];
|
||||
const bytes = @as([*]const u8, @ptrCast(arg.bytes))[start .. start + count];
|
||||
|
||||
if (isValidUnicode(bytes)) {
|
||||
// Make a seamless slice of the input.
|
||||
|
@ -1909,7 +1901,7 @@ pub fn fromUtf8Range(arg: RocList, start: usize, count: usize, update_mode: Upda
|
|||
.problem_code = Utf8ByteProblem.InvalidStartByte,
|
||||
};
|
||||
} else {
|
||||
const temp = errorToProblem(@ptrCast([*]u8, arg.bytes), arg.length);
|
||||
const temp = errorToProblem(@as([*]u8, @ptrCast(arg.bytes)), arg.length);
|
||||
|
||||
// decref the list
|
||||
arg.decref(RocStr.alignment);
|
||||
|
@ -1954,7 +1946,7 @@ pub fn isValidUnicode(buf: []const u8) bool {
|
|||
var i: usize = 0;
|
||||
while (i + step < buf.len) {
|
||||
var bytes: u64 = undefined;
|
||||
@memcpy(@ptrCast([*]u8, &bytes), @ptrCast([*]const u8, buf) + i, size);
|
||||
@memcpy(@as([*]u8, @ptrCast(&bytes))[0..size], buf[i..(i + size)]);
|
||||
const unicode_bytes = bytes & 0x8080_8080_8080_8080;
|
||||
if (unicode_bytes == 0) {
|
||||
i += step;
|
||||
|
@ -1967,7 +1959,7 @@ pub fn isValidUnicode(buf: []const u8) bool {
|
|||
// This forces prefetching, otherwise the loop can run at about half speed.
|
||||
if (i + 4 >= buf.len) break;
|
||||
var small_buf: [4]u8 = undefined;
|
||||
@memcpy(&small_buf, @ptrCast([*]const u8, buf) + i, 4);
|
||||
@memcpy(small_buf[0..4], buf[i..(i + 4)]);
|
||||
// TODO: Should we always inline these function calls below?
|
||||
if (std.unicode.utf8ByteSequenceLength(small_buf[0])) |cp_len| {
|
||||
if (std.meta.isError(std.unicode.utf8Decode(small_buf[0..cp_len]))) {
|
||||
|
@ -1986,7 +1978,7 @@ pub fn isValidUnicode(buf: []const u8) bool {
|
|||
if (i == buf.len) return true;
|
||||
}
|
||||
|
||||
return @call(.{ .modifier = always_inline }, unicode.utf8ValidateSlice, .{buf[i..]});
|
||||
return @call(.always_inline, unicode.utf8ValidateSlice, .{buf[i..]});
|
||||
}
|
||||
|
||||
const Utf8DecodeError = error{
|
||||
|
@ -2036,7 +2028,8 @@ fn expectOk(result: FromUtf8Result) !void {
|
|||
|
||||
fn sliceHelp(bytes: [*]const u8, length: usize) RocList {
|
||||
var list = RocList.allocate(RocStr.alignment, length, @sizeOf(u8));
|
||||
@memcpy(list.bytes orelse unreachable, bytes, length);
|
||||
var list_bytes = list.bytes orelse unreachable;
|
||||
@memcpy(list_bytes[0..length], bytes[0..length]);
|
||||
list.length = length;
|
||||
|
||||
return list;
|
||||
|
@ -2053,7 +2046,7 @@ fn toErrUtf8ByteResponse(index: usize, problem: Utf8ByteProblem) FromUtf8Result
|
|||
|
||||
test "validateUtf8Bytes: ascii" {
|
||||
const raw = "abc";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
const str_result = validateUtf8BytesX(list);
|
||||
|
@ -2063,7 +2056,7 @@ test "validateUtf8Bytes: ascii" {
|
|||
|
||||
test "validateUtf8Bytes: unicode œ" {
|
||||
const raw = "œ";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
const str_result = validateUtf8BytesX(list);
|
||||
|
@ -2073,7 +2066,7 @@ test "validateUtf8Bytes: unicode œ" {
|
|||
|
||||
test "validateUtf8Bytes: unicode ∆" {
|
||||
const raw = "∆";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
const str_result = validateUtf8BytesX(list);
|
||||
|
@ -2083,7 +2076,7 @@ test "validateUtf8Bytes: unicode ∆" {
|
|||
|
||||
test "validateUtf8Bytes: emoji" {
|
||||
const raw = "💖";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
const str_result = validateUtf8BytesX(list);
|
||||
|
@ -2093,7 +2086,7 @@ test "validateUtf8Bytes: emoji" {
|
|||
|
||||
test "validateUtf8Bytes: unicode ∆ in middle of array" {
|
||||
const raw = "œb∆c¬";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
const str_result = validateUtf8BytesX(list);
|
||||
|
@ -2102,7 +2095,7 @@ test "validateUtf8Bytes: unicode ∆ in middle of array" {
|
|||
}
|
||||
|
||||
fn expectErr(list: RocList, index: usize, err: Utf8DecodeError, problem: Utf8ByteProblem) !void {
|
||||
const str_ptr = @ptrCast([*]u8, list.bytes);
|
||||
const str_ptr = @as([*]u8, @ptrCast(list.bytes));
|
||||
const str_len = list.length;
|
||||
|
||||
try expectError(err, numberOfNextCodepointBytes(str_ptr, str_len, index));
|
||||
|
@ -2112,7 +2105,7 @@ fn expectErr(list: RocList, index: usize, err: Utf8DecodeError, problem: Utf8Byt
|
|||
test "validateUtf8Bytes: invalid start byte" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L426
|
||||
const raw = "ab\x80c";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 2, error.Utf8InvalidStartByte, Utf8ByteProblem.InvalidStartByte);
|
||||
|
@ -2121,7 +2114,7 @@ test "validateUtf8Bytes: invalid start byte" {
|
|||
test "validateUtf8Bytes: unexpected eof for 2 byte sequence" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L426
|
||||
const raw = "abc\xc2";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
|
@ -2130,7 +2123,7 @@ test "validateUtf8Bytes: unexpected eof for 2 byte sequence" {
|
|||
test "validateUtf8Bytes: expected continuation for 2 byte sequence" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L426
|
||||
const raw = "abc\xc2\x00";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
|
@ -2139,7 +2132,7 @@ test "validateUtf8Bytes: expected continuation for 2 byte sequence" {
|
|||
test "validateUtf8Bytes: unexpected eof for 3 byte sequence" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L430
|
||||
const raw = "abc\xe0\x00";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
|
@ -2148,7 +2141,7 @@ test "validateUtf8Bytes: unexpected eof for 3 byte sequence" {
|
|||
test "validateUtf8Bytes: expected continuation for 3 byte sequence" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L430
|
||||
const raw = "abc\xe0\xa0\xc0";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
|
@ -2157,7 +2150,7 @@ test "validateUtf8Bytes: expected continuation for 3 byte sequence" {
|
|||
test "validateUtf8Bytes: unexpected eof for 4 byte sequence" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L437
|
||||
const raw = "abc\xf0\x90\x00";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.UnexpectedEof, Utf8ByteProblem.UnexpectedEndOfSequence);
|
||||
|
@ -2166,7 +2159,7 @@ test "validateUtf8Bytes: unexpected eof for 4 byte sequence" {
|
|||
test "validateUtf8Bytes: expected continuation for 4 byte sequence" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L437
|
||||
const raw = "abc\xf0\x90\x80\x00";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.Utf8ExpectedContinuation, Utf8ByteProblem.ExpectedContinuation);
|
||||
|
@ -2175,7 +2168,7 @@ test "validateUtf8Bytes: expected continuation for 4 byte sequence" {
|
|||
test "validateUtf8Bytes: overlong" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L451
|
||||
const raw = "abc\xf0\x80\x80\x80";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.Utf8OverlongEncoding, Utf8ByteProblem.OverlongEncoding);
|
||||
|
@ -2184,7 +2177,7 @@ test "validateUtf8Bytes: overlong" {
|
|||
test "validateUtf8Bytes: codepoint out too large" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L465
|
||||
const raw = "abc\xf4\x90\x80\x80";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.Utf8CodepointTooLarge, Utf8ByteProblem.CodepointTooLarge);
|
||||
|
@ -2193,7 +2186,7 @@ test "validateUtf8Bytes: codepoint out too large" {
|
|||
test "validateUtf8Bytes: surrogate halves" {
|
||||
// https://github.com/ziglang/zig/blob/0.7.x/lib/std/unicode.zig#L468
|
||||
const raw = "abc\xed\xa0\x80";
|
||||
const ptr: [*]const u8 = @ptrCast([*]const u8, raw);
|
||||
const ptr: [*]const u8 = @as([*]const u8, @ptrCast(raw));
|
||||
const list = sliceHelp(ptr, raw.len);
|
||||
|
||||
try expectErr(list, 3, error.Utf8EncodesSurrogateHalf, Utf8ByteProblem.EncodesSurrogateHalf);
|
||||
|
@ -2269,7 +2262,7 @@ pub fn strTrim(input_string: RocStr) callconv(.C) RocStr {
|
|||
return RocStr{
|
||||
.str_bytes = bytes_ptr + leading_bytes,
|
||||
.str_len = new_len | SEAMLESS_SLICE_BIT,
|
||||
.str_capacity = @ptrToInt(bytes_ptr) >> 1,
|
||||
.str_capacity = @intFromPtr(bytes_ptr) >> 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2317,7 +2310,7 @@ pub fn strTrimStart(input_string: RocStr) callconv(.C) RocStr {
|
|||
return RocStr{
|
||||
.str_bytes = bytes_ptr + leading_bytes,
|
||||
.str_len = new_len | SEAMLESS_SLICE_BIT,
|
||||
.str_capacity = @ptrToInt(bytes_ptr) >> 1,
|
||||
.str_capacity = @intFromPtr(bytes_ptr) >> 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2365,7 +2358,7 @@ pub fn strTrimEnd(input_string: RocStr) callconv(.C) RocStr {
|
|||
return RocStr{
|
||||
.str_bytes = bytes_ptr,
|
||||
.str_len = new_len | SEAMLESS_SLICE_BIT,
|
||||
.str_capacity = @ptrToInt(bytes_ptr) >> 1,
|
||||
.str_capacity = @intFromPtr(bytes_ptr) >> 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2737,7 +2730,7 @@ test "capacity: big string" {
|
|||
}
|
||||
|
||||
pub fn appendScalar(string: RocStr, scalar_u32: u32) callconv(.C) RocStr {
|
||||
const scalar = @intCast(u21, scalar_u32);
|
||||
const scalar = @as(u21, @intCast(scalar_u32));
|
||||
const width = std.unicode.utf8CodepointSequenceLength(scalar) catch unreachable;
|
||||
|
||||
var output = string.reallocate(string.len() + width);
|
||||
|
@ -2827,10 +2820,10 @@ pub fn withCapacity(capacity: usize) callconv(.C) RocStr {
|
|||
|
||||
pub fn getScalarUnsafe(string: RocStr, index: usize) callconv(.C) extern struct { bytesParsed: usize, scalar: u32 } {
|
||||
const slice = string.asSlice();
|
||||
const bytesParsed = @intCast(usize, std.unicode.utf8ByteSequenceLength(slice[index]) catch unreachable);
|
||||
const bytesParsed = @as(usize, @intCast(std.unicode.utf8ByteSequenceLength(slice[index]) catch unreachable));
|
||||
const scalar = std.unicode.utf8Decode(slice[index .. index + bytesParsed]) catch unreachable;
|
||||
|
||||
return .{ .bytesParsed = bytesParsed, .scalar = @intCast(u32, scalar) };
|
||||
return .{ .bytesParsed = bytesParsed, .scalar = @as(u32, @intCast(scalar)) };
|
||||
}
|
||||
|
||||
test "getScalarUnsafe" {
|
||||
|
@ -2841,7 +2834,7 @@ test "getScalarUnsafe" {
|
|||
|
||||
const expected = try std.unicode.utf8Decode("A");
|
||||
|
||||
try expectEqual(result.scalar, @intCast(u32, expected));
|
||||
try expectEqual(result.scalar, @as(u32, @intCast(expected)));
|
||||
try expectEqual(result.bytesParsed, 1);
|
||||
}
|
||||
|
||||
|
@ -2853,7 +2846,7 @@ pub fn strCloneTo(
|
|||
) callconv(.C) usize {
|
||||
const WIDTH: usize = @sizeOf(RocStr);
|
||||
if (string.isSmallStr()) {
|
||||
const array: [@sizeOf(RocStr)]u8 = @bitCast([@sizeOf(RocStr)]u8, string);
|
||||
const array: [@sizeOf(RocStr)]u8 = @as([@sizeOf(RocStr)]u8, @bitCast(string));
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < WIDTH) : (i += 1) {
|
||||
|
@ -2865,14 +2858,14 @@ pub fn strCloneTo(
|
|||
const slice = string.asSlice();
|
||||
|
||||
var relative = string;
|
||||
relative.str_bytes = @intToPtr(?[*]u8, extra_offset); // i.e. just after the string struct
|
||||
relative.str_bytes = @as(?[*]u8, @ptrFromInt(extra_offset)); // i.e. just after the string struct
|
||||
|
||||
// write the string struct
|
||||
const array = relative.asArray();
|
||||
@memcpy(ptr + offset, &array, WIDTH);
|
||||
@memcpy(ptr[offset..(offset + WIDTH)], array[0..WIDTH]);
|
||||
|
||||
// write the string bytes just after the struct
|
||||
@memcpy(ptr + extra_offset, slice.ptr, slice.len);
|
||||
@memcpy(ptr[extra_offset..(extra_offset + slice.len)], slice);
|
||||
|
||||
return extra_offset + slice.len;
|
||||
}
|
||||
|
@ -2902,7 +2895,7 @@ pub fn strReleaseExcessCapacity(
|
|||
const source_ptr = string.asU8ptr();
|
||||
const dest_ptr = output.asU8ptrMut();
|
||||
|
||||
@memcpy(dest_ptr, source_ptr, old_length);
|
||||
@memcpy(dest_ptr[0..old_length], source_ptr[0..old_length]);
|
||||
string.decref();
|
||||
|
||||
return output;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
|
||||
const Monotonic = std.builtin.AtomicOrder.Monotonic;
|
||||
|
||||
const DEBUG_INCDEC = false;
|
||||
|
@ -62,7 +61,12 @@ comptime {
|
|||
}
|
||||
|
||||
fn testing_roc_alloc(size: usize, _: u32) callconv(.C) ?*anyopaque {
|
||||
const ptr = @ptrCast(?*anyopaque, std.testing.allocator.alloc(u8, size) catch unreachable);
|
||||
// We store an extra usize which is the size of the full allocation.
|
||||
const full_size = size + @sizeOf(usize);
|
||||
var raw_ptr = (std.testing.allocator.alloc(u8, full_size) catch unreachable).ptr;
|
||||
@as([*]usize, @alignCast(@ptrCast(raw_ptr)))[0] = full_size;
|
||||
raw_ptr += @sizeOf(usize);
|
||||
const ptr = @as(?*anyopaque, @ptrCast(raw_ptr));
|
||||
|
||||
if (DEBUG_TESTING_ALLOC and builtin.target.cpu.arch != .wasm32) {
|
||||
std.debug.print("+ alloc {*}: {} bytes\n", .{ ptr, size });
|
||||
|
@ -72,26 +76,32 @@ fn testing_roc_alloc(size: usize, _: u32) callconv(.C) ?*anyopaque {
|
|||
}
|
||||
|
||||
fn testing_roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, _: u32) callconv(.C) ?*anyopaque {
|
||||
const ptr = @ptrCast([*]u8, @alignCast(2 * @alignOf(usize), c_ptr));
|
||||
const slice = ptr[0..old_size];
|
||||
const raw_ptr = @as([*]u8, @ptrCast(c_ptr)) - @sizeOf(usize);
|
||||
const slice = raw_ptr[0..(old_size + @sizeOf(usize))];
|
||||
|
||||
const new = @ptrCast(?*anyopaque, std.testing.allocator.realloc(slice, new_size) catch unreachable);
|
||||
const new_full_size = new_size + @sizeOf(usize);
|
||||
var new_raw_ptr = (std.testing.allocator.realloc(slice, new_full_size) catch unreachable).ptr;
|
||||
@as([*]usize, @alignCast(@ptrCast(new_raw_ptr)))[0] = new_full_size;
|
||||
new_raw_ptr += @sizeOf(usize);
|
||||
const new_ptr = @as(?*anyopaque, @ptrCast(new_raw_ptr));
|
||||
|
||||
if (DEBUG_TESTING_ALLOC and builtin.target.cpu.arch != .wasm32) {
|
||||
std.debug.print("- realloc {*}\n", .{new});
|
||||
std.debug.print("- realloc {*}\n", .{new_ptr});
|
||||
}
|
||||
|
||||
return new;
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
fn testing_roc_dealloc(c_ptr: *anyopaque, _: u32) callconv(.C) void {
|
||||
const ptr = @ptrCast([*]u8, @alignCast(2 * @alignOf(usize), c_ptr));
|
||||
const raw_ptr = @as([*]u8, @ptrCast(c_ptr)) - @sizeOf(usize);
|
||||
const full_size = @as([*]usize, @alignCast(@ptrCast(raw_ptr)))[0];
|
||||
const slice = raw_ptr[0..full_size];
|
||||
|
||||
if (DEBUG_TESTING_ALLOC and builtin.target.cpu.arch != .wasm32) {
|
||||
std.debug.print("💀 dealloc {*}\n", .{ptr});
|
||||
std.debug.print("💀 dealloc {*}\n", .{slice.ptr});
|
||||
}
|
||||
|
||||
std.testing.allocator.destroy(ptr);
|
||||
std.testing.allocator.free(slice);
|
||||
}
|
||||
|
||||
fn testing_roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
|
@ -102,14 +112,14 @@ fn testing_roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
|||
}
|
||||
|
||||
pub fn alloc(size: usize, alignment: u32) ?[*]u8 {
|
||||
return @ptrCast(?[*]u8, roc_alloc(size, alignment));
|
||||
return @as(?[*]u8, @ptrCast(roc_alloc(size, alignment)));
|
||||
}
|
||||
|
||||
pub fn realloc(c_ptr: [*]u8, new_size: usize, old_size: usize, alignment: u32) [*]u8 {
|
||||
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
|
||||
std.debug.print("- realloc {*}\n", .{c_ptr});
|
||||
}
|
||||
return @ptrCast([*]u8, roc_realloc(c_ptr, new_size, old_size, alignment));
|
||||
return @as([*]u8, @ptrCast(roc_realloc(c_ptr, new_size, old_size, alignment)));
|
||||
}
|
||||
|
||||
pub fn dealloc(c_ptr: [*]u8, alignment: u32) void {
|
||||
|
@ -136,7 +146,7 @@ pub const Dec = fn (?[*]u8) callconv(.C) void;
|
|||
|
||||
const REFCOUNT_MAX_ISIZE: isize = 0;
|
||||
pub const REFCOUNT_ONE_ISIZE: isize = std.math.minInt(isize);
|
||||
pub const REFCOUNT_ONE: usize = @bitCast(usize, REFCOUNT_ONE_ISIZE);
|
||||
pub const REFCOUNT_ONE: usize = @as(usize, @bitCast(REFCOUNT_ONE_ISIZE));
|
||||
|
||||
pub const IntWidth = enum(u8) {
|
||||
U8 = 0,
|
||||
|
@ -173,8 +183,8 @@ pub fn increfRcPtrC(ptr_to_refcount: *isize, amount: isize) callconv(.C) void {
|
|||
switch (RC_TYPE) {
|
||||
Refcount.normal => {
|
||||
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
|
||||
const old = @bitCast(usize, ptr_to_refcount.*);
|
||||
const new = old + @intCast(usize, amount);
|
||||
const old = @as(usize, @bitCast(ptr_to_refcount.*));
|
||||
const new = old + @as(usize, @intCast(amount));
|
||||
|
||||
const oldH = old - REFCOUNT_ONE + 1;
|
||||
const newH = new - REFCOUNT_ONE + 1;
|
||||
|
@ -200,9 +210,9 @@ pub fn decrefRcPtrC(
|
|||
// (NOT the start of the data, or the start of the allocation)
|
||||
|
||||
// this is of course unsafe, but we trust what we get from the llvm side
|
||||
var bytes = @ptrCast([*]isize, bytes_or_null);
|
||||
var bytes = @as([*]isize, @ptrCast(bytes_or_null));
|
||||
|
||||
return @call(.{ .modifier = always_inline }, decref_ptr_to_refcount, .{ bytes, alignment });
|
||||
return @call(.always_inline, decref_ptr_to_refcount, .{ bytes, alignment });
|
||||
}
|
||||
|
||||
pub fn decrefCheckNullC(
|
||||
|
@ -210,8 +220,8 @@ pub fn decrefCheckNullC(
|
|||
alignment: u32,
|
||||
) callconv(.C) void {
|
||||
if (bytes_or_null) |bytes| {
|
||||
const isizes: [*]isize = @ptrCast([*]isize, @alignCast(@sizeOf(isize), bytes));
|
||||
return @call(.{ .modifier = always_inline }, decref_ptr_to_refcount, .{ isizes - 1, alignment });
|
||||
const isizes: [*]isize = @as([*]isize, @ptrCast(@alignCast(bytes)));
|
||||
return @call(.always_inline, decref_ptr_to_refcount, .{ isizes - 1, alignment });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,11 +231,11 @@ pub fn decrefDataPtrC(
|
|||
) callconv(.C) void {
|
||||
var bytes = bytes_or_null orelse return;
|
||||
|
||||
const data_ptr = @ptrToInt(bytes);
|
||||
const data_ptr = @intFromPtr(bytes);
|
||||
const tag_mask: usize = if (@sizeOf(usize) == 8) 0b111 else 0b11;
|
||||
const unmasked_ptr = data_ptr & ~tag_mask;
|
||||
|
||||
const isizes: [*]isize = @intToPtr([*]isize, unmasked_ptr);
|
||||
const isizes: [*]isize = @as([*]isize, @ptrFromInt(unmasked_ptr));
|
||||
const rc_ptr = isizes - 1;
|
||||
|
||||
return decrefRcPtrC(rc_ptr, alignment);
|
||||
|
@ -237,11 +247,11 @@ pub fn increfDataPtrC(
|
|||
) callconv(.C) void {
|
||||
var bytes = bytes_or_null orelse return;
|
||||
|
||||
const ptr = @ptrToInt(bytes);
|
||||
const ptr = @intFromPtr(bytes);
|
||||
const tag_mask: usize = if (@sizeOf(usize) == 8) 0b111 else 0b11;
|
||||
const masked_ptr = ptr & ~tag_mask;
|
||||
|
||||
const isizes: *isize = @intToPtr(*isize, masked_ptr - @sizeOf(usize));
|
||||
const isizes: *isize = @as(*isize, @ptrFromInt(masked_ptr - @sizeOf(usize)));
|
||||
|
||||
return increfRcPtrC(isizes, inc_amount);
|
||||
}
|
||||
|
@ -252,11 +262,11 @@ pub fn freeDataPtrC(
|
|||
) callconv(.C) void {
|
||||
var bytes = bytes_or_null orelse return;
|
||||
|
||||
const ptr = @ptrToInt(bytes);
|
||||
const ptr = @intFromPtr(bytes);
|
||||
const tag_mask: usize = if (@sizeOf(usize) == 8) 0b111 else 0b11;
|
||||
const masked_ptr = ptr & ~tag_mask;
|
||||
|
||||
const isizes: [*]isize = @intToPtr([*]isize, masked_ptr);
|
||||
const isizes: [*]isize = @as([*]isize, @ptrFromInt(masked_ptr));
|
||||
|
||||
return freeRcPtrC(isizes - 1, alignment);
|
||||
}
|
||||
|
@ -280,7 +290,7 @@ pub fn decref(
|
|||
|
||||
var bytes = bytes_or_null orelse return;
|
||||
|
||||
const isizes: [*]isize = @ptrCast([*]isize, @alignCast(@alignOf(isize), bytes));
|
||||
const isizes: [*]isize = @as([*]isize, @ptrCast(@alignCast(bytes)));
|
||||
|
||||
decref_ptr_to_refcount(isizes - 1, alignment);
|
||||
}
|
||||
|
@ -290,8 +300,8 @@ inline fn free_ptr_to_refcount(
|
|||
alignment: u32,
|
||||
) void {
|
||||
if (RC_TYPE == Refcount.none) return;
|
||||
const extra_bytes = std.math.max(alignment, @sizeOf(usize));
|
||||
const allocation_ptr = @ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize));
|
||||
const extra_bytes = @max(alignment, @sizeOf(usize));
|
||||
const allocation_ptr = @as([*]u8, @ptrCast(refcount_ptr)) - (extra_bytes - @sizeOf(usize));
|
||||
|
||||
// NOTE: we don't even check whether the refcount is "infinity" here!
|
||||
dealloc(allocation_ptr, alignment);
|
||||
|
@ -316,9 +326,9 @@ inline fn decref_ptr_to_refcount(
|
|||
if (refcount != REFCOUNT_MAX_ISIZE) {
|
||||
switch (RC_TYPE) {
|
||||
Refcount.normal => {
|
||||
const old = @bitCast(usize, refcount);
|
||||
const old = @as(usize, @bitCast(refcount));
|
||||
refcount_ptr[0] = refcount -% 1;
|
||||
const new = @bitCast(usize, refcount -% 1);
|
||||
const new = @as(usize, @bitCast(refcount -% 1));
|
||||
|
||||
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
|
||||
const oldH = old - REFCOUNT_ONE + 1;
|
||||
|
@ -347,11 +357,11 @@ pub fn isUnique(
|
|||
) callconv(.C) bool {
|
||||
var bytes = bytes_or_null orelse return true;
|
||||
|
||||
const ptr = @ptrToInt(bytes);
|
||||
const ptr = @intFromPtr(bytes);
|
||||
const tag_mask: usize = if (@sizeOf(usize) == 8) 0b111 else 0b11;
|
||||
const masked_ptr = ptr & ~tag_mask;
|
||||
|
||||
const isizes: [*]isize = @intToPtr([*]isize, masked_ptr);
|
||||
const isizes: [*]isize = @as([*]isize, @ptrFromInt(masked_ptr));
|
||||
|
||||
const refcount = (isizes - 1)[0];
|
||||
|
||||
|
@ -407,7 +417,7 @@ pub inline fn calculateCapacity(
|
|||
new_capacity = (old_capacity * 3 + 1) / 2;
|
||||
}
|
||||
|
||||
return std.math.max(new_capacity, requested_length);
|
||||
return @max(new_capacity, requested_length);
|
||||
}
|
||||
|
||||
pub fn allocateWithRefcountC(
|
||||
|
@ -422,7 +432,7 @@ pub fn allocateWithRefcount(
|
|||
element_alignment: u32,
|
||||
) [*]u8 {
|
||||
const ptr_width = @sizeOf(usize);
|
||||
const alignment = std.math.max(ptr_width, element_alignment);
|
||||
const alignment = @max(ptr_width, element_alignment);
|
||||
const length = alignment + data_bytes;
|
||||
|
||||
var new_bytes: [*]u8 = alloc(length, alignment) orelse unreachable;
|
||||
|
@ -432,7 +442,7 @@ pub fn allocateWithRefcount(
|
|||
}
|
||||
|
||||
const data_ptr = new_bytes + alignment;
|
||||
const refcount_ptr = @ptrCast([*]usize, @alignCast(ptr_width, data_ptr) - ptr_width);
|
||||
const refcount_ptr = @as([*]usize, @ptrCast(@as([*]align(ptr_width) u8, @alignCast(data_ptr)) - ptr_width));
|
||||
refcount_ptr[0] = if (RC_TYPE == Refcount.none) REFCOUNT_MAX_ISIZE else REFCOUNT_ONE;
|
||||
|
||||
return data_ptr;
|
||||
|
@ -450,7 +460,7 @@ pub fn unsafeReallocate(
|
|||
new_length: usize,
|
||||
element_width: usize,
|
||||
) [*]u8 {
|
||||
const align_width: usize = std.math.max(alignment, @sizeOf(usize));
|
||||
const align_width: usize = @max(alignment, @sizeOf(usize));
|
||||
|
||||
const old_width = align_width + old_length * element_width;
|
||||
const new_width = align_width + new_length * element_width;
|
||||
|
@ -464,7 +474,7 @@ pub fn unsafeReallocate(
|
|||
const old_allocation = source_ptr - align_width;
|
||||
const new_allocation = realloc(old_allocation, new_width, old_width, alignment);
|
||||
|
||||
const new_source = @ptrCast([*]u8, new_allocation) + align_width;
|
||||
const new_source = @as([*]u8, @ptrCast(new_allocation)) + align_width;
|
||||
return new_source;
|
||||
}
|
||||
|
||||
|
@ -502,5 +512,5 @@ test "increfC, static data" {
|
|||
// In wasm, the value will be constant to the build as a whole.
|
||||
// Either way, it can not be know by an attacker unless they get access to the executable.
|
||||
pub fn dictPseudoSeed() callconv(.C) u64 {
|
||||
return @intCast(u64, @ptrToInt(dictPseudoSeed));
|
||||
return @as(u64, @intCast(@intFromPtr(&dictPseudoSeed)));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue