const std = @import("std"); const bun = @import("root").bun; const string = bun.string; const Output = bun.Output; const Global = bun.Global; const Environment = bun.Environment; const strings = bun.strings; const default_allocator = bun.default_allocator; const C = bun.C; const typeBaseName = @import("./meta.zig").typeBaseName; const TagSize = u15; const AddressableSize = u49; pub const TaggedPointer = packed struct { _ptr: AddressableSize, data: TagSize, pub inline fn init(ptr: anytype, data: TagSize) TaggedPointer { const Ptr = @TypeOf(ptr); if (comptime @typeInfo(Ptr) != .Pointer and Ptr != ?*anyopaque) { @compileError(@typeName(Ptr) ++ " must be a ptr, received: " ++ @tagName(@typeInfo(Ptr))); } const address = @ptrToInt(ptr); return TaggedPointer{ ._ptr = @truncate(AddressableSize, address), .data = data, }; } pub inline fn get(this: TaggedPointer, comptime Type: type) *Type { return @intToPtr(*Type, @intCast(usize, this._ptr)); } pub inline fn from(val: anytype) TaggedPointer { const ValueType = @TypeOf(val); return switch (ValueType) { f64, i64, u64 => @bitCast(TaggedPointer, val), ?*anyopaque, *anyopaque => @bitCast(TaggedPointer, @ptrToInt(val)), else => @compileError("Unsupported type: " ++ @typeName(ValueType)), }; } pub inline fn to(this: TaggedPointer) *anyopaque { return @intToPtr(*anyopaque, @bitCast(u64, this)); } }; pub fn TaggedPointerUnion(comptime Types: anytype) type { const TagType: type = tag_break: { if (std.meta.trait.isIndexable(@TypeOf(Types))) { var enumFields: [Types.len]std.builtin.Type.EnumField = undefined; var decls = [_]std.builtin.Type.Declaration{}; inline for (Types, 0..) |field, i| { enumFields[i] = .{ .name = comptime typeBaseName(@typeName(field)), .value = 1024 - i, }; } break :tag_break @Type(.{ .Enum = .{ .tag_type = TagSize, .fields = &enumFields, .decls = &decls, .is_exhaustive = false, }, }); } else { const Fields: []const std.builtin.Type.StructField = std.meta.fields(@TypeOf(Types)); var enumFields: [Fields.len]std.builtin.Type.EnumField = undefined; var decls = [_]std.builtin.Type.Declaration{}; inline for (Fields, 0..) |field, i| { enumFields[i] = .{ .name = comptime typeBaseName(@typeName(field.default_value.?)), .value = 1024 - i, }; } break :tag_break @Type(.{ .Enum = .{ .tag_type = TagSize, .fields = &enumFields, .decls = &decls, .is_exhaustive = false, }, }); } }; return struct { pub const Tag = TagType; repr: TaggedPointer, const This = @This(); fn assert_type(comptime Type: type) void { var name = comptime typeBaseName(@typeName(Type)); if (!comptime @hasField(Tag, name)) { @compileError("TaggedPointerUnion does not have " ++ name ++ "."); } } pub inline fn get(this: This, comptime Type: anytype) ?*Type { comptime assert_type(Type); return if (this.is(Type)) this.as(Type) else null; } pub inline fn tag(this: This) TagType { return @intToEnum(TagType, this.repr.data); } /// unsafely cast a tagged pointer to a specific type, without checking that it's really that type pub inline fn as(this: This, comptime Type: type) *Type { comptime assert_type(Type); return this.repr.get(Type); } pub inline fn is(this: This, comptime Type: type) bool { comptime assert_type(Type); return this.repr.data == comptime @enumToInt(@field(Tag, typeBaseName(@typeName(Type)))); } pub fn set(this: *@This(), _ptr: anytype) void { this.* = @This().init(_ptr); } pub inline fn isValidPtr(_ptr: ?*anyopaque) bool { return This.isValid(This.from(_ptr)); } pub inline fn isValid(this: This) bool { return switch (this.repr.data) { @enumToInt( @field(Tag, typeBaseName(@typeName(Types[Types.len - 1]))), )...@enumToInt( @field(Tag, typeBaseName(@typeName(Types[0]))), ) => true, else => false, }; } pub inline fn from(_ptr: ?*anyopaque) This { return This{ .repr = TaggedPointer.from(_ptr) }; } pub inline fn ptr(this: This) *anyopaque { return this.repr.to(); } pub inline fn ptrUnsafe(this: This) *anyopaque { @setRuntimeSafety(false); return this.repr.to(); } pub inline fn init(_ptr: anytype) This { const Type = std.meta.Child(@TypeOf(_ptr)); const name = comptime typeBaseName(@typeName(Type)); // there will be a compiler error if the passed in type doesn't exist in the enum return This{ .repr = TaggedPointer.init(_ptr, @enumToInt(@field(Tag, name))) }; } }; } test "TaggedPointerUnion" { const IntPrimitive = struct { val: u32 = 0 }; const StringPrimitive = struct { val: []const u8 = "" }; const Object = struct { blah: u32, val: u32 }; // const Invalid = struct { // wrong: bool = true, // }; const Union = TaggedPointerUnion(.{ IntPrimitive, StringPrimitive, Object }); var str = try default_allocator.create(StringPrimitive); str.* = StringPrimitive{ .val = "hello!" }; var un = Union.init(str); try std.testing.expect(un.is(StringPrimitive)); try std.testing.expectEqualStrings(un.as(StringPrimitive).val, "hello!"); try std.testing.expect(!un.is(IntPrimitive)); const num = try default_allocator.create(IntPrimitive); num.val = 9999; var un2 = Union.init(num); try std.testing.expect(un2.as(IntPrimitive).val == 9999); try std.testing.expect(un.tag() == .StringPrimitive); try std.testing.expect(un2.tag() == .IntPrimitive); un2.repr.data = 0; try std.testing.expect(un2.tag() != .IntPrimitive); try std.testing.expect(un2.get(IntPrimitive) == null); // try std.testing.expect(un2.is(Invalid) == false); } test "TaggedPointer" { const Hello = struct { what: []const u8, }; var hello_struct_ptr = try default_allocator.create(Hello); hello_struct_ptr.* = Hello{ .what = "hiiii" }; var tagged = TaggedPointer.init(hello_struct_ptr, 0); try std.testing.expectEqual(tagged.get(Hello), hello_struct_ptr); try std.testing.expectEqualStrings(tagged.get(Hello).what, hello_struct_ptr.what); tagged = TaggedPointer.init(hello_struct_ptr, 100); try std.testing.expectEqual(tagged.get(Hello), hello_struct_ptr); try std.testing.expectEqualStrings(tagged.get(Hello).what, hello_struct_ptr.what); tagged = TaggedPointer.init(hello_struct_ptr, std.math.maxInt(TagSize) - 500); try std.testing.expectEqual(tagged.get(Hello), hello_struct_ptr); try std.testing.expectEqual(tagged.data, std.math.maxInt(TagSize) - 500); try std.testing.expectEqualStrings(tagged.get(Hello).what, hello_struct_ptr.what); var i: TagSize = 0; while (i < std.math.maxInt(TagSize) - 1) : (i += 1) { hello_struct_ptr = try default_allocator.create(Hello); const what = try std.fmt.allocPrint(default_allocator, "hiiii {d}", .{i}); hello_struct_ptr.* = Hello{ .what = what }; try std.testing.expectEqualStrings(TaggedPointer.from(TaggedPointer.init(hello_struct_ptr, i).to()).get(Hello).what, what); var this = TaggedPointer.from(TaggedPointer.init(hello_struct_ptr, i).to()); try std.testing.expect(this.data == i); try std.testing.expect(this.data != i + 1); } } d/isolation Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
path: root/test/bun.js/wasm.test.js (unfollow)
ges when running a script in Bun's runtime (#1...
AgeCommit message (Expand)AuthorFilesLines
Gravatar Jarred Sumner 35-1786/+5529
2022-11-06chore: remove space lookalike (#1465)Gravatar Carter Snook 2-2/+2
2022-11-06Fixes https://github.com/oven-sh/bun/issues/1451Gravatar Jarred Sumner 1-1/+7
2022-11-06Add way to explicitly coercion object to int32Gravatar Jarred Sumner 11-18/+55
2022-11-06Fix symbol error with `make headers`Gravatar Jarred Sumner 1-0/+3
2022-11-06Fix bug when passing ABI Types as integersGravatar Jarred Sumner 1-3/+5
2022-11-06Fixes https://github.com/oven-sh/bun/issues/1462Gravatar Jarred Sumner 2-4/+28
2022-11-06UndoGravatar Jarred Sumner 4-59/+12
2022-11-06Update action.ymlGravatar Jarred Sumner 1-1/+0
2022-11-06PrettierGravatar Jarred Sumner 1-1/+1
2022-11-06Pass `tar -C`Gravatar Jarred Sumner 4-6/+53
2022-11-06[TypeScript] Fix `export = value`Gravatar Jarred Sumner 2-0/+5
2022-11-06Fix artifact name, use tarballGravatar Jarred Sumner 3-12/+11
2022-11-06Try tarballGravatar Jarred Sumner 1-4/+4
2022-11-06Try againGravatar Jarred Sumner 4-0/+4
2022-11-06Node12 is deprecatedGravatar Jarred Sumner 4-28/+32
2022-11-06feat(child_process): add node:child_process polyfill (#1424)Gravatar Derrick Farris 4-3/+2756
2022-11-06fix(subprocess): fix typo in spawnSync (#1464)Gravatar Derrick Farris 1-2/+2
2022-11-05Fix fetch api to accept stringifier object (#1460)Gravatar zhiyuan 2-11/+25
2022-11-03Fix crash in setTimeout/setIntervalGravatar Jarred Sumner 1-0/+5
2022-11-03Fix incorrect exit codeGravatar Jarred Sumner 1-9/+15
2022-11-03Fix crash when reading promise value wihtout checking if nullGravatar Jarred Sumner 1-0/+1
2022-11-03Fix `which` not handling absolute paths to a binGravatar Jarred Sumner 1-3/+20
2022-11-03Fix `cmd not found in $PATH` printing raw structGravatar Jarred Sumner 1-1/+1
2022-11-03Delete unused fileGravatar Jarred Sumner 1-97/+0
2022-11-03Add minified prod build of react-dom/server.bun (#1458)Gravatar Colin McDonnell 2-6819/+138
2022-11-03chore: remove unecessary files (#1457)Gravatar Hyro 2-118/+0
2022-11-03Introduce `import.meta.primordials` for builtin JSGravatar Jarred Sumner 5-3/+95