diff --git a/.gitignore b/.gitignore index f105ccb..5dc021b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ package-lock.json test/temp/ /**/**/.DS_Store -cmake_install.cmake \ No newline at end of file +cmake_install.cmake +llvm-bindings.d.ts diff --git a/CMakeLists.txt b/CMakeLists.txt index 47ba68e..c61c0f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.17) project(llvm-bindings) +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) set(CMAKE_CXX_STANDARD 17) @@ -26,8 +27,29 @@ execute_process( string(REGEX REPLACE "[\r\n\"]" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR}) +# Add a library to generate the TypeScript declarations +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/llvm-bindings.d.ts.cpp + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/llvm-bindings.in.d.ts + ${CMAKE_CURRENT_BINARY_DIR}/llvm-bindings.d.ts.cpp + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/llvm-bindings.in.d.ts +) +add_library(ts_decl_lib OBJECT ${CMAKE_CURRENT_BINARY_DIR}/llvm-bindings.d.ts.cpp) +target_link_libraries(ts_decl_lib ${LLVM_LIBS}) +target_compile_options(ts_decl_lib PRIVATE -E -P --traditional-cpp) +target_include_directories(ts_decl_lib PRIVATE ${LLVM_INCLUDE_DIRS}) + target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_JS_INC} ${NODE_ADDON_API_DIR}) target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} ${LLVM_LIBS}) add_definitions(-DNAPI_VERSION=8) + +add_custom_target( + ts_declarations + COMMAND ${CMAKE_COMMAND} -E copy "$" ${CMAKE_CURRENT_SOURCE_DIR}/llvm-bindings.d.ts + DEPENDS ts_decl_lib +) + +add_dependencies(${PROJECT_NAME} ts_declarations) diff --git a/README.md b/README.md index 4e0b169..e53b782 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ Due to the limitation of `node-addon-api`, this project has not implemented inhe | 0.2.x | 12.0.x | | 0.3.x | 13.0.x | | 0.4.x | 14.0.x | +| 0.5.x | 16.0.x | ## Acknowledgments - [MichaReiser](https://github.com/MichaReiser): the creator of [llvm-node](https://github.com/MichaReiser/llvm-node) diff --git a/cmake/CMakeJS.cmake b/cmake/CMakeJS.cmake index 9cdaaab..c554a5d 100644 --- a/cmake/CMakeJS.cmake +++ b/cmake/CMakeJS.cmake @@ -37,17 +37,15 @@ endfunction(GET_VARIABLE) string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) if (CMAKE_BUILD_TYPE_LOWER STREQUAL "debug") - exec_program( - ${CMakeJS} - ${CMAKE_CURRENT_SOURCE_DIR} - ARGS print-configure --debug + execute_process( + COMMAND ${CMakeJS} print-configure --debug + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE CMAKE_JS_OUTPUT ) else () - exec_program( - ${CMakeJS} - ${CMAKE_CURRENT_SOURCE_DIR} - ARGS print-configure + execute_process( + COMMAND ${CMakeJS} print-configure + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE CMAKE_JS_OUTPUT ) endif () diff --git a/cmake/LLVM.cmake b/cmake/LLVM.cmake index 1c770b1..85a7d82 100644 --- a/cmake/LLVM.cmake +++ b/cmake/LLVM.cmake @@ -5,7 +5,7 @@ if (CMAKE_HOST_APPLE) endforeach () endif () -find_package(LLVM 14 REQUIRED CONFIG) +find_package(LLVM 16 REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") diff --git a/include/IR/DerivedTypes.h b/include/IR/DerivedTypes.h index ca6b974..ebc3687 100644 --- a/include/IR/DerivedTypes.h +++ b/include/IR/DerivedTypes.h @@ -228,5 +228,5 @@ class PointerType : public Napi::ObjectWrap { Napi::Value getTypeID(const Napi::CallbackInfo &info); - Napi::Value getPointerElementType(const Napi::CallbackInfo &info); + Napi::Value getNonOpaquePointerElementType(const Napi::CallbackInfo &info); }; diff --git a/include/IR/Type.h b/include/IR/Type.h index 1b4175a..fd0b83a 100644 --- a/include/IR/Type.h +++ b/include/IR/Type.h @@ -39,7 +39,7 @@ class Type : public Napi::ObjectWrap { return Napi::Boolean::New(info.Env(), (type->*method)()); } - Napi::Value getPointerElementType(const Napi::CallbackInfo &info); + Napi::Value getNonOpaquePointerElementType(const Napi::CallbackInfo &info); static Napi::Value isSameType(const Napi::CallbackInfo &info); }; diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 0000000..8ef0bcf --- /dev/null +++ b/include/assert.h @@ -0,0 +1,13 @@ +#ifndef __LLVM_BINDINGS_NODEJS_ASSERT__ +#define __LLVM_BINDINGS_NODEJS_ASSERT__ + +#ifdef __cplusplus +void llvm_bindings_assert(const char* expr, const char* file, int line); + +#define __assert(e, file, line) ((void)llvm_bindings_assert ((e), (file), (line))) + +#define assert(e) ((void) ((e) ? ((void)0) : __assert (#e, __FILE__, __LINE__))) + +#endif + +#endif diff --git a/llvm-bindings.d.ts b/llvm-bindings.in.d.ts similarity index 96% rename from llvm-bindings.d.ts rename to llvm-bindings.in.d.ts index ca993af..2bb6181 100644 --- a/llvm-bindings.d.ts +++ b/llvm-bindings.in.d.ts @@ -98,86 +98,13 @@ declare namespace llvm { class Attribute { public static readonly AttrKind: { - AlwaysInline: number; - ArgMemOnly: number; - Builtin: number; - Cold: number; - Convergent: number; - DisableSanitizerInstrumentation: number; - Hot: number; - ImmArg: number; - InReg: number; - InaccessibleMemOnly: number; - InaccessibleMemOrArgMemOnly: number; - InlineHint: number; - JumpTable: number; - MinSize: number; - MustProgress: number; - Naked: number; - Nest: number; - NoAlias: number; - NoBuiltin: number; - NoCallback: number; - NoCapture: number; - NoCfCheck: number; - NoDuplicate: number; - NoFree: number; - NoImplicitFloat: number; - NoInline: number; - NoMerge: number; - NoProfile: number; - NoRecurse: number; - NoRedZone: number; - NoReturn: number; - NoSanitizeCoverage: number; - NoSync: number; - NoUndef: number; - NoUnwind: number; - NonLazyBind: number; - NonNull: number; - NullPointerIsValid: number; - OptForFuzzing: number; - OptimizeForSize: number; - OptimizeNone: number; - ReadNone: number; - ReadOnly: number; - Returned: number; - ReturnsTwice: number; - SExt: number; - SafeStack: number; - SanitizeAddress: number; - SanitizeHWAddress: number; - SanitizeMemTag: number; - SanitizeMemory: number; - SanitizeThread: number; - ShadowCallStack: number; - Speculatable: number; - SpeculativeLoadHardening: number; - StackProtect: number; - StackProtectReq: number; - StackProtectStrong: number; - StrictFP: number; - SwiftAsync: number; - SwiftError: number; - SwiftSelf: number; - UWTable: number; - WillReturn: number; - WriteOnly: number; - LastEnumAttr: number; - ByRef: number; - ByVal: number; - ElementType: number; - InAlloca: number; - Preallocated: number; - LastTypeAttr: number; - Alignment: number; - AllocSize: number; - Dereferenceable: number; - DereferenceableOrNull: number; - StackAlignment: number; - VScaleRange: number; - }; +#define GET_ATTR_NAMES +#define ATTRIBUTE_ENUM(EnumName, lower) \ + EnumName: number; +#include "llvm/IR/Attributes.inc" + + }; public static get(context: LLVMContext, kind: number, value?: number): Attribute; public static get(context: LLVMContext, kind: string, value?: string): Attribute; public static get(context: LLVMContext, kind: number, type: Type): Attribute; @@ -374,7 +301,7 @@ declare namespace llvm { public getPrimitiveSizeInBits(): number; - public getPointerElementType(): Type; + public getNonOpaquePointerElementType(): Type; // extra public static isSameType(type1: Type, type2: Type): boolean; @@ -516,8 +443,10 @@ declare namespace llvm { // duplicated public getTypeID(): number; - // duplicated - public getPointerElementType(): Type; + /** + * @deprecated In LLVM 15,16 these are deprecated. LLVM 17 this is removed + */ + public getNonOpaquePointerElementType(): Type; protected constructor(); } diff --git a/package.json b/package.json index 3ff2cfc..21f818a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "llvm-bindings", - "version": "0.4.2", + "version": "0.5.0", "description": "LLVM bindings for Node.js/JavaScript/TypeScript", "keywords": [ "llvm", diff --git a/src/IR/Attributes.cpp b/src/IR/Attributes.cpp index 6b96e84..c86cf12 100644 --- a/src/IR/Attributes.cpp +++ b/src/IR/Attributes.cpp @@ -5,88 +5,10 @@ void Attribute::Init(Napi::Env env, Napi::Object &exports) { Napi::HandleScope scope(env); Napi::Object attributeKinds = Napi::Object::New(env); - attributeKinds.Set("AlwaysInline", Napi::Number::New(env, llvm::Attribute::AttrKind::AlwaysInline)); - attributeKinds.Set("ArgMemOnly", Napi::Number::New(env, llvm::Attribute::AttrKind::ArgMemOnly)); - attributeKinds.Set("Builtin", Napi::Number::New(env, llvm::Attribute::AttrKind::Builtin)); - attributeKinds.Set("Cold", Napi::Number::New(env, llvm::Attribute::AttrKind::Cold)); - attributeKinds.Set("Convergent", Napi::Number::New(env, llvm::Attribute::AttrKind::Convergent)); - attributeKinds.Set("DisableSanitizerInstrumentation", - Napi::Number::New(env, llvm::Attribute::AttrKind::DisableSanitizerInstrumentation)); - attributeKinds.Set("Hot", Napi::Number::New(env, llvm::Attribute::AttrKind::Hot)); - attributeKinds.Set("ImmArg", Napi::Number::New(env, llvm::Attribute::AttrKind::ImmArg)); - attributeKinds.Set("InReg", Napi::Number::New(env, llvm::Attribute::AttrKind::InReg)); - attributeKinds.Set("InaccessibleMemOnly", Napi::Number::New(env, llvm::Attribute::AttrKind::InaccessibleMemOnly)); - attributeKinds.Set("InaccessibleMemOrArgMemOnly", - Napi::Number::New(env, llvm::Attribute::AttrKind::InaccessibleMemOrArgMemOnly)); - attributeKinds.Set("InlineHint", Napi::Number::New(env, llvm::Attribute::AttrKind::InlineHint)); - attributeKinds.Set("JumpTable", Napi::Number::New(env, llvm::Attribute::AttrKind::JumpTable)); - attributeKinds.Set("MinSize", Napi::Number::New(env, llvm::Attribute::AttrKind::MinSize)); - attributeKinds.Set("MustProgress", Napi::Number::New(env, llvm::Attribute::AttrKind::MustProgress)); - attributeKinds.Set("Naked", Napi::Number::New(env, llvm::Attribute::AttrKind::Naked)); - attributeKinds.Set("Nest", Napi::Number::New(env, llvm::Attribute::AttrKind::Nest)); - attributeKinds.Set("NoAlias", Napi::Number::New(env, llvm::Attribute::AttrKind::NoAlias)); - attributeKinds.Set("NoBuiltin", Napi::Number::New(env, llvm::Attribute::AttrKind::NoBuiltin)); - attributeKinds.Set("NoCallback", Napi::Number::New(env, llvm::Attribute::AttrKind::NoCallback)); - attributeKinds.Set("NoCapture", Napi::Number::New(env, llvm::Attribute::AttrKind::NoCapture)); - attributeKinds.Set("NoCfCheck", Napi::Number::New(env, llvm::Attribute::AttrKind::NoCfCheck)); - attributeKinds.Set("NoDuplicate", Napi::Number::New(env, llvm::Attribute::AttrKind::NoDuplicate)); - attributeKinds.Set("NoFree", Napi::Number::New(env, llvm::Attribute::AttrKind::NoFree)); - attributeKinds.Set("NoImplicitFloat", Napi::Number::New(env, llvm::Attribute::AttrKind::NoImplicitFloat)); - attributeKinds.Set("NoInline", Napi::Number::New(env, llvm::Attribute::AttrKind::NoInline)); - attributeKinds.Set("NoMerge", Napi::Number::New(env, llvm::Attribute::AttrKind::NoMerge)); - attributeKinds.Set("NoProfile", Napi::Number::New(env, llvm::Attribute::AttrKind::NoProfile)); - attributeKinds.Set("NoRecurse", Napi::Number::New(env, llvm::Attribute::AttrKind::NoRecurse)); - attributeKinds.Set("NoRedZone", Napi::Number::New(env, llvm::Attribute::AttrKind::NoRedZone)); - attributeKinds.Set("NoReturn", Napi::Number::New(env, llvm::Attribute::AttrKind::NoReturn)); - attributeKinds.Set("NoSanitizeCoverage", Napi::Number::New(env, llvm::Attribute::AttrKind::NoSanitizeCoverage)); - attributeKinds.Set("NoSync", Napi::Number::New(env, llvm::Attribute::AttrKind::NoSync)); - attributeKinds.Set("NoUndef", Napi::Number::New(env, llvm::Attribute::AttrKind::NoUndef)); - attributeKinds.Set("NoUnwind", Napi::Number::New(env, llvm::Attribute::AttrKind::NoUnwind)); - attributeKinds.Set("NonLazyBind", Napi::Number::New(env, llvm::Attribute::AttrKind::NonLazyBind)); - attributeKinds.Set("NonNull", Napi::Number::New(env, llvm::Attribute::AttrKind::NonNull)); - attributeKinds.Set("NullPointerIsValid", Napi::Number::New(env, llvm::Attribute::AttrKind::NullPointerIsValid)); - attributeKinds.Set("OptForFuzzing", Napi::Number::New(env, llvm::Attribute::AttrKind::OptForFuzzing)); - attributeKinds.Set("OptimizeForSize", Napi::Number::New(env, llvm::Attribute::AttrKind::OptimizeForSize)); - attributeKinds.Set("OptimizeNone", Napi::Number::New(env, llvm::Attribute::AttrKind::OptimizeNone)); - attributeKinds.Set("ReadNone", Napi::Number::New(env, llvm::Attribute::AttrKind::ReadNone)); - attributeKinds.Set("ReadOnly", Napi::Number::New(env, llvm::Attribute::AttrKind::ReadOnly)); - attributeKinds.Set("Returned", Napi::Number::New(env, llvm::Attribute::AttrKind::Returned)); - attributeKinds.Set("ReturnsTwice", Napi::Number::New(env, llvm::Attribute::AttrKind::ReturnsTwice)); - attributeKinds.Set("SExt", Napi::Number::New(env, llvm::Attribute::AttrKind::SExt)); - attributeKinds.Set("SafeStack", Napi::Number::New(env, llvm::Attribute::AttrKind::SafeStack)); - attributeKinds.Set("SanitizeAddress", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeAddress)); - attributeKinds.Set("SanitizeHWAddress", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeHWAddress)); - attributeKinds.Set("SanitizeMemTag", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeMemTag)); - attributeKinds.Set("SanitizeMemory", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeMemory)); - attributeKinds.Set("SanitizeThread", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeThread)); - attributeKinds.Set("ShadowCallStack", Napi::Number::New(env, llvm::Attribute::AttrKind::ShadowCallStack)); - attributeKinds.Set("Speculatable", Napi::Number::New(env, llvm::Attribute::AttrKind::Speculatable)); - attributeKinds.Set("SpeculativeLoadHardening", - Napi::Number::New(env, llvm::Attribute::AttrKind::SpeculativeLoadHardening)); - attributeKinds.Set("StackProtect", Napi::Number::New(env, llvm::Attribute::AttrKind::StackProtect)); - attributeKinds.Set("StackProtectReq", Napi::Number::New(env, llvm::Attribute::AttrKind::StackProtectReq)); - attributeKinds.Set("StackProtectStrong", Napi::Number::New(env, llvm::Attribute::AttrKind::StackProtectStrong)); - attributeKinds.Set("StrictFP", Napi::Number::New(env, llvm::Attribute::AttrKind::StrictFP)); - attributeKinds.Set("SwiftAsync", Napi::Number::New(env, llvm::Attribute::AttrKind::SwiftAsync)); - attributeKinds.Set("SwiftError", Napi::Number::New(env, llvm::Attribute::AttrKind::SwiftError)); - attributeKinds.Set("SwiftSelf", Napi::Number::New(env, llvm::Attribute::AttrKind::SwiftSelf)); - attributeKinds.Set("UWTable", Napi::Number::New(env, llvm::Attribute::AttrKind::UWTable)); - attributeKinds.Set("WillReturn", Napi::Number::New(env, llvm::Attribute::AttrKind::WillReturn)); - attributeKinds.Set("WriteOnly", Napi::Number::New(env, llvm::Attribute::AttrKind::WriteOnly)); - attributeKinds.Set("LastEnumAttr", Napi::Number::New(env, llvm::Attribute::AttrKind::LastEnumAttr)); - attributeKinds.Set("ByRef", Napi::Number::New(env, llvm::Attribute::AttrKind::ByRef)); - attributeKinds.Set("ByVal", Napi::Number::New(env, llvm::Attribute::AttrKind::ByVal)); - attributeKinds.Set("ElementType", Napi::Number::New(env, llvm::Attribute::AttrKind::ElementType)); - attributeKinds.Set("InAlloca", Napi::Number::New(env, llvm::Attribute::AttrKind::InAlloca)); - attributeKinds.Set("Preallocated", Napi::Number::New(env, llvm::Attribute::AttrKind::Preallocated)); - attributeKinds.Set("LastTypeAttr", Napi::Number::New(env, llvm::Attribute::AttrKind::LastTypeAttr)); - attributeKinds.Set("Alignment", Napi::Number::New(env, llvm::Attribute::AttrKind::Alignment)); - attributeKinds.Set("AllocSize", Napi::Number::New(env, llvm::Attribute::AttrKind::AllocSize)); - attributeKinds.Set("Dereferenceable", Napi::Number::New(env, llvm::Attribute::AttrKind::Dereferenceable)); - attributeKinds.Set("DereferenceableOrNull", - Napi::Number::New(env, llvm::Attribute::AttrKind::DereferenceableOrNull)); - attributeKinds.Set("StackAlignment", Napi::Number::New(env, llvm::Attribute::AttrKind::StackAlignment)); - attributeKinds.Set("VScaleRange", Napi::Number::New(env, llvm::Attribute::AttrKind::VScaleRange)); + +#define GET_ATTR_NAMES +#define ATTRIBUTE_ENUM(EnumName, lower) attributeKinds.Set(#EnumName, Napi::Number::New(env, llvm::Attribute::AttrKind::EnumName)); +#include "llvm/IR/Attributes.inc" Napi::Function func = DefineClass(env, "Attribute", { StaticValue("AttrKind", attributeKinds), diff --git a/src/IR/DataLayout.cpp b/src/IR/DataLayout.cpp index 8341abf..87721ab 100644 --- a/src/IR/DataLayout.cpp +++ b/src/IR/DataLayout.cpp @@ -53,7 +53,7 @@ Napi::Value DataLayout::getTypeAllocSize(const Napi::CallbackInfo &info) { if (info.Length() == 1 && Type::IsClassOf(info[0])) { llvm::Type *type = Type::Extract(info[0]); auto allocSize = dataLayout->getTypeAllocSize(type); - return Napi::Number::New(env, double(allocSize.getFixedSize())); + return Napi::Number::New(env, static_cast(allocSize.getFixedValue())); } throw Napi::TypeError::New(env, ErrMsg::Class::DataLayout::getTypeAllocSize); } diff --git a/src/IR/DerivedTypes.cpp b/src/IR/DerivedTypes.cpp index ee573d2..7d48600 100644 --- a/src/IR/DerivedTypes.cpp +++ b/src/IR/DerivedTypes.cpp @@ -565,7 +565,7 @@ void PointerType::Init(Napi::Env env, Napi::Object &exports) { InstanceMethod("isIntegerTy", &PointerType::isIntegerTy), InstanceMethod("isVoidTy", &PointerType::isVoidTy), InstanceMethod("getTypeID", &PointerType::getTypeID), - InstanceMethod("getPointerElementType", &PointerType::getPointerElementType) + InstanceMethod("getNonOpaquePointerElementType", &PointerType::getNonOpaquePointerElementType) }); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -647,6 +647,6 @@ Napi::Value PointerType::getTypeID(const Napi::CallbackInfo &info) { return Napi::Number::New(info.Env(), pointerType->getTypeID()); } -Napi::Value PointerType::getPointerElementType(const Napi::CallbackInfo &info) { - return Type::New(info.Env(), pointerType->getPointerElementType()); +Napi::Value PointerType::getNonOpaquePointerElementType(const Napi::CallbackInfo &info) { + return Type::New(info.Env(), pointerType->getNonOpaquePointerElementType()); } diff --git a/src/IR/Function.cpp b/src/IR/Function.cpp index dcd9412..75d11a1 100644 --- a/src/IR/Function.cpp +++ b/src/IR/Function.cpp @@ -111,7 +111,7 @@ void Function::addBasicBlock(const Napi::CallbackInfo &info) { throw Napi::TypeError::New(env, ErrMsg::Class::Function::addBasicBlock); } llvm::BasicBlock *basicBlock = BasicBlock::Extract(info[0]); - function->getBasicBlockList().push_back(basicBlock); + function->insert(function->end(), basicBlock); } Napi::Value Function::getEntryBlock(const Napi::CallbackInfo &info) { @@ -129,7 +129,7 @@ void Function::insertAfter(const Napi::CallbackInfo &info) { } llvm::BasicBlock *where = BasicBlock::Extract(info[0]); llvm::BasicBlock *bb = BasicBlock::Extract(info[1]); - function->getBasicBlockList().insertAfter(where->getIterator(), bb); + function->insert(where->getIterator(), bb); } void Function::deleteBody(const Napi::CallbackInfo &info) { diff --git a/src/IR/IRBuilder.cpp b/src/IR/IRBuilder.cpp index f83d347..4c7d1c6 100644 --- a/src/IR/IRBuilder.cpp +++ b/src/IR/IRBuilder.cpp @@ -1,3 +1,5 @@ +#include + #include "IR/index.h" #include "ADT/APInt.h" #include "Util/index.h" @@ -486,7 +488,7 @@ Napi::Value IRBuilder::CreateInvoke(const Napi::CallbackInfo &info) { llvm::BasicBlock *normalDest = BasicBlock::Extract(info[1]); llvm::BasicBlock *unwindDest = BasicBlock::Extract(info[2]); std::string name = argsLen == 4 ? std::string(info[3].As()) : ""; - invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest, llvm::None, name); + invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest, std::nullopt, name); } else if (argsLen == 4 && Function::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() || argsLen == 5 && Function::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() && info[4].IsString()) { if (assembleArray(info[3].As(), calleeArgs)) { @@ -502,7 +504,7 @@ Napi::Value IRBuilder::CreateInvoke(const Napi::CallbackInfo &info) { llvm::BasicBlock *normalDest = BasicBlock::Extract(info[1]); llvm::BasicBlock *unwindDest = BasicBlock::Extract(info[2]); std::string name = argsLen == 4 ? std::string(info[3].As()) : ""; - invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest, llvm::None, name); + invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest, std::nullopt, name); } else if (argsLen == 4 && FunctionCallee::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() || argsLen == 5 && FunctionCallee::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() && info[4].IsString()) { if (assembleArray(info[3].As(), calleeArgs)) { @@ -521,7 +523,7 @@ Napi::Value IRBuilder::CreateInvoke(const Napi::CallbackInfo &info) { llvm::BasicBlock *normalDest = BasicBlock::Extract(info[2]); llvm::BasicBlock *unwindDest = BasicBlock::Extract(info[3]); std::string name = argsLen == 5 ? std::string(info[4].As()) : ""; - invokeInst = builder->CreateInvoke(funcType, callee, normalDest, unwindDest, llvm::None, name); + invokeInst = builder->CreateInvoke(funcType, callee, normalDest, unwindDest, std::nullopt, name); } else if (argsLen == 5 && FunctionType::IsClassOf(info[0]) && Function::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && BasicBlock::IsClassOf(info[3]) && info[4].IsArray() || argsLen == 6 && FunctionType::IsClassOf(info[0]) && Function::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && @@ -699,7 +701,7 @@ Napi::Value IRBuilder::CreateCall(const Napi::CallbackInfo &info) { argsLen == 2 && Function::IsClassOf(info[0]) && info[1].IsString()) { llvm::Function *callee = Function::Extract(info[0]); std::string name = argsLen == 2 ? std::string(info[1].As()) : ""; - callInst = builder->CreateCall(callee, llvm::None, name); + callInst = builder->CreateCall(callee, std::nullopt, name); } else if (argsLen == 2 && Function::IsClassOf(info[0]) && info[1].IsArray() || argsLen == 3 && Function::IsClassOf(info[0]) && info[1].IsArray() && info[2].IsString()) { if (assembleArray(info[1].As(), calleeArgs)) { @@ -711,7 +713,7 @@ Napi::Value IRBuilder::CreateCall(const Napi::CallbackInfo &info) { argsLen == 2 && FunctionCallee::IsClassOf(info[0]) && info[1].IsString()) { llvm::FunctionCallee callee = FunctionCallee::Extract(info[0]); std::string name = argsLen == 2 ? std::string(info[1].As()) : ""; - callInst = builder->CreateCall(callee, llvm::None, name); + callInst = builder->CreateCall(callee, std::nullopt, name); } else if (argsLen == 2 && FunctionCallee::IsClassOf(info[0]) && info[1].IsArray() || argsLen == 3 && FunctionCallee::IsClassOf(info[0]) && info[1].IsArray() && info[2].IsString()) { if (assembleArray(info[1].As(), calleeArgs)) { @@ -724,7 +726,7 @@ Napi::Value IRBuilder::CreateCall(const Napi::CallbackInfo &info) { llvm::FunctionType *funcType = FunctionType::Extract(info[0]); llvm::Value *callee = Value::Extract(info[1]); std::string name = argsLen == 3 ? std::string(info[2].As()) : ""; - callInst = builder->CreateCall(funcType, callee, llvm::None, name); + callInst = builder->CreateCall(funcType, callee, std::nullopt, name); } else if (argsLen == 3 && FunctionType::IsClassOf(info[0]) && Value::IsClassOf(info[1]) && info[2].IsArray() || argsLen == 4 && FunctionType::IsClassOf(info[0]) && Value::IsClassOf(info[1]) && info[2].IsArray() && info[3].IsString()) { if (assembleArray(info[2].As(), calleeArgs)) { diff --git a/src/IR/Intrinsic.cpp b/src/IR/Intrinsic.cpp index 1f7bcb1..f987d3e 100644 --- a/src/IR/Intrinsic.cpp +++ b/src/IR/Intrinsic.cpp @@ -107,7 +107,6 @@ void Intrinsic::Init(Napi::Env env, Napi::Object &exports) { intrinsicNS.Set("expect_with_probability", Napi::Number::New(env, llvm::Intrinsic::expect_with_probability)); intrinsicNS.Set("fabs", Napi::Number::New(env, llvm::Intrinsic::fabs)); intrinsicNS.Set("floor", Napi::Number::New(env, llvm::Intrinsic::floor)); - intrinsicNS.Set("flt_rounds", Napi::Number::New(env, llvm::Intrinsic::flt_rounds)); intrinsicNS.Set("fma", Napi::Number::New(env, llvm::Intrinsic::fma)); intrinsicNS.Set("fmuladd", Napi::Number::New(env, llvm::Intrinsic::fmuladd)); intrinsicNS.Set("fptosi_sat", Napi::Number::New(env, llvm::Intrinsic::fptosi_sat)); diff --git a/src/IR/Type.cpp b/src/IR/Type.cpp index f57c36b..4e1f0b1 100644 --- a/src/IR/Type.cpp +++ b/src/IR/Type.cpp @@ -129,7 +129,7 @@ void Type::Init(Napi::Env env, Napi::Object &exports) { InstanceMethod("isAggregateType", &Type::isTypeFactory<&llvm::Type::isAggregateType>), InstanceMethod("getPointerTo", &Type::getPointerTo), InstanceMethod("getPrimitiveSizeInBits", &Type::getPrimitiveSizeInBits), - InstanceMethod("getPointerElementType", &Type::getPointerElementType), + InstanceMethod("getNonOpaquePointerElementType", &Type::getNonOpaquePointerElementType), StaticMethod("isSameType", &Type::isSameType) }); constructor = Napi::Persistent(func); @@ -219,8 +219,8 @@ Napi::Value Type::isIntegerTy(const Napi::CallbackInfo &info) { return Napi::Boolean::New(env, result); } -Napi::Value Type::getPointerElementType(const Napi::CallbackInfo &info) { - return Type::New(info.Env(), type->getPointerElementType()); +Napi::Value Type::getNonOpaquePointerElementType(const Napi::CallbackInfo &info) { + return Type::New(info.Env(), type->getNonOpaquePointerElementType()); } static bool isSameType(llvm::Type *type1, llvm::Type *type2) { @@ -248,7 +248,11 @@ static bool isSameType(llvm::Type *type1, llvm::Type *type2) { } } } else if (type1->isPointerTy()) { - return isSameType(type1->getPointerElementType(), type2->getPointerElementType()); + if (type1->isOpaquePointerTy() || type2->isOpaquePointerTy()) { + return type1->isOpaquePointerTy() && type2->isOpaquePointerTy(); + } + + return isSameType(type1->getNonOpaquePointerElementType(), type2->getNonOpaquePointerElementType()); } else if (type1->isStructTy()) { unsigned numElements = type1->getStructNumElements(); if (numElements != type2->getStructNumElements()) { diff --git a/src/MC/TargetRegistry.cpp b/src/MC/TargetRegistry.cpp index 87d9ca7..2160e9f 100644 --- a/src/MC/TargetRegistry.cpp +++ b/src/MC/TargetRegistry.cpp @@ -45,7 +45,8 @@ Napi::Value Target::createTargetMachine(const Napi::CallbackInfo &info) { features = info[2].As(); } llvm::TargetOptions options{}; - llvm::TargetMachine *targetMachinePtr = target->createTargetMachine(targetTriple, cpu, features, options, llvm::Optional{}); + llvm::TargetMachine *targetMachinePtr = target->createTargetMachine( + targetTriple, cpu, features, options, std::optional{}); return TargetMachine::New(env, targetMachinePtr); } diff --git a/src/llvm-bindings.cpp b/src/llvm-bindings.cpp index ff01048..393f692 100644 --- a/src/llvm-bindings.cpp +++ b/src/llvm-bindings.cpp @@ -9,7 +9,27 @@ #include "Support/index.h" #include "Target/index.h" +template +std::string string_format( const std::string& format, Args ... args ) +{ + int size_s = std::snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0' + if( size_s <= 0 ){ throw std::runtime_error( "Error during formatting." ); } + auto size = static_cast( size_s ); + std::unique_ptr buf( new char[ size ] ); + std::snprintf( buf.get(), size, format.c_str(), args ... ); + return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside +} + +static std::unique_ptr node_env; + +void llvm_bindings_assert(const char* e, const char* file, int line) +{ + throw Napi::Error::New( + *node_env, string_format("%s:%d: failed assertion `%s'\n", file, line, e)); +} + Napi::Object Init(Napi::Env env, Napi::Object exports) { + node_env = std::make_unique(env); InitADT(env, exports); InitBinaryFormat(env, exports); InitBitCode(env, exports); diff --git a/test/exception.ts b/test/exception.ts index 7dfac6f..d479628 100644 --- a/test/exception.ts +++ b/test/exception.ts @@ -27,7 +27,7 @@ export default function testException() { const tmp2 = builder.CreateBitCast(tmp1, llvm.PointerType.getUnqual(builder.getInt8PtrTy())); builder.CreateStore( builder.CreateInBoundsGEP( - errMsgStr.getType().getPointerElementType(), + errMsgStr.getValueType(), errMsgStr, [builder.getInt64(0), builder.getInt64(0)] ),