Skip to content

Commit 2770943

Browse files
committed
Create intial debug bindings.
Signed-off-by: Vihan <vihan+github@vihan.org>
1 parent 35b7014 commit 2770943

File tree

13 files changed

+452
-0
lines changed

13 files changed

+452
-0
lines changed

llvm-node.d.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,69 @@ declare namespace llvm {
254254
private constructor();
255255
}
256256

257+
class DIBuilder {
258+
constructor(module: Module);
259+
260+
createCompileUnit(language: dwarf.SourceLanguage, file: DIFile, producer: string, isOptimized: boolean, flags?: string, runtimeVersion?: number): DICompileUnit;
261+
262+
createFile(filename: string, directory: string): DIFile;
263+
264+
finalize();
265+
}
266+
267+
class DICompileUnit {
268+
269+
}
270+
271+
class DIFile {
272+
readonly filename: string;
273+
readonly directory: string;
274+
275+
private constructor();
276+
}
277+
278+
namespace dwarf {
279+
enum SourceLanguage {
280+
C89,
281+
C,
282+
Ada83,
283+
C_plus_plus,
284+
Cobol74,
285+
Cobol85,
286+
Fortran77,
287+
Fortran90,
288+
Pascal83,
289+
Modula2,
290+
Java,
291+
C99,
292+
Ada95,
293+
Fortran95,
294+
PLI,
295+
ObjC,
296+
ObjC_plus_plus,
297+
UPC,
298+
D,
299+
Python,
300+
OpenCL,
301+
Go,
302+
Modula3,
303+
Haskell,
304+
C_plus_plus_03,
305+
C_plus_plus_11,
306+
OCaml,
307+
Rust,
308+
C11,
309+
Swift,
310+
Julia,
311+
Dylan,
312+
C_plus_plus_14,
313+
Fortran03,
314+
Fortran08,
315+
RenderScript,
316+
BLISS
317+
}
318+
}
319+
257320
class Function extends Constant {
258321
static create(functionType: FunctionType, linkageTypes: LinkageTypes, name?: string, module?: Module): Function;
259322

src/dwarf/dwarf.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <llvm/IR/Attributes.h>
2+
#include "source-language.h"
3+
4+
NAN_MODULE_INIT(InitDwarf) {
5+
auto dwarf = Nan::New<v8::Object>();
6+
7+
InitSourceLanguage(dwarf);
8+
9+
Nan::Set(target, Nan::New("dwarf").ToLocalChecked(), dwarf);
10+
}

src/dwarf/dwarf.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef LLVM_NODE_DWARF_H
2+
#define LLVM_NODE_DWARF_H
3+
4+
#include <nan.h>
5+
6+
NAN_MODULE_INIT(InitDwarf);
7+
8+
#endif //LLVM_NODE_DWARF_H

src/dwarf/source-language.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "source-language.h"
2+
3+
NAN_MODULE_INIT(InitSourceLanguage) {
4+
auto object = Nan::New<v8::Object>();
5+
6+
Nan::Set(object, Nan::New("C89").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C89));;
7+
Nan::Set(object, Nan::New("C").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C));;
8+
Nan::Set(object, Nan::New("Ada83").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Ada83));;
9+
Nan::Set(object, Nan::New("C_plus_plus").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C_plus_plus));;
10+
Nan::Set(object, Nan::New("Cobol74").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Cobol74));;
11+
Nan::Set(object, Nan::New("Cobol85").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Cobol85));;
12+
Nan::Set(object, Nan::New("Fortran77").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Fortran77));;
13+
Nan::Set(object, Nan::New("Fortran90").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Fortran90));;
14+
Nan::Set(object, Nan::New("Pascal83").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Pascal83));;
15+
Nan::Set(object, Nan::New("Modula2").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Modula2));;
16+
Nan::Set(object, Nan::New("Java").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Java));;
17+
Nan::Set(object, Nan::New("C99").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C99));;
18+
Nan::Set(object, Nan::New("Ada95").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Ada95));;
19+
Nan::Set(object, Nan::New("Fortran95").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Fortran95));;
20+
Nan::Set(object, Nan::New("PLI").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_PLI));;
21+
Nan::Set(object, Nan::New("ObjC").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_ObjC));;
22+
Nan::Set(object, Nan::New("ObjC_plus_plus").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_ObjC_plus_plus));;
23+
Nan::Set(object, Nan::New("UPC").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_UPC));;
24+
Nan::Set(object, Nan::New("D").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_D));;
25+
Nan::Set(object, Nan::New("Python").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Python));;
26+
Nan::Set(object, Nan::New("OpenCL").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_OpenCL));;
27+
Nan::Set(object, Nan::New("Go").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Go));;
28+
Nan::Set(object, Nan::New("Modula3").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Modula3));;
29+
Nan::Set(object, Nan::New("Haskell").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Haskell));;
30+
Nan::Set(object, Nan::New("C_plus_plus_03").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C_plus_plus_03));;
31+
Nan::Set(object, Nan::New("C_plus_plus_11").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C_plus_plus_11));;
32+
Nan::Set(object, Nan::New("OCaml").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_OCaml));;
33+
Nan::Set(object, Nan::New("Rust").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Rust));;
34+
Nan::Set(object, Nan::New("C11").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C11));;
35+
Nan::Set(object, Nan::New("Swift").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Swift));;
36+
Nan::Set(object, Nan::New("Julia").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Julia));;
37+
Nan::Set(object, Nan::New("Dylan").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Dylan));;
38+
Nan::Set(object, Nan::New("C_plus_plus_14").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_C_plus_plus_14));;
39+
Nan::Set(object, Nan::New("Fortran03").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Fortran03));;
40+
Nan::Set(object, Nan::New("Fortran08").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_Fortran08));;
41+
Nan::Set(object, Nan::New("RenderScript").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_RenderScript));;
42+
Nan::Set(object, Nan::New("BLISS").ToLocalChecked(), Nan::New(llvm::dwarf::DW_LANG_BLISS));
43+
44+
Nan::Set(target, Nan::New("SourceLanguage").ToLocalChecked(), object);
45+
}

