@@ -4,8 +4,9 @@ const EpochSeconds = std.time.epoch.EpochSeconds;
4
4
const mem = std .mem ;
5
5
const Allocator = mem .Allocator ;
6
6
7
- const Interner = @import ("../backend.zig" ).Interner ;
8
- const CodeGenOptions = @import ("../backend.zig" ).CodeGenOptions ;
7
+ const backend = @import ("../backend.zig" );
8
+ const Interner = backend .Interner ;
9
+ const CodeGenOptions = backend .CodeGenOptions ;
9
10
10
11
const Builtins = @import ("Builtins.zig" );
11
12
const Builtin = Builtins .Builtin ;
@@ -127,24 +128,24 @@ diagnostics: *Diagnostics,
127
128
128
129
code_gen_options : CodeGenOptions = .default ,
129
130
environment : Environment = .{},
130
- sources : std .StringArrayHashMapUnmanaged (Source ) = .{} ,
131
+ sources : std .StringArrayHashMapUnmanaged (Source ) = .empty ,
131
132
/// Allocated into `gpa`, but keys are externally managed.
132
- include_dirs : std .ArrayListUnmanaged ([]const u8 ) = .empty ,
133
+ include_dirs : std .ArrayList ([]const u8 ) = .empty ,
133
134
/// Allocated into `gpa`, but keys are externally managed.
134
- system_include_dirs : std .ArrayListUnmanaged ([]const u8 ) = .empty ,
135
+ system_include_dirs : std .ArrayList ([]const u8 ) = .empty ,
135
136
/// Allocated into `gpa`, but keys are externally managed.
136
- after_include_dirs : std .ArrayListUnmanaged ([]const u8 ) = .empty ,
137
+ after_include_dirs : std .ArrayList ([]const u8 ) = .empty ,
137
138
/// Allocated into `gpa`, but keys are externally managed.
138
- framework_dirs : std .ArrayListUnmanaged ([]const u8 ) = .empty ,
139
+ framework_dirs : std .ArrayList ([]const u8 ) = .empty ,
139
140
/// Allocated into `gpa`, but keys are externally managed.
140
- system_framework_dirs : std .ArrayListUnmanaged ([]const u8 ) = .empty ,
141
+ system_framework_dirs : std .ArrayList ([]const u8 ) = .empty ,
141
142
/// Allocated into `gpa`, but keys are externally managed.
142
- embed_dirs : std .ArrayListUnmanaged ([]const u8 ) = .empty ,
143
+ embed_dirs : std .ArrayList ([]const u8 ) = .empty ,
143
144
target : std.Target = @import ("builtin" ).target ,
144
145
cmodel : std.builtin.CodeModel = .default ,
145
- pragma_handlers : std .StringArrayHashMapUnmanaged (* Pragma ) = .{} ,
146
+ pragma_handlers : std .StringArrayHashMapUnmanaged (* Pragma ) = .empty ,
146
147
langopts : LangOpts = .{},
147
- generated_buf : std .ArrayListUnmanaged (u8 ) = .{} ,
148
+ generated_buf : std .ArrayList (u8 ) = .empty ,
148
149
builtins : Builtins = .{},
149
150
string_interner : StringInterner = .{},
150
151
interner : Interner = .{},
@@ -245,6 +246,13 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
245
246
try w .print ("#define __GNUC_PATCHLEVEL__ {d}\n " , .{comp .langopts .gnuc_version % 100 });
246
247
}
247
248
249
+ if (comp .code_gen_options .optimization_level .hasAnyOptimizations ()) {
250
+ try define (w , "__OPTIMIZE__" );
251
+ }
252
+ if (comp .code_gen_options .optimization_level .isSizeOptimized ()) {
253
+ try define (w , "__OPTIMIZE_SIZE__" );
254
+ }
255
+
248
256
// os macros
249
257
switch (comp .target .os .tag ) {
250
258
.linux = > try defineStd (w , "linux" , is_gnu ),
@@ -1384,8 +1392,8 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
1384
1392
const duped_path = try comp .gpa .dupe (u8 , path );
1385
1393
errdefer comp .gpa .free (duped_path );
1386
1394
1387
- var splice_list = std .array_list . Managed (u32 ). init ( comp . gpa ) ;
1388
- defer splice_list .deinit ();
1395
+ var splice_list : std .ArrayList (u32 ) = .empty ;
1396
+ defer splice_list .deinit (comp . gpa );
1389
1397
1390
1398
const source_id : Source.Id = @enumFromInt (comp .sources .count () + 2 );
1391
1399
@@ -1418,9 +1426,9 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
1418
1426
},
1419
1427
.back_slash , .trailing_ws , .back_slash_cr = > {
1420
1428
i = backslash_loc ;
1421
- try splice_list .append (i );
1429
+ try splice_list .append (comp . gpa , i );
1422
1430
if (state == .trailing_ws ) {
1423
- try comp .addNewlineEscapeError (path , buf , splice_list .items , i , line );
1431
+ try comp .addNewlineEscapeError (path , buf , splice_list .items , i , line , kind );
1424
1432
}
1425
1433
state = if (state == .back_slash_cr ) .cr else .back_slash_cr ;
1426
1434
},
@@ -1438,10 +1446,10 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
1438
1446
.back_slash , .trailing_ws = > {
1439
1447
i = backslash_loc ;
1440
1448
if (state == .back_slash or state == .trailing_ws ) {
1441
- try splice_list .append (i );
1449
+ try splice_list .append (comp . gpa , i );
1442
1450
}
1443
1451
if (state == .trailing_ws ) {
1444
- try comp .addNewlineEscapeError (path , buf , splice_list .items , i , line );
1452
+ try comp .addNewlineEscapeError (path , buf , splice_list .items , i , line , kind );
1445
1453
}
1446
1454
},
1447
1455
.bom1 , .bom2 = > break ,
@@ -1491,11 +1499,11 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
1491
1499
}
1492
1500
}
1493
1501
1494
- const splice_locs = try splice_list .toOwnedSlice ();
1502
+ const splice_locs = try splice_list .toOwnedSlice (comp . gpa );
1495
1503
errdefer comp .gpa .free (splice_locs );
1496
1504
1497
1505
if (i != contents .len ) {
1498
- var list : std .ArrayListUnmanaged (u8 ) = .{
1506
+ var list : std .ArrayList (u8 ) = .{
1499
1507
.items = contents [0.. i ],
1500
1508
.capacity = contents .len ,
1501
1509
};
@@ -1515,13 +1523,21 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
1515
1523
return source ;
1516
1524
}
1517
1525
1518
- fn addNewlineEscapeError (comp : * Compilation , path : []const u8 , buf : []const u8 , splice_locs : []const u32 , byte_offset : u32 , line : u32 ) ! void {
1526
+ fn addNewlineEscapeError (
1527
+ comp : * Compilation ,
1528
+ path : []const u8 ,
1529
+ buf : []const u8 ,
1530
+ splice_locs : []const u32 ,
1531
+ byte_offset : u32 ,
1532
+ line : u32 ,
1533
+ kind : Source.Kind ,
1534
+ ) ! void {
1519
1535
// Temporary source for getting the location for errors.
1520
1536
var tmp_source : Source = .{
1521
1537
.path = path ,
1522
1538
.buf = buf ,
1523
1539
.id = undefined ,
1524
- .kind = undefined ,
1540
+ .kind = kind ,
1525
1541
.splice_locs = splice_locs ,
1526
1542
};
1527
1543
@@ -1571,17 +1587,7 @@ fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kin
1571
1587
}
1572
1588
1573
1589
pub fn addSourceFromFile (comp : * Compilation , file : std.fs.File , path : []const u8 , kind : Source.Kind ) ! Source {
1574
- var file_buf : [4096 ]u8 = undefined ;
1575
- var file_reader = file .reader (& file_buf );
1576
- if (try file_reader .getSize () > std .math .maxInt (u32 )) return error .FileTooBig ;
1577
-
1578
- var allocating : std.Io.Writer.Allocating = .init (comp .gpa );
1579
- _ = allocating .writer .sendFileAll (& file_reader , .limited (std .math .maxInt (u32 ))) catch | e | switch (e ) {
1580
- error .WriteFailed = > return error .OutOfMemory ,
1581
- error .ReadFailed = > return file_reader .err .? ,
1582
- };
1583
-
1584
- const contents = try allocating .toOwnedSlice ();
1590
+ const contents = try comp .getFileContents (file , .unlimited );
1585
1591
errdefer comp .gpa .free (contents );
1586
1592
return comp .addSourceFromOwnedBuffer (path , contents , kind );
1587
1593
}
@@ -1676,7 +1682,7 @@ const FindInclude = struct {
1676
1682
if (try find .checkFrameworkDir (dir , .system )) | res | return res ;
1677
1683
}
1678
1684
for (comp .after_include_dirs .items ) | dir | {
1679
- if (try find .checkIncludeDir (dir , .user )) | res | return res ;
1685
+ if (try find .checkIncludeDir (dir , .system )) | res | return res ;
1680
1686
}
1681
1687
if (comp .ms_cwd_source_id ) | source_id | {
1682
1688
if (try find .checkMsCwdIncludeDir (source_id )) | res | return res ;
@@ -1771,26 +1777,38 @@ pub const IncludeType = enum {
1771
1777
angle_brackets ,
1772
1778
};
1773
1779
1774
- fn getFileContents (comp : * Compilation , path : []const u8 , limit : std.Io.Limit ) ! []const u8 {
1780
+ fn getPathContents (comp : * Compilation , path : []const u8 , limit : std.Io.Limit ) ! []u8 {
1775
1781
if (mem .indexOfScalar (u8 , path , 0 ) != null ) {
1776
1782
return error .FileNotFound ;
1777
1783
}
1778
1784
1779
1785
const file = try comp .cwd .openFile (path , .{});
1780
1786
defer file .close ();
1787
+ return comp .getFileContents (file , limit );
1788
+ }
1781
1789
1782
- var allocating : std.Io.Writer.Allocating = .init (comp .gpa );
1783
- defer allocating .deinit ();
1784
-
1790
+ fn getFileContents (comp : * Compilation , file : std.fs.File , limit : std.Io.Limit ) ! []u8 {
1785
1791
var file_buf : [4096 ]u8 = undefined ;
1786
1792
var file_reader = file .reader (& file_buf );
1787
- if (limit .minInt64 (try file_reader .getSize ()) > std .math .maxInt (u32 )) return error .FileTooBig ;
1788
-
1789
- _ = allocating .writer .sendFileAll (& file_reader , limit ) catch | err | switch (err ) {
1790
- error .WriteFailed = > return error .OutOfMemory ,
1791
- error .ReadFailed = > return file_reader .err .? ,
1792
- };
1793
1793
1794
+ var allocating : std.Io.Writer.Allocating = .init (comp .gpa );
1795
+ defer allocating .deinit ();
1796
+ if (file_reader .getSize ()) | size | {
1797
+ const limited_size = limit .minInt64 (size );
1798
+ if (limited_size > std .math .maxInt (u32 )) return error .FileTooBig ;
1799
+ try allocating .ensureUnusedCapacity (limited_size );
1800
+ } else | _ | {}
1801
+
1802
+ var remaining = limit .min (.limited (std .math .maxInt (u32 )));
1803
+ while (remaining .nonzero ()) {
1804
+ const n = file_reader .interface .stream (& allocating .writer , remaining ) catch | err | switch (err ) {
1805
+ error .EndOfStream = > return allocating .toOwnedSlice (),
1806
+ error .WriteFailed = > return error .OutOfMemory ,
1807
+ error .ReadFailed = > return file_reader .err .? ,
1808
+ };
1809
+ remaining = remaining .subtract (n ).? ;
1810
+ }
1811
+ if (limit == .unlimited ) return error .FileTooBig ;
1794
1812
return allocating .toOwnedSlice ();
1795
1813
}
1796
1814
@@ -1802,9 +1820,10 @@ pub fn findEmbed(
1802
1820
include_type : IncludeType ,
1803
1821
limit : std.Io.Limit ,
1804
1822
opt_dep_file : ? * DepFile ,
1805
- ) ! ? []const u8 {
1823
+ ) ! ? []u8 {
1806
1824
if (std .fs .path .isAbsolute (filename )) {
1807
- if (comp .getFileContents (filename , limit )) | some | {
1825
+ if (comp .getPathContents (filename , limit )) | some | {
1826
+ errdefer comp .gpa .free (some );
1808
1827
if (opt_dep_file ) | dep_file | try dep_file .addDependencyDupe (comp .gpa , comp .arena , filename );
1809
1828
return some ;
1810
1829
} else | err | switch (err ) {
@@ -1824,7 +1843,8 @@ pub fn findEmbed(
1824
1843
if (comp .langopts .ms_extensions ) {
1825
1844
std .mem .replaceScalar (u8 , path , '\\ ' , '/' );
1826
1845
}
1827
- if (comp .getFileContents (path , limit )) | some | {
1846
+ if (comp .getPathContents (path , limit )) | some | {
1847
+ errdefer comp .gpa .free (some );
1828
1848
if (opt_dep_file ) | dep_file | try dep_file .addDependencyDupe (comp .gpa , comp .arena , filename );
1829
1849
return some ;
1830
1850
} else | err | switch (err ) {
@@ -1840,7 +1860,8 @@ pub fn findEmbed(
1840
1860
if (comp .langopts .ms_extensions ) {
1841
1861
std .mem .replaceScalar (u8 , path , '\\ ' , '/' );
1842
1862
}
1843
- if (comp .getFileContents (path , limit )) | some | {
1863
+ if (comp .getPathContents (path , limit )) | some | {
1864
+ errdefer comp .gpa .free (some );
1844
1865
if (opt_dep_file ) | dep_file | try dep_file .addDependencyDupe (comp .gpa , comp .arena , filename );
1845
1866
return some ;
1846
1867
} else | err | switch (err ) {
0 commit comments