Skip to content

Commit 6faf263

Browse files
committed
Move NSIG, reorganize prompt stuff
1 parent 0d492e7 commit 6faf263

File tree

3 files changed

+60
-47
lines changed

3 files changed

+60
-47
lines changed

src/main.rs

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustpython_vm::{
1111
import,
1212
obj::objstr::PyStringRef,
1313
print_exception,
14-
pyobject::{ItemProtocol, PyResult},
14+
pyobject::{ItemProtocol, PyObjectRef, PyResult},
1515
scope::Scope,
1616
util, PySettings, VirtualMachine,
1717
};
@@ -434,40 +434,32 @@ fn test_run_script() {
434434
assert!(r.is_ok());
435435
}
436436

437-
fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> Result<(), CompileError> {
437+
enum ShellExecResult {
438+
Ok,
439+
PyErr(PyObjectRef),
440+
Continue,
441+
}
442+
443+
fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> ShellExecResult {
438444
match vm.compile(source, compile::Mode::Single, "<stdin>".to_string()) {
439445
Ok(code) => {
440446
match vm.run_code_obj(code, scope.clone()) {
441447
Ok(value) => {
442448
// Save non-None values as "_"
443-
444-
use rustpython_vm::pyobject::IdProtocol;
445-
446-
if !value.is(&vm.get_none()) {
449+
if !vm.is_none(&value) {
447450
let key = "_";
448451
scope.globals.set_item(key, value, vm).unwrap();
449452
}
453+
ShellExecResult::Ok
450454
}
451-
452-
Err(err) => {
453-
print_exception(vm, &err);
454-
}
455+
Err(err) => ShellExecResult::PyErr(err),
455456
}
456-
457-
Ok(())
458-
}
459-
// Don't inject syntax errors for line continuation
460-
Err(
461-
err @ CompileError {
462-
error: CompileErrorType::Parse(ParseErrorType::EOF),
463-
..
464-
},
465-
) => Err(err),
466-
Err(err) => {
467-
let exc = vm.new_syntax_error(&err);
468-
print_exception(vm, &exc);
469-
Err(err)
470457
}
458+
Err(CompileError {
459+
error: CompileErrorType::Parse(ParseErrorType::EOF),
460+
..
461+
}) => ShellExecResult::Continue,
462+
Err(err) => ShellExecResult::PyErr(vm.new_syntax_error(&err)),
471463
}
472464
}
473465

@@ -519,48 +511,66 @@ fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
519511
} else {
520512
get_prompt(vm, "ps1")
521513
};
522-
let prompt = prompt.as_ref().map(|s| s.as_str()).unwrap_or("");
523-
match repl.readline(prompt) {
514+
let prompt = match prompt {
515+
Some(ref s) => s.as_str(),
516+
None => "",
517+
};
518+
let result = match repl.readline(prompt) {
524519
Ok(line) => {
525520
debug!("You entered {:?}", line);
526-
input.push_str(&line);
527-
input.push('\n');
521+
528522
repl.add_history_entry(line.trim_end());
529523

524+
let stop_continuing = line.is_empty();
525+
526+
if input.is_empty() {
527+
input = line;
528+
} else {
529+
input.push_str(&line);
530+
}
531+
input.push_str("\n");
532+
530533
if continuing {
531-
if line.is_empty() {
534+
if stop_continuing {
532535
continuing = false;
533536
} else {
534537
continue;
535538
}
536539
}
537540

538541
match shell_exec(vm, &input, scope.clone()) {
539-
Err(CompileError {
540-
error: CompileErrorType::Parse(ParseErrorType::EOF),
541-
..
542-
}) => {
542+
ShellExecResult::Ok => {
543+
input = String::new();
544+
Ok(())
545+
}
546+
ShellExecResult::Continue => {
543547
continuing = true;
548+
Ok(())
544549
}
545-
_ => {
550+
ShellExecResult::PyErr(err) => {
546551
input = String::new();
552+
Err(err)
547553
}
548554
}
549555
}
550556
Err(ReadlineError::Interrupted) => {
551-
let exc = vm
557+
continuing = false;
558+
let keyboard_interrupt = vm
552559
.new_empty_exception(vm.ctx.exceptions.keyboard_interrupt.clone())
553560
.unwrap();
554-
print_exception(vm, &exc);
555-
continuing = false;
561+
Err(keyboard_interrupt)
556562
}
557563
Err(ReadlineError::Eof) => {
558564
break;
559565
}
560566
Err(err) => {
561-
println!("Error: {:?}", err);
567+
eprintln!("Readline error: {:?}", err);
562568
break;
563569
}
570+
};
571+
572+
if let Err(exc) = result {
573+
print_exception(vm, &exc);
564574
}
565575
}
566576
repl.save_history(repl_history_path_str).unwrap();
@@ -586,7 +596,11 @@ fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
586596
for line in stdin.lock().lines() {
587597
let mut line = line.expect("line failed");
588598
line.push('\n');
589-
let _ = shell_exec(vm, &line, scope.clone());
599+
match shell_exec(vm, &line, scope.clone()) {
600+
ShellExecResult::Ok => {}
601+
ShellExecResult::Continue => println!("Unexpected EOF"),
602+
ShellExecResult::PyErr(exc) => print_exception(vm, &exc),
603+
}
590604
print!("{}", get_prompt(vm, "ps1"));
591605
stdout.flush().expect("flush failed");
592606
}

vm/src/stdlib/signal.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::obj::objint::PyIntRef;
22
use crate::pyobject::{PyObjectRef, PyResult, TryFromObject};
3-
use crate::vm::VirtualMachine;
3+
use crate::vm::{VirtualMachine, NSIG};
44

55
use std::sync::atomic::{AtomicBool, Ordering};
66

@@ -23,8 +23,6 @@ const SIG_IGN: libc::sighandler_t = 1;
2323
#[cfg(windows)]
2424
const SIG_ERR: libc::sighandler_t = !0;
2525

26-
pub const NSIG: usize = 64;
27-
2826
// We cannot use the NSIG const in the arr macro. This will fail compilation if NSIG is different.
2927
static TRIGGERS: [AtomicBool; NSIG] = arr![AtomicBool::new(false); 64];
3028

@@ -33,7 +31,7 @@ extern "C" fn run_signal(signum: i32) {
3331
}
3432

3533
fn assert_in_range(signum: i32, vm: &VirtualMachine) -> PyResult<()> {
36-
if (1..=NSIG as i32).contains(&signum) {
34+
if (1..NSIG as i32).contains(&signum) {
3735
Ok(())
3836
} else {
3937
Err(vm.new_value_error("signal number out of range".to_owned()))

vm/src/vm.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,12 @@ pub struct VirtualMachine {
6363
pub profile_func: RefCell<PyObjectRef>,
6464
pub trace_func: RefCell<PyObjectRef>,
6565
pub use_tracing: RefCell<bool>,
66+
pub signal_handlers: RefCell<[PyObjectRef; NSIG]>,
6667
pub settings: PySettings,
67-
#[cfg(not(target_arch = "wasm32"))]
68-
pub signal_handlers: RefCell<[PyObjectRef; stdlib::signal::NSIG]>,
6968
}
7069

70+
pub const NSIG: usize = 64;
71+
7172
/// Struct containing all kind of settings for the python vm.
7273
pub struct PySettings {
7374
/// -d command line switch
@@ -168,10 +169,9 @@ impl VirtualMachine {
168169
let import_func = RefCell::new(ctx.none());
169170
let profile_func = RefCell::new(ctx.none());
170171
let trace_func = RefCell::new(ctx.none());
172+
let signal_handlers = RefCell::new(arr![ctx.none(); 64]);
171173

172174
let vm = VirtualMachine {
173-
#[cfg(not(target_arch = "wasm32"))]
174-
signal_handlers: RefCell::new(arr![ctx.none(); 64]),
175175
builtins: builtins.clone(),
176176
sys_module: sysmod.clone(),
177177
stdlib_inits,
@@ -184,6 +184,7 @@ impl VirtualMachine {
184184
profile_func,
185185
trace_func,
186186
use_tracing: RefCell::new(false),
187+
signal_handlers,
187188
settings,
188189
};
189190

0 commit comments

Comments
 (0)