src/dwarf/source-language.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef LLVM_NODE_SOURCE_LANGUAGE_H
2+
#define LLVM_NODE_SOURCE_LANGUAGE_H
3+
4+
#include <nan.h>
5+
#include <llvm/IR/GlobalValue.h>
6+
#include <llvm/BinaryFormat/Dwarf.h>
7+
8+
NAN_MODULE_INIT(InitSourceLanguage);
9+
10+
#endif //LLVM_NODE_SOURCE_LANGUAGE_H

src/ir/di-builder.cc

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#include "di-builder.h"
2+
#include "di-file.h"
3+
#include "di-compile-unit.h"
4+
#include "module.h"
5+
#include "../util/string.h"
6+
7+
NAN_MODULE_INIT(DIBuilderWrapper::Init) {
8+
v8::Local<v8::FunctionTemplate> functionTemplate = Nan::New<v8::FunctionTemplate>(New);
9+
functionTemplate->SetClassName(Nan::New("DIBuilder").ToLocalChecked());
10+
functionTemplate->InstanceTemplate()->SetInternalFieldCount(1);
11+
12+
Nan::SetPrototypeMethod(functionTemplate, "createCompileUnit", DIBuilderWrapper::CreateCompileUnit);
13+
Nan::SetPrototypeMethod(functionTemplate, "createFile", DIBuilderWrapper::CreateFile);
14+
Nan::SetPrototypeMethod(functionTemplate, "finalize", DIBuilderWrapper::Finalize);
15+
16+
auto constructorFunction = Nan::GetFunction(functionTemplate).ToLocalChecked();
17+
diBuilderConstructor().Reset(constructorFunction);
18+
19+
Nan::Set(target, Nan::New("DIBuilder").ToLocalChecked(), constructorFunction);
20+
}
21+
22+
NAN_METHOD(DIBuilderWrapper::New) {
23+
if (!info.IsConstructCall()) {
24+
return Nan::ThrowTypeError("DIBuilder constructor needs to be called with new");
25+
}
26+
27+
if (info.Length() != 1 || !ModuleWrapper::isInstance(info[0])) {
28+
return Nan::ThrowTypeError("IRBuilder constructor needs either be called with context: LLVMContext or basicBlock: BasicBlock, insertBefore?: Instruction");
29+
}
30+
31+
auto* module = ModuleWrapper::FromValue(info[0])->getModule();
32+
auto* diBuilder = new llvm::DIBuilder { *module };
33+
34+
DIBuilderWrapper* wrapper = new DIBuilderWrapper { diBuilder };
35+
36+
wrapper->Wrap(info.This());
37+
info.GetReturnValue().Set(info.This());
38+
}
39+
40+
NAN_METHOD(DIBuilderWrapper::CreateFile) {
41+
if (info.Length() != 2 || !info[0]->IsString() || !info[1]->IsString()) {
42+
return Nan::ThrowTypeError("createFile needs to be called with filename: string, directory: string");
43+
}
44+
45+
auto* diBuilder = DIBuilderWrapper::FromValue(info.Holder())->getDIBuilder();
46+
47+
std::string name = ToString(info[0]);
48+
std::string directory = ToString(info[1]);
49+
50+
auto *file = diBuilder->createFile(name, directory);
51+
52+
info.GetReturnValue().Set(DIFileWrapper::of(file));
53+
}
54+
55+
NAN_METHOD(DIBuilderWrapper::CreateCompileUnit) {
56+
auto* diBuilder = DIBuilderWrapper::FromValue(info.Holder())->getDIBuilder();
57+
58+
if (info.Length() < 4 || !info[0]->IsUint32() || !DIFileWrapper::isInstance(info[1]) || !info[2]->IsString() || !info[3]->IsBoolean()
59+
|| (info.Length() > 4 && !info[4]->IsString())
60+
|| (info.Length() > 5 && !info[5]->IsUint32())
61+
|| info.Length() > 6) {
62+
return Nan::ThrowTypeError("createCompileUnit needs to be called with language: dwarf.SourceLanguage, file: DIFile, producer: string, isOptimized: boolean, flags?: string, runtimeVersion?: number");
63+
}
64+
65+
unsigned lang = Nan::To<unsigned>(info[0]).FromJust();
66+
llvm::DIFile *file = DIFileWrapper::FromValue(info[1])->getDIFile();
67+
std::string producer = ToString(info[2]);
68+
bool isOptimized = Nan::To<bool>(info[3]).FromJust();
69+
70+
std::string flags = "";
71+
unsigned runtimeVersion = 0;
72+
73+
if (info.Length() > 4) {
74+
flags = ToString(info[4]);
75+
}
76+
77+
if (info.Length() > 5) {
78+
isOptimized = Nan::To<unsigned>(info[5]).FromJust();
79+
}
80+
81+
llvm::DICompileUnit *compileUnit = diBuilder->createCompileUnit(lang, file, producer, isOptimized, flags, runtimeVersion);
82+
return info.GetReturnValue().Set(DICompileUnitWrapper::of(compileUnit));
83+
}
84+
85+
NAN_METHOD(DIBuilderWrapper::Finalize) {
86+
auto* diBuilder = DIBuilderWrapper::FromValue(info.Holder())->getDIBuilder();
87+
diBuilder->finalize();
88+
}
89+
90+
llvm::DIBuilder *DIBuilderWrapper::getDIBuilder() {
91+
return this->diBuilder;
92+
}

