Files
bun.sh/src/javascript/jsc/rare_data.zig
2022-05-05 21:35:08 -07:00

159 lines
4.7 KiB
Zig

const EditorContext = @import("../../open.zig").EditorContext;
const Blob = @import("./webcore/response.zig").Blob;
const default_allocator = @import("../../global.zig").default_allocator;
const Output = @import("../../global.zig").Output;
const RareData = @This();
const Syscall = @import("./node/syscall.zig");
const JSC = @import("javascript_core");
const std = @import("std");
const BoringSSL = @import("boringssl");
boring_ssl_engine: ?*BoringSSL.ENGINE = null,
editor_context: EditorContext = EditorContext{},
stderr_store: ?*Blob.Store = null,
stdin_store: ?*Blob.Store = null,
stdout_store: ?*Blob.Store = null,
// TODO: make this per JSGlobalObject instead of global
// This does not handle ShadowRealm correctly!
tail_cleanup_hook: ?*CleanupHook = null,
cleanup_hook: ?*CleanupHook = null,
pub const CleanupHook = struct {
next: ?*CleanupHook = null,
ctx: ?*anyopaque,
func: Function,
globalThis: *JSC.JSGlobalObject,
pub fn eql(self: CleanupHook, other: CleanupHook) bool {
return self.ctx == other.ctx and self.func == other.func and self.globalThis == other.globalThis;
}
pub fn execute(self: CleanupHook) void {
self.func(self.ctx);
}
pub fn from(
globalThis: *JSC.JSGlobalObject,
ctx: ?*anyopaque,
func: CleanupHook.Function,
) CleanupHook {
return .{
.next = null,
.ctx = ctx,
.func = func,
.globalThis = globalThis,
};
}
pub const Function = fn (?*anyopaque) callconv(.C) void;
};
pub fn pushCleanupHook(
this: *RareData,
globalThis: *JSC.JSGlobalObject,
ctx: ?*anyopaque,
func: CleanupHook.Function,
) void {
var hook = JSC.VirtualMachine.vm.allocator.create(CleanupHook) catch unreachable;
hook.* = CleanupHook.from(globalThis, ctx, func);
if (this.cleanup_hook == null) {
this.cleanup_hook = hook;
this.tail_cleanup_hook = hook;
} else {
this.cleanup_hook.?.next = hook;
}
}
pub fn boringEngine(rare: *RareData) *BoringSSL.ENGINE {
return rare.boring_ssl_engine orelse brk: {
rare.boring_ssl_engine = BoringSSL.ENGINE_new();
break :brk rare.boring_ssl_engine.?;
};
}
pub fn stderr(rare: *RareData) *Blob.Store {
return rare.stderr_store orelse brk: {
var store = default_allocator.create(Blob.Store) catch unreachable;
var mode: JSC.Node.Mode = 0;
switch (Syscall.fstat(std.os.STDERR_FILENO)) {
.result => |stat| {
mode = stat.mode;
},
.err => {},
}
store.* = Blob.Store{
.ref_count = 2,
.allocator = default_allocator,
.data = .{
.file = Blob.FileStore{
.pathlike = .{
.fd = std.os.STDERR_FILENO,
},
.is_atty = Output.stderr_descriptor_type == .terminal,
.mode = mode,
},
},
};
rare.stderr_store = store;
break :brk store;
};
}
pub fn stdout(rare: *RareData) *Blob.Store {
return rare.stdout_store orelse brk: {
var store = default_allocator.create(Blob.Store) catch unreachable;
var mode: JSC.Node.Mode = 0;
switch (Syscall.fstat(std.os.STDOUT_FILENO)) {
.result => |stat| {
mode = stat.mode;
},
.err => {},
}
store.* = Blob.Store{
.ref_count = 2,
.allocator = default_allocator,
.data = .{
.file = Blob.FileStore{
.pathlike = .{
.fd = std.os.STDOUT_FILENO,
},
.is_atty = Output.stdout_descriptor_type == .terminal,
.mode = mode,
},
},
};
rare.stdout_store = store;
break :brk store;
};
}
pub fn stdin(rare: *RareData) *Blob.Store {
return rare.stdin_store orelse brk: {
var store = default_allocator.create(Blob.Store) catch unreachable;
var mode: JSC.Node.Mode = 0;
switch (Syscall.fstat(std.os.STDIN_FILENO)) {
.result => |stat| {
mode = stat.mode;
},
.err => {},
}
store.* = Blob.Store{
.allocator = default_allocator,
.ref_count = 2,
.data = .{
.file = Blob.FileStore{
.pathlike = .{
.fd = std.os.STDIN_FILENO,
},
.is_atty = std.os.isatty(std.os.STDIN_FILENO),
.mode = mode,
},
},
};
rare.stdin_store = store;
break :brk store;
};
}