Add JIT library & basic jit interface (not implemented yet)

This commit is contained in:
Nikita Lisitsa 2025-12-18 18:42:12 +03:00
parent d64b6db229
commit cad6c06607
10 changed files with 162 additions and 0 deletions

View file

@ -4,6 +4,7 @@ project(pslang CXX)
add_subdirectory(libs/type)
add_subdirectory(libs/ast)
add_subdirectory(libs/parser)
add_subdirectory(libs/jit)
add_subdirectory(libs/interpreter)
add_subdirectory(apps/interpreter)

View file

@ -46,6 +46,7 @@ int main(int argc, char ** argv)
std::cout << " -t, --trace Trace each line of execution\n";
std::cout << " -d, --dump Dump all variables after processing all files\n";
std::cout << " -p, --print Print the AST after parsing each file\n";
std::cout << " -j, --jit Just-in-time compile & execute the code instead of interpreting\n";
return 0;
}
@ -55,6 +56,7 @@ int main(int argc, char ** argv)
bool dump = false;
bool dump_ast = false;
bool jit = false;
std::vector<std::string> filenames;
std::vector<ast::statement_list_ptr> parsed;
@ -79,6 +81,13 @@ int main(int argc, char ** argv)
continue;
}
if (std::strcmp(argv[arg], "-j") == 0 || std::strcmp(argv[arg], "--jit") == 0)
{
std::cerr << "Warning: JIT-compilation not supported yet" << std::endl;
jit = true;
continue;
}
try
{
filenames.push_back(argv[arg]);

6
libs/jit/CMakeLists.txt Normal file
View file

@ -0,0 +1,6 @@
file(GLOB_RECURSE PSLANG_JIT_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp")
file(GLOB_RECURSE PSLANG_JIT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")
add_library(pslang-jit STATIC ${PSLANG_JIT_HEADERS} ${PSLANG_JIT_SOURCES})
target_include_directories(pslang-jit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(pslang-jit PUBLIC pslang-ast)

View file

@ -0,0 +1,13 @@
#pragma once
namespace pslang::jit
{
enum class abi
{
itanium,
msvc,
arm,
};
}

View file

@ -0,0 +1,43 @@
#pragma once
#include <cstdint>
#include <memory>
namespace pslang::jit
{
struct blob
{
std::shared_ptr<std::uint8_t> data;
std::size_t size;
blob()
: data{nullptr}
, size{0}
{}
blob(std::shared_ptr<std::uint8_t> data, std::size_t size)
: data{std::move(data)}
, size{size}
{}
blob(blob && other)
: data{std::move(other.data)}
, size{other.size}
{
other.size = 0;
}
blob & operator = (blob && other)
{
if (this == &other)
return *this;
data = std::move(other.data);
size = other.size;
other.size = 0;
return *this;
}
};
}

View file

@ -0,0 +1,20 @@
#pragma once
#include <pslang/jit/abi.hpp>
#include <pslang/jit/blob.hpp>
#include <string>
#include <unordered_map>
namespace pslang::jit
{
struct compiled_module
{
blob memory;
std::unordered_map<std::string, std::size_t> symbol_table;
std::size_t entry_point;
jit::abi abi;
};
}

View file

@ -0,0 +1,10 @@
#pragma once
#include <pslang/jit/compiled_module.hpp>
namespace pslang::jit
{
compiled_module make_host_executable(compiled_module module);
}

View file

@ -0,0 +1,12 @@
#pragma once
#include <pslang/ast/statement_fwd.hpp>
#include <pslang/jit/compiled_module.hpp>
#include <pslang/jit/abi.hpp>
namespace pslang::jit
{
compiled_module compile(ast::statement_list_ptr const & statements, abi abi);
}

View file

@ -0,0 +1,32 @@
#include <pslang/jit/executable.hpp>
#include <stdexcept>
#ifdef __linux__
#include <sys/mman.h>
#endif
namespace pslang::jit
{
compiled_module make_host_executable(compiled_module module)
{
#ifdef __linux__
if (module.abi != abi::itanium)
throw std::runtime_error("Abi mismatch");
auto ptr = (std::uint8_t *)mmap(nullptr, module.memory.size, PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
auto shared_ptr = std::shared_ptr<std::uint8_t>(ptr, [size = module.memory.size](std::uint8_t * ptr){ munmap(ptr, size); });
return compiled_module {
.memory = blob(shared_ptr, module.memory.size),
.symbol_table = std::move(module.symbol_table),
.entry_point = module.entry_point,
.abi = module.abi,
};
#else
throw std::runtime_error("Host-executable modules are not supported for this platform");
#endif
}
}

16
libs/jit/source/jit.cpp Normal file
View file

@ -0,0 +1,16 @@
#include <pslang/jit/jit.hpp>
namespace pslang::jit
{
compiled_module compile(ast::statement_list_ptr const & /* statements */, jit::abi abi)
{
return {
.memory = {},
.symbol_table = {},
.entry_point = 0,
.abi = abi,
};
}
}