src/ir/di-builder.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef LLVM_NODE_DI_BUILDER_H
2+
#define LLVM_NODE_DI_BUILDER_H
3+
4+
#include <nan.h>
5+
#include <llvm/IR/DIBuilder.h>
6+
#include <nan_callbacks_12_inl.h>
7+
#include "../util/from-value-mixin.h"
8+
#include "di-file.h"
9+
#include "../util/string.h"
10+
11+
class DIBuilderWrapper: public Nan::ObjectWrap, public FromValueMixin<DIBuilderWrapper> {
12+
public:
13+
static NAN_MODULE_INIT(Init);
14+
llvm::DIBuilder *getDIBuilder();
15+
16+
private:
17+
llvm::DIBuilder *diBuilder;
18+
19+
explicit DIBuilderWrapper(llvm::DIBuilder *diBuilder) : diBuilder { diBuilder } {
20+
}
21+
22+
// static
23+
static NAN_METHOD(New);
24+
25+
// instance
26+
static NAN_METHOD(CreateFile);
27+
static NAN_METHOD(CreateCompileUnit);
28+
static NAN_METHOD(Finalize);
29+
30+
static inline Nan::Persistent<v8::Function>& diBuilderConstructor() {
31+
static Nan::Persistent<v8::Function> constructor {};
32+
return constructor;
33+
}
34+
};
35+
36+
#endif //LLVM_NODE_DI_BUILDER_H

src/ir/di-compile-unit.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <iostream>
2+
#include "di-compile-unit.h"
3+
4+
Nan::Persistent<v8::FunctionTemplate> DICompileUnitWrapper::functionTemplate {};
5+
6+
NAN_MODULE_INIT(DICompileUnitWrapper::Init) {
7+
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
8+
tpl->SetClassName(Nan::New("DICompileUnit").ToLocalChecked());
9+
tpl->InstanceTemplate()->SetInternalFieldCount(1);
10+
11+
functionTemplate.Reset(tpl);
12+
13+
Nan::Set(target, Nan::New("DICompileUnit").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
14+
}
15+
16+
NAN_METHOD(DICompileUnitWrapper::New) {
17+
if (!info.IsConstructCall())
18+
{
19+
return Nan::ThrowTypeError("Class Constructor Value cannot be invoked without new");
20+
}
21+
22+
if (info.Length() != 1 || !info[0]->IsExternal())
23+
{
24+
return Nan::ThrowTypeError("External Value Pointer required");
25+
}
26+
27+
auto *file = static_cast<llvm::DICompileUnit *>(v8::External::Cast(*info[0])->Value());
28+
auto *wrapper = new DICompileUnitWrapper { file };
29+
30+
wrapper->Wrap(info.This());
31+
info.GetReturnValue().Set(info.This());
32+
}
33+
34+
v8::Local<v8::Object> DICompileUnitWrapper::of(llvm::DICompileUnit *compileUnit) {
35+
v8::Local<v8::FunctionTemplate> localFunctionTemplate = Nan::New(functionTemplate);
36+
v8::Local<v8::Object> object = Nan::NewInstance(localFunctionTemplate->InstanceTemplate()).ToLocalChecked();
37+
38+
DICompileUnitWrapper* wrapper = new DICompileUnitWrapper { compileUnit };
39+
wrapper->Wrap(object);
40+
41+
Nan::EscapableHandleScope escapeScope {};
42+
return escapeScope.Escape(object);
43+
}
44+
45+
llvm::DICompileUnit *DICompileUnitWrapper::getDICompileUnit() {
46+
return this->compileUnit;
47+
}
48+
49+
bool DICompileUnitWrapper::isInstance(v8::Local<v8::Value> value) {
50+
return Nan::New(functionTemplate)->HasInstance(value);
51+
}

src/ir/di-compile-unit.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef LLVM_NODE_DI_COMPILE_UNIT_H
2+
#define LLVM_NODE_DI_COMPILE_UNIT_H
3+
4+
#include <nan.h>
5+
#include <llvm/IR/DebugInfoMetadata.h>
6+
#include <nan_callbacks_12_inl.h>
7+
#include "../util/from-value-mixin.h"
8+
9+
class DICompileUnitWrapper: public Nan::ObjectWrap, public FromValueMixin<DICompileUnitWrapper> {
10+
public:
11+
static NAN_MODULE_INIT(Init);
12+
static v8::Local<v8::Object> of(llvm::DICompileUnit *compileUnit);
13+
14+
static bool isInstance(v8::Local<v8::Value> value);
15+
16+
llvm::DICompileUnit *getDICompileUnit();
17+
18+
private:
19+
llvm::DICompileUnit *compileUnit;
20+
21+
explicit DICompileUnitWrapper(llvm::DICompileUnit *compileUnit) : compileUnit { compileUnit } {
22+
}
23+
24+
static NAN_METHOD(New);
25+
26+
static Nan::Persistent<v8::FunctionTemplate> functionTemplate;
27+
};
28+
29+
#endif //LLVM_NODE_DI_COMPILE_UNIT_H

0 commit comments

Comments
 (0)