diff --git a/llvm-node.d.ts b/llvm-node.d.ts index b4874a2..6ba9ca2 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -98,6 +98,16 @@ declare namespace llvm { Protected } + enum AtomicOrdering { + NotAtomic, + Unordered, + Monotonic, + Acquire, + Release, + AcquireRelease, + SequentiallyConsistent + } + class Value { static MaxAlignmentExponent: number; static MaximumAlignment: number; @@ -173,6 +183,32 @@ declare namespace llvm { isAllOnesValue(): boolean; } + class ConstantAggregateZero extends Constant { + static get(type: Type): Constant; + + private constructor(); + } + + class ConstantExpr extends Constant { + static getPointerCast(constant: Constant, type: Type): Constant; + + static getIntegerCast(constant: Constant, type: Type): Constant; + + static getFPCast(constant: Constant, type: Type): Constant; + + static getBitCast(constant: Constant, type: Type): Constant; + + static getGetElementPtr(type: Type, constant: Constant, idxList: Constant[], inBounds?: boolean): Constant; + + static getOr(constant1: Constant, constant2: Constant): Constant; + + static getPointerBitCastOrAddrSpaceCast(constant: Constant, type: Type): Constant; + + static getAlignOf(type: Type): Constant; + + static getSizeOf(type: Type): Constant; + } + class ConstantFP extends Constant { static get(context: LLVMContext, value: number): ConstantFP; static get(type: Type, value: string): Constant; @@ -367,7 +403,11 @@ declare namespace llvm { getTypeStoreSize(type: Type): number; - getIntPtrType(context: LLVMContext, as: number): Type; + getTypeAllocSize(type: Type): number; + + getTypeAllocSizeInBits(type: Type): number; + + getIntPtrType(context: LLVMContext, as: number): IntegerType; } class Type { @@ -450,6 +490,7 @@ declare namespace llvm { isArrayTy(): boolean; + isFloatingPointTy(): boolean; isHalfTy(): boolean; isPointerTy(): this is PointerType; @@ -458,6 +499,7 @@ declare namespace llvm { getPrimitiveSizeInBits(): number; + toString(): string; } @@ -536,6 +578,8 @@ declare namespace llvm { createAShr(lhs: Value, rhs: Value, name?: string): Value; + createAtomicRMW(op: AtomicRMWInst.BinOp, ptr: Value, value: Value, ordering: AtomicOrdering): Value; + createBitCast(value: Value, destType: Type, name?: string): Value; createBr(basicBlock: BasicBlock): Value; @@ -583,6 +627,7 @@ declare namespace llvm { createFSub(lhs: Value, rhs: Value, name?: string): Value; createFPToSI(value: Value, type: Type, name?: string): Value; + createFPToUI(value: Value, type: Type, name?: string): Value; createGlobalString(str: string, name?: string, addressSpace?: number): Value; @@ -615,6 +660,8 @@ declare namespace llvm { createICmpULT(lhs: Value, rhs: Value, name?: string): Value; + createIsNull(ptr: Value, name?: string): Value; + createLoad(ptr: Value, name?: string): Value; createLShr(lhs: Value, rhs: Value, name?: string): Value; @@ -633,6 +680,8 @@ declare namespace llvm { createPtrToInt(value: Value, destType: Type, name?: string): Value; + createIntToPtr(value: Value, destType: Type, name?: string): Value; + createRet(value: Value): Value; createRetVoid(): Value; @@ -653,13 +702,36 @@ declare namespace llvm { createSRem(lhs: Value, rhs: Value, name?: string): Value; - CreateURem(lhs: Value, rhs: Value, name?: string): Value; + createUDiv(lhs: Value, rhs: Value, name?: string): Value; + + createURem(lhs: Value, rhs: Value, name?: string): Value; + + createUnreachable(): Value; createZExt(value: Value, destType: Type, name?: string): Value; + createZExtOrTrunc(value: Value, destType: Type, name?: string): Value; + + createSExtOrTrunc(value: Value, destType: Type, name?: string): Value; + getInsertBlock(): BasicBlock | undefined; } + namespace AtomicRMWInst { + enum BinOp { + Add, + Sub, + And, + Nand, + Or, + Xor, + Max, + Min, + UMax, + UMin + } + } + class LLVMContext { constructor(); diff --git a/src/ir/atomic-rmw-inst.cc b/src/ir/atomic-rmw-inst.cc new file mode 100644 index 0000000..48991c6 --- /dev/null +++ b/src/ir/atomic-rmw-inst.cc @@ -0,0 +1,22 @@ +#include +#include "atomic-rmw-inst.h" + +NAN_MODULE_INIT(InitAtomicRMWInst) { + auto atomicRMWInst = Nan::New(); + + auto binOp = Nan::New(); + Nan::Set(binOp, Nan::New("Add").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Add))); + Nan::Set(binOp, Nan::New("Sub").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Sub))); + Nan::Set(binOp, Nan::New("And").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::And))); + Nan::Set(binOp, Nan::New("Nand").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Nand))); + Nan::Set(binOp, Nan::New("Or").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Or))); + Nan::Set(binOp, Nan::New("Xor").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Xor))); + Nan::Set(binOp, Nan::New("Max").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Max))); + Nan::Set(binOp, Nan::New("Min").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Min))); + Nan::Set(binOp, Nan::New("UMax").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::UMax))); + Nan::Set(binOp, Nan::New("UMin").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::UMin))); + + Nan::Set(atomicRMWInst, Nan::New("BinOp").ToLocalChecked(), binOp); + + Nan::Set(target, Nan::New("AtomicRMWInst").ToLocalChecked(), atomicRMWInst); +} diff --git a/src/ir/atomic-rmw-inst.h b/src/ir/atomic-rmw-inst.h new file mode 100644 index 0000000..707db4d --- /dev/null +++ b/src/ir/atomic-rmw-inst.h @@ -0,0 +1,8 @@ +#ifndef LLVM_ATOMIC_RMW_INST_H +#define LLVM_ATOMIC_RMW_INST_H + +#include + +NAN_MODULE_INIT(InitAtomicRMWInst); + +#endif //LLVM_ATOMIC_RMW_INST_H diff --git a/src/ir/constant-aggregate-zero.cc b/src/ir/constant-aggregate-zero.cc new file mode 100644 index 0000000..d0eed42 --- /dev/null +++ b/src/ir/constant-aggregate-zero.cc @@ -0,0 +1,67 @@ +#include "constant-aggregate-zero.h" +#include "type.h" + +NAN_MODULE_INIT(ConstantAggregateZeroWrapper::Init) { + auto constantAggregateZero = Nan::GetFunction(Nan::New(constantAggregateZeroTemplate())).ToLocalChecked(); + + Nan::Set(target, Nan::New("ConstantAggregateZero").ToLocalChecked(), constantAggregateZero); +} + +v8::Local ConstantAggregateZeroWrapper::of(llvm::ConstantAggregateZero* constantAggregateZero) { + auto constructor = Nan::GetFunction(Nan::New(constantAggregateZeroTemplate())).ToLocalChecked(); + v8::Local args[1] = { Nan::New (constantAggregateZero) }; + + auto instance = Nan::NewInstance(constructor, 1, args).ToLocalChecked(); + + Nan::EscapableHandleScope escapableHandleScope {}; + return escapableHandleScope.Escape(instance); +} + +llvm::ConstantAggregateZero* ConstantAggregateZeroWrapper::getConstantAggregateZero() { + return static_cast(getValue()); +} + +Nan::Persistent& ConstantAggregateZeroWrapper::constantAggregateZeroTemplate() { + static Nan::Persistent functionTemplate {}; + + if (functionTemplate.IsEmpty()) { + v8::Local localTemplate = Nan::New(ConstantAggregateZeroWrapper::New); + localTemplate->SetClassName(Nan::New("ConstantAggregateZero").ToLocalChecked()); + localTemplate->InstanceTemplate()->SetInternalFieldCount(1); + localTemplate->Inherit(Nan::New(constantTemplate())); + + Nan::SetMethod(localTemplate, "get", ConstantAggregateZeroWrapper::get); + + functionTemplate.Reset(localTemplate); + } + + return functionTemplate; +} + +NAN_METHOD(ConstantAggregateZeroWrapper::New) { + if (!info.IsConstructCall()) { + return Nan::ThrowTypeError("ConstantAggregateZero constructor needs to be called with new"); + } + + if (!info[0]->IsExternal()) { + return Nan::ThrowTypeError("ConstantAggregateZero constructor needs to be called with: constantAggregateZero: External"); + } + + auto* constantAggregateZero = static_cast(v8::External::Cast(*info[0])->Value()); + auto* wrapper = new ConstantAggregateZeroWrapper { constantAggregateZero }; + wrapper->Wrap(info.This()); + + info.GetReturnValue().Set(info.This()); +} + + +NAN_METHOD(ConstantAggregateZeroWrapper::get) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[0])) { + return Nan::ThrowTypeError("get needs to be called with: type: Type"); + } + + auto* type = TypeWrapper::FromValue(info[0])->getType(); + auto constantAggregateZero = llvm::ConstantAggregateZero::get(type); + + info.GetReturnValue().Set(ConstantWrapper::of(constantAggregateZero)); +} diff --git a/src/ir/constant-aggregate-zero.h b/src/ir/constant-aggregate-zero.h new file mode 100644 index 0000000..a9bda14 --- /dev/null +++ b/src/ir/constant-aggregate-zero.h @@ -0,0 +1,25 @@ +#ifndef LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H +#define LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H + +#include +#include +#include "constant.h" + +class ConstantAggregateZeroWrapper: public ConstantWrapper, public FromValueMixin { +public: + static NAN_MODULE_INIT(Init); + static v8::Local of(llvm::ConstantAggregateZero* constantAggregateZero); + using FromValueMixin::FromValue; + llvm::ConstantAggregateZero* getConstantAggregateZero(); + +private: + explicit ConstantAggregateZeroWrapper(llvm::ConstantAggregateZero* constantAggregateZero) : ConstantWrapper { constantAggregateZero } + {} + + static Nan::Persistent& constantAggregateZeroTemplate(); + + static NAN_METHOD(New); + static NAN_METHOD(get); +}; + +#endif //LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H diff --git a/src/ir/constant-expr.cc b/src/ir/constant-expr.cc new file mode 100644 index 0000000..86e24e0 --- /dev/null +++ b/src/ir/constant-expr.cc @@ -0,0 +1,197 @@ +#include "constant-expr.h" +#include "type.h" + +NAN_MODULE_INIT(ConstantExprWrapper::Init) { + auto constantExpr = Nan::GetFunction(Nan::New(constantExprTemplate())).ToLocalChecked(); + + Nan::Set(target, Nan::New("ConstantExpr").ToLocalChecked(), constantExpr); +} + +v8::Local ConstantExprWrapper::of(llvm::ConstantExpr* constantExpr) { + auto constructor = Nan::GetFunction(Nan::New(constantExprTemplate())).ToLocalChecked(); + v8::Local args[1] = { Nan::New (constantExpr) }; + + auto instance = Nan::NewInstance(constructor, 1, args).ToLocalChecked(); + + Nan::EscapableHandleScope escapableHandleScope {}; + return escapableHandleScope.Escape(instance); +} + +llvm::ConstantExpr* ConstantExprWrapper::getConstantExpr() { + return static_cast(getValue()); +} + +Nan::Persistent& ConstantExprWrapper::constantExprTemplate() { + static Nan::Persistent functionTemplate {}; + + if (functionTemplate.IsEmpty()) { + v8::Local localTemplate = Nan::New(ConstantExprWrapper::New); + localTemplate->SetClassName(Nan::New("ConstantExpr").ToLocalChecked()); + localTemplate->InstanceTemplate()->SetInternalFieldCount(1); + localTemplate->Inherit(Nan::New(constantTemplate())); + + Nan::SetMethod(localTemplate, "getAlignOf", ConstantExprWrapper::getAlignOf); + Nan::SetMethod(localTemplate, "getSizeOf", ConstantExprWrapper::getSizeOf); + Nan::SetMethod(localTemplate, "getOr", ConstantExprWrapper::getOr); + Nan::SetMethod(localTemplate, "getPointerBitCastOrAddrSpaceCast", ConstantExprWrapper::getPointerBitCastOrAddrSpaceCast); + Nan::SetMethod(localTemplate, "getGetElementPtr", ConstantExprWrapper::getGetElementPtr); + Nan::SetMethod(localTemplate, "getPointerCast", ConstantExprWrapper::getPointerCast); + Nan::SetMethod(localTemplate, "getIntegerCast", ConstantExprWrapper::getIntegerCast); + Nan::SetMethod(localTemplate, "getFPCast", ConstantExprWrapper::getFPCast); + Nan::SetMethod(localTemplate, "getBitCast", ConstantExprWrapper::getBitCast); + + functionTemplate.Reset(localTemplate); + } + + return functionTemplate; +} + +NAN_METHOD(ConstantExprWrapper::New) { + if (!info.IsConstructCall()) { + return Nan::ThrowTypeError("ConstantExpr constructor needs to be called with new"); + } + + if (!info[0]->IsExternal()) { + return Nan::ThrowTypeError("ConstantExpr constructor needs to be called with: constantExpr: External"); + } + + auto* constantExpr = static_cast(v8::External::Cast(*info[0])->Value()); + auto* wrapper = new ConstantExprWrapper { constantExpr }; + wrapper->Wrap(info.This()); + + info.GetReturnValue().Set(info.This()); +} + +NAN_METHOD(ConstantExprWrapper::getAlignOf) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[1])) { + return Nan::ThrowTypeError("getAlignOf needs to be called with: type: Type"); + } + + auto type = TypeWrapper::FromValue(info[0])->getType(); + auto constantAlign = llvm::ConstantExpr::getAlignOf(type); + + info.GetReturnValue().Set(ConstantWrapper::of(constantAlign)); +} + +NAN_METHOD(ConstantExprWrapper::getSizeOf) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[1])) { + return Nan::ThrowTypeError("getSizeOf needs to be called with: type: Type"); + } + + auto type = TypeWrapper::FromValue(info[0])->getType(); + auto constantSize = llvm::ConstantExpr::getSizeOf(type); + + info.GetReturnValue().Set(ConstantWrapper::of(constantSize)); +} + +NAN_METHOD(ConstantExprWrapper::getFPCast) { + if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) { + return Nan::ThrowTypeError("getFPCast needs to be called with: constant: Constant, type: Type"); + } + + auto constant = ConstantWrapper::FromValue(info[0])->getConstant(); + auto type = TypeWrapper::FromValue(info[1])->getType(); + + auto constantCast = llvm::ConstantExpr::getFPCast(constant, type); + + info.GetReturnValue().Set(ConstantWrapper::of(constantCast)); +} + +NAN_METHOD(ConstantExprWrapper::getBitCast) { + if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) { + return Nan::ThrowTypeError("getBitCast needs to be called with: constant: Constant, type: Type"); + } + + auto constant = ConstantWrapper::FromValue(info[0])->getConstant(); + auto type = TypeWrapper::FromValue(info[1])->getType(); + + auto constantCast = llvm::ConstantExpr::getBitCast(constant, type); + + info.GetReturnValue().Set(ConstantWrapper::of(constantCast)); +} + +NAN_METHOD(ConstantExprWrapper::getIntegerCast) { + if (info.Length() != 3 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1]) || !info[2]->IsBoolean()) { + return Nan::ThrowTypeError("getIntegerCast needs to be called with: constant: Constant, type: Type, signed: Boolean"); + } + + auto constant = ConstantWrapper::FromValue(info[0])->getConstant(); + auto type = TypeWrapper::FromValue(info[1])->getType(); + bool isSigned = Nan::To(info[3]).FromJust(); + + auto constantCast = llvm::ConstantExpr::getIntegerCast(constant, type, isSigned); + + info.GetReturnValue().Set(ConstantWrapper::of(constantCast)); +} + +NAN_METHOD(ConstantExprWrapper::getGetElementPtr) { + if (info.Length() < 3 || !TypeWrapper::isInstance(info[0]) || !ConstantWrapper::isInstance(info[1]) || !info[2]->IsArray() || + (info.Length() == 4 && !info[3]->IsBoolean())) { + return Nan::ThrowTypeError("getGetElementPtr needs to be called with type: Type, constant: Constant, idxList: Constant[], inBounds?: boolean"); + } + + auto* type = TypeWrapper::FromValue(info[0])->getType(); + auto* ptr = ConstantWrapper::FromValue(info[1])->getConstant(); + auto indexValues = v8::Array::Cast(*info[2]); + std::vector idxList { indexValues->Length() }; + + for (uint32_t i = 0; i < indexValues->Length(); ++i) { + auto idx = indexValues->Get(i); + + if (!ConstantWrapper::isInstance(idx)) { + return Nan::ThrowTypeError("Constant expected for idxList element"); + } + + idxList[i] = ConstantWrapper::FromValue(idx)->getConstant(); + } + + bool inBounds = false; + + if (info.Length() == 4) { + inBounds = Nan::To(info[3]).FromJust(); + } + + auto* gep = llvm::ConstantExpr::getGetElementPtr(type, ptr, idxList, inBounds); + info.GetReturnValue().Set(ConstantWrapper::of(gep)); +} + +NAN_METHOD(ConstantExprWrapper::getOr) { + if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !ConstantWrapper::isInstance(info[1])) { + return Nan::ThrowTypeError("getOr needs to be called with: constant1: Constant, constant2: Constant"); + } + + auto constant1 = ConstantWrapper::FromValue(info[0])->getConstant(); + auto constant2 = ConstantWrapper::FromValue(info[1])->getConstant(); + + auto constant = llvm::ConstantExpr::getOr(constant1, constant2); + + info.GetReturnValue().Set(ConstantWrapper::of(constant)); +} + +NAN_METHOD(ConstantExprWrapper::getPointerBitCastOrAddrSpaceCast) { + if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) { + return Nan::ThrowTypeError("getPointerBitCastOrAddrSpaceCast needs to be called with: constant: Constant, type: Type"); + } + + + auto constant = ConstantWrapper::FromValue(info[0])->getConstant(); + auto type = TypeWrapper::FromValue(info[1])->getType(); + + auto constantBitCast = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(constant, type); + + info.GetReturnValue().Set(ConstantWrapper::of(constantBitCast)); +} + +NAN_METHOD(ConstantExprWrapper::getPointerCast) { + if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) { + return Nan::ThrowTypeError("getPointerCast needs to be called with: constant: Constant, type: Type"); + } + + + auto constant = ConstantWrapper::FromValue(info[0])->getConstant(); + auto type = TypeWrapper::FromValue(info[1])->getType(); + + auto constantBitCast = llvm::ConstantExpr::getPointerCast(constant, type); + + info.GetReturnValue().Set(ConstantWrapper::of(constantBitCast)); +} diff --git a/src/ir/constant-expr.h b/src/ir/constant-expr.h new file mode 100644 index 0000000..8ea0453 --- /dev/null +++ b/src/ir/constant-expr.h @@ -0,0 +1,33 @@ +#ifndef LLVM_NODE_CONSTANT_EXPR_H +#define LLVM_NODE_CONSTANT_EXPR_H + +#include +#include +#include "constant.h" + +class ConstantExprWrapper: public ConstantWrapper, public FromValueMixin { +public: + static NAN_MODULE_INIT(Init); + static v8::Local of(llvm::ConstantExpr* constantExpr); + using FromValueMixin::FromValue; + llvm::ConstantExpr* getConstantExpr(); + +private: + explicit ConstantExprWrapper(llvm::ConstantExpr* constantExpr) : ConstantWrapper { constantExpr } + {} + + static Nan::Persistent& constantExprTemplate(); + + static NAN_METHOD(New); + static NAN_METHOD(getAlignOf); + static NAN_METHOD(getSizeOf); + static NAN_METHOD(getOr); + static NAN_METHOD(getPointerBitCastOrAddrSpaceCast); + static NAN_METHOD(getGetElementPtr); + static NAN_METHOD(getPointerCast); + static NAN_METHOD(getIntegerCast); + static NAN_METHOD(getFPCast); + static NAN_METHOD(getBitCast); +}; + +#endif //LLVM_NODE_CONSTANT_EXPR_H diff --git a/src/ir/constant.cc b/src/ir/constant.cc index 2d8aa28..5be4194 100644 --- a/src/ir/constant.cc +++ b/src/ir/constant.cc @@ -13,9 +13,11 @@ #include "constant-int.h" #include "constant-data-array.h" #include "constant-pointer-null.h" +#include "constant-aggregate-zero.h" #include "global-variable.h" #include "constant-struct.h" #include "constant-array.h" +#include "constant-expr.h" #include "undef-value.h" NAN_MODULE_INIT(ConstantWrapper::Init) { @@ -42,8 +44,12 @@ v8::Local ConstantWrapper::of(llvm::Constant *constant) { result = ConstantStructWrapper::of(static_cast(constant)); } else if (llvm::ConstantArray::classof(constant)) { result = ConstantArrayWrapper::of(static_cast(constant)); + } else if (llvm::ConstantAggregateZero::classof(constant)) { + result = ConstantAggregateZeroWrapper::of(static_cast(constant)); } else if (llvm::UndefValue::classof(constant)) { result = UndefValueWrapper::of(static_cast(constant)); + } else if (llvm::ConstantExpr::classof(constant)) { + result = ConstantExprWrapper::of(static_cast(constant)); } else { auto constructorFunction = Nan::GetFunction(Nan::New(constantTemplate())).ToLocalChecked(); v8::Local argv[1] = { Nan::New(constant) }; @@ -130,4 +136,4 @@ Nan::Persistent& ConstantWrapper::constantTemplate() { llvm::Constant *ConstantWrapper::getConstant() { return static_cast(getValue()); -} \ No newline at end of file +} diff --git a/src/ir/data-layout.cc b/src/ir/data-layout.cc index eb632d9..f3a64f3 100644 --- a/src/ir/data-layout.cc +++ b/src/ir/data-layout.cc @@ -5,6 +5,7 @@ #include "../util/string.h" #include "data-layout.h" #include "type.h" +#include "integer-type.h" Nan::Persistent DataLayoutWrapper::functionTemplate {}; @@ -27,6 +28,8 @@ NAN_MODULE_INIT(DataLayoutWrapper::Init) { Nan::SetPrototypeMethod(tpl, "getStringRepresentation", DataLayoutWrapper::getStringRepresentation); Nan::SetPrototypeMethod(tpl, "getPrefTypeAlignment", DataLayoutWrapper::getPrefTypeAlignment); Nan::SetPrototypeMethod(tpl, "getTypeStoreSize", DataLayoutWrapper::getTypeStoreSize); + Nan::SetPrototypeMethod(tpl, "getTypeAllocSize", DataLayoutWrapper::getTypeAllocSize); + Nan::SetPrototypeMethod(tpl, "getTypeAllocSizeInBits", DataLayoutWrapper::getTypeAllocSizeInBits); Nan::SetPrototypeMethod(tpl, "getPointerSize", DataLayoutWrapper::getPointerSize); Nan::SetPrototypeMethod(tpl, "getIntPtrType", DataLayoutWrapper::getIntPtrType); @@ -92,6 +95,34 @@ NAN_METHOD(DataLayoutWrapper::getTypeStoreSize) { info.GetReturnValue().Set(Nan::New(static_cast(size))); } +NAN_METHOD(DataLayoutWrapper::getTypeAllocSize) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[0])) { + return Nan::ThrowTypeError("getTypeAllocSize needs to be called with: type: Type"); + } + + auto* type = TypeWrapper::FromValue(info[0])->getType(); + auto dataLayout = DataLayoutWrapper::FromValue(info.Holder())->getDataLayout(); + + auto size = dataLayout.getTypeAllocSize(type); + assert (size < UINT32_MAX && "V8 does not support uint64 but size overflows uint32"); // v8 does not support uint64_t :( + + info.GetReturnValue().Set(Nan::New(static_cast(size))); +} + +NAN_METHOD(DataLayoutWrapper::getTypeAllocSizeInBits) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[0])) { + return Nan::ThrowTypeError("getTypeAllocSizeInBits needs to be called with: type: Type"); + } + + auto* type = TypeWrapper::FromValue(info[0])->getType(); + auto dataLayout = DataLayoutWrapper::FromValue(info.Holder())->getDataLayout(); + + auto size = dataLayout.getTypeAllocSizeInBits(type); + assert (size < UINT32_MAX && "V8 does not support uint64 but size overflows uint32"); // v8 does not support uint64_t :( + + info.GetReturnValue().Set(Nan::New(static_cast(size))); +} + NAN_METHOD(DataLayoutWrapper::getIntPtrType) { if (info.Length() < 1 || !LLVMContextWrapper::isInstance(info[0]) || (info.Length() == 2 && !info[1]->IsUint32()) || @@ -108,7 +139,7 @@ NAN_METHOD(DataLayoutWrapper::getIntPtrType) { } auto* type = dataLayout.getIntPtrType(context, addressSpace); - info.GetReturnValue().Set(TypeWrapper::of(type)); + info.GetReturnValue().Set(IntegerTypeWrapper::of(type)); } llvm::DataLayout DataLayoutWrapper::getDataLayout() { diff --git a/src/ir/data-layout.h b/src/ir/data-layout.h index 1536784..27c99bc 100644 --- a/src/ir/data-layout.h +++ b/src/ir/data-layout.h @@ -28,6 +28,8 @@ class DataLayoutWrapper: public Nan::ObjectWrap, public FromValueMixinIsExternal()) { - return Nan::ThrowTypeError("Expected type pointer"); + return Nan::ThrowTypeError("Expected pointer type pointer"); } - auto *type = static_cast(v8::External::Cast(*info[0])->Value()); - auto *wrapper = new IntegerTypeWrapper { type }; + auto* type = static_cast(v8::External::Cast(*info[0])->Value()); + auto* wrapper = new IntegerTypeWrapper { type }; wrapper->Wrap(info.This()); info.GetReturnValue().Set(info.This()); } -v8::Local IntegerTypeWrapper::of(llvm::IntegerType* integerType) { - auto constructorFunction = Nan::GetFunction(Nan::New(integerTypeTemplate())).ToLocalChecked(); - v8::Local args[1] = { Nan::New (integerType) }; +NAN_METHOD(IntegerTypeWrapper::get) { + if (info.Length() != 2 || !LLVMContextWrapper::isInstance(info[0]) || !info[1]->IsUint32()) { + return Nan::ThrowTypeError("IntegerTypeWrapper.get needs to be called with: context: LLVMContext, bitWidth: uint32"); + } - auto instance = Nan::NewInstance(constructorFunction, 1, args).ToLocalChecked(); + auto& context = LLVMContextWrapper::FromValue(info[0])->getContext(); + unsigned bitWidth = Nan::To(info[1]).FromJust(); - Nan::EscapableHandleScope escapeScope {}; - return escapeScope.Escape(instance); -} + auto* integerType = llvm::IntegerType::get(context, bitWidth); -bool IntegerTypeWrapper::isInstance(v8::Local value) { - return Nan::New(integerTypeTemplate())->HasInstance(value); -} - -llvm::IntegerType* IntegerTypeWrapper::getIntegerType() { - return static_cast(getType()); + info.GetReturnValue().Set(IntegerTypeWrapper::of(integerType)); } NAN_METHOD(IntegerTypeWrapper::getBitWidth) { @@ -48,19 +42,40 @@ NAN_METHOD(IntegerTypeWrapper::getBitWidth) { info.GetReturnValue().Set(Nan::New(bitWidth)); } -v8::Persistent& IntegerTypeWrapper::integerTypeTemplate() { - static Nan::Persistent tmpl {}; +v8::Local IntegerTypeWrapper::of(llvm::IntegerType *type) { + Nan::EscapableHandleScope escapeScope {}; + + v8::Local functionTemplate = Nan::New(integerTypeTemplate()); + auto constructorFunction = Nan::GetFunction(functionTemplate).ToLocalChecked(); + v8::Local argv[1] = { Nan::New(type) }; + v8::Local object = Nan::NewInstance(constructorFunction, 1, argv).ToLocalChecked(); + + return escapeScope.Escape(object); +} + +Nan::Persistent& IntegerTypeWrapper::integerTypeTemplate() { + static Nan::Persistent persistentTemplate {}; - if (tmpl.IsEmpty()) { - auto integerTypeWrapperTemplate = Nan::New(IntegerTypeWrapper::New); - integerTypeWrapperTemplate->SetClassName(Nan::New("IntegerType").ToLocalChecked()); - integerTypeWrapperTemplate->InstanceTemplate()->SetInternalFieldCount(1); - integerTypeWrapperTemplate->Inherit(Nan::New(typeTemplate())); + if (persistentTemplate.IsEmpty()) { + v8::Local integerTypeTemplate = Nan::New(IntegerTypeWrapper::New); - Nan::SetPrototypeMethod(integerTypeWrapperTemplate, "getBitWidth", IntegerTypeWrapper::getBitWidth); + Nan::SetMethod(integerTypeTemplate, "get", IntegerTypeWrapper::get); + integerTypeTemplate->SetClassName(Nan::New("IntegerType").ToLocalChecked()); + integerTypeTemplate->InstanceTemplate()->SetInternalFieldCount(1); + integerTypeTemplate->Inherit(Nan::New(typeTemplate())); - tmpl.Reset(integerTypeWrapperTemplate); + Nan::SetPrototypeMethod(integerTypeTemplate, "getBitWidth", IntegerTypeWrapper::getBitWidth); + + persistentTemplate.Reset(integerTypeTemplate); } - return tmpl; + return persistentTemplate; +} + +bool IntegerTypeWrapper::isInstance(v8::Local object) { + return Nan::New(integerTypeTemplate())->HasInstance(object); +} + +llvm::IntegerType *IntegerTypeWrapper::getIntegerType() { + return static_cast(getType()); } diff --git a/src/ir/integer-type.h b/src/ir/integer-type.h index b023c39..8676f6c 100644 --- a/src/ir/integer-type.h +++ b/src/ir/integer-type.h @@ -1,27 +1,34 @@ - #ifndef LLVM_NODE_INTEGER_TYPE_H -#define LLVM_NODE_INTEGER_TYPE_H\ - +#define LLVM_NODE_INTEGER_TYPE_H #include +#include #include +#include "llvm-context.h" +#include "../util/from-value-mixin.h" #include "type.h" -class IntegerTypeWrapper : public TypeWrapper, public FromValueMixin { +class IntegerTypeWrapper: public TypeWrapper, public FromValueMixin { public: static NAN_MODULE_INIT(Init); - static v8::Local of(llvm::IntegerType* type); - static bool isInstance(v8::Local value); + static v8::Local of(llvm::IntegerType *type); using FromValueMixin::FromValue; + llvm::IntegerType* getIntegerType(); -private: + static bool isInstance(v8::Local value); + +protected: + llvm::Type* type; explicit IntegerTypeWrapper(llvm::IntegerType* type) : TypeWrapper { type } { } + static Nan::Persistent& integerTypeTemplate(); + +private: + // Static Methods static NAN_METHOD(New); + static NAN_METHOD(get); static NAN_METHOD(getBitWidth); - - static v8::Persistent& integerTypeTemplate(); }; #endif //LLVM_NODE_INTEGER_TYPE_H diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index 03216af..658361a 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -74,6 +74,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createAlignedStore", IRBuilderWrapper::CreateAlignedStore); Nan::SetPrototypeMethod(functionTemplate, "createAnd", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateAnd>>); Nan::SetPrototypeMethod(functionTemplate, "createAShr", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateAShr>>); + Nan::SetPrototypeMethod(functionTemplate, "createAtomicRMW", IRBuilderWrapper::CreateAtomicRMW); Nan::SetPrototypeMethod(functionTemplate, "createBitCast", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateBitCast>); Nan::SetPrototypeMethod(functionTemplate, "createBr", IRBuilderWrapper::CreateBr); Nan::SetPrototypeMethod(functionTemplate, "createCall", IRBuilderWrapper::CreateCall); @@ -92,10 +93,12 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createFCmpULT", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpULT>>); Nan::SetPrototypeMethod(functionTemplate, "createFCmpUEQ", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpUEQ>>); Nan::SetPrototypeMethod(functionTemplate, "createFCmpUNE", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpUNE>>); + Nan::SetPrototypeMethod(functionTemplate, "createFCmpUNO", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpUNO>>); Nan::SetPrototypeMethod(functionTemplate, "createFDiv", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFDiv>>); Nan::SetPrototypeMethod(functionTemplate, "createFMul", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFMul>>); Nan::SetPrototypeMethod(functionTemplate, "createFNeg", IRBuilderWrapper::CreateFNeg); Nan::SetPrototypeMethod(functionTemplate, "createFPToSI", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateFPToSI>); + Nan::SetPrototypeMethod(functionTemplate, "createFPToUI", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateFPToUI>); Nan::SetPrototypeMethod(functionTemplate, "createFRem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFRem>>); Nan::SetPrototypeMethod(functionTemplate, "createFSub", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFSub>>); Nan::SetPrototypeMethod(functionTemplate, "createGlobalString", IRBuilderWrapper::CreateGlobalString); @@ -113,6 +116,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createICmpUGT", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateICmpUGT>>); Nan::SetPrototypeMethod(functionTemplate, "createICmpULT", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateICmpULT>>); Nan::SetPrototypeMethod(functionTemplate, "createICmpULE", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateICmpULE>>); + Nan::SetPrototypeMethod(functionTemplate, "createIsNull", IRBuilderWrapper::CreateIsNull); Nan::SetPrototypeMethod(functionTemplate, "createLoad", IRBuilderWrapper::CreateLoad); Nan::SetPrototypeMethod(functionTemplate, "createLShr", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateLShr>>); Nan::SetPrototypeMethod(functionTemplate, "createMul", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateMul>>); @@ -121,6 +125,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createOr", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateOr>>); Nan::SetPrototypeMethod(functionTemplate, "createXor", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateXor>>); Nan::SetPrototypeMethod(functionTemplate, "createPhi", IRBuilderWrapper::CreatePhi); + Nan::SetPrototypeMethod(functionTemplate, "createIntToPtr", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateIntToPtr>); Nan::SetPrototypeMethod(functionTemplate, "createPtrToInt", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreatePtrToInt>); Nan::SetPrototypeMethod(functionTemplate, "createRet", IRBuilderWrapper::CreateRet); Nan::SetPrototypeMethod(functionTemplate, "createRetVoid", IRBuilderWrapper::CreateRetVoid); @@ -129,11 +134,15 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createShl", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateShl>>); Nan::SetPrototypeMethod(functionTemplate, "createSub", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSub>>); Nan::SetPrototypeMethod(functionTemplate, "createSRem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSRem>>); - Nan::SetPrototypeMethod(functionTemplate, "CreateURem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateURem>>); Nan::SetPrototypeMethod(functionTemplate, "createSIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateSIToFP>); + Nan::SetPrototypeMethod(functionTemplate, "createUDiv", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateUDiv>>); + Nan::SetPrototypeMethod(functionTemplate, "createURem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateURem>>); + Nan::SetPrototypeMethod(functionTemplate, "createUnreachable", IRBuilderWrapper::CreateUnreachable); Nan::SetPrototypeMethod(functionTemplate, "createUIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateUIToFP>); Nan::SetPrototypeMethod(functionTemplate, "createStore", IRBuilderWrapper::CreateStore); Nan::SetPrototypeMethod(functionTemplate, "createZExt", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateZExt>); + Nan::SetPrototypeMethod(functionTemplate, "createZExtOrTrunc", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateZExtOrTrunc>); + Nan::SetPrototypeMethod(functionTemplate, "createSExtOrTrunc", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateSExtOrTrunc>); Nan::SetPrototypeMethod(functionTemplate, "getInsertBlock", IRBuilderWrapper::GetInsertBlock); Nan::SetPrototypeMethod(functionTemplate, "setInsertionPoint", IRBuilderWrapper::SetInsertionPoint); @@ -259,6 +268,26 @@ NAN_METHOD(IRBuilderWrapper::CreateAlloca) { info.GetReturnValue().Set(AllocaInstWrapper::of(alloc)); } +NAN_METHOD(IRBuilderWrapper::CreateAtomicRMW) { + if (info.Length() < 4 || !info[0]->IsUint32() + || !ValueWrapper::isInstance(info[1]) + || !ValueWrapper::isInstance(info[2]) + || !info[3]->IsUint32()) { + return Nan::ThrowTypeError("createAtomicRMW needs to be called with: op: AtomicRMWInst.BinOp, ptr: Value, value: Value, ordering: AtomicOrdering"); + } + + auto& irBuilder = IRBuilderWrapper::FromValue(info.This())->getIRBuilder(); + + auto op = static_cast(Nan::To(info[0]).FromJust()); + llvm::Value *ptr = ValueWrapper::FromValue(info[1])->getValue(); + llvm::Value *value = ValueWrapper::FromValue(info[2])->getValue(); + auto ordering = static_cast(Nan::To(info[3]).FromJust()); + + auto *instruction = irBuilder.CreateAtomicRMW(op, ptr, value, ordering); + + info.GetReturnValue().Set(ValueWrapper::of(instruction)); +} + NAN_METHOD(IRBuilderWrapper::CreateExtractValue) { if (info.Length() < 2 || !ValueWrapper::isInstance(info[0]) || !info[1]->IsArray() || (info.Length() > 2 && !(info[2]->IsString() || info[2]->IsUndefined())) || @@ -395,6 +424,25 @@ NAN_METHOD(IRBuilderWrapper::CreateIntCast) { info.GetReturnValue().Set(ValueWrapper::of(casted)); } +NAN_METHOD(IRBuilderWrapper::CreateIsNull) { + if (info.Length() < 1 || !ValueWrapper::isInstance(info[0]) + || (info.Length() > 1 && !(info[1]->IsString() || info[1]->IsUndefined())) + || info.Length() > 2) { + return Nan::ThrowTypeError("createIsNull needs to be called with: value: Value, name?: string"); + } + + auto* value = ValueWrapper::FromValue(info[0])->getValue(); + std::string name {}; + + if (info.Length() > 1 && !info[1]->IsUndefined()) { + name = ToString(Nan::To(info[1]).ToLocalChecked()); + } + + auto& irBuilder = IRBuilderWrapper::FromValue(info.Holder())->irBuilder; + auto* inst = irBuilder.CreateIsNull(value, name); + info.GetReturnValue().Set(ValueWrapper::of(inst)); +} + NAN_METHOD(IRBuilderWrapper::CreateLoad) { if (info.Length() < 1 || !ValueWrapper::isInstance(info[0]) || (info.Length() > 1 && !(info[1]->IsString() || info[1]->IsUndefined())) @@ -615,6 +663,12 @@ NAN_METHOD(IRBuilderWrapper::CreateRetVoid) { info.GetReturnValue().Set(ValueWrapper::of(returnInstruction)); } +NAN_METHOD(IRBuilderWrapper::CreateUnreachable) { + auto& builder = IRBuilderWrapper::FromValue(info.Holder())->irBuilder; + auto* returnInstruction = builder.CreateUnreachable(); + info.GetReturnValue().Set(ValueWrapper::of(returnInstruction)); +} + NAN_METHOD(IRBuilderWrapper::CreateSelect) { if (info.Length() < 3 || !ValueWrapper::isInstance(info[0]) || !ValueWrapper::isInstance(info[1]) || !ValueWrapper::isInstance(info[2]) || (info.Length() == 4 && !(info[3]->IsString() || info[3]->IsUndefined())) || diff --git a/src/ir/ir-builder.h b/src/ir/ir-builder.h index 38b187a..0c3a902 100644 --- a/src/ir/ir-builder.h +++ b/src/ir/ir-builder.h @@ -31,13 +31,9 @@ class IRBuilderWrapper: public Nan::ObjectWrap, public FromValueMixin static NAN_METHOD(ConvertOperation); - static NAN_METHOD(CreateAdd); static NAN_METHOD(CreateAlloca); static NAN_METHOD(CreateAlignedLoad); static NAN_METHOD(CreateAlignedStore); - static NAN_METHOD(CreateAnd); - static NAN_METHOD(CreateAShr); - static NAN_METHOD(CreateBitCast); static NAN_METHOD(CreateBr); static NAN_METHOD(CreateCall); static NAN_METHOD(CreateCondBr); @@ -49,6 +45,7 @@ class IRBuilderWrapper: public Nan::ObjectWrap, public FromValueMixin &TypeWrapper::typeTemplate() Nan::SetPrototypeMethod(typeTemplate, "isStructTy", &isOfType<&llvm::Type::isStructTy>); Nan::SetPrototypeMethod(typeTemplate, "isArrayTy", &isOfType<&llvm::Type::isArrayTy>); Nan::SetPrototypeMethod(typeTemplate, "isPointerTy", &isOfType<&llvm::Type::isPointerTy>); + Nan::SetPrototypeMethod(typeTemplate, "isFloatingPointTy", &isOfType<&llvm::Type::isFloatingPointTy>); Nan::SetPrototypeMethod(typeTemplate, "isHalfTy", &isOfType<&llvm::Type::isHalfTy>); Nan::SetAccessor(typeTemplate->InstanceTemplate(), Nan::New("typeID").ToLocalChecked(), TypeWrapper::getTypeID); Nan::SetPrototypeMethod(typeTemplate, "getPointerTo", TypeWrapper::getPointerTo); diff --git a/src/llvm-node.cc b/src/llvm-node.cc index bc7c36c..943955c 100644 --- a/src/llvm-node.cc +++ b/src/llvm-node.cc @@ -14,4 +14,4 @@ NAN_MODULE_INIT(InitAll) { InitTarget(target); } -NODE_MODULE(llvm, InitAll) \ No newline at end of file +NODE_MODULE(llvm, InitAll) diff --git a/src/support/atomic-ordering.cc b/src/support/atomic-ordering.cc new file mode 100644 index 0000000..2302a33 --- /dev/null +++ b/src/support/atomic-ordering.cc @@ -0,0 +1,15 @@ +#include +#include "atomic-ordering.h" + +NAN_MODULE_INIT(InitAtomicOrdering) { + auto atomicOrdering = Nan::New(); + Nan::Set(atomicOrdering, Nan::New("NotAtomic").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::NotAtomic))); + Nan::Set(atomicOrdering, Nan::New("Unordered").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Unordered))); + Nan::Set(atomicOrdering, Nan::New("Monotonic").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Monotonic))); + Nan::Set(atomicOrdering, Nan::New("Acquire").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Acquire))); + Nan::Set(atomicOrdering, Nan::New("Release").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Release))); + Nan::Set(atomicOrdering, Nan::New("AcquireRelease").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::AcquireRelease))); + Nan::Set(atomicOrdering, Nan::New("SequentiallyConsistent").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::SequentiallyConsistent))); + + Nan::Set(target, Nan::New("AtomicOrdering").ToLocalChecked(), atomicOrdering); +} diff --git a/src/support/atomic-ordering.h b/src/support/atomic-ordering.h new file mode 100644 index 0000000..6c17684 --- /dev/null +++ b/src/support/atomic-ordering.h @@ -0,0 +1,8 @@ +#ifndef LLVM_NODE_ATOMIC_ORDERING_H +#define LLVM_NODE_ATOMIC_ORDERING_H + +#include + +NAN_MODULE_INIT(InitAtomicOrdering); + +#endif //LLVM_NODE_ATOMIC_ORDERING_H diff --git a/src/support/support.cc b/src/support/support.cc index e74c31b..9785562 100644 --- a/src/support/support.cc +++ b/src/support/support.cc @@ -1,5 +1,6 @@ #include #include "support.h" +#include "atomic-ordering.h" NAN_METHOD(InitializeAllTargetInfos) { llvm::InitializeAllTargetInfos(); @@ -22,31 +23,32 @@ NAN_METHOD(InitializeAllAsmPrinters) { } NAN_MODULE_INIT(InitSupport) { - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllTargetInfos").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllTargetInfos)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllTargets").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllTargets)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllTargetMCs").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllTargetMCs)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllAsmParsers").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllAsmParsers)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllAsmPrinters").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllAsmPrinters)).ToLocalChecked() ); + InitAtomicOrdering(target); TargetRegistryWrapper::Init(target); TargetWrapper::Init(target); -} \ No newline at end of file +} diff --git a/test/ir/constant-int.spec.ts b/test/ir/constant-int.spec.ts index 92c16a8..43ee7dc 100644 --- a/test/ir/constant-int.spec.ts +++ b/test/ir/constant-int.spec.ts @@ -43,7 +43,7 @@ describe("ir/constant-int", () => { it("returns the true value", () => { const trueValue = llvm.ConstantInt.getTrue(context); - expect(trueValue.type).toEqual(llvm.Type.getInt8Ty(context)); + expect(trueValue.type).toEqual(llvm.Type.getInt1Ty(context)); expect(trueValue.value).toBeDefined(); }); }); @@ -52,8 +52,8 @@ describe("ir/constant-int", () => { it("returns the false value", () => { const trueValue = llvm.ConstantInt.getFalse(context); - expect(trueValue.type).toEqual(llvm.Type.getInt8Ty(context)); + expect(trueValue.type).toEqual(llvm.Type.getInt1Ty(context)); expect(trueValue.value).toBe(0); }); }); -}); \ No newline at end of file +}); diff --git a/test/ir/ir-builder.spec.ts b/test/ir/ir-builder.spec.ts index 15a958c..8ace5ce 100644 --- a/test/ir/ir-builder.spec.ts +++ b/test/ir/ir-builder.spec.ts @@ -78,6 +78,29 @@ describe("IRBuilder", () => { expect(ashr).toEqual(llvm.ConstantInt.get(context, 2)); }); + test("create createAtomicRMW returns a value", () => { + const { builder, context } = createBuilderWithBlock(); + + // let %0: i32 = 3; + const value = builder.createAlloca( + llvm.Type.getInt32Ty(context) + ); + + builder.createStore( + llvm.ConstantInt.get(context, 3), + value + ); + + const atomicRMW = builder.createAtomicRMW( + llvm.AtomicRMWInst.BinOp.Add, + value, + llvm.ConstantInt.get(context, 1), + llvm.AtomicOrdering.AcquireRelease + ); + + expect(atomicRMW).toBeInstanceOf(llvm.Value); + }); + test("createBitCast returns a value", () => { const { builder, context } = createBuilderWithBlock(); @@ -88,7 +111,7 @@ describe("IRBuilder", () => { expect(cast).toBeInstanceOf(llvm.Value); expect(cast.type).toEqual( - llvm.PointerType.get(llvm.Type.getInt32Ty(context), 0) + llvm.Type.getInt8PtrTy(context) ); }); @@ -790,10 +813,22 @@ describe("IRBuilder", () => { expect(rem).toEqual(llvm.ConstantInt.get(context, 1)); }); - test("CreateURem", () => { + test("createUDiv", () => { + const { builder, context } = createBuilderWithBlock(); + + const div = builder.createUDiv( + llvm.ConstantInt.get(context, -1, 32, false), + llvm.ConstantInt.get(context, 2, 32) + ); + + expect(div).toBeInstanceOf(llvm.Value); + expect(div).toEqual(llvm.ConstantInt.get(context, 2147483647, 32)); + }); + + test("createURem", () => { const { builder, context } = createBuilderWithBlock(); - const rem = builder.CreateURem( + const rem = builder.createURem( llvm.ConstantInt.get(context, 11), llvm.ConstantInt.get(context, 2) );