mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #1116 from RustPython/remove-cpython-bytecode-tests
Remove bytecode compilation.
This commit is contained in:
9 files changed
+28
-92
No files matched your search
@@ -1,60 +0,0 @@
|
||||
import bytecode
|
||||
import sys
|
||||
import json
|
||||
import types
|
||||
|
||||
|
||||
class CodeEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if (isinstance(obj, types.CodeType)):
|
||||
return serialize_code(obj)
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
def serialize_code(code):
|
||||
c = bytecode.Bytecode().from_code(code).to_concrete_bytecode()
|
||||
return (
|
||||
{
|
||||
"co_consts": consts_to_rust_enum(c.consts),
|
||||
"co_names": c.names,
|
||||
"co_name": c.name,
|
||||
"co_code": parse_co_code_to_str(c),
|
||||
"co_varnames": c.varnames
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def consts_to_rust_enum(consts):
|
||||
def capitalize_first(s):
|
||||
return s[0].upper() + s[1:]
|
||||
|
||||
def const_to_rust_enum(const):
|
||||
if type(const).__name__ == "tuple":
|
||||
return {capitalize_first(str(type(const).__name__)): list(map(const_to_rust_enum, const))}
|
||||
else:
|
||||
return {capitalize_first(str(type(const).__name__)): const}
|
||||
return list(map(const_to_rust_enum, consts))
|
||||
|
||||
|
||||
def parse_co_code_to_str(c):
|
||||
return list(
|
||||
map(lambda op: (op.size, op.name, op.arg if op.arg != bytecode.UNSET else None),
|
||||
c)
|
||||
)
|
||||
|
||||
|
||||
def compile_to_bytecode(filename, out_file=None):
|
||||
with open(filename, 'rU') as f:
|
||||
code = f.read()
|
||||
|
||||
code = compile(code, filename, "exec")
|
||||
|
||||
print(CodeEncoder(indent=4).encode(code), file=out_file)
|
||||
|
||||
|
||||
def main():
|
||||
filename = sys.argv[1]
|
||||
compile_to_bytecode(filename)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -13,8 +13,6 @@ import enum
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
import compile_code
|
||||
|
||||
|
||||
class _TestType(enum.Enum):
|
||||
functional = 1
|
||||
@@ -40,8 +38,6 @@ def perform_test(filename, method, test_type):
|
||||
logger.info("Running %s via %s", filename, method)
|
||||
if method == "cpython":
|
||||
run_via_cpython(filename)
|
||||
elif method == "cpython_bytecode":
|
||||
run_via_cpython_bytecode(filename, test_type)
|
||||
elif method == "rustpython":
|
||||
run_via_rustpython(filename, test_type)
|
||||
else:
|
||||
@@ -54,20 +50,6 @@ def run_via_cpython(filename):
|
||||
subprocess.check_call([sys.executable, filename], env=env)
|
||||
|
||||
|
||||
def run_via_cpython_bytecode(filename, test_type):
|
||||
# Step1: Create bytecode file:
|
||||
bytecode_filename = filename + ".bytecode"
|
||||
with open(bytecode_filename, "w") as f:
|
||||
compile_code.compile_to_bytecode(filename, out_file=f)
|
||||
|
||||
# Step2: run cpython bytecode:
|
||||
env = os.environ.copy()
|
||||
env["RUST_LOG"] = "info,cargo=error,jobserver=error"
|
||||
env["RUST_BACKTRACE"] = "1"
|
||||
with pushd(CPYTHON_RUNNER_DIR):
|
||||
subprocess.check_call(["cargo", "run", bytecode_filename], env=env)
|
||||
|
||||
|
||||
def run_via_rustpython(filename, test_type):
|
||||
env = os.environ.copy()
|
||||
env['RUST_LOG'] = 'info,cargo=error,jobserver=error'
|
||||
@@ -142,7 +124,6 @@ def generate_slices(path):
|
||||
|
||||
|
||||
@populate("cpython")
|
||||
# @populate('cpython_bytecode')
|
||||
@populate("rustpython")
|
||||
class SampleTestCase(unittest.TestCase):
|
||||
@classmethod
|
||||
|
||||
@@ -10,6 +10,7 @@ include = ["src/**/*.rs", "Cargo.toml", "build.rs", "Lib/**/*.py"]
|
||||
|
||||
[features]
|
||||
default = ["rustpython-parser", "rustpython-compiler"]
|
||||
vm-tracing-logging = []
|
||||
|
||||
[dependencies]
|
||||
# Crypto:
|
||||
|
||||
+4
-1
@@ -295,7 +295,7 @@ impl Frame {
|
||||
let traceback = vm
|
||||
.get_attribute(exception.clone(), "__traceback__")
|
||||
.unwrap();
|
||||
trace!("Adding to traceback: {:?} {:?}", traceback, lineno);
|
||||
vm_trace!("Adding to traceback: {:?} {:?}", traceback, lineno);
|
||||
let raise_location = vm.ctx.new_tuple(vec![
|
||||
vm.ctx.new_str(filename.clone()),
|
||||
vm.ctx.new_int(lineno.row()),
|
||||
@@ -336,6 +336,8 @@ impl Frame {
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn execute_instruction(&self, vm: &VirtualMachine) -> FrameResult {
|
||||
let instruction = self.fetch_instruction();
|
||||
|
||||
#[cfg(feature = "vm-tracing-logging")]
|
||||
{
|
||||
trace!("=======");
|
||||
/* TODO:
|
||||
@@ -1143,6 +1145,7 @@ impl Frame {
|
||||
|
||||
fn jump(&self, label: bytecode::Label) {
|
||||
let target_pc = self.code.label_map[&label];
|
||||
#[cfg(feature = "vm-tracing-logging")]
|
||||
trace!("jump from {:?} to {:?}", self.lasti, target_pc);
|
||||
*self.lasti.borrow_mut() = target_pc;
|
||||
}
|
||||
|
||||
@@ -256,3 +256,13 @@ macro_rules! match_class {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Super detailed logging. Might soon overflow your logbuffers
|
||||
/// Default, this logging is discarded, except when a the `vm-tracing-logging`
|
||||
/// build feature is enabled.
|
||||
macro_rules! vm_trace {
|
||||
($($arg:tt)+) => {
|
||||
#[cfg(feature = "vm-tracing-logging")]
|
||||
trace!($($arg)+);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ impl PyNoneRef {
|
||||
}
|
||||
|
||||
fn get_attribute(self, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
trace!("None.__getattribute__({:?}, {:?})", self, name);
|
||||
vm_trace!("None.__getattribute__({:?}, {:?})", self, name);
|
||||
let cls = self.class();
|
||||
|
||||
// Properties use a comparision with None to determine if they are either invoked by am
|
||||
|
||||
@@ -66,7 +66,7 @@ fn object_setattr(
|
||||
value: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
trace!("object.__setattr__({:?}, {}, {:?})", obj, attr_name, value);
|
||||
vm_trace!("object.__setattr__({:?}, {}, {:?})", obj, attr_name, value);
|
||||
let cls = obj.class();
|
||||
|
||||
if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) {
|
||||
@@ -220,7 +220,7 @@ fn object_dict_setter(
|
||||
|
||||
fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
let name = &name_str.value;
|
||||
trace!("object.__getattribute__({:?}, {:?})", obj, name);
|
||||
vm_trace!("object.__getattribute__({:?}, {:?})", obj, name);
|
||||
let cls = obj.class();
|
||||
|
||||
if let Some(attr) = objtype::class_get_attr(&cls, &name) {
|
||||
|
||||
@@ -114,7 +114,7 @@ impl PyClassRef {
|
||||
|
||||
fn getattribute(self, name_ref: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
let name = &name_ref.value;
|
||||
trace!("type.__getattribute__({:?}, {:?})", self, name);
|
||||
vm_trace!("type.__getattribute__({:?}, {:?})", self, name);
|
||||
let mcl = self.class();
|
||||
|
||||
if let Some(attr) = class_get_attr(&mcl, &name) {
|
||||
@@ -241,7 +241,7 @@ pub fn issubclass(subclass: &PyClassRef, cls: &PyClassRef) -> bool {
|
||||
}
|
||||
|
||||
pub fn type_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
debug!("type.__new__ {:?}", args);
|
||||
vm_trace!("type.__new__ {:?}", args);
|
||||
if args.args.len() == 2 {
|
||||
Ok(args.args[1].class().into_object())
|
||||
} else if args.args.len() == 4 {
|
||||
@@ -265,7 +265,7 @@ pub fn type_new_class(
|
||||
}
|
||||
|
||||
pub fn type_call(class: PyClassRef, args: Args, kwargs: KwArgs, vm: &VirtualMachine) -> PyResult {
|
||||
debug!("type_call: {:?}", class);
|
||||
vm_trace!("type_call: {:?}", class);
|
||||
let new = class_get_attr(&class, "__new__").expect("All types should have a __new__.");
|
||||
let new_wrapped = vm.call_get_descriptor(new, class.into_object())?;
|
||||
let obj = vm.invoke(new_wrapped, (&args, &kwargs))?;
|
||||
@@ -353,7 +353,7 @@ fn take_next_base(mut bases: Vec<Vec<PyClassRef>>) -> Option<(PyClassRef, Vec<Ve
|
||||
}
|
||||
|
||||
fn linearise_mro(mut bases: Vec<Vec<PyClassRef>>) -> Option<Vec<PyClassRef>> {
|
||||
debug!("Linearising MRO: {:?}", bases);
|
||||
vm_trace!("Linearising MRO: {:?}", bases);
|
||||
let mut result = vec![];
|
||||
loop {
|
||||
if (&bases).iter().all(Vec::is_empty) {
|
||||
|
||||
+6
-5
@@ -170,7 +170,7 @@ impl VirtualMachine {
|
||||
|
||||
fn new_exception_obj(&self, exc_type: PyClassRef, args: Vec<PyObjectRef>) -> PyResult {
|
||||
// TODO: add repr of args into logging?
|
||||
info!("New exception created: {}", exc_type.name);
|
||||
vm_trace!("New exception created: {}", exc_type.name);
|
||||
self.invoke(exc_type.into_object(), args)
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ impl VirtualMachine {
|
||||
let cls = obj.class();
|
||||
match objtype::class_get_attr(&cls, method_name) {
|
||||
Some(func) => {
|
||||
trace!(
|
||||
vm_trace!(
|
||||
"vm.call_method {:?} {:?} {:?} -> {:?}",
|
||||
obj,
|
||||
cls,
|
||||
@@ -392,7 +392,8 @@ impl VirtualMachine {
|
||||
}
|
||||
|
||||
fn _invoke(&self, func_ref: PyObjectRef, args: PyFuncArgs) -> PyResult {
|
||||
trace!("Invoke: {:?} {:?}", func_ref, args);
|
||||
vm_trace!("Invoke: {:?} {:?}", func_ref, args);
|
||||
|
||||
if let Some(PyFunction {
|
||||
ref code,
|
||||
ref scope,
|
||||
@@ -411,7 +412,7 @@ impl VirtualMachine {
|
||||
value(self, args)
|
||||
} else {
|
||||
// TODO: is it safe to just invoke __call__ otherwise?
|
||||
trace!("invoke __call__ for: {:?}", &func_ref.payload);
|
||||
vm_trace!("invoke __call__ for: {:?}", &func_ref.payload);
|
||||
self.call_method(&func_ref, "__call__", args)
|
||||
}
|
||||
}
|
||||
@@ -630,7 +631,7 @@ impl VirtualMachine {
|
||||
T: TryIntoRef<PyString>,
|
||||
{
|
||||
let attr_name = attr_name.try_into_ref(self)?;
|
||||
trace!("vm.__getattribute__: {:?} {:?}", obj, attr_name);
|
||||
vm_trace!("vm.__getattribute__: {:?} {:?}", obj, attr_name);
|
||||
self.call_method(&obj, "__getattribute__", vec![attr_name.into_object()])
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user