@designliquido/llvm-bindings 1.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build.yml +6 -6
- package/CHANGELOG.md +12 -0
- package/CMakeLists.txt +2 -2
- package/README.md +2 -1
- package/cmake/LLVM.cmake +1 -1
- package/include/IR/DerivedTypes.h +1 -1
- package/include/IR/Type.h +1 -1
- package/include/assert.h +13 -0
- package/llvm-bindings.d.ts +5 -4
- package/package.json +4 -6
- package/src/IR/Attributes.cpp +6 -82
- package/src/IR/DataLayout.cpp +1 -1
- package/src/IR/DerivedTypes.cpp +3 -3
- package/src/IR/Function.cpp +4 -2
- package/src/IR/IRBuilder.cpp +6 -6
- package/src/IR/Intrinsic.cpp +0 -2
- package/src/IR/LLVMContext.cpp +0 -1
- package/src/IR/Type.cpp +4 -4
- package/src/MC/TargetRegistry.cpp +2 -1
- package/src/llvm-bindings.cpp +25 -0
- package/tests/IR/OpaquePointer.spec.ts +39 -0
- package/tests/IR/Type.spec.ts +24 -0
- package/tests/fixtures/add.spec.ts +24 -0
- package/tests/fixtures/attribute.spec.ts +27 -0
- package/tests/fixtures/bitcodeWriter.spec.ts +42 -0
- package/tests/fixtures/class.spec.ts +30 -0
- package/tests/fixtures/debugInfo.spec.ts +73 -0
- package/tests/fixtures/exception.spec.ts +42 -0
- package/tests/fixtures/fibonacci.spec.ts +36 -0
- package/tests/fixtures/gep.spec.ts +27 -0
- package/tests/fixtures/intrinsic.spec.ts +29 -0
- package/tests/fixtures/linker.spec.ts +30 -0
- package/tests/fixtures/str.spec.ts +14 -0
- package/tests/fixtures/switch.spec.ts +45 -0
- package/tests/fixtures/unary.spec.ts +44 -0
- package/tests/fixtures/variable.spec.ts +25 -0
- package/test/add.ts +0 -32
- package/test/attribute.ts +0 -37
- package/test/bitcodeWriter.ts +0 -44
- package/test/class.ts +0 -39
- package/test/debugInfo.ts +0 -181
- package/test/exception.ts +0 -57
- package/test/fibonacci.ts +0 -44
- package/test/gep.ts +0 -42
- package/test/index.ts +0 -33
- package/test/intrinsic.ts +0 -35
- package/test/linker.ts +0 -48
- package/test/str.ts +0 -19
- package/test/switch.ts +0 -58
- package/test/target.ts +0 -14
- package/test/type.ts +0 -21
- package/test/unary.ts +0 -53
- package/test/variable.ts +0 -37
- /package/{test → tests/fixtures}/bitcode/add.bc +0 -0
|
@@ -15,8 +15,8 @@ on:
|
|
|
15
15
|
- 'LICENSE'
|
|
16
16
|
|
|
17
17
|
env:
|
|
18
|
-
LLVM_VERSION:
|
|
19
|
-
LLVM_VERSION_MAJOR:
|
|
18
|
+
LLVM_VERSION: 17.0.6
|
|
19
|
+
LLVM_VERSION_MAJOR: 17
|
|
20
20
|
|
|
21
21
|
jobs:
|
|
22
22
|
build-push:
|
|
@@ -39,7 +39,7 @@ jobs:
|
|
|
39
39
|
if: startsWith(matrix.os, 'macos')
|
|
40
40
|
run: |
|
|
41
41
|
brew update
|
|
42
|
-
brew install llvm@${{ env.LLVM_VERSION_MAJOR }} ninja
|
|
42
|
+
brew install llvm@${{ env.LLVM_VERSION_MAJOR }} ninja || brew link --overwrite python@3.12
|
|
43
43
|
- name: Install LLVM and Ninja on Ubuntu (via llvm.sh)
|
|
44
44
|
if: startsWith(matrix.os, 'ubuntu') && matrix.os != 'ubuntu-24.04'
|
|
45
45
|
run: |
|
|
@@ -56,7 +56,7 @@ jobs:
|
|
|
56
56
|
if: startsWith(matrix.os, 'windows')
|
|
57
57
|
run: |
|
|
58
58
|
$LLVM_VERSION = "${{ env.LLVM_VERSION }}"
|
|
59
|
-
$LLVM_PREBUILT_FILE = "llvm-$LLVM_VERSION-windows-
|
|
59
|
+
$LLVM_PREBUILT_FILE = "llvm-$LLVM_VERSION-windows-2022.zip"
|
|
60
60
|
curl -sLO "https://github.com/DesignLiquido/llvm-windows/releases/download/llvmorg-$LLVM_VERSION/$LLVM_PREBUILT_FILE"
|
|
61
61
|
Expand-Archive -Path $LLVM_PREBUILT_FILE -DestinationPath .
|
|
62
62
|
$LLVM_CMAKE_DIR = "$pwd/LLVM-$LLVM_VERSION-win64/lib/cmake/llvm"
|
|
@@ -107,7 +107,7 @@ jobs:
|
|
|
107
107
|
if: startsWith(matrix.os, 'macos')
|
|
108
108
|
run: |
|
|
109
109
|
brew update
|
|
110
|
-
brew install llvm@${{ env.LLVM_VERSION_MAJOR }} ninja
|
|
110
|
+
brew install llvm@${{ env.LLVM_VERSION_MAJOR }} ninja || brew link --overwrite python@3.12
|
|
111
111
|
- name: Install LLVM and Ninja on Ubuntu (via llvm.sh)
|
|
112
112
|
if: startsWith(matrix.os, 'ubuntu') && matrix.os != 'ubuntu-24.04'
|
|
113
113
|
run: |
|
|
@@ -124,7 +124,7 @@ jobs:
|
|
|
124
124
|
if: startsWith(matrix.os, 'windows')
|
|
125
125
|
run: |
|
|
126
126
|
$LLVM_VERSION = "${{ env.LLVM_VERSION }}"
|
|
127
|
-
$LLVM_PREBUILT_FILE = "llvm-$LLVM_VERSION-windows-
|
|
127
|
+
$LLVM_PREBUILT_FILE = "llvm-$LLVM_VERSION-windows-2022.zip"
|
|
128
128
|
curl -sLO "https://github.com/DesignLiquido/llvm-windows/releases/download/llvmorg-$LLVM_VERSION/$LLVM_PREBUILT_FILE"
|
|
129
129
|
Expand-Archive -Path $LLVM_PREBUILT_FILE -DestinationPath .
|
|
130
130
|
$LLVM_CMAKE_DIR = "$pwd/LLVM-$LLVM_VERSION-win64/lib/cmake/llvm"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# [2.0.0](https://github.com/DesignLiquido/llvm-bindings/compare/v1.0.0...v2.0.0) (2026-03-08)
|
|
2
|
+
# [1.0.0](https://github.com/DesignLiquido/llvm-bindings/compare/v0.4.2...v1.0.0) (2026-03-08)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* uncomment test entry ([69c93f7](https://github.com/DesignLiquido/llvm-bindings/commit/69c93f7aae697c3cb3e75d01e447554b0565e3d5))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **Attribute:** add basic support for enum attributes ([#32](https://github.com/DesignLiquido/llvm-bindings/issues/32)) ([db45aa5](https://github.com/DesignLiquido/llvm-bindings/commit/db45aa583729956dfefa01772ab69f019e56b05a))
|
|
1
13
|
## [1.0.0] - 2026-03-07
|
|
2
14
|
|
|
3
15
|
### Added
|
package/CMakeLists.txt
CHANGED
|
@@ -19,8 +19,8 @@ add_library(${PROJECT_NAME} SHARED ${CMAKE_JS_SRC} ${SOURCE_FILES})
|
|
|
19
19
|
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node" LINKER_LANGUAGE CXX)
|
|
20
20
|
|
|
21
21
|
if (MSVC)
|
|
22
|
-
# cmake-js forces /MT (MultiThreaded static CRT), but LLVM
|
|
23
|
-
# libraries
|
|
22
|
+
# cmake-js forces /MT (MultiThreaded static CRT), but LLVM prebuilt Windows
|
|
23
|
+
# libraries are compiled with /MD (MultiThreadedDLL dynamic CRT). Override
|
|
24
24
|
# per-target so the linker can resolve __imp_strdup, __imp_read, etc. from ucrtbase.dll.
|
|
25
25
|
set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
|
|
26
26
|
endif ()
|
package/README.md
CHANGED
|
@@ -148,8 +148,9 @@ To opt into opaque pointers, pass an `LLVMContext` to `PointerType.get` / `getUn
|
|
|
148
148
|
| (original llvm-bindings repo) 0.2.x | 12.0.x |
|
|
149
149
|
| (original llvm-bindings repo) 0.3.x | 13.0.x |
|
|
150
150
|
| (original llvm-bindings repo) 0.4.x | 14.0.x |
|
|
151
|
-
| (@designliquido/llvm-bindings) 0.1.x |
|
|
151
|
+
| (@designliquido/llvm-bindings) 0.1.x | 14.0.x |
|
|
152
152
|
| (@designliquido/llvm-bindings) 1.0.x | 15.0.x |
|
|
153
|
+
| (@designliquido/llvm-bindings) 2.0.x | 16.0.x |
|
|
153
154
|
|
|
154
155
|
## Acknowledgments
|
|
155
156
|
|
package/cmake/LLVM.cmake
CHANGED
|
@@ -228,7 +228,7 @@ private:
|
|
|
228
228
|
|
|
229
229
|
Napi::Value getTypeID(const Napi::CallbackInfo &info);
|
|
230
230
|
|
|
231
|
-
Napi::Value
|
|
231
|
+
Napi::Value getNonOpaquePointerElementType(const Napi::CallbackInfo &info);
|
|
232
232
|
|
|
233
233
|
Napi::Value isOpaque(const Napi::CallbackInfo &info);
|
|
234
234
|
};
|
package/include/IR/Type.h
CHANGED
|
@@ -39,7 +39,7 @@ private:
|
|
|
39
39
|
return Napi::Boolean::New(info.Env(), (type->*method)());
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
Napi::Value
|
|
42
|
+
Napi::Value getNonOpaquePointerElementType(const Napi::CallbackInfo &info);
|
|
43
43
|
|
|
44
44
|
static Napi::Value isSameType(const Napi::CallbackInfo &info);
|
|
45
45
|
};
|
package/include/assert.h
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#ifndef LLVM_BINDINGS_NODEJS_ASSERT_H
|
|
2
|
+
#define LLVM_BINDINGS_NODEJS_ASSERT_H
|
|
3
|
+
|
|
4
|
+
#ifdef __cplusplus
|
|
5
|
+
void llvm_bindings_assert(const char* expr, const char* file, int line);
|
|
6
|
+
|
|
7
|
+
#define LLVM_BINDINGS_ASSERT_IMPL(e, file, line) ((void)llvm_bindings_assert ((e), (file), (line)))
|
|
8
|
+
|
|
9
|
+
#define assert(e) ((void) ((e) ? ((void)0) : LLVM_BINDINGS_ASSERT_IMPL (#e, __FILE__, __LINE__)))
|
|
10
|
+
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#endif
|
package/llvm-bindings.d.ts
CHANGED
|
@@ -369,7 +369,7 @@ declare namespace llvm {
|
|
|
369
369
|
|
|
370
370
|
public getPrimitiveSizeInBits(): number;
|
|
371
371
|
|
|
372
|
-
public
|
|
372
|
+
public getNonOpaquePointerElementType(): Type;
|
|
373
373
|
|
|
374
374
|
// extra
|
|
375
375
|
public static isSameType(type1: Type, type2: Type): boolean;
|
|
@@ -513,8 +513,10 @@ declare namespace llvm {
|
|
|
513
513
|
// duplicated
|
|
514
514
|
public getTypeID(): number;
|
|
515
515
|
|
|
516
|
-
|
|
517
|
-
|
|
516
|
+
/**
|
|
517
|
+
* @deprecated In LLVM 15/16 this is deprecated. LLVM 17 removes it.
|
|
518
|
+
*/
|
|
519
|
+
public getNonOpaquePointerElementType(): Type;
|
|
518
520
|
|
|
519
521
|
public isOpaque(): boolean;
|
|
520
522
|
|
|
@@ -1943,7 +1945,6 @@ declare namespace llvm {
|
|
|
1943
1945
|
const expect_with_probability: number;
|
|
1944
1946
|
const fabs: number;
|
|
1945
1947
|
const floor: number;
|
|
1946
|
-
const flt_rounds: number;
|
|
1947
1948
|
const fma: number;
|
|
1948
1949
|
const fmuladd: number;
|
|
1949
1950
|
const fptosi_sat: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@designliquido/llvm-bindings",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "LLVM bindings for Node.js/JavaScript/TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"llvm",
|
|
@@ -25,14 +25,13 @@
|
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "yarn build:ts",
|
|
28
|
-
"build:ts": "tsc",
|
|
28
|
+
"build:ts": "yarn tsc",
|
|
29
29
|
"prepare": "yarn build:ts",
|
|
30
30
|
"postinstall": "cmake-js compile",
|
|
31
31
|
"build:debug": "cmake-js build -D",
|
|
32
32
|
"build:release": "cmake-js build",
|
|
33
|
-
"clear": "rimraf build dist",
|
|
34
|
-
"test
|
|
35
|
-
"test": "yarn build:ts && yarn test:legacy && yarn jest --verbose",
|
|
33
|
+
"clear": "yarn rimraf build dist",
|
|
34
|
+
"test": "yarn build:ts && yarn jest --verbose",
|
|
36
35
|
"release:patch": "release-it patch",
|
|
37
36
|
"release:minor": "release-it minor",
|
|
38
37
|
"release:major": "release-it major"
|
|
@@ -51,7 +50,6 @@
|
|
|
51
50
|
"release-it": "^19.2.4",
|
|
52
51
|
"rimraf": "^6.1.3",
|
|
53
52
|
"ts-jest": "^28.0.5",
|
|
54
|
-
"ts-node": "^10.8.1",
|
|
55
53
|
"typescript": "^5.9.3"
|
|
56
54
|
},
|
|
57
55
|
"jest": {
|
package/src/IR/Attributes.cpp
CHANGED
|
@@ -5,88 +5,12 @@ void Attribute::Init(Napi::Env env, Napi::Object &exports) {
|
|
|
5
5
|
Napi::HandleScope scope(env);
|
|
6
6
|
|
|
7
7
|
Napi::Object attributeKinds = Napi::Object::New(env);
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Napi::Number::New(env, llvm::Attribute::AttrKind::DisableSanitizerInstrumentation));
|
|
15
|
-
attributeKinds.Set("Hot", Napi::Number::New(env, llvm::Attribute::AttrKind::Hot));
|
|
16
|
-
attributeKinds.Set("ImmArg", Napi::Number::New(env, llvm::Attribute::AttrKind::ImmArg));
|
|
17
|
-
attributeKinds.Set("InReg", Napi::Number::New(env, llvm::Attribute::AttrKind::InReg));
|
|
18
|
-
attributeKinds.Set("InaccessibleMemOnly", Napi::Number::New(env, llvm::Attribute::AttrKind::InaccessibleMemOnly));
|
|
19
|
-
attributeKinds.Set("InaccessibleMemOrArgMemOnly",
|
|
20
|
-
Napi::Number::New(env, llvm::Attribute::AttrKind::InaccessibleMemOrArgMemOnly));
|
|
21
|
-
attributeKinds.Set("InlineHint", Napi::Number::New(env, llvm::Attribute::AttrKind::InlineHint));
|
|
22
|
-
attributeKinds.Set("JumpTable", Napi::Number::New(env, llvm::Attribute::AttrKind::JumpTable));
|
|
23
|
-
attributeKinds.Set("MinSize", Napi::Number::New(env, llvm::Attribute::AttrKind::MinSize));
|
|
24
|
-
attributeKinds.Set("MustProgress", Napi::Number::New(env, llvm::Attribute::AttrKind::MustProgress));
|
|
25
|
-
attributeKinds.Set("Naked", Napi::Number::New(env, llvm::Attribute::AttrKind::Naked));
|
|
26
|
-
attributeKinds.Set("Nest", Napi::Number::New(env, llvm::Attribute::AttrKind::Nest));
|
|
27
|
-
attributeKinds.Set("NoAlias", Napi::Number::New(env, llvm::Attribute::AttrKind::NoAlias));
|
|
28
|
-
attributeKinds.Set("NoBuiltin", Napi::Number::New(env, llvm::Attribute::AttrKind::NoBuiltin));
|
|
29
|
-
attributeKinds.Set("NoCallback", Napi::Number::New(env, llvm::Attribute::AttrKind::NoCallback));
|
|
30
|
-
attributeKinds.Set("NoCapture", Napi::Number::New(env, llvm::Attribute::AttrKind::NoCapture));
|
|
31
|
-
attributeKinds.Set("NoCfCheck", Napi::Number::New(env, llvm::Attribute::AttrKind::NoCfCheck));
|
|
32
|
-
attributeKinds.Set("NoDuplicate", Napi::Number::New(env, llvm::Attribute::AttrKind::NoDuplicate));
|
|
33
|
-
attributeKinds.Set("NoFree", Napi::Number::New(env, llvm::Attribute::AttrKind::NoFree));
|
|
34
|
-
attributeKinds.Set("NoImplicitFloat", Napi::Number::New(env, llvm::Attribute::AttrKind::NoImplicitFloat));
|
|
35
|
-
attributeKinds.Set("NoInline", Napi::Number::New(env, llvm::Attribute::AttrKind::NoInline));
|
|
36
|
-
attributeKinds.Set("NoMerge", Napi::Number::New(env, llvm::Attribute::AttrKind::NoMerge));
|
|
37
|
-
attributeKinds.Set("NoProfile", Napi::Number::New(env, llvm::Attribute::AttrKind::NoProfile));
|
|
38
|
-
attributeKinds.Set("NoRecurse", Napi::Number::New(env, llvm::Attribute::AttrKind::NoRecurse));
|
|
39
|
-
attributeKinds.Set("NoRedZone", Napi::Number::New(env, llvm::Attribute::AttrKind::NoRedZone));
|
|
40
|
-
attributeKinds.Set("NoReturn", Napi::Number::New(env, llvm::Attribute::AttrKind::NoReturn));
|
|
41
|
-
attributeKinds.Set("NoSanitizeCoverage", Napi::Number::New(env, llvm::Attribute::AttrKind::NoSanitizeCoverage));
|
|
42
|
-
attributeKinds.Set("NoSync", Napi::Number::New(env, llvm::Attribute::AttrKind::NoSync));
|
|
43
|
-
attributeKinds.Set("NoUndef", Napi::Number::New(env, llvm::Attribute::AttrKind::NoUndef));
|
|
44
|
-
attributeKinds.Set("NoUnwind", Napi::Number::New(env, llvm::Attribute::AttrKind::NoUnwind));
|
|
45
|
-
attributeKinds.Set("NonLazyBind", Napi::Number::New(env, llvm::Attribute::AttrKind::NonLazyBind));
|
|
46
|
-
attributeKinds.Set("NonNull", Napi::Number::New(env, llvm::Attribute::AttrKind::NonNull));
|
|
47
|
-
attributeKinds.Set("NullPointerIsValid", Napi::Number::New(env, llvm::Attribute::AttrKind::NullPointerIsValid));
|
|
48
|
-
attributeKinds.Set("OptForFuzzing", Napi::Number::New(env, llvm::Attribute::AttrKind::OptForFuzzing));
|
|
49
|
-
attributeKinds.Set("OptimizeForSize", Napi::Number::New(env, llvm::Attribute::AttrKind::OptimizeForSize));
|
|
50
|
-
attributeKinds.Set("OptimizeNone", Napi::Number::New(env, llvm::Attribute::AttrKind::OptimizeNone));
|
|
51
|
-
attributeKinds.Set("ReadNone", Napi::Number::New(env, llvm::Attribute::AttrKind::ReadNone));
|
|
52
|
-
attributeKinds.Set("ReadOnly", Napi::Number::New(env, llvm::Attribute::AttrKind::ReadOnly));
|
|
53
|
-
attributeKinds.Set("Returned", Napi::Number::New(env, llvm::Attribute::AttrKind::Returned));
|
|
54
|
-
attributeKinds.Set("ReturnsTwice", Napi::Number::New(env, llvm::Attribute::AttrKind::ReturnsTwice));
|
|
55
|
-
attributeKinds.Set("SExt", Napi::Number::New(env, llvm::Attribute::AttrKind::SExt));
|
|
56
|
-
attributeKinds.Set("SafeStack", Napi::Number::New(env, llvm::Attribute::AttrKind::SafeStack));
|
|
57
|
-
attributeKinds.Set("SanitizeAddress", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeAddress));
|
|
58
|
-
attributeKinds.Set("SanitizeHWAddress", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeHWAddress));
|
|
59
|
-
attributeKinds.Set("SanitizeMemTag", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeMemTag));
|
|
60
|
-
attributeKinds.Set("SanitizeMemory", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeMemory));
|
|
61
|
-
attributeKinds.Set("SanitizeThread", Napi::Number::New(env, llvm::Attribute::AttrKind::SanitizeThread));
|
|
62
|
-
attributeKinds.Set("ShadowCallStack", Napi::Number::New(env, llvm::Attribute::AttrKind::ShadowCallStack));
|
|
63
|
-
attributeKinds.Set("Speculatable", Napi::Number::New(env, llvm::Attribute::AttrKind::Speculatable));
|
|
64
|
-
attributeKinds.Set("SpeculativeLoadHardening",
|
|
65
|
-
Napi::Number::New(env, llvm::Attribute::AttrKind::SpeculativeLoadHardening));
|
|
66
|
-
attributeKinds.Set("StackProtect", Napi::Number::New(env, llvm::Attribute::AttrKind::StackProtect));
|
|
67
|
-
attributeKinds.Set("StackProtectReq", Napi::Number::New(env, llvm::Attribute::AttrKind::StackProtectReq));
|
|
68
|
-
attributeKinds.Set("StackProtectStrong", Napi::Number::New(env, llvm::Attribute::AttrKind::StackProtectStrong));
|
|
69
|
-
attributeKinds.Set("StrictFP", Napi::Number::New(env, llvm::Attribute::AttrKind::StrictFP));
|
|
70
|
-
attributeKinds.Set("SwiftAsync", Napi::Number::New(env, llvm::Attribute::AttrKind::SwiftAsync));
|
|
71
|
-
attributeKinds.Set("SwiftError", Napi::Number::New(env, llvm::Attribute::AttrKind::SwiftError));
|
|
72
|
-
attributeKinds.Set("SwiftSelf", Napi::Number::New(env, llvm::Attribute::AttrKind::SwiftSelf));
|
|
73
|
-
attributeKinds.Set("UWTable", Napi::Number::New(env, llvm::Attribute::AttrKind::UWTable));
|
|
74
|
-
attributeKinds.Set("WillReturn", Napi::Number::New(env, llvm::Attribute::AttrKind::WillReturn));
|
|
75
|
-
attributeKinds.Set("WriteOnly", Napi::Number::New(env, llvm::Attribute::AttrKind::WriteOnly));
|
|
76
|
-
attributeKinds.Set("LastEnumAttr", Napi::Number::New(env, llvm::Attribute::AttrKind::LastEnumAttr));
|
|
77
|
-
attributeKinds.Set("ByRef", Napi::Number::New(env, llvm::Attribute::AttrKind::ByRef));
|
|
78
|
-
attributeKinds.Set("ByVal", Napi::Number::New(env, llvm::Attribute::AttrKind::ByVal));
|
|
79
|
-
attributeKinds.Set("ElementType", Napi::Number::New(env, llvm::Attribute::AttrKind::ElementType));
|
|
80
|
-
attributeKinds.Set("InAlloca", Napi::Number::New(env, llvm::Attribute::AttrKind::InAlloca));
|
|
81
|
-
attributeKinds.Set("Preallocated", Napi::Number::New(env, llvm::Attribute::AttrKind::Preallocated));
|
|
82
|
-
attributeKinds.Set("LastTypeAttr", Napi::Number::New(env, llvm::Attribute::AttrKind::LastTypeAttr));
|
|
83
|
-
attributeKinds.Set("Alignment", Napi::Number::New(env, llvm::Attribute::AttrKind::Alignment));
|
|
84
|
-
attributeKinds.Set("AllocSize", Napi::Number::New(env, llvm::Attribute::AttrKind::AllocSize));
|
|
85
|
-
attributeKinds.Set("Dereferenceable", Napi::Number::New(env, llvm::Attribute::AttrKind::Dereferenceable));
|
|
86
|
-
attributeKinds.Set("DereferenceableOrNull",
|
|
87
|
-
Napi::Number::New(env, llvm::Attribute::AttrKind::DereferenceableOrNull));
|
|
88
|
-
attributeKinds.Set("StackAlignment", Napi::Number::New(env, llvm::Attribute::AttrKind::StackAlignment));
|
|
89
|
-
attributeKinds.Set("VScaleRange", Napi::Number::New(env, llvm::Attribute::AttrKind::VScaleRange));
|
|
8
|
+
|
|
9
|
+
#define GET_ATTR_NAMES
|
|
10
|
+
#define ATTRIBUTE_ENUM(EnumName, lower) attributeKinds.Set(#EnumName, Napi::Number::New(env, llvm::Attribute::AttrKind::EnumName));
|
|
11
|
+
#include "llvm/IR/Attributes.inc"
|
|
12
|
+
#undef GET_ATTR_NAMES
|
|
13
|
+
#undef ATTRIBUTE_ENUM
|
|
90
14
|
|
|
91
15
|
Napi::Function func = DefineClass(env, "Attribute", {
|
|
92
16
|
StaticValue("AttrKind", attributeKinds),
|
package/src/IR/DataLayout.cpp
CHANGED
|
@@ -53,7 +53,7 @@ Napi::Value DataLayout::getTypeAllocSize(const Napi::CallbackInfo &info) {
|
|
|
53
53
|
if (info.Length() == 1 && Type::IsClassOf(info[0])) {
|
|
54
54
|
llvm::Type *type = Type::Extract(info[0]);
|
|
55
55
|
auto allocSize = dataLayout->getTypeAllocSize(type);
|
|
56
|
-
return Napi::Number::New(env, double(allocSize.
|
|
56
|
+
return Napi::Number::New(env, static_cast<double>(allocSize.getFixedValue()));
|
|
57
57
|
}
|
|
58
58
|
throw Napi::TypeError::New(env, ErrMsg::Class::DataLayout::getTypeAllocSize);
|
|
59
59
|
}
|
package/src/IR/DerivedTypes.cpp
CHANGED
|
@@ -565,7 +565,7 @@ void PointerType::Init(Napi::Env env, Napi::Object &exports) {
|
|
|
565
565
|
InstanceMethod("isIntegerTy", &PointerType::isIntegerTy),
|
|
566
566
|
InstanceMethod("isVoidTy", &PointerType::isVoidTy),
|
|
567
567
|
InstanceMethod("getTypeID", &PointerType::getTypeID),
|
|
568
|
-
InstanceMethod("
|
|
568
|
+
InstanceMethod("getNonOpaquePointerElementType", &PointerType::getNonOpaquePointerElementType),
|
|
569
569
|
InstanceMethod("isOpaque", &PointerType::isOpaque)
|
|
570
570
|
});
|
|
571
571
|
constructor = Napi::Persistent(func);
|
|
@@ -664,8 +664,8 @@ Napi::Value PointerType::getTypeID(const Napi::CallbackInfo &info) {
|
|
|
664
664
|
return Napi::Number::New(info.Env(), pointerType->getTypeID());
|
|
665
665
|
}
|
|
666
666
|
|
|
667
|
-
Napi::Value PointerType::
|
|
668
|
-
return Type::New(info.Env(), pointerType->
|
|
667
|
+
Napi::Value PointerType::getNonOpaquePointerElementType(const Napi::CallbackInfo &info) {
|
|
668
|
+
return Type::New(info.Env(), pointerType->getNonOpaquePointerElementType());
|
|
669
669
|
}
|
|
670
670
|
|
|
671
671
|
Napi::Value PointerType::isOpaque(const Napi::CallbackInfo &info) {
|
package/src/IR/Function.cpp
CHANGED
|
@@ -111,7 +111,7 @@ void Function::addBasicBlock(const Napi::CallbackInfo &info) {
|
|
|
111
111
|
throw Napi::TypeError::New(env, ErrMsg::Class::Function::addBasicBlock);
|
|
112
112
|
}
|
|
113
113
|
llvm::BasicBlock *basicBlock = BasicBlock::Extract(info[0]);
|
|
114
|
-
function->
|
|
114
|
+
function->insert(function->end(), basicBlock);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
Napi::Value Function::getEntryBlock(const Napi::CallbackInfo &info) {
|
|
@@ -129,7 +129,9 @@ void Function::insertAfter(const Napi::CallbackInfo &info) {
|
|
|
129
129
|
}
|
|
130
130
|
llvm::BasicBlock *where = BasicBlock::Extract(info[0]);
|
|
131
131
|
llvm::BasicBlock *bb = BasicBlock::Extract(info[1]);
|
|
132
|
-
|
|
132
|
+
auto it = where->getIterator();
|
|
133
|
+
++it;
|
|
134
|
+
function->insert(it, bb);
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
void Function::deleteBody(const Napi::CallbackInfo &info) {
|
package/src/IR/IRBuilder.cpp
CHANGED
|
@@ -498,7 +498,7 @@ Napi::Value IRBuilder::CreateInvoke(const Napi::CallbackInfo &info) {
|
|
|
498
498
|
llvm::BasicBlock *normalDest = BasicBlock::Extract(info[1]);
|
|
499
499
|
llvm::BasicBlock *unwindDest = BasicBlock::Extract(info[2]);
|
|
500
500
|
std::string name = argsLen == 4 ? std::string(info[3].As<Napi::String>()) : "";
|
|
501
|
-
invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest,
|
|
501
|
+
invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest, {}, name);
|
|
502
502
|
} else if (argsLen == 4 && Function::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() ||
|
|
503
503
|
argsLen == 5 && Function::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() && info[4].IsString()) {
|
|
504
504
|
if (assembleArray<WrappedValue>(info[3].As<Napi::Array>(), calleeArgs)) {
|
|
@@ -514,7 +514,7 @@ Napi::Value IRBuilder::CreateInvoke(const Napi::CallbackInfo &info) {
|
|
|
514
514
|
llvm::BasicBlock *normalDest = BasicBlock::Extract(info[1]);
|
|
515
515
|
llvm::BasicBlock *unwindDest = BasicBlock::Extract(info[2]);
|
|
516
516
|
std::string name = argsLen == 4 ? std::string(info[3].As<Napi::String>()) : "";
|
|
517
|
-
invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest,
|
|
517
|
+
invokeInst = builder->CreateInvoke(callee, normalDest, unwindDest, {}, name);
|
|
518
518
|
} else if (argsLen == 4 && FunctionCallee::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() ||
|
|
519
519
|
argsLen == 5 && FunctionCallee::IsClassOf(info[0]) && BasicBlock::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) && info[3].IsArray() && info[4].IsString()) {
|
|
520
520
|
if (assembleArray<WrappedValue>(info[3].As<Napi::Array>(), calleeArgs)) {
|
|
@@ -533,7 +533,7 @@ Napi::Value IRBuilder::CreateInvoke(const Napi::CallbackInfo &info) {
|
|
|
533
533
|
llvm::BasicBlock *normalDest = BasicBlock::Extract(info[2]);
|
|
534
534
|
llvm::BasicBlock *unwindDest = BasicBlock::Extract(info[3]);
|
|
535
535
|
std::string name = argsLen == 5 ? std::string(info[4].As<Napi::String>()) : "";
|
|
536
|
-
invokeInst = builder->CreateInvoke(funcType, callee, normalDest, unwindDest,
|
|
536
|
+
invokeInst = builder->CreateInvoke(funcType, callee, normalDest, unwindDest, {}, name);
|
|
537
537
|
} else if (argsLen == 5 && FunctionType::IsClassOf(info[0]) && Function::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) &&
|
|
538
538
|
BasicBlock::IsClassOf(info[3]) && info[4].IsArray() ||
|
|
539
539
|
argsLen == 6 && FunctionType::IsClassOf(info[0]) && Function::IsClassOf(info[1]) && BasicBlock::IsClassOf(info[2]) &&
|
|
@@ -711,7 +711,7 @@ Napi::Value IRBuilder::CreateCall(const Napi::CallbackInfo &info) {
|
|
|
711
711
|
argsLen == 2 && Function::IsClassOf(info[0]) && info[1].IsString()) {
|
|
712
712
|
llvm::Function *callee = Function::Extract(info[0]);
|
|
713
713
|
std::string name = argsLen == 2 ? std::string(info[1].As<Napi::String>()) : "";
|
|
714
|
-
callInst = builder->CreateCall(callee,
|
|
714
|
+
callInst = builder->CreateCall(callee, {}, name);
|
|
715
715
|
} else if (argsLen == 2 && Function::IsClassOf(info[0]) && info[1].IsArray() ||
|
|
716
716
|
argsLen == 3 && Function::IsClassOf(info[0]) && info[1].IsArray() && info[2].IsString()) {
|
|
717
717
|
if (assembleArray<WrappedValue>(info[1].As<Napi::Array>(), calleeArgs)) {
|
|
@@ -723,7 +723,7 @@ Napi::Value IRBuilder::CreateCall(const Napi::CallbackInfo &info) {
|
|
|
723
723
|
argsLen == 2 && FunctionCallee::IsClassOf(info[0]) && info[1].IsString()) {
|
|
724
724
|
llvm::FunctionCallee callee = FunctionCallee::Extract(info[0]);
|
|
725
725
|
std::string name = argsLen == 2 ? std::string(info[1].As<Napi::String>()) : "";
|
|
726
|
-
callInst = builder->CreateCall(callee,
|
|
726
|
+
callInst = builder->CreateCall(callee, {}, name);
|
|
727
727
|
} else if (argsLen == 2 && FunctionCallee::IsClassOf(info[0]) && info[1].IsArray() ||
|
|
728
728
|
argsLen == 3 && FunctionCallee::IsClassOf(info[0]) && info[1].IsArray() && info[2].IsString()) {
|
|
729
729
|
if (assembleArray<WrappedValue>(info[1].As<Napi::Array>(), calleeArgs)) {
|
|
@@ -736,7 +736,7 @@ Napi::Value IRBuilder::CreateCall(const Napi::CallbackInfo &info) {
|
|
|
736
736
|
llvm::FunctionType *funcType = FunctionType::Extract(info[0]);
|
|
737
737
|
llvm::Value *callee = Value::Extract(info[1]);
|
|
738
738
|
std::string name = argsLen == 3 ? std::string(info[2].As<Napi::String>()) : "";
|
|
739
|
-
callInst = builder->CreateCall(funcType, callee,
|
|
739
|
+
callInst = builder->CreateCall(funcType, callee, {}, name);
|
|
740
740
|
} else if (argsLen == 3 && FunctionType::IsClassOf(info[0]) && Value::IsClassOf(info[1]) && info[2].IsArray() ||
|
|
741
741
|
argsLen == 4 && FunctionType::IsClassOf(info[0]) && Value::IsClassOf(info[1]) && info[2].IsArray() && info[3].IsString()) {
|
|
742
742
|
if (assembleArray<WrappedValue>(info[2].As<Napi::Array>(), calleeArgs)) {
|
package/src/IR/Intrinsic.cpp
CHANGED
|
@@ -81,7 +81,6 @@ void Intrinsic::Init(Napi::Env env, Napi::Object &exports) {
|
|
|
81
81
|
intrinsicNS.Set("ctlz", Napi::Number::New(env, llvm::Intrinsic::ctlz));
|
|
82
82
|
intrinsicNS.Set("ctpop", Napi::Number::New(env, llvm::Intrinsic::ctpop));
|
|
83
83
|
intrinsicNS.Set("cttz", Napi::Number::New(env, llvm::Intrinsic::cttz));
|
|
84
|
-
intrinsicNS.Set("dbg_addr", Napi::Number::New(env, llvm::Intrinsic::dbg_addr));
|
|
85
84
|
intrinsicNS.Set("dbg_declare", Napi::Number::New(env, llvm::Intrinsic::dbg_declare));
|
|
86
85
|
intrinsicNS.Set("dbg_label", Napi::Number::New(env, llvm::Intrinsic::dbg_label));
|
|
87
86
|
intrinsicNS.Set("dbg_value", Napi::Number::New(env, llvm::Intrinsic::dbg_value));
|
|
@@ -107,7 +106,6 @@ void Intrinsic::Init(Napi::Env env, Napi::Object &exports) {
|
|
|
107
106
|
intrinsicNS.Set("expect_with_probability", Napi::Number::New(env, llvm::Intrinsic::expect_with_probability));
|
|
108
107
|
intrinsicNS.Set("fabs", Napi::Number::New(env, llvm::Intrinsic::fabs));
|
|
109
108
|
intrinsicNS.Set("floor", Napi::Number::New(env, llvm::Intrinsic::floor));
|
|
110
|
-
intrinsicNS.Set("flt_rounds", Napi::Number::New(env, llvm::Intrinsic::flt_rounds));
|
|
111
109
|
intrinsicNS.Set("fma", Napi::Number::New(env, llvm::Intrinsic::fma));
|
|
112
110
|
intrinsicNS.Set("fmuladd", Napi::Number::New(env, llvm::Intrinsic::fmuladd));
|
|
113
111
|
intrinsicNS.Set("fptosi_sat", Napi::Number::New(env, llvm::Intrinsic::fptosi_sat));
|
package/src/IR/LLVMContext.cpp
CHANGED
|
@@ -23,7 +23,6 @@ LLVMContext::LLVMContext(const Napi::CallbackInfo &info) : ObjectWrap(info) {
|
|
|
23
23
|
throw Napi::TypeError::New(env, ErrMsg::Class::LLVMContext::constructor);
|
|
24
24
|
}
|
|
25
25
|
context = new llvm::LLVMContext();
|
|
26
|
-
context->setOpaquePointers(false);
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
llvm::LLVMContext &LLVMContext::getLLVMPrimitive() {
|
package/src/IR/Type.cpp
CHANGED
|
@@ -126,7 +126,7 @@ void Type::Init(Napi::Env env, Napi::Object &exports) {
|
|
|
126
126
|
InstanceMethod("isAggregateType", &Type::isTypeFactory<&llvm::Type::isAggregateType>),
|
|
127
127
|
InstanceMethod("getPointerTo", &Type::getPointerTo),
|
|
128
128
|
InstanceMethod("getPrimitiveSizeInBits", &Type::getPrimitiveSizeInBits),
|
|
129
|
-
InstanceMethod("
|
|
129
|
+
InstanceMethod("getNonOpaquePointerElementType", &Type::getNonOpaquePointerElementType),
|
|
130
130
|
StaticMethod("isSameType", &Type::isSameType)
|
|
131
131
|
});
|
|
132
132
|
constructor = Napi::Persistent(func);
|
|
@@ -216,8 +216,8 @@ Napi::Value Type::isIntegerTy(const Napi::CallbackInfo &info) {
|
|
|
216
216
|
return Napi::Boolean::New(env, result);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
Napi::Value Type::
|
|
220
|
-
return Type::New(info.Env(), type->
|
|
219
|
+
Napi::Value Type::getNonOpaquePointerElementType(const Napi::CallbackInfo &info) {
|
|
220
|
+
return Type::New(info.Env(), type->getNonOpaquePointerElementType());
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
static bool isSameType(llvm::Type *type1, llvm::Type *type2) {
|
|
@@ -248,7 +248,7 @@ static bool isSameType(llvm::Type *type1, llvm::Type *type2) {
|
|
|
248
248
|
if (type1->isOpaquePointerTy() || type2->isOpaquePointerTy()) {
|
|
249
249
|
return type1->isOpaquePointerTy() && type2->isOpaquePointerTy();
|
|
250
250
|
}
|
|
251
|
-
return isSameType(type1->
|
|
251
|
+
return isSameType(type1->getNonOpaquePointerElementType(), type2->getNonOpaquePointerElementType());
|
|
252
252
|
} else if (type1->isStructTy()) {
|
|
253
253
|
unsigned numElements = type1->getStructNumElements();
|
|
254
254
|
if (numElements != type2->getStructNumElements()) {
|
|
@@ -45,7 +45,8 @@ Napi::Value Target::createTargetMachine(const Napi::CallbackInfo &info) {
|
|
|
45
45
|
features = info[2].As<Napi::String>();
|
|
46
46
|
}
|
|
47
47
|
llvm::TargetOptions options{};
|
|
48
|
-
llvm::TargetMachine *targetMachinePtr = target->createTargetMachine(
|
|
48
|
+
llvm::TargetMachine *targetMachinePtr = target->createTargetMachine(
|
|
49
|
+
targetTriple, cpu, features, options, std::optional<llvm::Reloc::Model>{});
|
|
49
50
|
return TargetMachine::New(env, targetMachinePtr);
|
|
50
51
|
}
|
|
51
52
|
|
package/src/llvm-bindings.cpp
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
#include <cstdio>
|
|
2
|
+
#include <memory>
|
|
3
|
+
#include <stdexcept>
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
1
6
|
#include "ADT/index.h"
|
|
2
7
|
#include "BinaryFormat/index.h"
|
|
3
8
|
#include "Bitcode/index.h"
|
|
@@ -9,7 +14,27 @@
|
|
|
9
14
|
#include "Support/index.h"
|
|
10
15
|
#include "Target/index.h"
|
|
11
16
|
|
|
17
|
+
template<typename ... Args>
|
|
18
|
+
std::string string_format( const std::string& format, Args ... args )
|
|
19
|
+
{
|
|
20
|
+
int size_s = std::snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
|
|
21
|
+
if( size_s <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
|
|
22
|
+
auto size = static_cast<size_t>( size_s );
|
|
23
|
+
std::unique_ptr<char[]> buf( new char[ size ] );
|
|
24
|
+
std::snprintf( buf.get(), size, format.c_str(), args ... );
|
|
25
|
+
return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static std::unique_ptr<Napi::Env> node_env;
|
|
29
|
+
|
|
30
|
+
void llvm_bindings_assert(const char* e, const char* file, int line)
|
|
31
|
+
{
|
|
32
|
+
throw Napi::Error::New(
|
|
33
|
+
*node_env, string_format("%s:%d: failed assertion `%s'\n", file, line, e));
|
|
34
|
+
}
|
|
35
|
+
|
|
12
36
|
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
37
|
+
node_env = std::make_unique<Napi::Env>(env);
|
|
13
38
|
InitADT(env, exports);
|
|
14
39
|
InitBinaryFormat(env, exports);
|
|
15
40
|
InitBitCode(env, exports);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import llvm from '../..';
|
|
2
|
+
|
|
3
|
+
describe('Test Opaque Pointer (LLVM 17)', () => {
|
|
4
|
+
test('PointerType.getUnqual returns a pointer type', () => {
|
|
5
|
+
const context = new llvm.LLVMContext();
|
|
6
|
+
const ptr = llvm.PointerType.getUnqual(llvm.Type.getInt8Ty(context));
|
|
7
|
+
expect(ptr.isPointerTy()).toBe(true);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('PointerType.get(type, addrSpace) returns a pointer type', () => {
|
|
11
|
+
const context = new llvm.LLVMContext();
|
|
12
|
+
const ptr = llvm.PointerType.get(llvm.Type.getInt8Ty(context), 0);
|
|
13
|
+
expect(ptr.isPointerTy()).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('getUnqual, get(AS0), and getInt8PtrTy all resolve to the same type', () => {
|
|
17
|
+
const context = new llvm.LLVMContext();
|
|
18
|
+
const a = llvm.PointerType.getUnqual(llvm.Type.getInt8Ty(context));
|
|
19
|
+
const b = llvm.PointerType.get(llvm.Type.getInt8Ty(context), 0);
|
|
20
|
+
const c = llvm.Type.getInt8PtrTy(context);
|
|
21
|
+
expect(llvm.Type.isSameType(a, b)).toBe(true);
|
|
22
|
+
expect(llvm.Type.isSameType(a, c)).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('pointers in different address spaces are both pointer types', () => {
|
|
26
|
+
const context = new llvm.LLVMContext();
|
|
27
|
+
const as0 = llvm.PointerType.get(llvm.Type.getInt8Ty(context), 0);
|
|
28
|
+
const as1 = llvm.PointerType.get(llvm.Type.getInt8Ty(context), 1);
|
|
29
|
+
expect(as0.isPointerTy()).toBe(true);
|
|
30
|
+
expect(as1.isPointerTy()).toBe(true);
|
|
31
|
+
// Note: isSameType does not currently compare address spaces for opaque
|
|
32
|
+
// pointers — that is a known limitation of the binding's implementation.
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// The following require a binary rebuilt against LLVM 17:
|
|
36
|
+
// - PointerType.getUnqual(context) — context overload
|
|
37
|
+
// - PointerType.get(context, addrSpace) — context overload
|
|
38
|
+
// - ptr.isOpaque() — method not yet registered
|
|
39
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import llvm from '../..';
|
|
2
|
+
|
|
3
|
+
describe('Test Type', () => {
|
|
4
|
+
test('isSameType correctly compares primitive and pointer types', () => {
|
|
5
|
+
const context = new llvm.LLVMContext();
|
|
6
|
+
|
|
7
|
+
const int32 = llvm.Type.getInt32Ty(context);
|
|
8
|
+
const int32b = llvm.IntegerType.get(context, 32);
|
|
9
|
+
const int8Ptr = llvm.Type.getInt8PtrTy(context);
|
|
10
|
+
const unqualPtr = llvm.PointerType.getUnqual(llvm.Type.getInt8Ty(context));
|
|
11
|
+
const voidTy = llvm.Type.getVoidTy(context);
|
|
12
|
+
|
|
13
|
+
expect(llvm.Type.isSameType(int32, int32b)).toBe(true);
|
|
14
|
+
expect(llvm.Type.isSameType(int32, int8Ptr)).toBe(false);
|
|
15
|
+
expect(llvm.Type.isSameType(int32, unqualPtr)).toBe(false);
|
|
16
|
+
expect(llvm.Type.isSameType(int32, voidTy)).toBe(false);
|
|
17
|
+
expect(llvm.Type.isSameType(int32b, int8Ptr)).toBe(false);
|
|
18
|
+
expect(llvm.Type.isSameType(int32b, unqualPtr)).toBe(false);
|
|
19
|
+
expect(llvm.Type.isSameType(int32b, voidTy)).toBe(false);
|
|
20
|
+
expect(llvm.Type.isSameType(int8Ptr, unqualPtr)).toBe(true);
|
|
21
|
+
expect(llvm.Type.isSameType(int8Ptr, voidTy)).toBe(false);
|
|
22
|
+
expect(llvm.Type.isSameType(unqualPtr, voidTy)).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import llvm from '../..';
|
|
2
|
+
|
|
3
|
+
describe('Test Add', () => {
|
|
4
|
+
test('builds and verifies valid IR for an add function', () => {
|
|
5
|
+
const context = new llvm.LLVMContext();
|
|
6
|
+
const module = new llvm.Module('add', context);
|
|
7
|
+
const builder = new llvm.IRBuilder(context);
|
|
8
|
+
|
|
9
|
+
const returnType = builder.getInt32Ty();
|
|
10
|
+
const paramTypes = [builder.getInt32Ty(), builder.getInt32Ty()];
|
|
11
|
+
const functionType = llvm.FunctionType.get(returnType, paramTypes, false);
|
|
12
|
+
const func = llvm.Function.Create(functionType, llvm.Function.LinkageTypes.ExternalLinkage, 'add', module);
|
|
13
|
+
|
|
14
|
+
const entryBB = llvm.BasicBlock.Create(context, 'entry', func);
|
|
15
|
+
builder.SetInsertPoint(entryBB);
|
|
16
|
+
const paramA = func.getArg(0);
|
|
17
|
+
const paramB = func.getArg(1);
|
|
18
|
+
const result = builder.CreateAdd(paramA, paramB);
|
|
19
|
+
builder.CreateRet(result);
|
|
20
|
+
|
|
21
|
+
expect(llvm.verifyFunction(func)).toBe(false);
|
|
22
|
+
expect(llvm.verifyModule(module)).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import llvm from '../..';
|
|
2
|
+
|
|
3
|
+
describe('Test Attribute', () => {
|
|
4
|
+
test('builds and verifies valid IR with function and parameter attributes', () => {
|
|
5
|
+
const context = new llvm.LLVMContext();
|
|
6
|
+
const module = new llvm.Module('attribute', context);
|
|
7
|
+
const builder = new llvm.IRBuilder(context);
|
|
8
|
+
|
|
9
|
+
const returnType = builder.getInt32Ty();
|
|
10
|
+
const paramTypes = [builder.getInt32Ty(), builder.getInt32Ty()];
|
|
11
|
+
const functionType = llvm.FunctionType.get(returnType, paramTypes, false);
|
|
12
|
+
const func = llvm.Function.Create(functionType, llvm.Function.LinkageTypes.ExternalLinkage, 'addWithAttributes', module);
|
|
13
|
+
|
|
14
|
+
const noInlineAttr = llvm.Attribute.get(context, llvm.Attribute.AttrKind.NoInline);
|
|
15
|
+
const inRegAttr = llvm.Attribute.get(context, llvm.Attribute.AttrKind.InReg, builder.getInt32Ty());
|
|
16
|
+
func.addFnAttr(noInlineAttr);
|
|
17
|
+
func.addParamAttr(0, inRegAttr);
|
|
18
|
+
|
|
19
|
+
const entryBB = llvm.BasicBlock.Create(context, 'entry', func);
|
|
20
|
+
builder.SetInsertPoint(entryBB);
|
|
21
|
+
const result = builder.CreateAdd(func.getArg(0), func.getArg(1));
|
|
22
|
+
builder.CreateRet(result);
|
|
23
|
+
|
|
24
|
+
expect(llvm.verifyFunction(func)).toBe(false);
|
|
25
|
+
expect(llvm.verifyModule(module)).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|