fix: 添加标签表索引校验
This commit is contained in:
@@ -93,6 +93,13 @@ impl CompileCtx {
|
|||||||
idx as u16
|
idx as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn resolve_label(&self, label: Label) -> Result<usize, String> {
|
||||||
|
self.label_map
|
||||||
|
.get(&label)
|
||||||
|
.copied()
|
||||||
|
.ok_or_else(|| format!("Label {:?} not found in bytecode map", label))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn push_scope(&mut self) {
|
pub(crate) fn push_scope(&mut self) {
|
||||||
self.symbols.push_scope();
|
self.symbols.push_scope();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ impl Compiler {
|
|||||||
|
|
||||||
let test_reg = self.emit_expression(&ifs.test, ctx)?;
|
let test_reg = self.emit_expression(&ifs.test, ctx)?;
|
||||||
|
|
||||||
let else_pos = ctx.label_map[&else_label];
|
let else_pos = ctx.resolve_label(else_label)?;
|
||||||
let offset = (else_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (else_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ impl Compiler {
|
|||||||
|
|
||||||
let has_alt = ifs.alternate.is_some();
|
let has_alt = ifs.alternate.is_some();
|
||||||
if has_alt {
|
if has_alt {
|
||||||
let end_pos = ctx.label_map[&end_label];
|
let end_pos = ctx.resolve_label(end_label)?;
|
||||||
let offset = (end_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (end_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp(offset as i16));
|
ctx.emit(opcode::encode_jmp(offset as i16));
|
||||||
}
|
}
|
||||||
@@ -126,13 +126,13 @@ impl Compiler {
|
|||||||
|
|
||||||
let test_reg = self.emit_expression(&wh.test, ctx)?;
|
let test_reg = self.emit_expression(&wh.test, ctx)?;
|
||||||
|
|
||||||
let end_pos = ctx.label_map[&end_label];
|
let end_pos = ctx.resolve_label(end_label)?;
|
||||||
let offset = (end_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (end_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
||||||
|
|
||||||
self.emit_statement(&wh.body, ctx)?;
|
self.emit_statement(&wh.body, ctx)?;
|
||||||
|
|
||||||
let start_pos = ctx.label_map[&start_label];
|
let start_pos = ctx.resolve_label(start_label)?;
|
||||||
let offset = (start_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (start_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp(offset as i16));
|
ctx.emit(opcode::encode_jmp(offset as i16));
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ impl Compiler {
|
|||||||
|
|
||||||
if let Some(test) = &fr.test {
|
if let Some(test) = &fr.test {
|
||||||
let test_reg = self.emit_expression(test, ctx)?;
|
let test_reg = self.emit_expression(test, ctx)?;
|
||||||
let end_pos = ctx.label_map[&end_label];
|
let end_pos = ctx.resolve_label(end_label)?;
|
||||||
let offset = (end_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (end_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ impl Compiler {
|
|||||||
self.emit_expression(update, ctx)?;
|
self.emit_expression(update, ctx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let start_pos = ctx.label_map[&start_label];
|
let start_pos = ctx.resolve_label(start_label)?;
|
||||||
let offset = (start_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (start_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp(offset as i16));
|
ctx.emit(opcode::encode_jmp(offset as i16));
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ impl Compiler {
|
|||||||
Statement::BreakStatement(_) => {
|
Statement::BreakStatement(_) => {
|
||||||
let (break_label, _) =
|
let (break_label, _) =
|
||||||
ctx.current_loop().ok_or("break outside loop".to_string())?;
|
ctx.current_loop().ok_or("break outside loop".to_string())?;
|
||||||
let break_pos = ctx.label_map[break_label];
|
let break_pos = ctx.resolve_label(*break_label)?;
|
||||||
let offset = (break_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (break_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp(offset as i16));
|
ctx.emit(opcode::encode_jmp(offset as i16));
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -202,7 +202,7 @@ impl Compiler {
|
|||||||
let (_, continue_label) = ctx
|
let (_, continue_label) = ctx
|
||||||
.current_loop()
|
.current_loop()
|
||||||
.ok_or("continue outside loop".to_string())?;
|
.ok_or("continue outside loop".to_string())?;
|
||||||
let continue_pos = ctx.label_map[continue_label];
|
let continue_pos = ctx.resolve_label(*continue_label)?;
|
||||||
let offset = (continue_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (continue_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp(offset as i16));
|
ctx.emit(opcode::encode_jmp(offset as i16));
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -319,8 +319,8 @@ impl Compiler {
|
|||||||
let end_label = Label::TernaryEnd(id);
|
let end_label = Label::TernaryEnd(id);
|
||||||
|
|
||||||
let test_reg = self.emit_expression(&cond.test, ctx)?;
|
let test_reg = self.emit_expression(&cond.test, ctx)?;
|
||||||
let else_pos = ctx.label_map[&else_label];
|
let else_pos = ctx.resolve_label(else_label)?;
|
||||||
let end_pos = ctx.label_map[&end_label];
|
let end_pos = ctx.resolve_label(end_label)?;
|
||||||
|
|
||||||
let offset = (else_pos as isize) - (ctx.bytecode.len() as isize);
|
let offset = (else_pos as isize) - (ctx.bytecode.len() as isize);
|
||||||
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
ctx.emit(opcode::encode_jmp_if_false(test_reg, offset as i16));
|
||||||
@@ -362,7 +362,7 @@ impl Compiler {
|
|||||||
return Err("nullish coalescing not supported".into());
|
return Err("nullish coalescing not supported".into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let skip_pos = ctx.label_map[&skip_label];
|
let skip_pos = ctx.resolve_label(skip_label)?;
|
||||||
|
|
||||||
let dup_reg = ctx.alloc_reg();
|
let dup_reg = ctx.alloc_reg();
|
||||||
ctx.emit(opcode::encode(OpCode::LOAD_VAR, dup_reg, left_reg, 0));
|
ctx.emit(opcode::encode(OpCode::LOAD_VAR, dup_reg, left_reg, 0));
|
||||||
|
|||||||
Reference in New Issue
Block a user