From da0458bf6ec909e202a4e8b87196aba31134e20a Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Thu, 18 May 2023 12:03:29 +0100 Subject: [PATCH] Add CodeGen C API (#931) I'd like to experiment with the codegen feature (currently experimental) and need a public C API for this. This PR addresses this. --- CMakeLists.txt | 3 +++ CodeGen/include/luacodegen.h | 18 ++++++++++++++++++ CodeGen/src/lcodegen.cpp | 21 +++++++++++++++++++++ Sources.cmake | 2 ++ tests/Conformance.test.cpp | 18 +++++++++--------- 5 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 CodeGen/include/luacodegen.h create mode 100644 CodeGen/src/lcodegen.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b3b1573a..b6e8b591 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,9 @@ endif() if(LUAU_NATIVE) target_compile_definitions(Luau.VM PUBLIC LUA_CUSTOM_EXECUTION=1) + if(LUAU_EXTERN_C) + target_compile_definitions(Luau.CodeGen PUBLIC LUACODEGEN_API=extern\"C\") + endif() endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER_EQUAL 1924) diff --git a/CodeGen/include/luacodegen.h b/CodeGen/include/luacodegen.h new file mode 100644 index 00000000..1eb185d2 --- /dev/null +++ b/CodeGen/include/luacodegen.h @@ -0,0 +1,18 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +// Can be used to reconfigure visibility/exports for public APIs +#ifndef LUACODEGEN_API +#define LUACODEGEN_API extern +#endif + +struct lua_State; + +// returns 1 if Luau code generator is supported, 0 otherwise +LUACODEGEN_API int luau_codegen_supported(); + +// create an instance of Luau code generator. you must check that this feature is supported using luau_codegen_supported(). +LUACODEGEN_API void luau_codegen_create(lua_State* L); + +// build target function and all inner functions +LUACODEGEN_API void luau_codegen_compile(lua_State* L, int idx); diff --git a/CodeGen/src/lcodegen.cpp b/CodeGen/src/lcodegen.cpp new file mode 100644 index 00000000..0795cd48 --- /dev/null +++ b/CodeGen/src/lcodegen.cpp @@ -0,0 +1,21 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#include "luacodegen.h" + +#include "Luau/CodeGen.h" + +#include "lapi.h" + +int luau_codegen_supported() +{ + return Luau::CodeGen::isSupported(); +} + +void luau_codegen_create(lua_State* L) +{ + Luau::CodeGen::create(L); +} + +void luau_codegen_compile(lua_State* L, int idx) +{ + Luau::CodeGen::compile(L, idx); +} diff --git a/Sources.cmake b/Sources.cmake index 6beb02cb..2b51721e 100644 --- a/Sources.cmake +++ b/Sources.cmake @@ -79,6 +79,7 @@ target_sources(Luau.CodeGen PRIVATE CodeGen/include/Luau/UnwindBuilder.h CodeGen/include/Luau/UnwindBuilderDwarf2.h CodeGen/include/Luau/UnwindBuilderWin.h + CodeGen/include/luacodegen.h CodeGen/src/AssemblyBuilderA64.cpp CodeGen/src/AssemblyBuilderX64.cpp @@ -104,6 +105,7 @@ target_sources(Luau.CodeGen PRIVATE CodeGen/src/IrTranslation.cpp CodeGen/src/IrUtils.cpp CodeGen/src/IrValueLocationTracking.cpp + CodeGen/src/lcodegen.cpp CodeGen/src/NativeState.cpp CodeGen/src/OptimizeConstProp.cpp CodeGen/src/OptimizeFinalX64.cpp diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index 6a2c528d..9e5ae30e 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -2,13 +2,13 @@ #include "lua.h" #include "lualib.h" #include "luacode.h" +#include "luacodegen.h" #include "Luau/BuiltinDefinitions.h" #include "Luau/ModuleResolver.h" #include "Luau/TypeInfer.h" #include "Luau/StringUtils.h" #include "Luau/BytecodeBuilder.h" -#include "Luau/CodeGen.h" #include "Luau/Frontend.h" #include "doctest.h" @@ -159,8 +159,8 @@ static StateRef runConformance(const char* name, void (*setup)(lua_State* L) = n StateRef globalState(initialLuaState, lua_close); lua_State* L = globalState.get(); - if (codegen && !skipCodegen && Luau::CodeGen::isSupported()) - Luau::CodeGen::create(L); + if (codegen && !skipCodegen && luau_codegen_supported()) + luau_codegen_create(L); luaL_openlibs(L); @@ -213,8 +213,8 @@ static StateRef runConformance(const char* name, void (*setup)(lua_State* L) = n int result = luau_load(L, chunkname.c_str(), bytecode, bytecodeSize, 0); free(bytecode); - if (result == 0 && codegen && !skipCodegen && Luau::CodeGen::isSupported()) - Luau::CodeGen::compile(L, -1); + if (result == 0 && codegen && !skipCodegen && luau_codegen_supported()) + luau_codegen_compile(L, -1); int status = (result == 0) ? lua_resume(L, nullptr, 0) : LUA_ERRSYNTAX; @@ -1679,8 +1679,8 @@ TEST_CASE("HugeFunction") StateRef globalState(luaL_newstate(), lua_close); lua_State* L = globalState.get(); - if (codegen && Luau::CodeGen::isSupported()) - Luau::CodeGen::create(L); + if (codegen && luau_codegen_supported()) + luau_codegen_create(L); luaL_openlibs(L); luaL_sandbox(L); @@ -1693,8 +1693,8 @@ TEST_CASE("HugeFunction") REQUIRE(result == 0); - if (codegen && Luau::CodeGen::isSupported()) - Luau::CodeGen::compile(L, -1); + if (codegen && luau_codegen_supported()) + luau_codegen_compile(L, -1); int status = lua_resume(L, nullptr, 0); REQUIRE(status == 0);