Skip to content
Closed
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
7 changes: 6 additions & 1 deletion backend-v2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(BACKEND_SOURCES
bridge/Exceptions.cpp
bridge/InstanceCallStub.cpp
bridge/ClassLookup.cpp
bridge/JITEngineBridge.cpp
bridge/ClassExtension.cpp
types/ObjectTypeSet.cpp
tools/ThreadPool.cpp
jit/JITEngine.cpp
Expand Down Expand Up @@ -139,7 +142,9 @@ set(BACKEND_SOURCES
codegen/ops/LocalNode.cpp
codegen/ops/WithMetaNode.cpp
codegen/ops/InstanceCallNode.cpp
codegen/ops/HostInteropNode.cpp)
codegen/ops/HostInteropNode.cpp
codegen/ops/NewNode.cpp
codegen/ops/IsInstanceNode.cpp)

add_subdirectory(runtime)

Expand Down
70 changes: 70 additions & 0 deletions backend-v2/bridge/ClassExtension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "ClassExtension.h"
#include "../tools/EdnParser.h"
#include "Exceptions.h"
#include <string>

using namespace rt;

extern "C" {
int32_t ClassExtension_fieldIndex(void *ext, RTValue field) {
ClassDescription *description = (ClassDescription *)ext;
String *s = String_compactify(::toString(field));
std::string key = String_c_str(s);
Ptr_release(s);

auto it = description->instanceFields.find(key);
if (it != description->instanceFields.end()) {
return it->second;
}
return -1;
}

int32_t ClassExtension_staticFieldIndex(void *ext, RTValue staticField) {
ClassDescription *description = (ClassDescription *)ext;
String *s = String_compactify(::toString(staticField));
std::string key = String_c_str(s);
Ptr_release(s);

auto it = description->staticFieldIndices.find(key);
if (it != description->staticFieldIndices.end()) {
return it->second;
}
return -1;
}

RTValue ClassExtension_getIndexedStaticField(void *ext, int32_t i) {
ClassDescription *description = (ClassDescription *)ext;
if (i >= 0 && i < (int32_t)description->staticFieldValues.size()) {
RTValue val = description->staticFieldValues[i];
retain(val);
return val;
}
return RT_boxNil();
}

RTValue ClassExtension_setIndexedStaticField(void *ext, int32_t i,
RTValue value) {
ClassDescription *description = (ClassDescription *)ext;
if (i >= 0 && i < (int32_t)description->staticFieldValues.size()) {
RTValue old = description->staticFieldValues[i];
description->staticFieldValues[i] = value;
release(old);
return value;
}
return value;
}

ClojureFunction *ClassExtension_resolveInstanceCall(void *ext, RTValue name,
int32_t argCount) {
ClassDescription *description = (ClassDescription *)ext;
String *s = String_compactify(::toString(name));
std::string key = String_c_str(s);
Ptr_release(s);

auto it = description->instanceFns.find(key);
if (it != description->instanceFns.end()) {
// Currently returns nullptr as in the original implementation
}
return nullptr;
}
}
15 changes: 15 additions & 0 deletions backend-v2/bridge/ClassExtension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef BRIDGE_CLASS_EXTENSION_H
#define BRIDGE_CLASS_EXTENSION_H

#include "../RuntimeHeaders.h"
#include <cstdint>

extern "C" {
int32_t ClassExtension_fieldIndex(void *ext, RTValue field);
int32_t ClassExtension_staticFieldIndex(void *ext, RTValue staticField);
RTValue ClassExtension_getIndexedStaticField(void *ext, int32_t i);
RTValue ClassExtension_setIndexedStaticField(void *ext, int32_t i, RTValue value);
ClojureFunction *ClassExtension_resolveInstanceCall(void *ext, RTValue name, int32_t argCount);
}

#endif
20 changes: 20 additions & 0 deletions backend-v2/bridge/ClassLookup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "ClassLookup.h"
#include "../jit/JITEngine.h"
#include "Exceptions.h"
#include <string>

using namespace rt;

