summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-06-22 09:55:49 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-06-22 09:55:49 +0800
commit49cf8a3182e66f041168959cdceead051be27895 (patch)
tree00a747e1f0303367b1d0e9462713a257f4fbb6a5 /src
parentb352b6acb1f13484550ab6db48464f41bf72e0f1 (diff)
downloadmrust-49cf8a3182e66f041168959cdceead051be27895.tar.gz
Expand/Trans - Better handling of #[panic_implementation]
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.hpp1
-rw-r--r--src/expand/lang_item.cpp39
-rw-r--r--src/expand/mod.cpp8
-rw-r--r--src/trans/codegen_c.cpp11
4 files changed, 52 insertions, 7 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index bfef9cff..a6c06e76 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -51,6 +51,7 @@ enum eItemType
ITEM_ENUM,
ITEM_UNION,
ITEM_FN,
+ ITEM_EXTERN_FN,
ITEM_STATIC,
};
diff --git a/src/expand/lang_item.cpp b/src/expand/lang_item.cpp
index 8dd481f3..035bd5bd 100644
--- a/src/expand/lang_item.cpp
+++ b/src/expand/lang_item.cpp
@@ -99,12 +99,16 @@ void handle_lang_item(const Span& sp, AST::Crate& crate, const AST::Path& path,
// Statics
else if( name == "msvc_try_filter" ) { }
+ // Extern functions
+ else if( name == "panic_impl" ) {
+ }
+ else if( name == "oom" ) {
+ }
+
// Functions
else if( name == "panic" ) { }
else if( name == "panic_bounds_check" ) { }
- else if( name == "panic_fmt" ) {
-
- }
+ else if( name == "panic_fmt" ) { }
else if( name == "str_eq" ) { }
else if( name == "drop_in_place" ) { }
else if( name == "align_offset" ) { }
@@ -148,6 +152,12 @@ void handle_lang_item(const Span& sp, AST::Crate& crate, const AST::Path& path,
ERROR(sp, E0000, "Unknown language item '" << name << "'");
}
+ if( type == AST::ITEM_EXTERN_FN )
+ {
+ // TODO: This should force a specific link name instead
+ return ;
+ }
+
auto rv = crate.m_lang_items.insert( ::std::make_pair( name, ::AST::Path(path) ) );
if( !rv.second ) {
const auto& other_path = rv.first->second;
@@ -177,7 +187,7 @@ public:
handle_lang_item(sp, crate, path, attr.string(), AST::ITEM_FN);
}
else {
- //handle_lang_item(sp, crate, path, attr.string(), AST::ITEM_EXTERN_FN);
+ handle_lang_item(sp, crate, path, attr.string(), AST::ITEM_EXTERN_FN);
}
),
(Static,
@@ -280,9 +290,30 @@ public:
}
};
+class Decorator_PanicImplementation:
+ public ExpandDecorator
+{
+public:
+ AttrStage stage() const override { return AttrStage::Post; }
+ void handle(const Span& sp, const AST::Attribute& attr, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override
+ {
+ TU_IFLET(::AST::Item, i, Function, e,
+ auto rv = crate.m_lang_items.insert(::std::make_pair( ::std::string("mrustc-panic_implementation"), ::AST::Path(path) ));
+ if( !rv.second )
+ {
+ const auto& other_path = rv.first->second;
+ ERROR(sp, E0000, "Duplicate definition of #[panic_implementation] - " << other_path << " and " << path);
+ }
+ )
+ else {
+ ERROR(sp, E0000, "#[panic_implementation] on non-function " << path);
+ }
+ }
+};
STATIC_DECORATOR("lang", Decorator_LangItem)
STATIC_DECORATOR("main", Decorator_Main);
STATIC_DECORATOR("start", Decorator_Start);
+STATIC_DECORATOR("panic_implementation", Decorator_PanicImplementation);
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index e3cef375..d9a19b2c 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -55,14 +55,22 @@ void ExpandDecorator::unexpected(const Span& sp, const AST::Attribute& mi, const
void Expand_Attr(const Span& sp, const ::AST::Attribute& a, AttrStage stage, ::std::function<void(const Span& sp, const ExpandDecorator& d,const ::AST::Attribute& a)> f)
{
+ bool found = false;
for( auto& d : g_decorators ) {
if( a.name() == d.first ) {
DEBUG("#[" << d.first << "] " << (int)d.second->stage() << "-" << (int)stage);
if( d.second->stage() == stage ) {
f(sp, *d.second, a);
+ // TODO: Early return?
+ // TODO: Annotate the attribute as having been handled
}
+ found = true;
}
}
+ if( !found ) {
+ // TODO: Create no-op handlers for a whole heap of attributes
+ //WARNING(sp, W0000, "Unknown attribute " << a.name());
+ }
}
void Expand_Attrs(/*const */::AST::AttributeList& attrs, AttrStage stage, ::std::function<void(const Span& sp, const ExpandDecorator& d,const ::AST::Attribute& a)> f)
{
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 9af87d47..c148c51f 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -713,10 +713,14 @@ namespace {
}
// TODO: Bind `panic_impl` lang item to the item tagged with `panic_implementation`
+ m_of << "uint32_t panic_impl(uintptr_t payload) {";
+ const auto& panic_impl_path = m_crate.get_lang_item_path(Span(), "mrustc-panic_implementation");
+ m_of << "extern uint32_t " << Trans_Mangle(panic_impl_path) << "(uintptr_t payload);";
+ m_of << "return " << Trans_Mangle(panic_impl_path) << "(payload);";
+ m_of << "}\n";
// TODO: Bind `oom` lang item to the item tagged with `alloc_error_handler`
// - Can do this in enumerate/auto_impls instead, for better iteraction with enum
// XXX: HACK HACK HACK - This only works with libcore/libstd's current layout
- m_of << "uint32_t panic_impl(uintptr_t payload) { extern uint32_t __rust_start_panic(uintptr_t payload); return __rust_start_panic(payload); }\n";
m_of << "struct s__ZN4core5alloc6Layout_A { uintptr_t a, b; };\n";
m_of << "void oom_impl(struct s__ZN4core5alloc6Layout_A l) { extern void _ZN3std5alloc8rust_oom(struct s__ZN4core5alloc6Layout_A l); _ZN3std5alloc8rust_oom(l); }\n";
}
@@ -4475,7 +4479,7 @@ namespace {
{
case Compiler::Gcc:
m_of << "{ ";
- m_of << " jmp_buf jmpbuf; mrustc_panic_target = &jmpbuf;";
+ m_of << " jmp_buf jmpbuf, *old = mrustc_panic_target; mrustc_panic_target = &jmpbuf;";
m_of << " if(setjmp(jmpbuf)) {";
// NOTE: gcc unwind has a pointer as its `local_ptr` parameter
m_of << " *(void**)("; emit_param(e.args.at(2)); m_of << ") = mrustc_panic_value;";
@@ -4493,7 +4497,8 @@ namespace {
case Compiler::Gcc:
m_of << ";";
m_of << " }";
- m_of << " mrustc_panic_target = NULL;";
+ m_of << " if(mrustc_panic_target != &jmpbuf) { abort(); }";
+ m_of << " mrustc_panic_target = old;";
m_of << " }";
break;
default: