diff options
author | 2021-06-06 18:34:01 -0700 | |
---|---|---|
committer | 2021-06-06 18:34:01 -0700 | |
commit | d49e0a5fa129152c27b70a57d1cc7a2af770577c (patch) | |
tree | 1ac581bda71fec5dfd09a6ab508a1adfca80b358 /src/node_module_bundle.zig | |
parent | e66466cc1a453db1370a199a32729441747761bb (diff) | |
download | bun-d49e0a5fa129152c27b70a57d1cc7a2af770577c.tar.gz bun-d49e0a5fa129152c27b70a57d1cc7a2af770577c.tar.zst bun-d49e0a5fa129152c27b70a57d1cc7a2af770577c.zip |
WIP node module bundles
Former-commit-id: 797b2ff557542e9d318c953b840b102695711888
Diffstat (limited to 'src/node_module_bundle.zig')
-rw-r--r-- | src/node_module_bundle.zig | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/node_module_bundle.zig b/src/node_module_bundle.zig new file mode 100644 index 000000000..11150f376 --- /dev/null +++ b/src/node_module_bundle.zig @@ -0,0 +1,69 @@ +const Api = @import("./api/schema.zig").Api; +const std = @import("std"); +usingnamespace @import("global.zig"); + +pub const NodeModuleBundle = struct { + container: *Api.JavascriptBundleContainer, + bundle: *Api.JavascriptBundle, + allocator: *std.mem.Allocator, + fd: FileDescriptorType = 0, + + pub const magic_bytes = "#!/usr/bin/env speedy\n\n"; + threadlocal var jsbundle_prefix: [magic_bytes.len + 5]u8 = undefined; + + pub fn getCodeEndPosition(stream: anytype, comptime needs_seek: bool) !u32 { + if (needs_seek) try stream.seekTo(0); + + const read_bytes = try stream.read(&jsbundle_prefix); + if (read_bytes != jsbundle_prefix.len) { + return error.JSBundleBadHeaderTooShort; + } + + return std.mem.readIntNative(u32, jsbundle_prefix[magic_bytes.len .. magic_bytes.len + 4]); + } + + pub fn loadBundle(allocator: *std.mem.Allocator, stream: anytype) !NodeModuleBundle { + const end = try getCodeEndPosition(stream); + try stream.seekTo(end + 1); + var reader = stream.reader(); + var container = try Api.JavascriptBundleContainer.decode(allocator, reader); + return NodeModuleBundle{ + .allocator = allocator, + .container = container, + .bundle = container.bundle, + .fd = if (std.meta.trait.hasField("handle")(stream)) stream.handle else 0, + }; + } + + pub fn printBundle( + comptime StreamType: type, + input: StreamType, + comptime DestinationStreamType: type, + output: DestinationStreamType, + ) !void { + const BufferStreamContext = struct { + pub fn run(in: StreamType, out: DestinationStreamType, end_at: u32) !void { + var buf: [4096]u8 = undefined; + var remain = @intCast(i64, end_at); + var read_amount: i64 = @intCast(i64, in.read(&buf) catch 0); + while (remain > 0 and read_amount > 0) { + remain -= @intCast(i64, try out.write(buf[0..@intCast(usize, std.math.min(read_amount, remain))])); + read_amount = @intCast(i64, in.read(&buf) catch 0); + } + + _ = try out.write(buf[0..@intCast(usize, remain + 1)]); + } + }; + if (isMac) { + // darwin only allows reading ahead on/off, not specific amount + _ = std.os.fcntl(input.handle, std.os.F_RDAHEAD, 1) catch 0; + } + const end = try getCodeEndPosition(input, false); + + try BufferStreamContext.run( + input, + output, + end, + ); + } +}; |