extern "C" __attribute__((visibility("default"))) ::Class *
ClassLookup(const char *className, void *jitEngine) {
if (!jitEngine) {
throwInternalInconsistencyException("ClassLookup: jitEngine is null");
}
JITEngine *engine = static_cast<JITEngine *>(jitEngine);
Class *cls = engine->threadsafeState.classRegistry.getCurrent(className);
if (!cls) {
throwInternalInconsistencyException("ClassLookup: class not found: " +
std::string(className));
}
return cls;
}
17 changes: 17 additions & 0 deletions backend-v2/bridge/ClassLookup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef RT_CLASS_LOOKUP_H
#define RT_CLASS_LOOKUP_H

#ifdef __cplusplus
extern "C" {
#endif

struct Class;

__attribute__((visibility("default"))) ::Class *
ClassLookup(const char *className, void *jitEngine);

#ifdef __cplusplus
}
#endif

#endif // RT_CLASS_LOOKUP_H
17 changes: 17 additions & 0 deletions backend-v2/bridge/Exceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,23 @@ LanguageException::~LanguageException() noexcept {
release(payload);
}

const char *LanguageException::what() const noexcept {
static thread_local std::string whatBuffer;
try {
whatBuffer = name;
if (message != 0) {
String *s = ::toString(message);
String *msgStr = String_compactify(s);
whatBuffer += ": ";
whatBuffer += String_c_str(msgStr);
Ptr_release(msgStr);
}
return whatBuffer.c_str();
} catch (...) {
return "LanguageException (what() failed)";
}
}

