authorchloe caruso <git@paperclover.net> 2025-02-22 17:26:13-08:00
committerchloe caruso <git@paperclover.net> 2025-02-22 18:30:48-08:00
log79de6d7ec05e2811a2acc459ed5f28d4cf454348
treeddf4e5227a44edc0c4d323de27f076584bee8a11
parent2bcfa5e47db1ba080d7add7d2cd7a59e0e249bd1

upgrade zig


17 files changed, 86 insertions(+), 77 deletions(-)

build.zig+16-3
...@@ -236,9 +236,8 @@ fn createModuleTests(module: *Build.Module, options: Options) *Build.Step.Compil...@@ -236,9 +236,8 @@ fn createModuleTests(module: *Build.Module, options: Options) *Build.Step.Compil
236}236}
237237
238pub fn build(b: *Build) !void {238pub fn build(b: *Build) !void {
239 b.reference_trace = 32;239 var target = b.standardTargetOptions(.{});
240240 var host = b.graph.host;
241 const target = b.standardTargetOptions(.{});
242241
243 // I disagree with how the standard optimize flag works242 // I disagree with how the standard optimize flag works
244 const optimize_fallback = switch (b.release_mode) {243 const optimize_fallback = switch (b.release_mode) {
...@@ -272,6 +271,12 @@ pub fn build(b: *Build) !void {...@@ -272,6 +271,12 @@ pub fn build(b: *Build) !void {
272 "Experiment with the Zig self-hosted backends",271 "Experiment with the Zig self-hosted backends",
273 ) orelse false;272 ) orelse false;
274273
274 if (no_llvm) {
275 if (b.user_input_options.getPtr("target") == null)
276 target = mapTargetForSelfHosted(target);
277 host = mapTargetForSelfHosted(host);
278 }
279
275 const have_embedded_quickjs = b.option(280 const have_embedded_quickjs = b.option(
276 bool,281 bool,
277 "quickjs",282 "quickjs",
...@@ -599,6 +604,14 @@ fn crossTarget(cpu_arch: std.Target.Cpu.Arch, os_tag: std.Target.Os.Tag) Build.R...@@ -599,6 +604,14 @@ fn crossTarget(cpu_arch: std.Target.Cpu.Arch, os_tag: std.Target.Os.Tag) Build.R
599 };604 };
600}605}
601606
607fn mapTargetForSelfHosted(target: Build.ResolvedTarget) Build.ResolvedTarget {
608 if (target.result.os.tag == .macos and target.result.cpu.arch == .aarch64) {
609 var mut = target;
610 mut.result.cpu = std.Target.Cpu.baseline(.x86_64, target.result.os);
611 }
612 return target;
613}
614
602pub const PathOrString = union(enum) {615pub const PathOrString = union(enum) {
603 path: LazyPath,616 path: LazyPath,
604 string: []const u8,617 string: []const u8,
build.zig.zon+2-2
...@@ -7,8 +7,8 @@...@@ -7,8 +7,8 @@
7 .dependencies = .{7 .dependencies = .{
8 // Used to determine unicode properties to tokenize identifiers8 // Used to determine unicode properties to tokenize identifiers
9 .zg = .{9 .zg = .{
10 .url = "https://codeberg.org/dude_the_builder/zg/archive/c425c9c8511bf92e14b8b612d1d16e774b186f2e.tar.gz",10 .url = "https://codeberg.org/atman/zg/archive/4a002763419a34d61dcbb1f415821b83b9bf8ddc.tar.gz",
11 .hash = "1220c79009f1e443b015db4de6e5319432538ead2fea10d271f3f35d3ae83c996789",11 .hash = "1220f3e29bc40856bfc06e0ee133f814b0011c76de987d8a6a458c2f34d82708899a",
12 },12 },
13 // Optional: Used for tracing13 // Optional: Used for tracing
14 .tracer = .{14 .tracer = .{
doc/language-manual.md+1-2
...@@ -1,7 +1,6 @@...@@ -1,7 +1,6 @@
1# Ix Programming Language1# Ix Programming Language
22
3Ix (**I**nferable E**x**pression) is a high-level programming language for3Ix (**I**nferable E**x**pression) is an experimental programming language.
4developing web applications and games.
54
6Key goals of this project are:5Key goals of this project are:
76
src/Cli.zig+10-10
...@@ -5,6 +5,8 @@...@@ -5,6 +5,8 @@
5//!5//!
6//! See `fn main` for a basic usage example. Parsing subcommands is done in6//! See `fn main` for a basic usage example. Parsing subcommands is done in
7//! `main.zig`, utilizing a different `Cli` for each option set.7//! `main.zig`, utilizing a different `Cli` for each option set.
8const Cli = @This();
9
8options: []const Option,10options: []const Option,
9positionals: Positionals,11positionals: Positionals,
10help: HelpConfig = .{},12help: HelpConfig = .{},
...@@ -57,14 +59,15 @@ pub const Positionals = union(enum) {...@@ -57,14 +59,15 @@ pub const Positionals = union(enum) {
57 /// Store the start and count of positionals. Call59 /// Store the start and count of positionals. Call
58 /// 'parsed.positionals.iterator(args)' with the60 /// 'parsed.positionals.iterator(args)' with the
59 /// original argument array to read positionals.61 /// original argument array to read positionals.
60 unlimited,
61 /// Same strategy as .unlimited, with a limit
62 limited: usize,62 limited: usize,
63 /// Use a bounded array to store positionals, using63 /// Use a bounded array to store positionals, using
64 /// a stack allocated buffer that can hold enough64 /// a stack allocated buffer that can hold enough
65 /// '[]const u8's as allowed by the bound.65 /// '[]const u8's as allowed by the bound.
66 bounded: usize,66 bounded: usize,
6767
68 /// Shorthand for an unlimited amount of positionals.
69 const unlimited: Positionals = .{ .limited = std.math.maxInt(usize) };
70
68 pub fn Type(p: Positionals) type {71 pub fn Type(p: Positionals) type {
69 return switch (p) {72 return switch (p) {
70 .none => void,73 .none => void,
...@@ -73,7 +76,6 @@ pub const Positionals = union(enum) {...@@ -73,7 +76,6 @@ pub const Positionals = union(enum) {
73 0 => void,76 0 => void,
74 else => Multi,77 else => Multi,
75 },78 },
76 .unlimited => Multi,
77 .bounded => |n| std.BoundedArray([]const u8, n),79 .bounded => |n| std.BoundedArray([]const u8, n),
78 };80 };
79 }81 }
...@@ -83,7 +85,6 @@ pub const Positionals = union(enum) {...@@ -83,7 +85,6 @@ pub const Positionals = union(enum) {
83 .none => 0,85 .none => 0,
84 .single => 1,86 .single => 1,
85 inline .limited, .bounded => |limit| limit,87 inline .limited, .bounded => |limit| limit,
86 .unlimited => std.math.maxInt(usize),
87 };88 };
88 }89 }
8990
...@@ -188,7 +189,7 @@ pub fn Parsed(p: Cli) type {...@@ -188,7 +189,7 @@ pub fn Parsed(p: Cli) type {
188 field.* = .{189 field.* = .{
189 .name = fieldName(def.name),190 .name = fieldName(def.name),
190 .alignment = @alignOf(Wrapped),191 .alignment = @alignOf(Wrapped),
191 .default_value = &@as(Wrapped, null),192 .default_value_ptr = &@as(Wrapped, null),
192 .is_comptime = false,193 .is_comptime = false,
193 .type = Wrapped,194 .type = Wrapped,
194 };195 };
...@@ -199,10 +200,10 @@ pub fn Parsed(p: Cli) type {...@@ -199,10 +200,10 @@ pub fn Parsed(p: Cli) type {
199 .name = "positionals",200 .name = "positionals",
200 .alignment = @alignOf(Pos),201 .alignment = @alignOf(Pos),
201 .type = Pos,202 .type = Pos,
202 .default_value = &@as(Pos, switch (p.positionals) {203 .default_value_ptr = &@as(Pos, switch (p.positionals) {
203 .none => {},204 .none => {},
204 .single => null,205 .single => null,
205 .limited, .unlimited => .empty,206 .limited => .empty,
206 .bounded => .{},207 .bounded => .{},
207 }),208 }),
208 .is_comptime = false,209 .is_comptime = false,
...@@ -466,7 +467,7 @@ pub fn parseWithErrorWriter(...@@ -466,7 +467,7 @@ pub fn parseWithErrorWriter(
466 else467 else
467 null,468 null,
468 .bounded => out.positionals, // already correct469 .bounded => out.positionals, // already correct
469 .unlimited, .limited => if (max_positionals > 0) .{470 .limited => if (max_positionals > 0) .{
470 .first = first_positional,471 .first = first_positional,
471 .len = positionals_counted,472 .len = positionals_counted,
472 .first_is_after_double_dash = if (double_dash) |dd|473 .first_is_after_double_dash = if (double_dash) |dd|
...@@ -662,7 +663,7 @@ pub fn main() !void {...@@ -662,7 +663,7 @@ pub fn main() !void {
662 std.debug.print("--enum: {any}\n", .{parsed.@"enum"});663 std.debug.print("--enum: {any}\n", .{parsed.@"enum"});
663 std.debug.print("positionals({d}):\n", .{parsed.positionals.len});664 std.debug.print("positionals({d}):\n", .{parsed.positionals.len});
664665
665 // if using '.positionals = .unlimited'666 // if using '.positionals = .limited'
666 // var it = parsed.positionals.iterator(args[1..]);667 // var it = parsed.positionals.iterator(args[1..]);
667 // while (it.next()) |item| {668 // while (it.next()) |item| {
668 // std.debug.print(" - {s}\n", .{item});669 // std.debug.print(" - {s}\n", .{item});
...@@ -673,7 +674,6 @@ pub fn main() !void {...@@ -673,7 +674,6 @@ pub fn main() !void {
673 }674 }
674}675}
675676
676const Cli = @This();
677const std = @import("std");677const std = @import("std");
678const mem = std.mem;678const mem = std.mem;
679const Type = std.builtin.Type;679const Type = std.builtin.Type;
src/core/Ast.zig+1-1
...@@ -351,7 +351,7 @@ pub const Node = struct {...@@ -351,7 +351,7 @@ pub const Node = struct {
351 });351 });
352352
353 pub const Data = union {353 pub const Data = union {
354 none: struct { Unused = .zero, Unused = .zero },354 none: struct { a: Unused = .zero, b: Unused = .zero },
355 function: struct {355 function: struct {
356 /// A `Fn`356 /// A `Fn`
357 extra: ExtraIndex,357 extra: ExtraIndex,
src/core/Comp.zig+3-6
...@@ -322,8 +322,9 @@ pub const File = struct {...@@ -322,8 +322,9 @@ pub const File = struct {
322 return source;322 return source;
323 }323 }
324324
325 // Keep track of inode, file size, mtime, hash so we can detect which files325 // Keep track of inode, file size, mtime, hash so the incremental
326 // have been modified when an incremental update is requested.326 // compiler can detect which files have been modified when an
327 // incremental update is requested.
327 var f = try std.fs.openFileAbsolute(file.file_path, .{});328 var f = try std.fs.openFileAbsolute(file.file_path, .{});
328 defer f.close();329 defer f.close();
329330
...@@ -338,10 +339,6 @@ pub const File = struct {...@@ -338,10 +339,6 @@ pub const File = struct {
338 if (amt != stat.size)339 if (amt != stat.size)
339 return error.UnexpectedEndOfFile;340 return error.UnexpectedEndOfFile;
340341
341 // Here we do not modify stat fields because this function is the one
342 // used for error reporting. We need to keep the stat fields stale so that
343 // transformFile can know to regenerate Hir.
344
345 const loaded_source: Source = .{342 const loaded_source: Source = .{
346 .code = source,343 .code = source,
347 .stat = .{344 .stat = .{
src/core/InternPool.zig+8-7
...@@ -25,10 +25,10 @@ map: std.AutoArrayHashMapUnmanaged(void, void) = .empty,...@@ -25,10 +25,10 @@ map: std.AutoArrayHashMapUnmanaged(void, void) = .empty,
25items: std.MultiArrayList(Item) = .empty,25items: std.MultiArrayList(Item) = .empty,
26extra: Extra = .empty,26extra: Extra = .empty,
2727
28/// In order to store references to strings in fewer bytes, we copy all28/// In order to store references to strings in fewer bytes, all string bytes are
29/// string bytes into here. String bytes can be null. It is up to whoever29/// placed here. String bytes can be null. It is up to whoever is referencing
30/// is referencing the data here whether they want to store both index and length,30/// the data here whether they want to store both index and length, thus
31/// thus allowing null bytes, or store only index, and use null-termination. The31/// allowing null bytes, or store only index, and use null-termination. The
32/// `string_bytes` array is agnostic to either usage.32/// `string_bytes` array is agnostic to either usage.
33string_bytes: std.ArrayListUnmanaged(u8) = .empty,33string_bytes: std.ArrayListUnmanaged(u8) = .empty,
3434
...@@ -451,6 +451,7 @@ pub const Type = enum(u32) {...@@ -451,6 +451,7 @@ pub const Type = enum(u32) {
451 };451 };
452452
453 pub const Slice = Extra.Slice(Type);453 pub const Slice = Extra.Slice(Type);
454 const y = Slice{};
454455
455 pub fn value(ty: Type) Value {456 pub fn value(ty: Type) Value {
456 return @enumFromInt(@intFromEnum(ty));457 return @enumFromInt(@intFromEnum(ty));
...@@ -1712,7 +1713,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalysisUnit, de...@@ -1712,7 +1713,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalysisUnit, de
1712 }1713 }
17131714
1714 // Prepend a new dependency.1715 // Prepend a new dependency.
1715 const new_index: DepEntry.Index, const ptr = if (ip.free_dep_entries.popOrNull()) |new_index| new: {1716 const new_index: DepEntry.Index, const ptr = if (ip.free_dep_entries.pop()) |new_index| new: {
1716 break :new .{ new_index, &ip.dep_entries.items[@intFromEnum(new_index)] };1717 break :new .{ new_index, &ip.dep_entries.items[@intFromEnum(new_index)] };
1717 } else .{ @enumFromInt(ip.dep_entries.items.len), ip.dep_entries.addOneAssumeCapacity() };1718 } else .{ @enumFromInt(ip.dep_entries.items.len), ip.dep_entries.addOneAssumeCapacity() };
1718 ptr.next = if (gop.found_existing) gop.value_ptr.*.toOptional() else .none;1719 ptr.next = if (gop.found_existing) gop.value_ptr.*.toOptional() else .none;
...@@ -1751,7 +1752,7 @@ pub fn createDecl(...@@ -1751,7 +1752,7 @@ pub fn createDecl(
1751 const t = tracer.trace(@src());1752 const t = tracer.trace(@src());
1752 defer t.end();1753 defer t.end();
17531754
1754 if (ip.decls_free_list.popOrNull()) |index| {1755 if (ip.decls_free_list.pop()) |index| {
1755 ip.allocated_decls.at(@intFromEnum(index)).* = initialization;1756 ip.allocated_decls.at(@intFromEnum(index)).* = initialization;
1756 return index;1757 return index;
1757 }1758 }
...@@ -1779,7 +1780,7 @@ pub fn createNamespace(...@@ -1779,7 +1780,7 @@ pub fn createNamespace(
1779 const t = tracer.trace(@src());1780 const t = tracer.trace(@src());
1780 defer t.end();1781 defer t.end();
17811782
1782 if (ip.namespaces_free_list.popOrNull()) |index| {1783 if (ip.namespaces_free_list.pop()) |index| {
1783 ip.allocated_namespaces.at(@intFromEnum(index)).* = initialization;1784 ip.allocated_namespaces.at(@intFromEnum(index)).* = initialization;
1784 return index;1785 return index;
1785 }1786 }
src/core/Sema.zig+3-3
...@@ -172,7 +172,7 @@ const Frame = struct {...@@ -172,7 +172,7 @@ const Frame = struct {
172 data: Data,172 data: Data,
173173
174 const Data = union {174 const Data = union {
175 pub const none = .{ .undefined = {} };175 pub const none: Data = .{ .undefined = {} };
176176
177 undefined: void,177 undefined: void,
178 conditional: Conditional,178 conditional: Conditional,
...@@ -961,7 +961,7 @@ fn stepInner(s: *Sema, comptime tag: Hir.Tag) Error!InstructionKind.fromTag(tag)...@@ -961,7 +961,7 @@ fn stepInner(s: *Sema, comptime tag: Hir.Tag) Error!InstructionKind.fromTag(tag)
961 const data: Hir.Func = s.frame.currentPayload(.func);961 const data: Hir.Func = s.frame.currentPayload(.func);
962 const reserve = try s.scratch.reserveMulti(962 const reserve = try s.scratch.reserveMulti(
963 s.arena(),963 s.arena(),
964 .{ .params = Type, .captures = Air.Inst.Ref },964 FunctionReserve.reserve_types,
965 .{ data.params.len, data.captures.len },965 .{ data.params.len, data.captures.len },
966 );966 );
967 if (data.captures.len > 0) @panic("TODO: captures");967 if (data.captures.len > 0) @panic("TODO: captures");
...@@ -2453,7 +2453,7 @@ fn pushFrame(s: *Sema) !void {...@@ -2453,7 +2453,7 @@ fn pushFrame(s: *Sema) !void {
2453}2453}
24542454
2455fn popFrame(s: *Sema) void {2455fn popFrame(s: *Sema) void {
2456 s.frame = s.frame_stack.pop();2456 s.frame = s.frame_stack.pop() orelse unreachable;
2457}2457}
24582458
2459fn addIndexUntracked(s: *Sema, comptime tag: Air.Inst.Tag, data: tag.Data()) !Air.Inst.Index {2459fn addIndexUntracked(s: *Sema, comptime tag: Air.Inst.Tag, data: tag.Data()) !Air.Inst.Index {
src/core/Tokenizer.zig+2-2
...@@ -275,8 +275,8 @@ pub const Token = struct {...@@ -275,8 +275,8 @@ pub const Token = struct {
275 }275 }
276 };276 };
277277
278 /// Instead of storing the length of a token, we can recompute this278 /// Instead of storing the length of a token, it's recomputed on demand by
279 /// information on demand, as it is not often needed.279 /// tokenizing the text. This trade-off was done to preserve memory.
280 ///280 ///
281 /// When computing the length of something that can be known without281 /// When computing the length of something that can be known without
282 /// the source code, use token.tag.staticLen() instead.282 /// the source code, use token.tag.staticLen() instead.
src/core/Transform.zig+12-13
...@@ -369,18 +369,18 @@ const BuiltIn = struct {...@@ -369,18 +369,18 @@ const BuiltIn = struct {
369};369};
370370
371const built_in_ids = std.StaticStringMap(BuiltIn).initComptime(.{371const built_in_ids = std.StaticStringMap(BuiltIn).initComptime(.{
372 .{ "void", .{ .value = .void, .type = .void } },372 .{ "void", BuiltIn{ .value = .void, .type = .void } },
373 .{ "true", .{ .value = .bool_true, .type = .bool_type } },373 .{ "true", BuiltIn{ .value = .bool_true, .type = .bool_type } },
374 .{ "false", .{ .value = .bool_false, .type = .bool_type } },374 .{ "false", BuiltIn{ .value = .bool_false, .type = .bool_type } },
375 .{ "int", .{ .value = .int32_type, .type = .type_type } },375 .{ "int", BuiltIn{ .value = .int32_type, .type = .type_type } },
376 .{ "float", .{ .value = .float_type, .type = .type_type } },376 .{ "float", BuiltIn{ .value = .float_type, .type = .type_type } },
377 .{ "string", .{ .value = .string_type, .type = .type_type } },377 .{ "string", BuiltIn{ .value = .string_type, .type = .type_type } },
378 .{ "opaque", .{ .value = .opaque_type, .type = .type_type } },378 .{ "opaque", BuiltIn{ .value = .opaque_type, .type = .type_type } },
379 // .{ "bigint", .{ .value = .bigint_type, .type = .type_type } },379 // .{ "bigint", BuiltIn{ .value = .bigint_type, .type = .type_type } },
380 .{ "bool", .{ .value = .bool_type, .type = .type_type } },380 .{ "bool", BuiltIn{ .value = .bool_type, .type = .type_type } },
381 .{ "never", .{ .value = .never_type, .type = .type_type } },381 .{ "never", BuiltIn{ .value = .never_type, .type = .type_type } },
382 .{ "type", .{ .value = .type_type, .type = .type_type } },382 .{ "type", BuiltIn{ .value = .type_type, .type = .type_type } },
383 // .{ "std", .{ .value = .standard_library, .type = ... } },383 // .{ "std", BuiltIn{ .value = .standard_library, .type = ... } },
384});384});
385385
386fn transformModule(t: *Transform, module_node: NodeIndex) Allocator.Error!Inst.Index {386fn transformModule(t: *Transform, module_node: NodeIndex) Allocator.Error!Inst.Index {
...@@ -412,7 +412,6 @@ fn transformModule(t: *Transform, module_node: NodeIndex) Allocator.Error!Inst.I...@@ -412,7 +412,6 @@ fn transformModule(t: *Transform, module_node: NodeIndex) Allocator.Error!Inst.I
412 defer t.gpa.free(decls);412 defer t.gpa.free(decls);
413413
414 {414 {
415 // `transformDecl` is not allowed to mutate symbols as we rely on the stable value.
416 s.symbols.lockPointers();415 s.symbols.lockPointers();
417 defer s.symbols.unlockPointers();416 defer s.symbols.unlockPointers();
418417
src/core/array.zig+14-16
...@@ -90,7 +90,7 @@ pub const StoreKind = enum {...@@ -90,7 +90,7 @@ pub const StoreKind = enum {
9090
91 pub fn ResolvedStore(kind: StoreKind, Owner: type) type {91 pub fn ResolvedStore(kind: StoreKind, Owner: type) type {
92 const ptr = @typeInfo(Owner).pointer;92 const ptr = @typeInfo(Owner).pointer;
93 assert(ptr.size == .One);93 assert(ptr.size == .one);
94 const mutability = brk: for (@typeInfo(ptr.child).@"struct".fields) |field| {94 const mutability = brk: for (@typeInfo(ptr.child).@"struct".fields) |field| {
95 if (std.mem.eql(u8, field.name, "extra")) {95 if (std.mem.eql(u8, field.name, "extra")) {
96 break :brk field.type.mutability;96 break :brk field.type.mutability;
...@@ -100,7 +100,7 @@ pub const StoreKind = enum {...@@ -100,7 +100,7 @@ pub const StoreKind = enum {
100 }100 }
101101
102 pub fn ResolvedStorePtr(kind: StoreKind, Owner: type) type {102 pub fn ResolvedStorePtr(kind: StoreKind, Owner: type) type {
103 return kind.ItemPointer(Owner, .One, kind.ResolvedStore(Owner));103 return kind.ItemPointer(Owner, .one, kind.ResolvedStore(Owner));
104 }104 }
105105
106 pub fn ItemPointer(106 pub fn ItemPointer(
...@@ -110,18 +110,16 @@ pub const StoreKind = enum {...@@ -110,18 +110,16 @@ pub const StoreKind = enum {
110 child: type,110 child: type,
111 ) type {111 ) type {
112 const ptr = @typeInfo(Owner).pointer;112 const ptr = @typeInfo(Owner).pointer;
113 return @Type(.{113 return @Type(.{ .pointer = .{
114 .pointer = .{114 .size = size,
115 .size = size,115 .is_const = ptr.is_const or ResolvedStore(kind, Owner).mutability == .@"const",
116 .is_const = ptr.is_const or ResolvedStore(kind, Owner).mutability == .@"const",116 .is_volatile = false,
117 .is_volatile = false,117 .is_allowzero = false,
118 .is_allowzero = false,118 .alignment = @alignOf(child),
119 .alignment = @alignOf(child),119 .address_space = .generic,
120 .address_space = .generic,120 .child = child,
121 .child = child,121 .sentinel_ptr = null,
122 .sentinel = null,122 } });
123 },
124 });
125 }123 }
126};124};
127125
...@@ -264,7 +262,7 @@ pub fn Store(set_kind: StoreKind, set_mutability: Mutability) type {...@@ -264,7 +262,7 @@ pub fn Store(set_kind: StoreKind, set_mutability: Mutability) type {
264 .len = 0,262 .len = 0,
265 };263 };
266264
267 pub fn get(slice: @This(), owner: anytype) kind.ItemPointer(@TypeOf(owner), .Slice, T) {265 pub fn get(slice: @This(), owner: anytype) kind.ItemPointer(@TypeOf(owner), .slice, T) {
268 return @ptrCast(kind.resolveStore(owner).list.items[slice.start..][0..slice.len]);266 return @ptrCast(kind.resolveStore(owner).list.items[slice.start..][0..slice.len]);
269 }267 }
270268
...@@ -448,7 +446,7 @@ pub fn Store(set_kind: StoreKind, set_mutability: Mutability) type {...@@ -448,7 +446,7 @@ pub fn Store(set_kind: StoreKind, set_mutability: Mutability) type {
448446
449 pub fn appendSlice(store: *Self, gpa: Allocator, data: anytype) !Slice(std.meta.Child(@TypeOf(data))) {447 pub fn appendSlice(store: *Self, gpa: Allocator, data: anytype) !Slice(std.meta.Child(@TypeOf(data))) {
450 const idx = store.list.items.len;448 const idx = store.list.items.len;
451 comptime assert(@typeInfo(@TypeOf(data)).pointer.size == .Slice);449 comptime assert(@typeInfo(@TypeOf(data)).pointer.size == .slice);
452 comptime assert(@typeInfo(@TypeOf(data)).pointer.alignment == @alignOf(u32));450 comptime assert(@typeInfo(@TypeOf(data)).pointer.alignment == @alignOf(u32));
453 comptime assert(@sizeOf(@TypeOf(data[0])) == @sizeOf(u32));451 comptime assert(@sizeOf(@TypeOf(data[0])) == @sizeOf(u32));
454 comptime assert(@alignOf(@TypeOf(data[0])) == @alignOf(u32));452 comptime assert(@alignOf(@TypeOf(data[0])) == @alignOf(u32));
src/core/js/Link.zig+4-4
...@@ -677,10 +677,10 @@ fn writeString(decoded: []const u8, writer: Writer) !void {...@@ -677,10 +677,10 @@ fn writeString(decoded: []const u8, writer: Writer) !void {
677 text = text[width..];677 text = text[width..];
678678
679 switch (c) {679 switch (c) {
680 // Special-case the bell character since it may cause dumping this file to680 // Special-case the bell character since it may cause dumping this
681 // the terminal to make a sound, which is undesirable. Note that we can't681 // file to the terminal to make a sound, which is undesirable. Note
682 // use an octal literal to print this shorter since octal literals are not682 // that an octal literal to print this shorter since octal literals
683 // allowed in strict mode (or in template strings).683 // are not allowed in strict mode (or in template strings).
684 0x07 => {684 0x07 => {
685 try writer.writeAll("\\x07");685 try writer.writeAll("\\x07");
686 },686 },
src/core/js/NodeGen.zig+1-1
...@@ -456,7 +456,7 @@ fn codeGenInst(c: *NodeGen, inst: Air.Inst.Index) Error!void {...@@ -456,7 +456,7 @@ fn codeGenInst(c: *NodeGen, inst: Air.Inst.Index) Error!void {
456 // of a block.456 // of a block.
457 //457 //
458 // This is also required for the main function, which cannot return458 // This is also required for the main function, which cannot return
459 // anything. We don't want to emit return instructions here.459 // anything, so this prevents that invalid codegen.
460 const main_insts = c.air.instData(.block, .main_block).get(&c.air);460 const main_insts = c.air.instData(.block, .main_block).get(&c.air);
461 if (main_insts[main_insts.len - 1] == inst) {461 if (main_insts[main_insts.len - 1] == inst) {
462 return;462 return;
src/core/stack.zig+4-2
...@@ -104,6 +104,8 @@ pub fn Stack(comptime Base: type) type {...@@ -104,6 +104,8 @@ pub fn Stack(comptime Base: type) type {
104 starts: [fields.len]u32,104 starts: [fields.len]u32,
105 lengths: [fields.len]u32,105 lengths: [fields.len]u32,
106106
107 pub const reserve_types = types;
108
107 fn Type(comptime field: FieldEnum) type {109 fn Type(comptime field: FieldEnum) type {
108 return @field(types, @tagName(field));110 return @field(types, @tagName(field));
109 }111 }
...@@ -156,10 +158,10 @@ pub fn Stack(comptime Base: type) type {...@@ -156,10 +158,10 @@ pub fn Stack(comptime Base: type) type {
156 stack: *Self,158 stack: *Self,
157 allocator: Allocator,159 allocator: Allocator,
158 comptime types: anytype,160 comptime types: anytype,
159 lengths: [std.meta.fields(@TypeOf(types)).len]u32,161 lengths: [@typeInfo(@TypeOf(types)).@"struct".fields.len]u32,
160 ) !ReserveMulti(types) {162 ) !ReserveMulti(types) {
161 var all_lengths: usize = 0;163 var all_lengths: usize = 0;
162 var starts: [std.meta.fields(@TypeOf(types)).len]u32 = undefined;164 var starts: [@typeInfo(@TypeOf(types)).@"struct".fields.len]u32 = undefined;
163 const start = stack.list.items.len;165 const start = stack.list.items.len;
164 inline for (lengths, &starts) |len, *slice_start| {166 inline for (lengths, &starts) |len, *slice_start| {
165 slice_start.* = @intCast(start + all_lengths);167 slice_start.* = @intCast(start + all_lengths);
src/core/unicode_props.zig+3-3
...@@ -6,7 +6,7 @@ const tracer = @import("tracer");...@@ -6,7 +6,7 @@ const tracer = @import("tracer");
6var props: ?PropsData = undefined;6var props: ?PropsData = undefined;
7var props_memory: []u8 = undefined;7var props_memory: []u8 = undefined;
88
9const raw_allocator = if (@import("builtin").target.isWasm())9const raw_allocator = if (@import("builtin").target.cpu.arch.isWasm())
10 std.heap.wasm_allocator10 std.heap.wasm_allocator
11else11else
12 std.heap.page_allocator;12 std.heap.page_allocator;
...@@ -17,9 +17,9 @@ pub fn init() !void {...@@ -17,9 +17,9 @@ pub fn init() !void {
17 const trace = tracer.trace(@src());17 const trace = tracer.trace(@src());
18 defer trace.end();18 defer trace.end();
1919
20 // We know exactly how much this uses, so let's preallocate these pages and use a FBA.20 // The uncompressed unicode data has a fixed size allocated on startup.
21 // In practice, it is never freed.
21 const allocation_size = 8704 + 34560 + 8704 + 17664 + 8704 + 25856;22 const allocation_size = 8704 + 34560 + 8704 + 17664 + 8704 + 25856;
22
23 if (allocation_size == 0) {23 if (allocation_size == 0) {
24 var logging_alloc = std.heap.loggingAllocator(std.heap.page_allocator);24 var logging_alloc = std.heap.loggingAllocator(std.heap.page_allocator);
25 props = try PropsData.init(logging_alloc.allocator());25 props = try PropsData.init(logging_alloc.allocator());
src/deps/quickjs/build.zig+1-1
...@@ -163,7 +163,7 @@ fn runQjsc(b: *Build, qjsc: *Build.Step.Compile, in: Build.LazyPath) Build.LazyP...@@ -163,7 +163,7 @@ fn runQjsc(b: *Build, qjsc: *Build.Step.Compile, in: Build.LazyPath) Build.LazyP
163 return out;163 return out;
164}164}
165165
166/// Zig doesnt include winpthreads, so we build it from source. This helper166/// Zig doesnt include winpthreads, so it's built from source. This helper
167/// decides if it is needed, and provides a no-op `configure` function if it is167/// decides if it is needed, and provides a no-op `configure` function if it is
168/// not actually needed. Call .configure on any object files you need.168/// not actually needed. Call .configure on any object files you need.
169const WinPthreads = struct {169const WinPthreads = struct {
src/main.zig+1-1
...@@ -41,7 +41,7 @@ const top_level_commands: []const Command.ListItem = &.{...@@ -41,7 +41,7 @@ const top_level_commands: []const Command.ListItem = &.{
41 .name = "run",41 .name = "run",
42 .description = "Create executable and run with QuickJS",42 .description = "Create executable and run with QuickJS",
43 .cli = .{43 .cli = .{
44 .options = general_compiler_options ++ .{44 .options = general_compiler_options ++ [_]Cli.Option{
45 .{ .name = "--dump-code", .desc = "Dump compiled JavaScript to standard out" },45 .{ .name = "--dump-code", .desc = "Dump compiled JavaScript to standard out" },
46 },46 },
47 .positionals = .single,47 .positionals = .single,