// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. /* Upcalls These are runtime functions that the compiler knows about and generates calls to. They are called on the Rust stack and, in most cases, immediately switch to the C stack. */ #include "rust_globals.h" #include "rust_util.h" //Unwinding ABI declarations. typedef int _Unwind_Reason_Code; typedef int _Unwind_Action; struct _Unwind_Context; struct _Unwind_Exception; typedef void (*CDECL stack_switch_shim)(void*); /********************************************************************** * Switches to the C-stack and invokes |fn_ptr|, passing |args| as argument. * This is used by the C compiler to call foreign functions and by other * upcalls to switch to the C stack. The return value is passed through a * field in the args parameter. This upcall is specifically for switching * to the shim functions generated by rustc. */ extern "C" CDECL void upcall_call_shim_on_c_stack(void *args, void *fn_ptr) { stack_switch_shim f = (stack_switch_shim)fn_ptr; f(args); } /* * The opposite of above. Starts on a C stack and switches to the Rust * stack. This is the only upcall that runs from the C stack. */ extern "C" CDECL void upcall_call_shim_on_rust_stack(void *args, void *fn_ptr) { // There's no task. Call the function and hope for the best stack_switch_shim f = (stack_switch_shim)fn_ptr; f(args); } /**********************************************************************/ extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exception_class, _Unwind_Exception *ue_header, _Unwind_Context *context); struct s_rust_personality_args { _Unwind_Reason_Code retval; int version; _Unwind_Action actions; uint64_t exception_class; _Unwind_Exception *ue_header; _Unwind_Context *context; }; extern "C" void upcall_s_rust_personality(s_rust_personality_args *args) { args->retval = __gxx_personality_v0(args->version, args->actions, args->exception_class, args->ue_header, args->context); } /** The exception handling personality function. It figures out what to do with each landing pad. Just a stack-switching wrapper around the C++ personality function. */ extern "C" _Unwind_Reason_Code upcall_rust_personality(int version, _Unwind_Action actions, uint64_t exception_class, _Unwind_Exception *ue_header, _Unwind_Context *context) { s_rust_personality_args args = {(_Unwind_Reason_Code)0, version, actions, exception_class, ue_header, context}; upcall_s_rust_personality(&args); return args.retval; } // NB: This needs to be blazing fast. Don't switch stacks extern "C" CDECL void * upcall_new_stack(size_t stk_sz, void *args_addr, size_t args_sz) { assert(false && "newsched shouldn't be growing the stack"); return NULL; } // NB: This needs to be blazing fast. Don't switch stacks extern "C" CDECL void upcall_del_stack() { assert(false && "newsched shouldn't be growing the stack"); } // Landing pads need to call this to insert the // correct limit into TLS. // NB: This must run on the Rust stack because it // needs to acquire the value of the stack pointer extern "C" CDECL void upcall_reset_stack_limit() { } // // Local Variables: // mode: C++ // fill-column: 78; // indent-tabs-mode: nil // c-basic-offset: 4 // buffer-file-coding-system: utf-8-unix // End: //