@@ -2,13 +2,23 @@ use crate::object::define_py_check;
22use crate :: util:: CStrExt ;
33use crate :: { PyObject , pystate:: with_vm} ;
44use core:: convert:: Infallible ;
5- use core:: ffi:: { c_char, c_int} ;
5+ use core:: ffi:: { CStr , c_char, c_int} ;
66use core:: ptr:: NonNull ;
7- use core :: slice ;
7+ pub use errno :: * ;
88use rustpython_vm:: builtins:: { PyBaseException , PyTuple , PyType } ;
99use rustpython_vm:: convert:: IntoObject ;
1010use rustpython_vm:: exceptions:: ExceptionZoo ;
11+ use rustpython_vm:: signal:: set_interrupt_ex;
1112use rustpython_vm:: { AsObject , PyObjectRef , PyResult } ;
13+ use std:: process:: abort;
14+ pub use unicode:: * ;
15+ #[ cfg( windows) ]
16+ pub use windows:: * ;
17+
18+ mod errno;
19+ mod unicode;
20+ #[ cfg( windows) ]
21+ mod windows;
1222
1323macro_rules! define_exception_statics {
1424 ( $( $( #[ $meta: meta] ) * $export: ident => $exc: ident ) ,* $( , ) ?) => {
@@ -318,55 +328,249 @@ pub unsafe extern "C" fn PyException_SetContext(exc: *mut PyObject, context: *mu
318328}
319329
320330#[ unsafe( no_mangle) ]
321- pub unsafe extern "C" fn PyUnicodeDecodeError_Create (
322- encoding : * const c_char ,
323- object : * const c_char ,
324- length : isize ,
325- start : isize ,
326- end : isize ,
327- reason : * const c_char ,
328- ) -> * mut PyObject {
331+ pub unsafe extern "C" fn PyException_SetTraceback ( exc : * mut PyObject , tb : * mut PyObject ) -> c_int {
329332 with_vm ( |vm| {
330- let encoding = unsafe { encoding . try_as_str ( vm) } ?;
331- let reason = unsafe { reason . try_as_str ( vm ) } ? ;
332- let length : usize = length
333- . try_into ( )
334- . map_err ( |_| vm . new_system_error ( "length must be non-negative" ) ) ? ;
335- let start : usize = start
336- . try_into ( )
337- . map_err ( |_| vm . new_system_error ( "start must be non-negative" ) ) ? ;
338- let end : usize = end
339- . try_into ( )
340- . map_err ( |_| vm . new_system_error ( "end must be non-negative" ) ) ? ;
341-
342- let bytes = if object . is_null ( ) {
343- if length != 0 {
344- return Err ( vm. new_system_error (
345- "PyUnicodeDecodeError_Create called with null object and non-zero length" ,
346- ) ) ;
347- }
348- Vec :: new ( )
333+ let exc = unsafe { & * exc } . try_downcast_ref :: < PyBaseException > ( vm) ?;
334+ let traceback = unsafe { tb . as_ref ( ) } . map ( |obj| obj . to_owned ( ) ) ;
335+ exc . set___traceback__ ( vm . unwrap_or_none ( traceback ) , vm )
336+ } )
337+ }
338+
339+ # [ unsafe ( no_mangle ) ]
340+ pub extern "C" fn PyErr_Clear ( ) {
341+ with_vm ( |vm| vm . set_exception ( None ) )
342+ }
343+
344+ # [ unsafe ( no_mangle ) ]
345+ pub unsafe extern "C" fn PyErr_ExceptionMatches ( exc : * mut PyObject ) -> c_int {
346+ with_vm ( |vm| {
347+ if let Some ( current ) = vm. current_exception ( ) {
348+ current
349+ . class ( )
350+ . as_object ( )
351+ . is_subclass ( unsafe { & * exc } , vm )
349352 } else {
350- unsafe { slice:: from_raw_parts ( object. cast :: < u8 > ( ) , length) } . to_vec ( )
353+ Ok ( false )
354+ }
355+ } )
356+ }
357+
358+ #[ unsafe( no_mangle) ]
359+ pub extern "C" fn PyErr_BadArgument ( ) -> c_int {
360+ with_vm :: < PyResult < Infallible > , ( ) > ( |vm| {
361+ Err ( vm. new_type_error ( "bad argument type for built-in operation" ) )
362+ } ) ;
363+ 0
364+ }
365+
366+ #[ unsafe( no_mangle) ]
367+ pub extern "C" fn PyErr_BadInternalCall ( ) {
368+ with_vm :: < PyResult < Infallible > , _ > ( |vm| {
369+ Err ( vm. new_system_error ( "bad argument to internal function" ) )
370+ } )
371+ }
372+
373+ #[ unsafe( no_mangle) ]
374+ pub extern "C" fn PyErr_CheckSignals ( ) -> c_int {
375+ with_vm ( |vm| vm. check_signals ( ) )
376+ }
377+
378+ #[ unsafe( no_mangle) ]
379+ pub extern "C" fn PyErr_SetInterrupt ( ) {
380+ PyErr_SetInterruptEx ( libc:: SIGINT ) ;
381+ }
382+
383+ #[ unsafe( no_mangle) ]
384+ pub extern "C" fn PyErr_SetInterruptEx ( signum : c_int ) -> c_int {
385+ let Ok ( signum) = signum. try_into ( ) else {
386+ return -1 ;
387+ } ;
388+ set_interrupt_ex ( signum) . map_or ( -1 , |_| 0 )
389+ }
390+
391+ #[ unsafe( no_mangle) ]
392+ pub unsafe extern "C" fn Py_FatalError ( message : * const c_char ) -> ! {
393+ let message = if message. is_null ( ) {
394+ c"(null)"
395+ } else {
396+ unsafe { CStr :: from_ptr ( message) }
397+ } ;
398+ eprintln ! ( "Fatal Python error: {message:?}" ) ;
399+ abort ( )
400+ }
401+
402+ #[ unsafe( no_mangle) ]
403+ pub unsafe extern "C" fn PyErr_SetNone ( exception : * mut PyObject ) {
404+ with_vm :: < PyResult < Infallible > , _ > ( |vm| {
405+ let exc_type = unsafe { ( & * exception) . to_owned ( ) } ;
406+ let normalized = vm. normalize_exception ( exc_type, vm. ctx . none ( ) , vm. ctx . none ( ) ) ?;
407+ Err ( normalized)
408+ } )
409+ }
410+
411+ #[ unsafe( no_mangle) ]
412+ pub extern "C" fn PyErr_NoMemory ( ) -> * mut PyObject {
413+ with_vm :: < PyResult < * mut PyObject > , _ > ( |vm| Err ( vm. new_memory_error ( "" ) ) )
414+ }
415+
416+ #[ unsafe( no_mangle) ]
417+ pub unsafe extern "C" fn PyErr_Fetch (
418+ ptype : * mut * mut PyObject ,
419+ pvalue : * mut * mut PyObject ,
420+ ptraceback : * mut * mut PyObject ,
421+ ) {
422+ with_vm ( |vm| {
423+ let ( ty, value, tb) = vm. take_raised_exception ( ) . map_or_else (
424+ || {
425+ (
426+ core:: ptr:: null_mut ( ) ,
427+ core:: ptr:: null_mut ( ) ,
428+ core:: ptr:: null_mut ( ) ,
429+ )
430+ } ,
431+ |exc| {
432+ let ( ty, value, tb) = vm. split_exception ( exc) ;
433+ let tb = if vm. is_none ( & tb) {
434+ core:: ptr:: null_mut ( )
435+ } else {
436+ tb. into_raw ( ) . as_ptr ( )
437+ } ;
438+ ( ty. into_raw ( ) . as_ptr ( ) , value. into_raw ( ) . as_ptr ( ) , tb)
439+ } ,
440+ ) ;
441+
442+ if let Some ( ptype) = NonNull :: new ( ptype) {
443+ unsafe { ptype. write ( ty) } ;
444+ }
445+ if let Some ( pvalue) = NonNull :: new ( pvalue) {
446+ unsafe { pvalue. write ( value) } ;
447+ }
448+ if let Some ( ptraceback) = NonNull :: new ( ptraceback) {
449+ unsafe { ptraceback. write ( tb) } ;
450+ }
451+ } )
452+ }
453+
454+ #[ unsafe( no_mangle) ]
455+ pub unsafe extern "C" fn PyErr_Restore (
456+ exc_type : * mut PyObject ,
457+ exc_val : * mut PyObject ,
458+ exc_tb : * mut PyObject ,
459+ ) {
460+ with_vm ( |vm| {
461+ let exc_type = NonNull :: new ( exc_type) . map ( |ptr| unsafe { PyObjectRef :: from_raw ( ptr) } ) ;
462+ let exc_val = NonNull :: new ( exc_val) . map ( |ptr| unsafe { PyObjectRef :: from_raw ( ptr) } ) ;
463+ let exc_tb = NonNull :: new ( exc_tb) . map ( |ptr| unsafe { PyObjectRef :: from_raw ( ptr) } ) ;
464+
465+ if let Some ( exc_type) = exc_type {
466+ let normalized = vm. normalize_exception (
467+ exc_type,
468+ vm. unwrap_or_none ( exc_val) ,
469+ vm. unwrap_or_none ( exc_tb) ,
470+ ) ?;
471+ vm. set_exception ( Some ( normalized) ) ;
472+ } else {
473+ vm. set_exception ( None ) ;
351474 } ;
352475
353- let exc = vm. new_unicode_decode_error_real (
354- vm. ctx . new_str ( encoding) ,
355- vm. ctx . new_bytes ( bytes) ,
356- start,
357- end,
358- vm. ctx . new_str ( reason) ,
476+ Ok ( ( ) )
477+ } )
478+ }
479+
480+ #[ unsafe( no_mangle) ]
481+ pub extern "C" fn PyErr_GetHandledException ( ) -> * mut PyObject {
482+ with_vm ( |vm| {
483+ vm. current_exception ( )
484+ . map ( |exc| exc. into_object ( ) . into_raw ( ) . as_ptr ( ) )
485+ . unwrap_or_default ( )
486+ } )
487+ }
488+
489+ #[ unsafe( no_mangle) ]
490+ pub unsafe extern "C" fn PyErr_SetHandledException ( exc : * mut PyObject ) {
491+ with_vm ( |vm| {
492+ if let Some ( exc) = NonNull :: new ( exc) {
493+ let exception = unsafe { PyObjectRef :: from_raw ( exc) . downcast_unchecked ( ) } ;
494+ vm. set_exception ( Some ( exception) ) ;
495+ } else {
496+ vm. set_exception ( None ) ;
497+ }
498+ } )
499+ }
500+
501+ #[ unsafe( no_mangle) ]
502+ pub unsafe extern "C" fn PyErr_GetExcInfo (
503+ ptype : * mut * mut PyObject ,
504+ pvalue : * mut * mut PyObject ,
505+ ptraceback : * mut * mut PyObject ,
506+ ) {
507+ with_vm ( |vm| {
508+ let ( ty, value, tb) = vm. current_exception ( ) . map_or_else (
509+ || {
510+ (
511+ core:: ptr:: null_mut ( ) ,
512+ core:: ptr:: null_mut ( ) ,
513+ core:: ptr:: null_mut ( ) ,
514+ )
515+ } ,
516+ |exc| {
517+ let ( ty, value, tb) = vm. split_exception ( exc) ;
518+ let tb = if vm. is_none ( & tb) {
519+ core:: ptr:: null_mut ( )
520+ } else {
521+ tb. into_raw ( ) . as_ptr ( )
522+ } ;
523+ ( ty. into_raw ( ) . as_ptr ( ) , value. into_raw ( ) . as_ptr ( ) , tb)
524+ } ,
359525 ) ;
360- Ok ( exc)
526+
527+ if let Some ( ptype) = NonNull :: new ( ptype) {
528+ unsafe { ptype. write ( ty) } ;
529+ }
530+ if let Some ( pvalue) = NonNull :: new ( pvalue) {
531+ unsafe { pvalue. write ( value) } ;
532+ }
533+ if let Some ( ptraceback) = NonNull :: new ( ptraceback) {
534+ unsafe { ptraceback. write ( tb) } ;
535+ }
361536 } )
362537}
363538
364539#[ unsafe( no_mangle) ]
365- pub unsafe extern "C" fn PyException_SetTraceback ( exc : * mut PyObject , tb : * mut PyObject ) -> c_int {
540+ pub unsafe extern "C" fn PyErr_SetExcInfo (
541+ exc_type : * mut PyObject ,
542+ exc_val : * mut PyObject ,
543+ exc_tb : * mut PyObject ,
544+ ) {
545+ with_vm ( |vm| {
546+ let _exc_type = NonNull :: new ( exc_type) . map ( |ptr| unsafe { PyObjectRef :: from_raw ( ptr) } ) ;
547+ let _exc_tb = NonNull :: new ( exc_tb) . map ( |ptr| unsafe { PyObjectRef :: from_raw ( ptr) } ) ;
548+ let exc_val = NonNull :: new ( exc_val) . map ( |ptr| unsafe { PyObjectRef :: from_raw ( ptr) } ) ;
549+ let exc = exc_val
550+ . map ( |obj| {
551+ obj. downcast :: < PyBaseException > ( )
552+ . map_err ( |_| vm. new_type_error ( "exception value must be an exception instance" ) )
553+ } )
554+ . transpose ( ) ?;
555+ vm. set_exception ( exc) ;
556+ Ok ( ( ) )
557+ } )
558+ }
559+
560+ #[ unsafe( no_mangle) ]
561+ pub unsafe extern "C" fn PyException_GetArgs ( exc : * mut PyObject ) -> * mut PyObject {
366562 with_vm ( |vm| {
367563 let exc = unsafe { & * exc } . try_downcast_ref :: < PyBaseException > ( vm) ?;
368- let traceback = unsafe { tb. as_ref ( ) } . map ( |obj| obj. to_owned ( ) ) ;
369- exc. set___traceback__ ( vm. unwrap_or_none ( traceback) , vm)
564+ Ok ( exc. args ( ) )
565+ } )
566+ }
567+
568+ #[ unsafe( no_mangle) ]
569+ pub unsafe extern "C" fn PyException_SetArgs ( exc : * mut PyObject , args : * mut PyObject ) {
570+ with_vm ( |vm| {
571+ let exc = unsafe { & * exc } . try_downcast_ref :: < PyBaseException > ( vm) ?;
572+ let args = unsafe { & * args } . to_owned ( ) ;
573+ exc. as_object ( ) . set_attr ( "args" , args, vm)
370574 } )
371575}
372576
0 commit comments