split SelectDefault -> SelectStatic & Jump...

This commit is contained in:
2026-04-19 13:49:58 +08:00
parent 74866ec1d3
commit f66752afa5
3 changed files with 123 additions and 200 deletions
+29 -29
View File
@@ -45,8 +45,9 @@ pub enum Op {
MakeAttrs,
MakeEmptyAttrs,
Select,
SelectDefault,
SelectStatic,
SelectDynamic,
JumpIfSelectSucceeded,
HasAttr,
MakeList,
@@ -114,13 +115,6 @@ pub enum OperandType {
BigInt,
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, TryFromPrimitive)]
pub enum AttrKeyType {
Static,
Dynamic,
}
pub enum Const {
Smi(i32),
Float(f64),
@@ -130,6 +124,13 @@ pub enum Const {
Null,
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, TryFromPrimitive)]
pub enum AttrKeyType {
Static,
Dynamic,
}
pub enum InlineOperand {
Const(Const),
Local { layer: u16, local: u32 },
@@ -626,6 +627,7 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> {
self.emit_with(namespace, body, thunks);
}
&Ir::WithLookup(name) => {
// TODO: specialize shallow with lookups
self.emit_op(Op::PrepareWith);
self.emit_op(Op::LookupWith);
self.emit_str_id(name);
@@ -819,34 +821,32 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> {
span: TextRange,
) {
self.emit_expr(expr);
for attr in attrpath.iter() {
if let Attr::Dynamic(expr, _) = *attr {
self.emit_expr(expr);
}
}
if let Some(default) = default {
self.emit_expr(default);
let span_id = self.ctx.register_span(span);
self.emit_op(Op::SelectDefault);
self.emit_u16(attrpath.len() as u16);
self.emit_u32(span_id);
} else {
let span_id = self.ctx.register_span(span);
self.emit_op(Op::Select);
self.emit_u16(attrpath.len() as u16);
self.emit_u32(span_id);
}
for attr in attrpath.iter() {
match *attr {
Attr::Str(sym, _) => {
self.emit_u8(AttrKeyType::Static as u8);
let span_id = self.ctx.register_span(span);
self.emit_op(Op::SelectStatic);
self.emit_u32(span_id);
self.emit_str_id(sym);
}
Attr::Dynamic(_, _) => {
self.emit_u8(AttrKeyType::Dynamic as u8);
Attr::Dynamic(key_expr, _) => {
self.emit_expr(key_expr);
let span_id = self.ctx.register_span(span);
self.emit_op(Op::SelectDynamic);
self.emit_u32(span_id);
}
}
}
if let Some(default) = default {
self.emit_op(Op::JumpIfSelectSucceeded);
let placeholder = self.emit_i32_placeholder();
let before: i32 = self.ctx.get_code().len().try_into().unwrap();
self.emit_expr(default);
let after: i32 = self.ctx.get_code().len().try_into().unwrap();
self.patch_i32(placeholder, after - before);
}
}
fn emit_has_attr(&mut self, lhs: RawIrRef<'_>, rhs: &[Attr<RawIrRef<'_>>]) {