Make Instruction only 8 bytes

This commit is contained in:
Noah 2020-12-14 15:55:47 -06:00
parent 1575382577
commit b9875ff9bf

View file

@ -76,8 +76,8 @@ impl CodeInfo {
// this is a little bit hacky, as until now the data stored inside Labels in // this is a little bit hacky, as until now the data stored inside Labels in
// Instructions is just bookkeeping, but I think it's the best way to do this // Instructions is just bookkeeping, but I think it's the best way to do this
if let Some(l) = instruction.label_arg_mut() { if let Some(l) = instruction.label_arg_mut() {
let real_label = label_map[l.0]; let real_label = label_map[l.0 as usize];
debug_assert!(real_label.0 != usize::MAX, "label wasn't set"); debug_assert!(real_label.0 != u32::MAX, "label wasn't set");
*l = real_label; *l = real_label;
} }
} }
@ -303,7 +303,7 @@ impl Compiler {
let cache = cache(self.current_codeinfo()); let cache = cache(self.current_codeinfo());
cache cache
.get_index_of(name) .get_index_of(name)
.unwrap_or_else(|| cache.insert_full(name.to_owned()).0) .unwrap_or_else(|| cache.insert_full(name.to_owned()).0) as u32
} }
fn compile_program( fn compile_program(
@ -470,7 +470,7 @@ impl Compiler {
NameUsage::Delete => Instruction::DeleteLocal, NameUsage::Delete => Instruction::DeleteLocal,
}, },
}; };
self.emit(op(idx)); self.emit(op(idx as u32));
} }
fn compile_statement(&mut self, statement: &ast::Statement) -> CompileResult<()> { fn compile_statement(&mut self, statement: &ast::Statement) -> CompileResult<()> {
@ -665,23 +665,22 @@ impl Compiler {
body, body,
orelse, orelse,
} => self.compile_for(target, iter, body, orelse, *is_async)?, } => self.compile_for(target, iter, body, orelse, *is_async)?,
Raise { exception, cause } => match exception { Raise { exception, cause } => {
Some(value) => { let kind = match exception {
self.compile_expression(value)?; Some(value) => {
match cause { self.compile_expression(value)?;
Some(cause) => { match cause {
self.compile_expression(cause)?; Some(cause) => {
self.emit(Instruction::Raise { argc: 2 }); self.compile_expression(cause)?;
} bytecode::RaiseKind::RaiseCause
None => { }
self.emit(Instruction::Raise { argc: 1 }); None => bytecode::RaiseKind::Raise,
} }
} }
} None => bytecode::RaiseKind::Reraise,
None => { };
self.emit(Instruction::Raise { argc: 0 }); self.emit(Instruction::Raise { kind });
} }
},
Try { Try {
body, body,
handlers, handlers,
@ -721,7 +720,9 @@ impl Compiler {
self.emit(Instruction::CallFunctionPositional { nargs: 0 }); self.emit(Instruction::CallFunctionPositional { nargs: 0 });
} }
} }
self.emit(Instruction::Raise { argc: 1 }); self.emit(Instruction::Raise {
kind: bytecode::RaiseKind::Raise,
});
self.set_label(end_label); self.set_label(end_label);
} }
} }
@ -835,7 +836,7 @@ impl Compiler {
let have_defaults = !args.defaults.is_empty(); let have_defaults = !args.defaults.is_empty();
if have_defaults { if have_defaults {
// Construct a tuple: // Construct a tuple:
let size = args.defaults.len(); let size = args.defaults.len() as u32;
for element in &args.defaults { for element in &args.defaults {
self.compile_expression(element)?; self.compile_expression(element)?;
} }
@ -1003,7 +1004,9 @@ impl Compiler {
self.set_label(handler_label); self.set_label(handler_label);
// If code flows here, we have an unhandled exception, // If code flows here, we have an unhandled exception,
// raise the exception again! // raise the exception again!
self.emit(Instruction::Raise { argc: 0 }); self.emit(Instruction::Raise {
kind: bytecode::RaiseKind::Reraise,
});
// We successfully ran the try block: // We successfully ran the try block:
// else: // else:
@ -1177,10 +1180,10 @@ impl Compiler {
if let SymbolScope::Free = symbol.scope { if let SymbolScope::Free = symbol.scope {
idx += parent_code.cellvar_cache.len(); idx += parent_code.cellvar_cache.len();
} }
self.emit(Instruction::LoadClosure(idx)) self.emit(Instruction::LoadClosure(idx as u32))
} }
self.emit(Instruction::BuildTuple { self.emit(Instruction::BuildTuple {
size: code.freevars.len(), size: code.freevars.len() as u32,
unpack: false, unpack: false,
}); });
true true
@ -1305,7 +1308,7 @@ impl Compiler {
.position(|var| *var == "__class__"); .position(|var| *var == "__class__");
if let Some(classcell_idx) = classcell_idx { if let Some(classcell_idx) = classcell_idx {
self.emit(Instruction::LoadClosure(classcell_idx)); self.emit(Instruction::LoadClosure(classcell_idx as u32));
self.emit(Instruction::Duplicate); self.emit(Instruction::Duplicate);
let classcell = self.name("__classcell__"); let classcell = self.name("__classcell__");
self.emit(Instruction::StoreLocal(classcell)); self.emit(Instruction::StoreLocal(classcell));
@ -1362,11 +1365,11 @@ impl Compiler {
elements: kwarg_names, elements: kwarg_names,
}); });
self.emit(Instruction::CallFunctionKeyword { self.emit(Instruction::CallFunctionKeyword {
nargs: 2 + keywords.len() + bases.len(), nargs: (2 + keywords.len() + bases.len()) as u32,
}); });
} else { } else {
self.emit(Instruction::CallFunctionPositional { self.emit(Instruction::CallFunctionPositional {
nargs: 2 + bases.len(), nargs: (2 + bases.len()) as u32,
}); });
} }
@ -1461,7 +1464,9 @@ impl Compiler {
op: bytecode::ComparisonOperator::ExceptionMatch, op: bytecode::ComparisonOperator::ExceptionMatch,
}); });
self.emit(Instruction::JumpIfTrue { target: else_label }); self.emit(Instruction::JumpIfTrue { target: else_label });
self.emit(Instruction::Raise { argc: 0 }); self.emit(Instruction::Raise {
kind: bytecode::RaiseKind::Reraise,
});
let was_in_loop = self.ctx.loop_data; let was_in_loop = self.ctx.loop_data;
self.ctx.loop_data = Some((start_label, end_label)); self.ctx.loop_data = Some((start_label, end_label));
@ -1649,7 +1654,7 @@ impl Compiler {
if !seen_star { if !seen_star {
self.emit(Instruction::UnpackSequence { self.emit(Instruction::UnpackSequence {
size: elements.len(), size: elements.len() as u32,
}); });
} }
@ -1917,7 +1922,7 @@ impl Compiler {
self.emit_constant(const_value); self.emit_constant(const_value);
} }
List { elements } => { List { elements } => {
let size = elements.len(); let size = elements.len() as u32;
let must_unpack = self.gather_elements(elements)?; let must_unpack = self.gather_elements(elements)?;
self.emit(Instruction::BuildList { self.emit(Instruction::BuildList {
size, size,
@ -1925,7 +1930,7 @@ impl Compiler {
}); });
} }
Tuple { elements } => { Tuple { elements } => {
let size = elements.len(); let size = elements.len() as u32;
let must_unpack = self.gather_elements(elements)?; let must_unpack = self.gather_elements(elements)?;
self.emit(Instruction::BuildTuple { self.emit(Instruction::BuildTuple {
size, size,
@ -1933,7 +1938,7 @@ impl Compiler {
}); });
} }
Set { elements } => { Set { elements } => {
let size = elements.len(); let size = elements.len() as u32;
let must_unpack = self.gather_elements(elements)?; let must_unpack = self.gather_elements(elements)?;
self.emit(Instruction::BuildSet { self.emit(Instruction::BuildSet {
size, size,
@ -1944,11 +1949,11 @@ impl Compiler {
self.compile_dict(elements)?; self.compile_dict(elements)?;
} }
Slice { elements } => { Slice { elements } => {
let size = elements.len(); let step = elements.len() >= 3;
for element in elements { for element in elements {
self.compile_expression(element)?; self.compile_expression(element)?;
} }
self.emit(Instruction::BuildSlice { size }); self.emit(Instruction::BuildSlice { step });
} }
Yield { value } => { Yield { value } => {
if !self.ctx.in_func() { if !self.ctx.in_func() {
@ -2107,7 +2112,7 @@ impl Compiler {
keywords: &[ast::Keyword], keywords: &[ast::Keyword],
) -> CompileResult<()> { ) -> CompileResult<()> {
self.compile_expression(function)?; self.compile_expression(function)?;
let count = args.len() + keywords.len(); let count = (args.len() + keywords.len()) as u32;
// Normal arguments: // Normal arguments:
let must_unpack = self.gather_elements(args)?; let must_unpack = self.gather_elements(args)?;
@ -2116,7 +2121,7 @@ impl Compiler {
if must_unpack || has_double_star { if must_unpack || has_double_star {
// Create a tuple with positional args: // Create a tuple with positional args:
self.emit(Instruction::BuildTuple { self.emit(Instruction::BuildTuple {
size: args.len(), size: args.len() as u32,
unpack: must_unpack, unpack: must_unpack,
}); });
@ -2295,13 +2300,13 @@ impl Compiler {
ast::ComprehensionKind::List { element } => { ast::ComprehensionKind::List { element } => {
compile_element(element)?; compile_element(element)?;
self.emit(Instruction::ListAppend { self.emit(Instruction::ListAppend {
i: 1 + generators.len(), i: (1 + generators.len()) as u32,
}); });
} }
ast::ComprehensionKind::Set { element } => { ast::ComprehensionKind::Set { element } => {
compile_element(element)?; compile_element(element)?;
self.emit(Instruction::SetAdd { self.emit(Instruction::SetAdd {
i: 1 + generators.len(), i: (1 + generators.len()) as u32,
}); });
} }
ast::ComprehensionKind::Dict { key, value } => { ast::ComprehensionKind::Dict { key, value } => {
@ -2310,7 +2315,7 @@ impl Compiler {
self.compile_expression(value)?; self.compile_expression(value)?;
self.emit(Instruction::MapAddRev { self.emit(Instruction::MapAddRev {
i: 1 + generators.len(), i: (1 + generators.len()) as u32,
}); });
} }
} }
@ -2370,7 +2375,9 @@ impl Compiler {
for value in values { for value in values {
self.compile_string(value)?; self.compile_string(value)?;
} }
self.emit(Instruction::BuildString { size: values.len() }) self.emit(Instruction::BuildString {
size: values.len() as u32,
})
} }
ast::StringGroup::Constant { value } => { ast::StringGroup::Constant { value } => {
self.emit_constant(ConstantData::Str { self.emit_constant(ConstantData::Str {
@ -2390,7 +2397,7 @@ impl Compiler {
}; };
self.compile_expression(value)?; self.compile_expression(value)?;
self.emit(Instruction::FormatValue { self.emit(Instruction::FormatValue {
conversion: conversion.map(compile_conversion_flag), conversion: compile_conversion_flag(*conversion),
}); });
} }
} }
@ -2431,7 +2438,7 @@ impl Compiler {
fn emit_constant(&mut self, constant: ConstantData) { fn emit_constant(&mut self, constant: ConstantData) {
let info = self.current_codeinfo(); let info = self.current_codeinfo();
let idx = info.constants.len(); let idx = info.constants.len() as u32;
info.constants.push(constant); info.constants.push(constant);
self.emit(Instruction::LoadConst { idx }) self.emit(Instruction::LoadConst { idx })
} }
@ -2447,8 +2454,8 @@ impl Compiler {
// Generate a new label // Generate a new label
fn new_label(&mut self) -> Label { fn new_label(&mut self) -> Label {
let label_map = &mut self.current_codeinfo().label_map; let label_map = &mut self.current_codeinfo().label_map;
let label = Label(label_map.len()); let label = Label(label_map.len() as u32);
label_map.push(Label(usize::MAX)); label_map.push(Label(u32::MAX));
label label
} }
@ -2459,10 +2466,10 @@ impl Compiler {
label_map, label_map,
.. ..
} = self.current_codeinfo(); } = self.current_codeinfo();
let actual_label = Label(instructions.len()); let actual_label = Label(instructions.len() as u32);
let prev_val = std::mem::replace(&mut label_map[label.0], actual_label); let prev_val = std::mem::replace(&mut label_map[label.0 as usize], actual_label);
debug_assert!( debug_assert!(
prev_val.0 == usize::MAX || prev_val == actual_label, prev_val.0 == u32::MAX || prev_val == actual_label,
"double-set a label" "double-set a label"
); );
} }
@ -2526,11 +2533,14 @@ fn compile_location(location: &ast::Location) -> bytecode::Location {
bytecode::Location::new(location.row(), location.column()) bytecode::Location::new(location.row(), location.column())
} }
fn compile_conversion_flag(conversion_flag: ast::ConversionFlag) -> bytecode::ConversionFlag { fn compile_conversion_flag(
conversion_flag: Option<ast::ConversionFlag>,
) -> bytecode::ConversionFlag {
match conversion_flag { match conversion_flag {
ast::ConversionFlag::Ascii => bytecode::ConversionFlag::Ascii, None => bytecode::ConversionFlag::None,
ast::ConversionFlag::Repr => bytecode::ConversionFlag::Repr, Some(ast::ConversionFlag::Ascii) => bytecode::ConversionFlag::Ascii,
ast::ConversionFlag::Str => bytecode::ConversionFlag::Str, Some(ast::ConversionFlag::Repr) => bytecode::ConversionFlag::Repr,
Some(ast::ConversionFlag::Str) => bytecode::ConversionFlag::Str,
} }
} }