Make Instruction only 8 bytes

This commit is contained in:
Noah committed 2020-12-14 15:55:47 -06:00
1 parent e87144e2c5
commit 1be79c93b0
5 files changed
+193 -176

No files matched your search

+58 -46
View File
@@ -143,7 +143,7 @@ impl CodeFlags {
#[repr(transparent)]
// XXX: if you add a new instruction that stores a Label, make sure to add it in
// Instruction::label_arg{,_mut}
pub struct Label(pub usize);
pub struct Label(pub u32);
impl fmt::Display for Label {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
@@ -153,6 +153,8 @@ impl fmt::Display for Label {
/// Transforms a value prior to formatting it.
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ConversionFlag {
/// No conversion
None,
/// Converts by calling `str(<value>)`.
Str,
/// Converts by calling `ascii(<value>)`.
@@ -161,7 +163,14 @@ pub enum ConversionFlag {
Repr,
}
pub type NameIdx = usize;
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum RaiseKind {
Reraise,
Raise,
RaiseCause,
}
pub type NameIdx = u32;
/// A Single bytecode instruction.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -199,7 +208,7 @@ pub enum Instruction {
},
LoadConst {
/// index into constants vec
idx: usize,
idx: u32,
},
UnaryOperation {
op: UnaryOperator,
@@ -218,7 +227,7 @@ pub enum Instruction {
},
Pop,
Rotate {
amount: usize,
amount: u32,
},
Duplicate,
GetIter,
@@ -249,10 +258,10 @@ pub enum Instruction {
},
MakeFunction(MakeFunctionFlags),
CallFunctionPositional {
nargs: usize,
nargs: u32,
},
CallFunctionKeyword {
nargs: usize,
nargs: u32,
},
CallFunctionEx {
has_kwargs: bool,
@@ -297,56 +306,57 @@ pub enum Instruction {
WithCleanupFinish,
PopBlock,
Raise {
argc: usize,
kind: RaiseKind,
},
BuildString {
size: usize,
size: u32,
},
BuildTuple {
size: usize,
unpack: bool,
size: u32,
},
BuildList {
size: usize,
unpack: bool,
size: u32,
},
BuildSet {
size: usize,
unpack: bool,
size: u32,
},
BuildMap {
size: usize,
unpack: bool,
for_call: bool,
size: u32,
},
BuildSlice {
size: usize,
/// whether build a slice with a third step argument
step: bool,
},
ListAppend {
i: usize,
i: u32,
},
SetAdd {
i: usize,
i: u32,
},
MapAdd {
i: usize,
i: u32,
},
PrintExpr,
LoadBuildClass,
UnpackSequence {
size: usize,
size: u32,
},
UnpackEx {
before: u8,
after: u8,
},
FormatValue {
conversion: Option<ConversionFlag>,
conversion: ConversionFlag,
},
PopException,
Reverse {
amount: usize,
amount: u32,
},
GetAwaitable,
BeforeAsyncWith,
@@ -360,7 +370,7 @@ pub enum Instruction {
/// required to support named expressions of Python 3.8 in dict comprehension
/// today (including Py3.9) only required in dict comprehension.
MapAddRev {
i: usize,
i: u32,
},
}
@@ -612,7 +622,7 @@ impl<C: Constant> CodeObject<C> {
let label_targets = self.label_targets();
for (offset, instruction) in self.instructions.iter().enumerate() {
let arrow = if label_targets.contains(&Label(offset)) {
let arrow = if label_targets.contains(&Label(offset as u32)) {
">>"
} else {
" "
@@ -819,39 +829,41 @@ impl Instruction {
};
}
let cellname = |i: usize| {
let varname = |i: u32| varnames[i as usize].as_ref();
let name = |i: u32| names[i as usize].as_ref();
let cellname = |i: u32| {
cellvars
.get(i)
.unwrap_or_else(|| &freevars[i - cellvars.len()])
.get(i as usize)
.unwrap_or_else(|| &freevars[i as usize - cellvars.len()])
.as_ref()
};
match self {
ImportName { idx } => w!(ImportName, names[*idx].as_ref()),
ImportName { idx } => w!(ImportName, name(*idx)),
ImportNameless => w!(ImportNameless),
ImportStar => w!(ImportStar),
ImportFrom { idx } => w!(ImportFrom, names[*idx].as_ref()),
LoadFast(idx) => w!(LoadFast, *idx, varnames[*idx].as_ref()),
LoadNameAny(idx) => w!(LoadNameAny, *idx, names[*idx].as_ref()),
LoadGlobal(idx) => w!(LoadGlobal, *idx, names[*idx].as_ref()),
ImportFrom { idx } => w!(ImportFrom, name(*idx)),
LoadFast(idx) => w!(LoadFast, *idx, varname(*idx)),
LoadNameAny(idx) => w!(LoadNameAny, *idx, name(*idx)),
LoadGlobal(idx) => w!(LoadGlobal, *idx, name(*idx)),
LoadDeref(idx) => w!(LoadDeref, *idx, cellname(*idx)),
LoadClassDeref(idx) => w!(LoadClassDeref, *idx, cellname(*idx)),
StoreFast(idx) => w!(StoreFast, *idx, varnames[*idx].as_ref()),
StoreLocal(idx) => w!(StoreLocal, *idx, names[*idx].as_ref()),
StoreGlobal(idx) => w!(StoreGlobal, *idx, names[*idx].as_ref()),
StoreFast(idx) => w!(StoreFast, *idx, varname(*idx)),
StoreLocal(idx) => w!(StoreLocal, *idx, name(*idx)),
StoreGlobal(idx) => w!(StoreGlobal, *idx, name(*idx)),
StoreDeref(idx) => w!(StoreDeref, *idx, cellname(*idx)),
DeleteFast(idx) => w!(DeleteFast, *idx, varnames[*idx].as_ref()),
DeleteLocal(idx) => w!(DeleteLocal, *idx, names[*idx].as_ref()),
DeleteGlobal(idx) => w!(DeleteGlobal, *idx, names[*idx].as_ref()),
DeleteFast(idx) => w!(DeleteFast, *idx, varname(*idx)),
DeleteLocal(idx) => w!(DeleteLocal, *idx, name(*idx)),
DeleteGlobal(idx) => w!(DeleteGlobal, *idx, name(*idx)),
DeleteDeref(idx) => w!(DeleteDeref, *idx, cellname(*idx)),
LoadClosure(i) => w!(LoadClosure, *i, cellname(*i)),
Subscript => w!(Subscript),
StoreSubscript => w!(StoreSubscript),
DeleteSubscript => w!(DeleteSubscript),
StoreAttr { idx } => w!(StoreAttr, names[*idx].as_ref()),
DeleteAttr { idx } => w!(DeleteAttr, names[*idx].as_ref()),
StoreAttr { idx } => w!(StoreAttr, name(*idx)),
DeleteAttr { idx } => w!(DeleteAttr, name(*idx)),
LoadConst { idx } => {
let value = &constants[*idx];
let value = &constants[*idx as usize];
match value.borrow_constant() {
BorrowedConstant::Code { code } if expand_codeobjects => {
writeln!(f, "{:20} ({:?}):", "LoadConst", code)?;
@@ -865,13 +877,13 @@ impl Instruction {
}
}
}
UnaryOperation { op } => w!(UnaryOperation, format!("{:?}", op)),
BinaryOperation { op } => w!(BinaryOperation, format!("{:?}", op)),
UnaryOperation { op } => w!(UnaryOperation, format_args!("{:?}", op)),
BinaryOperation { op } => w!(BinaryOperation, format_args!("{:?}", op)),
BinaryOperationInplace { op } => {
w!(BinaryOperationInplace, format!("{:?}", op))
w!(BinaryOperationInplace, format_args!("{:?}", op))
}
LoadAttr { idx } => w!(LoadAttr, names[*idx].as_ref()),
CompareOperation { op } => w!(CompareOperation, format!("{:?}", op)),
LoadAttr { idx } => w!(LoadAttr, name(*idx)),
CompareOperation { op } => w!(CompareOperation, format_args!("{:?}", op)),
Pop => w!(Pop),
Rotate { amount } => w!(Rotate, amount),
Duplicate => w!(Duplicate),
@@ -903,7 +915,7 @@ impl Instruction {
BeforeAsyncWith => w!(BeforeAsyncWith),
SetupAsyncWith { end } => w!(SetupAsyncWith, end),
PopBlock => w!(PopBlock),
Raise { argc } => w!(Raise, argc),
Raise { kind } => w!(Raise, format_args!("{:?}", kind)),
BuildString { size } => w!(BuildString, size),
BuildTuple { size, unpack } => w!(BuildTuple, size, unpack),
BuildList { size, unpack } => w!(BuildList, size, unpack),
@@ -913,7 +925,7 @@ impl Instruction {
unpack,
for_call,
} => w!(BuildMap, size, unpack, for_call),
BuildSlice { size } => w!(BuildSlice, size),
BuildSlice { step } => w!(BuildSlice, step),
ListAppend { i } => w!(ListAppend, i),
SetAdd { i } => w!(SetAdd, i),
MapAddRev { i } => w!(MapAddRev, i),
@@ -921,7 +933,7 @@ impl Instruction {
LoadBuildClass => w!(LoadBuildClass),
UnpackSequence { size } => w!(UnpackSequence, size),
UnpackEx { before, after } => w!(UnpackEx, before, after),
FormatValue { .. } => w!(FormatValue), // TODO: write conversion
FormatValue { conversion } => w!(FormatValue, format_args!("{:?}", conversion)),
PopException => w!(PopException),
Reverse { amount } => w!(Reverse, amount),
GetAwaitable => w!(GetAwaitable),
+61 -51
View File
@@ -76,8 +76,8 @@ impl CodeInfo {
// 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
if let Some(l) = instruction.label_arg_mut() {
let real_label = label_map[l.0];
debug_assert!(real_label.0 != usize::MAX, "label wasn't set");
let real_label = label_map[l.0 as usize];
debug_assert!(real_label.0 != u32::MAX, "label wasn't set");
*l = real_label;
}
}
@@ -303,7 +303,7 @@ impl Compiler {
let cache = cache(self.current_codeinfo());
cache
.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(
@@ -470,7 +470,7 @@ impl Compiler {
NameUsage::Delete => Instruction::DeleteLocal,
},
};
self.emit(op(idx));
self.emit(op(idx as u32));
}
fn compile_statement(&mut self, statement: &ast::Statement) -> CompileResult<()> {
@@ -665,23 +665,22 @@ impl Compiler {
body,
orelse,
} => self.compile_for(target, iter, body, orelse, *is_async)?,
Raise { exception, cause } => match exception {
Some(value) => {
self.compile_expression(value)?;
match cause {
Some(cause) => {
self.compile_expression(cause)?;
self.emit(Instruction::Raise { argc: 2 });
}
None => {
self.emit(Instruction::Raise { argc: 1 });
Raise { exception, cause } => {
let kind = match exception {
Some(value) => {
self.compile_expression(value)?;
match cause {
Some(cause) => {
self.compile_expression(cause)?;
bytecode::RaiseKind::RaiseCause
}
None => bytecode::RaiseKind::Raise,
}
}
}
None => {
self.emit(Instruction::Raise { argc: 0 });
}
},
None => bytecode::RaiseKind::Reraise,
};
self.emit(Instruction::Raise { kind });
}
Try {
body,
handlers,
@@ -721,7 +720,9 @@ impl Compiler {
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);
}
}
@@ -835,7 +836,7 @@ impl Compiler {
let have_defaults = !args.defaults.is_empty();
if have_defaults {
// Construct a tuple:
let size = args.defaults.len();
let size = args.defaults.len() as u32;
for element in &args.defaults {
self.compile_expression(element)?;
}
@@ -1003,7 +1004,9 @@ impl Compiler {
self.set_label(handler_label);
// If code flows here, we have an unhandled exception,
// raise the exception again!
self.emit(Instruction::Raise { argc: 0 });
self.emit(Instruction::Raise {
kind: bytecode::RaiseKind::Reraise,
});
// We successfully ran the try block:
// else:
@@ -1177,10 +1180,10 @@ impl Compiler {
if let SymbolScope::Free = symbol.scope {
idx += parent_code.cellvar_cache.len();
}
self.emit(Instruction::LoadClosure(idx))
self.emit(Instruction::LoadClosure(idx as u32))
}
self.emit(Instruction::BuildTuple {
size: code.freevars.len(),
size: code.freevars.len() as u32,
unpack: false,
});
true
@@ -1305,7 +1308,7 @@ impl Compiler {
.position(|var| *var == "__class__");
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);
let classcell = self.name("__classcell__");
self.emit(Instruction::StoreLocal(classcell));
@@ -1362,11 +1365,11 @@ impl Compiler {
elements: kwarg_names,
});
self.emit(Instruction::CallFunctionKeyword {
nargs: 2 + keywords.len() + bases.len(),
nargs: (2 + keywords.len() + bases.len()) as u32,
});
} else {
self.emit(Instruction::CallFunctionPositional {
nargs: 2 + bases.len(),
nargs: (2 + bases.len()) as u32,
});
}
@@ -1461,7 +1464,9 @@ impl Compiler {
op: bytecode::ComparisonOperator::ExceptionMatch,
});
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;
self.ctx.loop_data = Some((start_label, end_label));
@@ -1649,7 +1654,7 @@ impl Compiler {
if !seen_star {
self.emit(Instruction::UnpackSequence {
size: elements.len(),
size: elements.len() as u32,
});
}
@@ -1917,7 +1922,7 @@ impl Compiler {
self.emit_constant(const_value);
}
List { elements } => {
let size = elements.len();
let size = elements.len() as u32;
let must_unpack = self.gather_elements(elements)?;
self.emit(Instruction::BuildList {
size,
@@ -1925,7 +1930,7 @@ impl Compiler {
});
}
Tuple { elements } => {
let size = elements.len();
let size = elements.len() as u32;
let must_unpack = self.gather_elements(elements)?;
self.emit(Instruction::BuildTuple {
size,
@@ -1933,7 +1938,7 @@ impl Compiler {
});
}
Set { elements } => {
let size = elements.len();
let size = elements.len() as u32;
let must_unpack = self.gather_elements(elements)?;
self.emit(Instruction::BuildSet {
size,
@@ -1944,11 +1949,11 @@ impl Compiler {
self.compile_dict(elements)?;
}
Slice { elements } => {
let size = elements.len();
let step = elements.len() >= 3;
for element in elements {
self.compile_expression(element)?;
}
self.emit(Instruction::BuildSlice { size });
self.emit(Instruction::BuildSlice { step });
}
Yield { value } => {
if !self.ctx.in_func() {
@@ -2107,7 +2112,7 @@ impl Compiler {
keywords: &[ast::Keyword],
) -> CompileResult<()> {
self.compile_expression(function)?;
let count = args.len() + keywords.len();
let count = (args.len() + keywords.len()) as u32;
// Normal arguments:
let must_unpack = self.gather_elements(args)?;
@@ -2116,7 +2121,7 @@ impl Compiler {
if must_unpack || has_double_star {
// Create a tuple with positional args:
self.emit(Instruction::BuildTuple {
size: args.len(),
size: args.len() as u32,
unpack: must_unpack,
});
@@ -2295,13 +2300,13 @@ impl Compiler {
ast::ComprehensionKind::List { element } => {
compile_element(element)?;
self.emit(Instruction::ListAppend {
i: 1 + generators.len(),
i: (1 + generators.len()) as u32,
});
}
ast::ComprehensionKind::Set { element } => {
compile_element(element)?;
self.emit(Instruction::SetAdd {
i: 1 + generators.len(),
i: (1 + generators.len()) as u32,
});
}
ast::ComprehensionKind::Dict { key, value } => {
@@ -2310,7 +2315,7 @@ impl Compiler {
self.compile_expression(value)?;
self.emit(Instruction::MapAddRev {
i: 1 + generators.len(),
i: (1 + generators.len()) as u32,
});
}
}
@@ -2370,7 +2375,9 @@ impl Compiler {
for value in values {
self.compile_string(value)?;
}
self.emit(Instruction::BuildString { size: values.len() })
self.emit(Instruction::BuildString {
size: values.len() as u32,
})
}
ast::StringGroup::Constant { value } => {
self.emit_constant(ConstantData::Str {
@@ -2390,7 +2397,7 @@ impl Compiler {
};
self.compile_expression(value)?;
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) {
let info = self.current_codeinfo();
let idx = info.constants.len();
let idx = info.constants.len() as u32;
info.constants.push(constant);
self.emit(Instruction::LoadConst { idx })
}
@@ -2447,8 +2454,8 @@ impl Compiler {
// Generate a new label
fn new_label(&mut self) -> Label {
let label_map = &mut self.current_codeinfo().label_map;
let label = Label(label_map.len());
label_map.push(Label(usize::MAX));
let label = Label(label_map.len() as u32);
label_map.push(Label(u32::MAX));
label
}
@@ -2459,10 +2466,10 @@ impl Compiler {
label_map,
..
} = self.current_codeinfo();
let actual_label = Label(instructions.len());
let prev_val = std::mem::replace(&mut label_map[label.0], actual_label);
let actual_label = Label(instructions.len() as u32);
let prev_val = std::mem::replace(&mut label_map[label.0 as usize], actual_label);
debug_assert!(
prev_val.0 == usize::MAX || prev_val == actual_label,
prev_val.0 == u32::MAX || prev_val == actual_label,
"double-set a label"
);
}
@@ -2526,11 +2533,14 @@ fn compile_location(location: &ast::Location) -> bytecode::Location {
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 {
ast::ConversionFlag::Ascii => bytecode::ConversionFlag::Ascii,
ast::ConversionFlag::Repr => bytecode::ConversionFlag::Repr,
ast::ConversionFlag::Str => bytecode::ConversionFlag::Str,
None => bytecode::ConversionFlag::None,
Some(ast::ConversionFlag::Ascii) => bytecode::ConversionFlag::Ascii,
Some(ast::ConversionFlag::Repr) => bytecode::ConversionFlag::Repr,
Some(ast::ConversionFlag::Str) => bytecode::ConversionFlag::Str,
}
}
+1 -1
View File
@@ -73,7 +73,7 @@ impl FrameRef {
}
#[pyproperty]
fn f_lasti(self) -> usize {
fn f_lasti(self) -> u32 {
self.lasti()
}
+3 -3
View File
@@ -8,7 +8,7 @@ use crate::vm::VirtualMachine;
pub struct PyTraceback {
pub next: Option<PyTracebackRef>, // TODO: Make mutable
pub frame: FrameRef,
pub lasti: usize,
pub lasti: u32,
pub lineno: usize,
}
@@ -22,7 +22,7 @@ impl PyValue for PyTraceback {
#[pyimpl]
impl PyTraceback {
pub fn new(next: Option<PyRef<Self>>, frame: FrameRef, lasti: usize, lineno: usize) -> Self {
pub fn new(next: Option<PyRef<Self>>, frame: FrameRef, lasti: u32, lineno: usize) -> Self {
PyTraceback {
next,
frame,
@@ -37,7 +37,7 @@ impl PyTraceback {
}
#[pyproperty(name = "tb_lasti")]
fn lasti(&self) -> usize {
fn lasti(&self) -> u32 {
self.lasti
}
+70 -75
View File
@@ -1,5 +1,5 @@
use std::fmt;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::atomic::{AtomicU32, Ordering};
use indexmap::IndexMap;
use itertools::Itertools;
@@ -99,7 +99,7 @@ pub struct Frame {
pub builtins: PyDictRef,
/// index of last instruction ran
pub lasti: AtomicUsize,
pub lasti: AtomicU32,
/// tracer function for this frame (usually is None)
pub trace: PyMutex<PyObjectRef>,
state: PyMutex<FrameState>,
@@ -186,7 +186,7 @@ impl Frame {
globals: scope.globals,
builtins,
code,
lasti: AtomicUsize::new(0),
lasti: AtomicU32::new(0),
state: PyMutex::new(FrameState {
stack: Vec::new(),
blocks: Vec::new(),
@@ -283,14 +283,14 @@ impl FrameRef {
}
pub fn current_location(&self) -> bytecode::Location {
self.code.locations[self.lasti.load(Ordering::Relaxed) - 1]
self.code.locations[self.lasti.load(Ordering::Relaxed) as usize - 1]
}
pub fn yield_from_target(&self) -> Option<PyObjectRef> {
self.with_exec(|exec| exec.yield_from_target())
}
pub fn lasti(&self) -> usize {
pub fn lasti(&self) -> u32 {
self.lasti.load(Ordering::Relaxed)
}
}
@@ -305,7 +305,7 @@ struct ExecutingFrame<'a> {
globals: &'a PyDictRef,
builtins: &'a PyDictRef,
object: &'a FrameRef,
lasti: &'a AtomicUsize,
lasti: &'a AtomicU32,
state: &'a mut FrameState,
}
@@ -325,7 +325,7 @@ impl ExecutingFrame<'_> {
flame_guard!(format!("Frame::run({})", self.code.obj_name));
// Execute until return or exception:
loop {
let idx = self.lasti.fetch_add(1, Ordering::Relaxed);
let idx = self.lasti.fetch_add(1, Ordering::Relaxed) as usize;
let instr = &self.code.instructions[idx];
let result = self.execute_instruction(instr, vm);
match result {
@@ -365,7 +365,9 @@ impl ExecutingFrame<'_> {
}
fn yield_from_target(&self) -> Option<PyObjectRef> {
if let Some(bytecode::Instruction::YieldFrom) = self.code.instructions.get(self.lasti()) {
if let Some(bytecode::Instruction::YieldFrom) =
self.code.instructions.get(self.lasti() as usize)
{
Some(self.last_value())
} else {
None
@@ -442,22 +444,23 @@ impl ExecutingFrame<'_> {
match instruction {
bytecode::Instruction::LoadConst { idx } => {
self.push_value(self.code.constants[*idx].0.clone());
self.push_value(self.code.constants[*idx as usize].0.clone());
Ok(None)
}
bytecode::Instruction::ImportName { idx } => {
self.import(vm, Some(self.code.names[*idx].clone()))
self.import(vm, Some(self.code.names[*idx as usize].clone()))
}
bytecode::Instruction::ImportNameless => self.import(vm, None),
bytecode::Instruction::ImportStar => self.import_star(vm),
bytecode::Instruction::ImportFrom { idx } => self.import_from(vm, *idx),
bytecode::Instruction::LoadFast(idx) => {
let x = self.fastlocals.lock()[*idx].clone().ok_or_else(|| {
let idx = *idx as usize;
let x = self.fastlocals.lock()[idx].clone().ok_or_else(|| {
vm.new_exception_msg(
vm.ctx.exceptions.unbound_local_error.clone(),
format!(
"local variable '{}' referenced before assignment",
self.code.varnames[*idx]
self.code.varnames[idx]
),
)
})?;
@@ -465,7 +468,7 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::LoadNameAny(idx) => {
let name = &self.code.names[*idx];
let name = &self.code.names[*idx as usize];
let x = self.locals.get_item_option(name.clone(), vm)?;
let x = match x {
Some(x) => x,
@@ -475,13 +478,13 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::LoadGlobal(idx) => {
let name = &self.code.names[*idx];
let name = &self.code.names[*idx as usize];
let x = self.load_global_or_builtin(name, vm)?;
self.push_value(x);
Ok(None)
}
bytecode::Instruction::LoadDeref(i) => {
let i = *i;
let i = *i as usize;
let x = self.cells_frees[i]
.get()
.ok_or_else(|| self.unbound_cell_exception(i, vm))?;
@@ -489,7 +492,7 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::LoadClassDeref(i) => {
let i = *i;
let i = *i as usize;
let name = self.code.freevars[i - self.code.cellvars.len()].clone();
let value = if let Some(value) = self.locals.get_item_option(name, vm)? {
value
@@ -503,32 +506,32 @@ impl ExecutingFrame<'_> {
}
bytecode::Instruction::StoreFast(idx) => {
let value = self.pop_value();
self.fastlocals.lock()[*idx] = Some(value);
self.fastlocals.lock()[*idx as usize] = Some(value);
Ok(None)
}
bytecode::Instruction::StoreLocal(idx) => {
let value = self.pop_value();
self.locals
.set_item(self.code.names[*idx].clone(), value, vm)?;
.set_item(self.code.names[*idx as usize].clone(), value, vm)?;
Ok(None)
}
bytecode::Instruction::StoreGlobal(idx) => {
let value = self.pop_value();
self.globals
.set_item(self.code.names[*idx].clone(), value, vm)?;
.set_item(self.code.names[*idx as usize].clone(), value, vm)?;
Ok(None)
}
bytecode::Instruction::StoreDeref(i) => {
let value = self.pop_value();
self.cells_frees[*i].set(Some(value));
self.cells_frees[*i as usize].set(Some(value));
Ok(None)
}
bytecode::Instruction::DeleteFast(idx) => {
self.fastlocals.lock()[*idx] = None;
self.fastlocals.lock()[*idx as usize] = None;
Ok(None)
}
bytecode::Instruction::DeleteLocal(idx) => {
let name = &self.code.names[*idx];
let name = &self.code.names[*idx as usize];
match self.locals.del_item(name.clone(), vm) {
Ok(()) => {}
Err(e) if e.isinstance(&vm.ctx.exceptions.key_error) => {
@@ -539,7 +542,7 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::DeleteGlobal(idx) => {
let name = &self.code.names[*idx];
let name = &self.code.names[*idx as usize];
match self.globals.del_item(name.clone(), vm) {
Ok(()) => {}
Err(e) if e.isinstance(&vm.ctx.exceptions.key_error) => {
@@ -550,11 +553,11 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::DeleteDeref(i) => {
self.cells_frees[*i].set(None);
self.cells_frees[*i as usize].set(None);
Ok(None)
}
bytecode::Instruction::LoadClosure(i) => {
let value = self.cells_frees[*i].clone();
let value = self.cells_frees[*i as usize].clone();
self.push_value(value.into_object());
Ok(None)
}
@@ -576,7 +579,7 @@ impl ExecutingFrame<'_> {
bytecode::Instruction::Rotate { amount } => self.execute_rotate(*amount),
bytecode::Instruction::BuildString { size } => {
let s = self
.pop_multiple(*size)
.pop_multiple(*size as usize)
.as_slice()
.iter()
.map(|pyobj| pystr::borrow_value(&pyobj))
@@ -586,7 +589,7 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::BuildList { size, unpack } => {
let elements = self.get_elements(vm, *size, *unpack)?;
let elements = self.get_elements(vm, *size as usize, *unpack)?;
let list_obj = vm.ctx.new_list(elements);
self.push_value(list_obj);
Ok(None)
@@ -594,7 +597,7 @@ impl ExecutingFrame<'_> {
bytecode::Instruction::BuildSet { size, unpack } => {
let set = vm.ctx.new_set();
{
let elements = self.pop_multiple(*size);
let elements = self.pop_multiple(*size as usize);
if *unpack {
for element in elements {
vm.map_iterable_object(&element, |x| set.add(x, vm))??;
@@ -609,7 +612,7 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::BuildTuple { size, unpack } => {
let elements = self.get_elements(vm, *size, *unpack)?;
let elements = self.get_elements(vm, *size as usize, *unpack)?;
let list_obj = vm.ctx.new_tuple(elements);
self.push_value(list_obj);
Ok(None)
@@ -619,7 +622,7 @@ impl ExecutingFrame<'_> {
unpack,
for_call,
} => self.execute_build_map(vm, *size, *unpack, *for_call),
bytecode::Instruction::BuildSlice { size } => self.execute_build_slice(vm, *size),
bytecode::Instruction::BuildSlice { step } => self.execute_build_slice(vm, *step),
bytecode::Instruction::ListAppend { i } => {
let list_obj = self.nth_value(*i);
let item = self.pop_value();
@@ -872,7 +875,7 @@ impl ExecutingFrame<'_> {
Ok(None)
}
bytecode::Instruction::Raise { argc } => self.execute_raise(vm, *argc),
bytecode::Instruction::Raise { kind } => self.execute_raise(vm, *kind),
bytecode::Instruction::Break => self.unwind_blocks(vm, UnwindReason::Break),
bytecode::Instruction::Continue { target } => {
@@ -904,7 +907,7 @@ impl ExecutingFrame<'_> {
e
}
})?;
let msg = match elements.len().cmp(size) {
let msg = match elements.len().cmp(&(*size as usize)) {
std::cmp::Ordering::Equal => {
for element in elements.into_iter().rev() {
self.push_value(element);
@@ -930,12 +933,13 @@ impl ExecutingFrame<'_> {
self.execute_unpack_ex(vm, *before, *after)
}
bytecode::Instruction::FormatValue { conversion } => {
use bytecode::ConversionFlag::*;
use bytecode::ConversionFlag;
let value = self.pop_value();
let value = match conversion {
Some(Str) => vm.to_str(&self.pop_value())?.into_object(),
Some(Repr) => vm.to_repr(&self.pop_value())?.into_object(),
Some(Ascii) => vm.ctx.new_str(builtins::ascii(self.pop_value(), vm)?),
None => self.pop_value(),
ConversionFlag::Str => vm.to_str(&value)?.into_object(),
ConversionFlag::Repr => vm.to_repr(&value)?.into_object(),
ConversionFlag::Ascii => vm.ctx.new_str(builtins::ascii(value, vm)?),
ConversionFlag::None => value,
};
let spec = self.pop_value();
@@ -954,7 +958,7 @@ impl ExecutingFrame<'_> {
}
bytecode::Instruction::Reverse { amount } => {
let stack_len = self.state.stack.len();
self.state.stack[stack_len - amount..stack_len].reverse();
self.state.stack[stack_len - *amount as usize..stack_len].reverse();
Ok(None)
}
}
@@ -1001,7 +1005,7 @@ impl ExecutingFrame<'_> {
#[cfg_attr(feature = "flame-it", flame("Frame"))]
fn import_from(&mut self, vm: &VirtualMachine, idx: bytecode::NameIdx) -> FrameResult {
let module = self.last_value();
let name = &self.code.names[idx];
let name = &self.code.names[idx as usize];
// Load attribute, and transform any error into import error.
let obj = vm.get_attribute(module, name.clone()).map_err(|_| {
vm.new_import_error(format!("cannot import name '{}'", name), name.clone())
@@ -1106,7 +1110,7 @@ impl ExecutingFrame<'_> {
}
}
fn execute_rotate(&mut self, amount: usize) -> FrameResult {
fn execute_rotate(&mut self, amount: u32) -> FrameResult {
// Shuffles top of stack amount down
if amount < 2 {
panic!("Can only rotate two or more values");
@@ -1156,10 +1160,11 @@ impl ExecutingFrame<'_> {
fn execute_build_map(
&mut self,
vm: &VirtualMachine,
size: usize,
size: u32,
unpack: bool,
for_call: bool,
) -> FrameResult {
let size = size as usize;
let map_obj = vm.ctx.new_dict();
if unpack {
for obj in self.pop_multiple(size) {
@@ -1191,14 +1196,8 @@ impl ExecutingFrame<'_> {
Ok(None)
}
fn execute_build_slice(&mut self, vm: &VirtualMachine, size: usize) -> FrameResult {
assert!(size == 2 || size == 3);
let step = if size == 3 {
Some(self.pop_value())
} else {
None
};
fn execute_build_slice(&mut self, vm: &VirtualMachine, step: bool) -> FrameResult {
let step = if step { Some(self.pop_value()) } else { None };
let stop = self.pop_value();
let start = self.pop_value();
@@ -1212,13 +1211,9 @@ impl ExecutingFrame<'_> {
Ok(None)
}
fn execute_call_function_positional(
&mut self,
vm: &VirtualMachine,
nargs: usize,
) -> FrameResult {
fn execute_call_function_positional(&mut self, vm: &VirtualMachine, nargs: u32) -> FrameResult {
let args = FuncArgs {
args: self.pop_multiple(nargs).collect(),
args: self.pop_multiple(nargs as usize).collect(),
kwargs: IndexMap::new(),
};
@@ -1228,12 +1223,12 @@ impl ExecutingFrame<'_> {
Ok(None)
}
fn execute_call_function_keyword(&mut self, vm: &VirtualMachine, nargs: usize) -> FrameResult {
fn execute_call_function_keyword(&mut self, vm: &VirtualMachine, nargs: u32) -> FrameResult {
let kwarg_names = self
.pop_value()
.downcast::<PyTuple>()
.expect("kwarg names should be tuple of strings");
let args = self.pop_multiple(nargs);
let args = self.pop_multiple(nargs as usize);
let kwarg_names = kwarg_names
.borrow_value()
@@ -1274,9 +1269,9 @@ impl ExecutingFrame<'_> {
Ok(None)
}
fn execute_raise(&mut self, vm: &VirtualMachine, argc: usize) -> FrameResult {
let cause = match argc {
2 => {
fn execute_raise(&mut self, vm: &VirtualMachine, kind: bytecode::RaiseKind) -> FrameResult {
let cause = match kind {
bytecode::RaiseKind::RaiseCause => {
let val = self.pop_value();
Some(if vm.is_none(&val) {
// if the cause arg is none, we clear the cause
@@ -1287,19 +1282,19 @@ impl ExecutingFrame<'_> {
})
}
// if there's no cause arg, we keep the cause as is
_ => None,
bytecode::RaiseKind::Raise | bytecode::RaiseKind::Reraise => None,
};
let exception = match argc {
0 => vm
let exception = match kind {
bytecode::RaiseKind::RaiseCause | bytecode::RaiseKind::Raise => {
ExceptionCtor::try_from_object(vm, self.pop_value())?.instantiate(vm)?
}
bytecode::RaiseKind::Reraise => vm
.current_exception()
.ok_or_else(|| vm.new_runtime_error("No active exception to reraise".to_owned()))?,
1 | 2 => ExceptionCtor::try_from_object(vm, self.pop_value())?.instantiate(vm)?,
3 => panic!("Not implemented!"),
_ => panic!("Invalid parameter for RAISE_VARARGS, must be between 0 to 3"),
};
let context = match argc {
0 => None, // We have already got the exception,
_ => vm.current_exception(),
let context = match kind {
bytecode::RaiseKind::RaiseCause | bytecode::RaiseKind::Raise => vm.current_exception(),
bytecode::RaiseKind::Reraise => None, // We have already got the current exception
};
info!(
"Exception raised: {:?} with cause: {:?} and context: {:?}",
@@ -1620,7 +1615,7 @@ impl ExecutingFrame<'_> {
}
fn load_attr(&mut self, vm: &VirtualMachine, attr: bytecode::NameIdx) -> FrameResult {
let attr_name = self.code.names[attr].clone();
let attr_name = self.code.names[attr as usize].clone();
let parent = self.pop_value();
let obj = vm.get_attribute(parent, attr_name)?;
self.push_value(obj);
@@ -1628,7 +1623,7 @@ impl ExecutingFrame<'_> {
}
fn store_attr(&mut self, vm: &VirtualMachine, attr: bytecode::NameIdx) -> FrameResult {
let attr_name = self.code.names[attr].clone();
let attr_name = self.code.names[attr as usize].clone();
let parent = self.pop_value();
let value = self.pop_value();
vm.set_attr(&parent, attr_name, value)?;
@@ -1636,13 +1631,13 @@ impl ExecutingFrame<'_> {
}
fn delete_attr(&mut self, vm: &VirtualMachine, attr: bytecode::NameIdx) -> FrameResult {
let attr_name = self.code.names[attr].clone().into_object();
let attr_name = self.code.names[attr as usize].clone().into_object();
let parent = self.pop_value();
vm.del_attr(&parent, attr_name)?;
Ok(None)
}
fn lasti(&self) -> usize {
fn lasti(&self) -> u32 {
// it's okay to make this Relaxed, because we know that we only
// mutate lasti if the mutex is held, and any other thread that
// wants to guarantee the value of this will use a Lock anyway
@@ -1686,8 +1681,8 @@ impl ExecutingFrame<'_> {
self.state.stack.last().unwrap().clone()
}
fn nth_value(&self, depth: usize) -> PyObjectRef {
self.state.stack[self.state.stack.len() - depth - 1].clone()
fn nth_value(&self, depth: u32) -> PyObjectRef {
self.state.stack[self.state.stack.len() - depth as usize - 1].clone()
}
}