mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-26 08:33:14 +01:00
Emit all D inline asm labels as local labels.
On OS X, there is an actual significance to the distinction, which before lead e.g. to exception throwing in the below example being broken:
---
import core.exception;
void main() {
asm {
jmp Lfoo;
Lfoo:
;
}
throw cast(OutOfMemoryError)cast(void*)OutOfMemoryError.classinfo.init;
assert(0);
}
---
This commit is contained in:
@@ -1592,7 +1592,7 @@ namespace AsmParserx8632
|
||||
|
||||
void addLabel ( char* id )
|
||||
{
|
||||
insnTemplate << sc->func->mangle() << "_" << id;
|
||||
printLabelName(insnTemplate, sc->func->mangle(), id);
|
||||
}
|
||||
|
||||
/* Determines whether the operand is a register, memory reference
|
||||
|
||||
@@ -1725,7 +1725,7 @@ namespace AsmParserx8664
|
||||
|
||||
void addLabel ( char* id )
|
||||
{
|
||||
insnTemplate << sc->func->mangle() << "_" << id;
|
||||
printLabelName(insnTemplate, sc->func->mangle(), id);
|
||||
}
|
||||
|
||||
/* Determines whether the operand is a register, memory reference
|
||||
|
||||
@@ -561,7 +561,8 @@ void AsmBlockStatement::toIR(IRState* p)
|
||||
// we use a simple static counter to make sure the new end labels are unique
|
||||
static size_t uniqueLabelsId = 0;
|
||||
std::ostringstream asmGotoEndLabel;
|
||||
asmGotoEndLabel << "." << fdmangle << "__llvm_asm_end" << uniqueLabelsId++;
|
||||
printLabelName(asmGotoEndLabel, fdmangle, "_llvm_asm_end");
|
||||
asmGotoEndLabel << uniqueLabelsId++;
|
||||
|
||||
// initialize the setter statement we're going to build
|
||||
IRAsmStmt* outSetterStmt = new IRAsmStmt;
|
||||
@@ -599,7 +600,8 @@ void AsmBlockStatement::toIR(IRState* p)
|
||||
|
||||
// provide an in-asm target for the branch and set value
|
||||
Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string);
|
||||
code << fdmangle << '_' << a->isBranchToLabel->string << ":\n\t";
|
||||
printLabelName(code, fdmangle, a->isBranchToLabel->string);
|
||||
code << ":\n\t";
|
||||
code << "movl $<<in" << n_goto << ">>, $<<out0>>\n";
|
||||
//FIXME: Store the value -> label mapping somewhere, so it can be referenced later
|
||||
outSetterStmt->in.push_back(DtoConstUint(n_goto));
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include "template.h"
|
||||
#include "module.h"
|
||||
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
#include "gen/tollvm.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/runtime.h"
|
||||
@@ -1851,3 +1854,11 @@ void callPostblit(Loc &loc, Expression *exp, LLValue *val)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void printLabelName(std::ostream& target, const char* func_mangle, const char* label_name)
|
||||
{
|
||||
target << gTargetMachine->getMCAsmInfo()->getPrivateGlobalPrefix() <<
|
||||
func_mangle << "_" << label_name;
|
||||
}
|
||||
|
||||
@@ -185,4 +185,6 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
||||
|
||||
Type* stripModifiers(Type* type);
|
||||
|
||||
void printLabelName(std::ostream& target, const char* func_mangle, const char* label_name);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -85,7 +85,8 @@ void LabelStatement::toNakedIR(IRState *p)
|
||||
Logger::println("LabelStatement::toNakedIR(): %s", loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
p->nakedAsm << p->func()->decl->mangle() << "_" << ident->toChars() << ":";
|
||||
printLabelName(p->nakedAsm, p->func()->decl->mangle(), ident->toChars());
|
||||
p->nakedAsm << ":";
|
||||
|
||||
if (statement)
|
||||
statement->toNakedIR(p);
|
||||
|
||||
@@ -1388,10 +1388,10 @@ void LabelStatement::toIR(IRState* p)
|
||||
if (p->asmBlock)
|
||||
{
|
||||
IRAsmStmt* a = new IRAsmStmt;
|
||||
a->code += p->func()->decl->mangle();
|
||||
a->code += "_";
|
||||
a->code += ident->toChars();
|
||||
a->code += ":";
|
||||
std::stringstream label;
|
||||
printLabelName(label, p->func()->decl->mangle(), ident->toChars());
|
||||
label << ":";
|
||||
a->code = label.str();
|
||||
p->asmBlock->s.push_back(a);
|
||||
p->asmBlock->internalLabels.push_back(ident);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user