Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion backend-v2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ set(BACKEND_SOURCES
codegen/ops/VectorNode.cpp
codegen/ops/MapNode.cpp
codegen/ops/StaticCallNode.cpp
codegen/ops/IfNode.cpp)
codegen/ops/IfNode.cpp
codegen/ops/DefNode.cpp
codegen/ops/TheVarNode.cpp
codegen/ops/VarNode.cpp)


# 2. Protobuf Detection
Expand Down
46 changes: 32 additions & 14 deletions backend-v2/codegen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@
#include "../bridge/Exceptions.h"
#include "../cljassert.h"
#include "TypedValue.h"
#include "runtime/RTValue.h"
#include "runtime/String.h"
#include "runtime/Object.h"

using namespace llvm;

namespace rt {

CodeGen::~CodeGen() {
for (auto &val : generatedConstants) {
Ptr_release(RT_unboxPtr(val));
}
}

CodeGenResult CodeGen::release() && {
DIB->finalize();
return {std::move(TSContext), std::move(TheModule),
std::move(generatedConstants)};
auto constants = std::move(generatedConstants);
generatedConstants.clear(); // Ensure destructor doesn't re-release
return {std::move(TSContext), std::move(TheModule), std::move(constants)};
}

std::string CodeGen::codegenTopLevel(const Node &node) {
Expand Down Expand Up @@ -99,8 +110,8 @@ TypedValue CodeGen::codegen(const Node &node,
// return codegen(node, node.subnode().casethen(), typeRestrictions);
// case opCatch:
// return codegen(node, node.subnode().catch_(), typeRestrictions);
// case opDef:
// return codegen(node, node.subnode().def(), typeRestrictions);
case opDef:
return codegen(node, node.subnode().def(), typeRestrictions);
// case opDeftype:
// return codegen(node, node.subnode().deftype(), typeRestrictions);
// case opDo:
Expand Down Expand Up @@ -155,14 +166,14 @@ TypedValue CodeGen::codegen(const Node &node,
// return codegen(node, node.subnode().mutateset(), typeRestrictions);
// case opStaticField:
// return codegen(node, node.subnode().staticfield(), typeRestrictions);
// case opTheVar:
// return codegen(node, node.subnode().thevar(), typeRestrictions);
case opTheVar:
return codegen(node, node.subnode().thevar(), typeRestrictions);
// case opThrow:
// return codegen(node, node.subnode().throw_(), typeRestrictions);
// case opTry:
// return codegen(node, node.subnode().try_(), typeRestrictions);
// case opVar:
// return codegen(node, node.subnode().var(), typeRestrictions);
case opVar:
return codegen(node, node.subnode().var(), typeRestrictions);
// case opWithMeta:
// return codegen(node, node.subnode().withmeta(), typeRestrictions);
default:
Expand Down Expand Up @@ -199,8 +210,8 @@ ObjectTypeSet CodeGen::getType(const Node &node,
// return getType(node, node.subnode().casethen(), typeRestrictions);
// case opCatch:
// return getType(node, node.subnode().catch_(), typeRestrictions);
// case opDef:
// return getType(node, node.subnode().def(), typeRestrictions);
case opDef:
return getType(node, node.subnode().def(), typeRestrictions);
// case opDeftype:
// return getType(node, node.subnode().deftype(), typeRestrictions);
// case opDo:
Expand Down Expand Up @@ -255,14 +266,14 @@ ObjectTypeSet CodeGen::getType(const Node &node,
// return getType(node, node.subnode().mutateset(), typeRestrictions);
// case opStaticField:
// return getType(node, node.subnode().staticfield(), typeRestrictions);
// case opTheVar:
// return getType(node, node.subnode().thevar(), typeRestrictions);
case opTheVar:
return getType(node, node.subnode().thevar(), typeRestrictions);
// case opThrow:
// return getType(node, node.subnode().throw_(), typeRestrictions);
// case opTry:
// return getType(node, node.subnode().try_(), typeRestrictions);
// case opVar:
// return getType(node, node.subnode().var(), typeRestrictions);
case opVar:
return getType(node, node.subnode().var(), typeRestrictions);
// case opWithMeta:
// return getType(node, node.subnode().withmeta(), typeRestrictions);
default:
Expand All @@ -274,5 +285,12 @@ ObjectTypeSet CodeGen::getType(const Node &node,
return ObjectTypeSet::all();
}

Var *CodeGen::getOrCreateVar(std::string_view name) {
return compilerState.varRegistry.getOrCreate(
std::string(name).c_str(), [this, name]() {
auto n = std::string(name);
return dynamicConstructor.createVarRaw(n.c_str());
});
}

} // namespace rt
30 changes: 17 additions & 13 deletions backend-v2/codegen/CodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,6 @@ struct CodeGenResult {
std::vector<RTValue> constants;
};

class CodeGenerationException : public std::runtime_error {
const Node *node;

public:
CodeGenerationException(const std::string &msg, const Node &n)
: std::runtime_error(msg), node(&n) {}
const Node &getNode() const { return *node; }
};

class CodeGen {
std::unique_ptr<llvm::orc::ThreadSafeContext> TSContext;

Expand Down Expand Up @@ -88,6 +79,8 @@ class CodeGen {
false, "", 0);
}

~CodeGen();

CodeGenResult release() &&;

std::string codegenTopLevel(const Node &node);
Expand All @@ -104,16 +97,22 @@ class CodeGen {
const ObjectTypeSet &typeRestrictions);
TypedValue codegen(const Node &node, const StaticCallNode &subnode,
const ObjectTypeSet &typeRestrictions);

TypedValue codegen(const Node &node, const TheVarNode &subnode,
const ObjectTypeSet &typeRestrictions);
TypedValue codegen(const Node &node, const IfNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const IfNode &subnode,
const ObjectTypeSet &typeRestrictions);

TypedValue codegen(const Node &node, const VarNode &subnode,
const ObjectTypeSet &typeRestrictions);
TypedValue codegen(const Node &node, const DefNode &subnode,
const ObjectTypeSet &typeRestrictions);

ObjectTypeSet getType(const Node &node,
const ObjectTypeSet &typeRestrictions);

ObjectTypeSet getType(const Node &node, const TheVarNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const IfNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const ConstNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const QuoteNode &subnode,
Expand All @@ -124,6 +123,11 @@ class CodeGen {
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const StaticCallNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const VarNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const DefNode &subnode,
const ObjectTypeSet &typeRestrictions);
Var *getOrCreateVar(std::string_view name);
};
} // namespace rt

Expand Down
16 changes: 16 additions & 0 deletions backend-v2/codegen/DynamicConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include "TypedValue.h"
#include "ValueEncoder.h"
#include "invoke/InvokeManager.h"
#include "runtime/Keyword.h"
#include "runtime/RTValue.h"
#include "runtime/Var.h"
#include "llvm/ADT/StringSwitch.h"
#include <cstdint>
#include <llvm/IR/Constants.h>
Expand Down Expand Up @@ -71,6 +74,19 @@ TypedValue DynamicConstructor::createString(const char *s) {
types.ptrTy));
}

TypedValue DynamicConstructor::createVar(const char *name) {
Var *var = Var_create(Keyword_create(String_createDynamicStr(name)));
uintptr_t address = reinterpret_cast<uintptr_t>(var);
return TypedValue(ObjectTypeSet(varType),
ConstantExpr::getIntToPtr(
ConstantInt::get(types.i64Ty, address), types.ptrTy));
}

Var *DynamicConstructor::createVarRaw(const char *name) {
Var *var = Var_create(Keyword_create(String_createDynamicStr(name)));
return var;
}

TypedValue DynamicConstructor::createKeyword(const char *s) {
String *str = String_createDynamicStr(s);
RTValue kwVal = Keyword_create(str);
Expand Down
2 changes: 2 additions & 0 deletions backend-v2/codegen/DynamicConstructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class DynamicConstructor {
TypedValue createSymbol(const char *s);
TypedValue createBigInteger(const char *s);
TypedValue createRatio(const char *s);
TypedValue createVar(const char *name);
Var *createVarRaw(const char *name);

/*
* TODO:
Expand Down
46 changes: 27 additions & 19 deletions backend-v2/codegen/ops/ConstNode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "../../bridge/Exceptions.h"
#include "../../tools/RTValueWrapper.h"
#include "../CodeGen.h"
#include "codegen/TypedValue.h"
#include <string>

using namespace std;
using namespace llvm;
Expand Down Expand Up @@ -84,17 +87,21 @@ TypedValue CodeGen::codegen(const Node &node, const ConstNode &subnode,
retVal = dynamicConstructor.createRatio(subnode.val().c_str());
memoryManagement.dynamicRetain(retVal);
break;
// case varType:
// {
// Var *var = TheProgramme->getVarByName(subnode.val());
// if (!var) {
// throwCodeGenerationException("Unable to resolve var: " +
// subnode.val() + " in this context", node);
// }
// retVal =
// Builder->CreateBitOrPointerCast(ConstantInt::get(Type::getInt64Ty(*TheContext),
// APInt(64, (uint64_t) var, false)), ptrT); dynamicRetain(retVal); break;
// }
case varType: {
const std::string name = subnode.val();
ScopedRef<Var> var(compilerState.varRegistry.getCurrent(name.c_str()));
if (!var) {
throwCodeGenerationException(
string("Unable to resolve var: ") + name + " in this context", node);
}
uint64_t address = reinterpret_cast<uint64_t>(var.get());
retVal = TypedValue(
ObjectTypeSet(varType),
ConstantExpr::getIntToPtr(ConstantInt::get(this->types.i64Ty, address),
this->types.ptrTy));
memoryManagement.dynamicRetain(retVal);
break;
}
case persistentListType:

case persistentVectorType:
Expand Down Expand Up @@ -139,7 +146,8 @@ ObjectTypeSet CodeGen::getType(const Node &node, const ConstNode &subnode,
}

if (node.tag() == "double" || node.otag() == "double" ||
node.tag() == "class java.lang.Double" || subnode.val().find('.') != string::npos) {
node.tag() == "class java.lang.Double" ||
subnode.val().find('.') != string::npos) {
return ObjectTypeSet(doubleType, false,
new ConstantDouble(stod(subnode.val())))
.restriction(typeRestrictions);
Expand All @@ -162,10 +170,11 @@ ObjectTypeSet CodeGen::getType(const Node &node, const ConstNode &subnode,
}
}
} catch (...) {
if (!subnode.val().empty() && (isdigit(subnode.val()[0]) || subnode.val()[0] == '-')) {
return ObjectTypeSet(bigIntegerType, true,
new ConstantBigInteger(subnode.val()))
.restriction(typeRestrictions);
if (!subnode.val().empty() &&
(isdigit(subnode.val()[0]) || subnode.val()[0] == '-')) {
return ObjectTypeSet(bigIntegerType, true,
new ConstantBigInteger(subnode.val()))
.restriction(typeRestrictions);
}
}
}
Expand All @@ -192,10 +201,9 @@ ObjectTypeSet CodeGen::getType(const Node &node, const ConstNode &subnode,
.restriction(typeRestrictions);
// case ConstNode_ConstType_constTypeClass:
// return ObjectTypeSet(classType).restriction(typeRestrictions);
// case ConstNode_ConstType_constTypeVar:
// return ObjectTypeSet(varType).restriction(typeRestrictions);
case ConstNode_ConstType_constTypeVar:
return ObjectTypeSet(varType).restriction(typeRestrictions);
case ConstNode_ConstType_constTypeType:

case ConstNode_ConstType_constTypeRecord:
case ConstNode_ConstType_constTypeMap:
case ConstNode_ConstType_constTypeVector:
Expand Down
44 changes: 44 additions & 0 deletions backend-v2/codegen/ops/DefNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "../CodeGen.h"
#include "bridge/Exceptions.h"
#include "tools/RTValueWrapper.h"
#include "types/ObjectTypeSet.h"

using namespace std;
using namespace llvm;

namespace rt {

TypedValue CodeGen::codegen(const Node &node, const DefNode &subnode,
const ObjectTypeSet &typeRestrictions) {
auto varName = subnode.var().substr(2);
ScopedRef<Var> var(getOrCreateVar(varName));
uint64_t address = reinterpret_cast<uint64_t>(var.get());
TypedValue varPtr = TypedValue(
ObjectTypeSet(varType),
ConstantExpr::getIntToPtr(ConstantInt::get(this->types.i64Ty, address),
this->types.ptrTy));
memoryManagement.dynamicRetain(varPtr);
if (subnode.has_init()) {
TypedValue initValue = codegen(subnode.init(), ObjectTypeSet::all());
memoryManagement.dynamicRetain(varPtr);
invokeManager.invokeRuntime(
"Var_bindRoot", nullptr,
{ObjectTypeSet(varType), ObjectTypeSet::dynamicType()},
{varPtr, initValue});
}

return varPtr;
}

ObjectTypeSet CodeGen::getType(const Node &node, const DefNode &subnode,
const ObjectTypeSet &typeRestrictions) {
auto varName = subnode.var().substr(2);
if (!typeRestrictions.contains(varType)) {
throwCodeGenerationException(
"Def cannot be used here because it returns var: " + varName, node);
}
getOrCreateVar(varName);
return ObjectTypeSet(varType);
}

} // namespace rt
31 changes: 31 additions & 0 deletions backend-v2/codegen/ops/TheVarNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "../CodeGen.h"
#include "bridge/Exceptions.h"
#include "../../tools/RTValueWrapper.h"

using namespace std;
using namespace llvm;

namespace rt {

TypedValue CodeGen::codegen(const Node &node, const TheVarNode &subnode,
const ObjectTypeSet &typeRestrictions) {
auto varName = subnode.var().substr(2);
ScopedRef<Var> var(compilerState.varRegistry.getCurrent(varName.c_str()));
if (!var)
throwCodeGenerationException(
"Unable to resolve var: " + varName + " in this context", node);
uintptr_t address = reinterpret_cast<uintptr_t>(var.get());
auto retVal = TypedValue(
ObjectTypeSet(varType),
ConstantExpr::getIntToPtr(ConstantInt::get(this->types.i64Ty, address),
this->types.ptrTy));
memoryManagement.dynamicRetain(retVal);
return retVal;
}

ObjectTypeSet CodeGen::getType(const Node &node, const TheVarNode &subnode,
const ObjectTypeSet &typeRestrictions) {
return ObjectTypeSet(varType);
}

} // namespace rt
Loading
Loading