diff --git a/fix-codegen/src/disassembler.rs b/fix-codegen/src/disassembler.rs index e2b561a..5aba5c5 100644 --- a/fix-codegen/src/disassembler.rs +++ b/fix-codegen/src/disassembler.rs @@ -418,7 +418,10 @@ impl<'a, Ctx: DisassemblerContext> Disassembler<'a, Ctx> { let span_id = self.read_u32(); ("Assert", format!("text_id={} span={}", raw_idx, span_id)) } - Op::PushWith => ("PushWith", String::new()), + Op::PushWith => { + self.read_operand_data(); + ("PushWith", String::new()) + } Op::PopWith => ("PopWith", String::new()), Op::PrepareWith => ("PrepareWith", String::new()), Op::LookupWith => { diff --git a/fix-codegen/src/lib.rs b/fix-codegen/src/lib.rs index af8841e..b6f571a 100644 --- a/fix-codegen/src/lib.rs +++ b/fix-codegen/src/lib.rs @@ -103,7 +103,7 @@ pub enum Op { } struct ScopeInfo { - depth: u16, + depth: u8, thunk_map: HashMap, } @@ -143,7 +143,7 @@ pub enum AttrKeyType { pub enum InlineOperand { Const(Const), - Local { layer: u16, local: u32 }, + Local { layer: u8, local: u32 }, Builtins, BigInt(i64), } @@ -168,8 +168,8 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { use MaybeThunk::*; match val { Int(x) => { - if x <= i32::MAX as i64 { - InlineOperand::Const(Const::Smi(x as i32)) + if let Ok(x) = x.try_into() { + InlineOperand::Const(Const::Smi(x)) } else { InlineOperand::BigInt(x) } @@ -183,7 +183,7 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { InlineOperand::Local { layer, local } } Arg { layer } => InlineOperand::Local { - layer: layer.try_into().expect("scope too deep!"), + layer, local: 0, }, _ => todo!(), @@ -200,7 +200,7 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { } InlineOperand::Local { layer, local } => { self.emit_u8(OperandType::Local as u8); - self.emit_u8(layer as u8); + self.emit_u8(layer); self.emit_u32(local); } InlineOperand::Builtins => { @@ -289,11 +289,11 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { .extend_from_slice(&(id.0.to_usize() as u32).to_le_bytes()); } - fn current_depth(&self) -> u16 { + fn current_depth(&self) -> u8 { self.scope_stack.last().map_or(0, |s| s.depth) } - fn resolve_thunk(&self, id: ThunkId) -> (u16, u32) { + fn resolve_thunk(&self, id: ThunkId) -> (u8, u32) { for scope in self.scope_stack.iter().rev() { if let Some(&local_idx) = scope.thunk_map.get(&id) { let layer = self.current_depth() - scope.depth; @@ -303,13 +303,13 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { panic!("ThunkId {:?} not found in any scope", id); } - fn emit_load(&mut self, layer: u16, local: u32) { + fn emit_load(&mut self, layer: u8, local: u32) { if layer == 0 { self.emit_op(Op::LoadLocal); self.emit_u32(local); } else { self.emit_op(Op::LoadOuter); - self.emit_u8(layer as u8); + self.emit_u8(layer); self.emit_u32(local); } } @@ -407,7 +407,7 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { } fn push_scope(&mut self, has_arg: bool, thunk_ids: &[ThunkId]) { - let depth = self.scope_stack.len() as u16; + let depth = self.scope_stack.len().try_into().expect("scope too deep!"); let thunk_base = if has_arg { 1u32 } else { 0u32 }; let thunk_map = thunk_ids .iter() @@ -554,7 +554,7 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { self.emit_maybe_thunk(arg); } &Ir::Arg { layer } => { - self.emit_load(layer.try_into().expect("scope too deep!"), 0); + self.emit_load(layer, 0); } &Ir::TopLevel { body, ref thunks } => { self.emit_toplevel_inner(body, thunks); diff --git a/fix-ir/src/lib.rs b/fix-ir/src/lib.rs index 0336568..15ee0c2 100644 --- a/fix-ir/src/lib.rs +++ b/fix-ir/src/lib.rs @@ -73,7 +73,7 @@ pub enum MaybeThunk { Str(StringId), Path(StringId), Thunk(ThunkId), - Arg { layer: usize }, + Arg { layer: u8 }, Builtin(BuiltinId), Builtins, ReplBinding(StringId), @@ -172,7 +172,7 @@ pub enum Ir<'ir, Ref> { thunks: Vec<'ir, (ThunkId, Ref)>, }, Arg { - layer: usize, + layer: u8, }, Call { func: Ref, diff --git a/fix/src/lib.rs b/fix/src/lib.rs index 22b6d4c..69b26c6 100644 --- a/fix/src/lib.rs +++ b/fix/src/lib.rs @@ -431,9 +431,10 @@ impl<'ctx: 'ir, 'id, 'ir, R: VmRuntimeCtx> DowngradeContext<'id, 'ir> abs_layer, } => { if param_sym == sym { - return Ok(MaybeThunk::Arg { - layer: self.thunk_scopes.len() - abs_layer, - }); + let layers: u8 = + self.thunk_scopes.len().try_into().expect("scope too deep!"); + let layer = layers - abs_layer; + return Ok(MaybeThunk::Arg { layer }); } } } @@ -484,7 +485,7 @@ impl<'ctx: 'ir, 'id, 'ir, R: VmRuntimeCtx> DowngradeContext<'id, 'ir> { self.scopes.push(Scope::Param { sym, - abs_layer: self.thunk_scopes.len(), + abs_layer: self.thunk_scopes.len().try_into().expect("scope too deep!"), }); let mut guard = ScopeGuard { ctx: self }; f(guard.as_ctx()) @@ -510,6 +511,9 @@ impl<'ctx: 'ir, 'id, 'ir, R: VmRuntimeCtx> DowngradeContext<'id, 'ir> where F: FnOnce(&mut Self) -> Ret, { + if self.thunk_scopes.len() == u8::MAX as usize { + panic!("scope too deep!"); + } self.thunk_scopes.push(ThunkScope::new_in(self.bump)); let ret = f(self); ( @@ -564,7 +568,7 @@ enum Scope<'ctx> { Repl(&'ctx HashSet), ScopedImport(HashSet), Let(HashMap), - Param { sym: StringId, abs_layer: usize }, + Param { sym: StringId, abs_layer: u8 }, } struct ScopeGuard<'a, 'ctx, 'id, 'ir, R: VmRuntimeCtx> { diff --git a/flake.nix b/flake.nix index 72fedc4..418dc23 100644 --- a/flake.nix +++ b/flake.nix @@ -48,6 +48,7 @@ samply tokei + llm-agents.codex llm-agents.claude-code llm-agents.opencode llm-agents.forge