aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/CppBackend/CPPBackend.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-29 12:39:07 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-29 13:26:57 -0800
commit4545acff1c34d644a663953c3019ce4cf4df8bd1 (patch)
treed520d3890b2182b996b14b2de1fbeef3776124eb /lib/Target/CppBackend/CPPBackend.cpp
parentf72784546ad3575b0fd3288d8194605d0088d34c (diff)
generate postSets
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index fb79bee20d..a13dc57b5d 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -139,6 +139,7 @@ namespace {
HeapData GlobalData64;
GlobalAddressMap GlobalAddresses;
NameSet Externals;
+ std::string PostSets;
#include "CallHandlers.h"
@@ -207,15 +208,20 @@ namespace {
dump("TODO: function indexing");
return 0;
}
- unsigned getConstAsOffset(const Value *V) {
+ // Return a constant we are about to write into a global as a numeric offset. If the
+ // value is not known at compile time, emit a postSet to that location.
+ unsigned getConstAsOffset(const Value *V, unsigned AbsoluteTarget) {
if (const Function *F = dyn_cast<const Function>(V)) {
return getFunctionIndex(F);
} else {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
if (GV->hasExternalLinkage()) {
+ // We don't have a constant to emit here, so we must emit a postSet
+ // All postsets are of external values, so they are pointers, hence 32-bit
std::string Name = getOpName(V);
Externals.insert(Name);
- return 0;
+ PostSets += "HEAP32[" + utostr(AbsoluteTarget>>2) + "] = " + Name + ';';
+ return 0; // emit zero in there for now, until the postSet
}
}
return getGlobalAddress(V->getName().str());
@@ -2235,6 +2241,10 @@ void CppWriter::printModuleBody() {
nl(Out);
}
}
+ Out << " function runPostSets() {\n";
+ Out << " " + PostSets + "\n";
+ Out << " }\n";
+ PostSets = "";
Out << "// EMSCRIPTEN_END_FUNCTIONS\n\n";
// TODO fix commas
@@ -2386,6 +2396,8 @@ void CppWriter::parseConstant(std::string name, const Constant* CV, bool calcula
// This is the only constant where we cannot just emit everything during the first phase, 'calculate', as we may refer to other globals
unsigned Num = CS->getNumOperands();
unsigned Offset = getRelativeGlobalAddress(name);
+ unsigned OffsetStart = Offset;
+ unsigned Absolute = getGlobalAddress(name);
for (unsigned i = 0; i < Num; i++) {
const Constant* C = CS->getOperand(i);
if (isa<ConstantAggregateZero>(C)) {
@@ -2396,10 +2408,10 @@ void CppWriter::parseConstant(std::string name, const Constant* CV, bool calcula
Value *V = CE->getOperand(0);
unsigned Data = 0;
if (CE->getOpcode() == Instruction::PtrToInt) {
- Data = getConstAsOffset(V);
+ Data = getConstAsOffset(V, Absolute + Offset - OffsetStart);
} else if (CE->getOpcode() == Instruction::Add) {
V = dyn_cast<ConstantExpr>(V)->getOperand(0);
- Data = getConstAsOffset(V);
+ Data = getConstAsOffset(V, Absolute + Offset - OffsetStart);
ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(1));
Data += *CI->getValue().getRawData();
} else {
@@ -2442,7 +2454,7 @@ void CppWriter::parseConstant(std::string name, const Constant* CV, bool calcula
} else {
unsigned Offset = getRelativeGlobalAddress(name);
Value *V = CE->getOperand(0);
- unsigned Data = getConstAsOffset(V);
+ unsigned Data = getConstAsOffset(V, getGlobalAddress(name));
union { unsigned i; unsigned char b[sizeof(unsigned)]; } integer;
integer.i = Data;
assert(Offset+4 <= GlobalData32.size());