std::string
LanguageException::toString(llvm::symbolize::LLVMSymbolizer &symbolizer,
const std::string &moduleName, const intptr_t slide,
Expand Down
1 change: 1 addition & 0 deletions backend-v2/bridge/Exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class LanguageException : public std::exception {
LanguageException(const LanguageException &other);
LanguageException &operator=(const LanguageException &other);
~LanguageException() noexcept override;
const char *what() const noexcept override;
void printRawTrace() const;

std::string toString(llvm::symbolize::LLVMSymbolizer &symbolizer,
Expand Down
16 changes: 16 additions & 0 deletions backend-v2/bridge/JITEngineBridge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "../runtime/JITSafety.h"
#include "../jit/JITEngine.h"

extern "C" {

void JITEngine_slowPath_enter(void *engine, rt_jt_epoch_t *epochPtr) {
if (engine)
static_cast<rt::JITEngine *>(engine)->registerThread(epochPtr);
}

void JITEngine_slowPath_leave(void *engine) {
if (engine)
static_cast<rt::JITEngine *>(engine)->unregisterThread();
}

}
16 changes: 8 additions & 8 deletions backend-v2/codegen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ TypedValue CodeGen::codegen(const Node &node,
return codegen(node, node.subnode().instancecall(), typeRestrictions);
// case opInstanceField:
// return codegen(node, node.subnode().instancefield(), typeRestrictions);
// case opIsInstance:
// return codegen(node, node.subnode().isinstance(), typeRestrictions);
case opIsInstance:
return codegen(node, node.subnode().isinstance(), typeRestrictions);
// case opInvoke:
// return codegen(node, node.subnode().invoke(), typeRestrictions);
// case opKeywordInvoke:
Expand All @@ -258,8 +258,8 @@ TypedValue CodeGen::codegen(const Node &node,
// return codegen(node, node.subnode().monitorenter(), typeRestrictions);
// case opMonitorExit:
// return codegen(node, node.subnode().monitorexit(), typeRestrictions);
// case opNew:
// return codegen(node, node.subnode().new_(), typeRestrictions);
case opNew:
return codegen(node, node.subnode().new_(), typeRestrictions);
// case opPrimInvoke:
// return codegen(node, node.subnode().priminvoke(), typeRestrictions);
// case opProtocolInvoke:
Expand Down Expand Up @@ -340,8 +340,8 @@ ObjectTypeSet CodeGen::getType(const Node &node,
return getType(node, node.subnode().instancecall(), typeRestrictions);
// case opInstanceField:
// return getType(node, node.subnode().instancefield(), typeRestrictions);
// case opIsInstance:
// return getType(node, node.subnode().isinstance(), typeRestrictions);
case opIsInstance:
return getType(node, node.subnode().isinstance(), typeRestrictions);
// case opInvoke:
// return getType(node, node.subnode().invoke(), typeRestrictions);
// case opKeywordInvoke:
Expand All @@ -360,8 +360,8 @@ ObjectTypeSet CodeGen::getType(const Node &node,
// return getType(node, node.subnode().monitorenter(), typeRestrictions);
// case opMonitorExit:
// return getType(node, node.subnode().monitorexit(), typeRestrictions);
// case opNew:
// return getType(node, node.subnode().new_(), typeRestrictions);
case opNew:
return getType(node, node.subnode().new_(), typeRestrictions);
// case opPrimInvoke:
// return getType(node, node.subnode().priminvoke(), typeRestrictions);
// case opProtocolInvoke:
Expand Down
8 changes: 8 additions & 0 deletions backend-v2/codegen/CodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ class CodeGen {
const ObjectTypeSet &typeRestrictions);
TypedValue codegen(const Node &node, const HostInteropNode &subnode,
const ObjectTypeSet &typeRestrictions);
TypedValue codegen(const Node &node, const NewNode &subnode,
const ObjectTypeSet &typeRestrictions);
TypedValue codegen(const Node &node, const IsInstanceNode &subnode,
const ObjectTypeSet &typeRestrictions);

ObjectTypeSet getType(const Node &node,
const ObjectTypeSet &typeRestrictions);
Expand Down Expand Up @@ -174,6 +178,10 @@ class CodeGen {
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const HostInteropNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const NewNode &subnode,
const ObjectTypeSet &typeRestrictions);
ObjectTypeSet getType(const Node &node, const IsInstanceNode &subnode,
const ObjectTypeSet &typeRestrictions);

Var *getOrCreateVar(std::string_view name);
bool canThrow(const clojure::rt::protobuf::bytecode::Node &node);
Expand Down
14 changes: 11 additions & 3 deletions backend-v2/codegen/DynamicConstructor.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "DynamicConstructor.h"
#include "CodeGen.h"
#include "../RuntimeHeaders.h"
#include "../bridge/Exceptions.h"
#include "../cljassert.h"
#include "../runtime/word.h"
#include "CodeGen.h"
#include "LLVMTypes.h"
#include "TypedValue.h"
#include "ValueEncoder.h"
Expand Down Expand Up @@ -74,6 +74,14 @@ TypedValue DynamicConstructor::createString(const char *s) {
types.ptrTy));
}

TypedValue DynamicConstructor::createClass(::Class *cls, std::string &name) {
generatedConstants.push_back(RT_boxPtr((void *)cls));
uintptr_t address = reinterpret_cast<uintptr_t>(cls);
return TypedValue(ObjectTypeSet(classType, false, new ConstantClass(name)),
ConstantExpr::getIntToPtr(
ConstantInt::get(types.i64Ty, address), types.ptrTy));
}

TypedValue DynamicConstructor::createKeyword(const char *s) {
String *str = String_createDynamicStr(s);
RTValue kwVal = Keyword_create(str);
Expand Down Expand Up @@ -112,7 +120,7 @@ TypedValue DynamicConstructor::createRatio(const char *s) {
}

TypedValue DynamicConstructor::createVector(std::vector<TypedValue> &items,
CleanupChainGuard *guard) {
CleanupChainGuard *guard) {
auto retValType = ObjectTypeSet(persistentVectorType, false);
std::vector<TypedValue> allArgs;
allArgs.push_back(createInt32(items.size()));
Expand Down Expand Up @@ -149,7 +157,7 @@ TypedValue DynamicConstructor::createArrayMap(std::vector<TypedValue> &keys,
}

TypedValue DynamicConstructor::createList(std::vector<TypedValue> &items,
CleanupChainGuard *guard) {
CleanupChainGuard *guard) {
auto retValType = ObjectTypeSet(persistentListType, false);
std::vector<TypedValue> allArgs;
allArgs.push_back(createInt32(items.size()));
Expand Down
1 change: 1 addition & 0 deletions backend-v2/codegen/DynamicConstructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class DynamicConstructor {
TypedValue createSymbol(const char *s);
TypedValue createBigInteger(const char *s);
TypedValue createRatio(const char *s);
TypedValue createClass(::Class *cls, std::string &name);

/*
* It is currently assumed the runtime constructors never throw
Expand Down
4 changes: 2 additions & 2 deletions backend-v2/codegen/ValueEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ TypedValue ValueEncoder::unboxPointer(TypedValue boxedVal) {
}

TypedValue ValueEncoder::unboxKeyword(TypedValue boxedVal) {
if (boxedVal.type.isBoxedType(keywordType))
if (boxedVal.type.isUnboxedType(keywordType))
return boxedVal;
// Strip the tag and return the ID (usually i32 is enough for enum IDs)
return TypedValue(
Expand All @@ -378,7 +378,7 @@ TypedValue ValueEncoder::unboxKeyword(TypedValue boxedVal) {
}

TypedValue ValueEncoder::unboxSymbol(TypedValue boxedVal) {
if (boxedVal.type.isBoxedType(symbolType))
if (boxedVal.type.isUnboxedType(symbolType))
return boxedVal;
// Strip the tag and return the ID (usually i32 is enough for enum IDs)
return TypedValue(
Expand Down
38 changes: 2 additions & 36 deletions backend-v2/codegen/invoke/InvokeManager_InstanceCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,20 +189,6 @@ TypedValue InvokeManager::generateDeterminedInstanceCall(
::Class *targetClass =
this->compilerState.classRegistry.getCurrent((int32_t)objType);

if (objType == classType && instance.type.getConstant()) {
if (auto *cc = dynamic_cast<ConstantClass *>(instance.type.getConstant())) {
::Class *constantClassPtr = (::Class *)cc->value;
if (targetClass && targetClass != constantClassPtr) {
Ptr_release(targetClass);
targetClass = constantClassPtr;
Ptr_retain(targetClass);
} else if (!targetClass) {
targetClass = constantClassPtr;
Ptr_retain(targetClass);
}
}
}

PtrWrapper<Class> cls(targetClass);
if (!cls) {
std::ostringstream oss;
Expand Down Expand Up @@ -457,9 +443,8 @@ TypedValue InvokeManager::generateDeterminedInstanceCall(
Value *methNameVal =
this->builder.CreateGlobalString(methodName, "instance_call_method");

FunctionType *fnTy = FunctionType::get(this->types.voidTy,
{this->types.ptrTy, this->types.ptrTy},
false);
FunctionType *fnTy = FunctionType::get(
this->types.voidTy, {this->types.ptrTy, this->types.ptrTy}, false);
this->invokeRaw("throwNoMatchingOverloadException_C", fnTy,
{classNameVal, methNameVal}, guard);
this->builder.CreateUnreachable();
Expand All @@ -486,25 +471,6 @@ InvokeManager::predictInstanceCallType(const std::string &methodName,
::Class *targetClass =
compilerState.classRegistry.getCurrent((int32_t)objType);

if (objType == classType && instanceType.getConstant()) {
if (auto *cc = dynamic_cast<ConstantClass *>(instanceType.getConstant())) {
::Class *constantClassPtr = (::Class *)cc->value;
if (targetClass && targetClass != constantClassPtr) {
Ptr_release(targetClass);
targetClass = constantClassPtr;
Ptr_retain(targetClass);
} else if (!targetClass) {
targetClass = constantClassPtr;
Ptr_retain(targetClass);
}
}
}

if (!targetClass) {
string name = ObjectTypeSet::toHumanReadableName(objType);
targetClass = compilerState.classRegistry.getCurrent(name.c_str());
}

PtrWrapper<Class> cls(targetClass);
if (!cls)
return ObjectTypeSet::dynamicType();
Expand Down
Loading
Loading