Repository: oven-sh/bun
File: src/ast/Macro.zig (Zig)

Code before:
                    return Expr.init(E.String, E.String.init(out_slice), this.caller.loc);
                },
                .Promise => {
                    const _entry = this.visited.getOrPut(this.allocator, value) catch unreachable;
                    if (_entry.found_existing) {
                        return _entry.value_ptr.*;
                    }

                    const promise = value.asAnyPromise() orelse @panic("Unexpected promise type");

                    this.macro.vm.waitForPromise(promise);

                    const promise_result = promise.result(this.macro.vm.jsc_vm);
                    const rejected = promise.status() == .rejected;

                    if (promise_result.isUndefined() and this.is_top_level) {
                        this.is_top_level = false;
                        return this.caller;
                    }

                    if (rejected or promise_result.isError() or promise_result.isAggregateError(this.global) or promise_result.isException(this.global.vm())) {
                        this.macro.vm.unhandledRejection(this.global, promise_result, promise.asValue());
                        return error.MacroFailed;
                    }
                    this.is_top_level = false;
                    const result = try this.run(promise_result);

                    _entry.value_ptr.* = result;
                    return result;
                },
                else => {},
            }

            this.log.addErrorFmt(
                this.source,
                this.caller.loc,
                this.allocator,
                "cannot coerce {s} to Bun's AST. Please return a simpler type",
                .{@tagName(value.jsType())},
            ) catch unreachable;
            return error.MacroFailed;
        }
    };

    pub fn run(
        macro: Macro,
        log: *logger.Log,
        allocator: std.mem.Allocator,
        function_name: string,
        caller: Expr,
        source: *const logger.Source,

Review comment (bug):
That's where the bug happened
```zig
const _entry = this.visited.getOrPut(this.allocator, value) catch unreachable;
// ...
// A recursive function that can call `this.visited.getOrPut` inside which could reallocate its internal storage
const result = try this.run(promise_result);
// ...
// If reallocated, the pointer doesn't belong to the hash map anymore
_entry.value_ptr.* = result;
```


Code after:
                },
                .Promise => {
                    if (this.visited.get(value)) |cached| {
                        return cached;
                    }

                    const promise = value.asAnyPromise() orelse @panic("Unexpected promise type");

                    this.macro.vm.waitForPromise(promise);

                    const promise_result = promise.result(this.macro.vm.jsc_vm);
                    const rejected = promise.status() == .rejected;

                    if (promise_result.isUndefined() and this.is_top_level) {
                        this.is_top_level = false;
                        return this.caller;
                    }

                    if (rejected or promise_result.isError() or promise_result.isAggregateError(this.global) or promise_result.isException(this.global.vm())) {
                        this.macro.vm.unhandledRejection(this.global, promise_result, promise.asValue());
                        return error.MacroFailed;
                    }
                    this.is_top_level = false;
                    const result = try this.run(promise_result);

                    this.visited.put(this.allocator, value, result) catch unreachable;
                    return result;
                },
                else => {},
            }

            this.log.addErrorFmt(
                this.source,
                this.caller.loc,
                this.allocator,
                "cannot coerce {s} to Bun's AST. Please return a simpler type",
                .{@tagName(value.jsType())},
            ) catch unreachable;
            return error.MacroFailed;
        }
    };

    pub fn run(
        macro: Macro,
        log: *logger.Log,
        allocator: std.mem.Allocator,
        function_name: string,
        caller: Expr,
        source: *const logger.Source,
        id: i32,
        javascript_object: jsc.JSValue,