authorchloe caruso <git@paperclover.net> 2024-09-12 00:26:23-07:00
committerchloe caruso <git@paperclover.net> 2024-09-12 00:26:23-07:00
logcd425afcbd7d3d51c85e8d68cdfd2bf29e7c1b1d
treee8fcf2e5974c6ec39dd8884d60f43d8f0fda13af
parent5aa61b184fe1500707e632aad732bdad792fab93

fix: do not emit direct eval


9 files changed, 56 insertions(+), 25 deletions(-)

CHANGELOG.md+1
......@@ -16,6 +16,7 @@
1616- fix: crash when analyzing an empty array without a result type
1717- fix: binary operands with float and float would not resolve
1818- fix: assertion false-positive when using an extern global more than once
19- fix: do not emit direct eval
1920
2021## 0.1.5
2122
src/core/Air.Dump.zig+12
......@@ -249,6 +249,18 @@ pub const State = struct {
249249 try w.writeAll(">");
250250 try tty.setColor(w, .reset);
251251 },
252 .opaque_value => |inner| {
253 try tty.setColor(w, .bright_black);
254 try w.writeAll("<");
255 try tty.setColor(w, .blue);
256 try w.writeAll("opaque");
257 try tty.setColor(w, .reset);
258 try tty.setColor(w, .bright_black);
259 try w.writeAll(", ");
260 try s.dumpValue(w, inner);
261 try w.writeAll(">");
262 try tty.setColor(w, .reset);
263 },
252264 .string => |data| {
253265 try w.writeAll("<");
254266 try tty.setColor(w, .blue);
src/core/InternPool.zig+10-1
......@@ -127,6 +127,8 @@ pub const Tag = enum(u8) {
127127 array_value,
128128 /// An extern reference. For JS, this can be a property access
129129 external_value,
130 /// A value masked as "opaque" type
131 opaque_value,
130132
131133 pub fn Data(comptime tag: Tag) type {
132134 return switch (tag) {
......@@ -135,6 +137,7 @@ pub const Tag = enum(u8) {
135137 .simple_type => SimpleType,
136138 .simple_value => SimpleValue,
137139 .int32 => i32,
140 .opaque_value => Value,
138141
139142 else => ExtraIndex(tag.Payload()),
140143 };
......@@ -147,6 +150,7 @@ pub const Tag = enum(u8) {
147150 .simple_type,
148151 .simple_value,
149152 .int32,
153 .opaque_value,
150154 => unreachable, // does not have a payload
151155 .float, .comptime_float => Float,
152156 .func => FuncDecl,
......@@ -327,7 +331,7 @@ pub const Value = enum(u32) {
327331 .func => value.toKey(ip).func.ty,
328332 .struct_value => value.toKey(ip).struct_value.ty,
329333 .array_value => value.toKey(ip).array_value.type,
330 .external_value => .@"opaque",
334 .external_value, .opaque_value => .@"opaque",
331335 };
332336 }
333337
......@@ -871,6 +875,7 @@ pub const Key = union(enum) {
871875 struct_value: StructValue,
872876 func: Func,
873877 array_value: ArrayValue,
878 opaque_value: Value,
874879 // Types
875880 simple_type: SimpleType,
876881 function_type: FunctionType,
......@@ -991,6 +996,7 @@ pub const Key = union(enum) {
991996 inline .int32,
992997 .simple_value,
993998 .simple_type,
999 .opaque_value,
9941000 => |x| Hash.hash(seed, asBytes(&x)),
9951001 .string,
9961002 => |x| Hash.hash(seed, x),
......@@ -1023,6 +1029,7 @@ pub const Key = union(enum) {
10231029 inline .int32,
10241030 .simple_value,
10251031 .simple_type,
1032 .opaque_value,
10261033 => |x, tag| x == @field(b, @tagName(tag)),
10271034 .string,
10281035 => |x| std.mem.eql(u8, x, b.string),
......@@ -1272,6 +1279,7 @@ pub fn valueToKey(ip: *const InternPool, index: Value) Key {
12721279
12731280 .simple_type => .{ .simple_type = data.decode(.simple_type, item.tag) },
12741281 .simple_value => .{ .simple_value = data.decode(.simple_value, item.tag) },
1282 .opaque_value => .{ .opaque_value = data.decode(.opaque_value, item.tag) },
12751283 .int32 => .{ .int32 = data.decode(.int32, item.tag) },
12761284 .float => .{ .float = data.decode(.float, item.tag).get(ip).decode() },
12771285 .comptime_float => .{
......@@ -1350,6 +1358,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) !Value {
13501358 inline .int32,
13511359 .simple_type,
13521360 .simple_value,
1361 .opaque_value,
13531362 => |s, tag| Item.encode(@field(Tag, @tagName(tag)), s),
13541363 .string => |s| Item.encode(
13551364 .string,
src/core/Report.zig+5-13
......@@ -1202,19 +1202,11 @@ pub const LazyNode = struct {
12021202 else => {},
12031203 }
12041204
1205 if (builtin.mode == .Debug) {
1206 std.debug.panic("TODO: operand lookup: .{s} + .{s} + {}", .{
1207 @tagName(teg.instTag(lazy.inst)),
1208 @tagName(ctx.ast.nodeTag(base_node)),
1209 lazy.operand,
1210 });
1211 } else {
1212 std.debug.print("TODO: operand lookup: .{s} + .{s} + {}", .{
1213 @tagName(teg.instTag(lazy.inst)),
1214 @tagName(ctx.ast.nodeTag(base_node)),
1215 lazy.operand,
1216 });
1217 }
1205 std.debug.print("TODO: operand lookup: .{s} + .{s} + {}\n", .{
1206 @tagName(teg.instTag(lazy.inst)),
1207 @tagName(ctx.ast.nodeTag(base_node)),
1208 lazy.operand,
1209 });
12181210
12191211 return base_node;
12201212 }
src/core/Sema.zig+1-1
......@@ -1548,7 +1548,7 @@ fn coerceValue(s: *Sema, src: LazyNode, value: Value, to: Type) Error!Value {
15481548 }
15491549 switch (to) {
15501550 .@"opaque" => {
1551 // TODO:
1551 return try s.makeValue(.{ .opaque_value = value });
15521552 },
15531553 .bool => {
15541554 // TODO:
src/core/Transform.zig+1
......@@ -366,6 +366,7 @@ const built_in_ids = std.StaticStringMap(Inst.Ref).initComptime(.{
366366 .{ "int", .int32_type },
367367 .{ "float", .float_type },
368368 .{ "string", .string_type },
369 .{ "opaque", .opaque_type },
369370 // .{ "bigint", .bigint_type },
370371 .{ "bool", .bool_type },
371372 .{ "never", .never_type },
src/core/js/Link.zig+12-1
......@@ -482,7 +482,18 @@ fn printExprLevel(
482482 const call: Tree.Call = tree.nodeData(.call, node);
483483 const args = call.args.get(tree);
484484
485 try link.printExpr(tree, call.base, writer);
485 if (tree.nodeTag(call.base) == .plain_value and brk: {
486 const k = tree.nodeData(.plain_value, call.base).value.toKey(&link.comp.intern_pool);
487 break :brk k == .external_value and
488 k.external_value.key.len == 1 and
489 std.mem.eql(u8, k.external_value.key[0].toSlice(&link.comp.intern_pool), "eval");
490 }) {
491 @branchHint(.unlikely);
492 try writer.writeAll("(0, eval)");
493 } else {
494 try link.printExpr(tree, call.base, writer);
495 }
496
486497 try writer.writeAll("(");
487498
488499 for (args.slice(tree), 0..) |arg, i| {
src/core/js/NodeGen.zig+8-9
......@@ -137,14 +137,6 @@ fn codeGenInst(c: *NodeGen, inst: Air.Inst.Index) Error!void {
137137
138138 .block => try c.codeGenBlock(inst),
139139
140 // .js_global_ref => {
141 // const data: InternPool.String.WithLen = c.air.instData(.js_global_ref, inst);
142 // try c.extern_symbols.put(c.gpa, data, {});
143 // c.air_node_map[@intFromEnum(inst)] = .{
144 // .node = try c.add(.global, .{ .name = data }),
145 // };
146 // },
147
148140 .memory => {
149141 const i = @intFromEnum(inst);
150142 const data: Air.Memory = c.air.instData(.memory, inst);
......@@ -574,9 +566,16 @@ fn valueToExpression(c: *NodeGen, v: Value) !Node.Index {
574566 .simple_value,
575567 .struct_value,
576568 .array_value,
577 .external_value,
578569 => return try c.add(.plain_value, .{ .value = v }),
579570
571 .external_value => {
572 const external = v.toKey(c.ip).external_value;
573 try c.extern_symbols.put(c.gpa, external.key[0].toString().withLen(external.key[0].length(c.ip)), {});
574 return try c.add(.plain_value, .{ .value = v });
575 },
576
577 .opaque_value => return c.valueToExpression(v.toKey(c.ip).opaque_value),
578
580579 // Hoist functions as top level values
581580 // TODO: Consider hoisting large values too
582581 .func => {
test/behavior/direct_eval created+6
......@@ -0,0 +1,6 @@
1let eval = @extern("eval");
2
3fn main {
4 eval("var x = 1");
5 eval("if (globalThis.x != 1) throw new Error('Emitted as direct eval');");
6}