From 792ac2e9809ff2f17bf651e3c0c194949083ac3c Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Fri, 5 Jul 2024 22:32:27 +0200 Subject: [PATCH] Added method 'getTypeAllocSizeInBits' to class 'DataLayout', added additional constructor allowing to instantiate 'DataLayout' based on the existing 'Module' added corresponding tests --- include/IR/DataLayout.h | 2 ++ llvm-bindings.d.ts | 4 ++++ src/IR/DataLayout.cpp | 20 +++++++++++++++++--- tests/IR/Type.spec.ts | 11 +++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/IR/DataLayout.h b/include/IR/DataLayout.h index c6275c1..9e43ce0 100644 --- a/include/IR/DataLayout.h +++ b/include/IR/DataLayout.h @@ -25,4 +25,6 @@ class DataLayout : public Napi::ObjectWrap { Napi::Value getStringRepresentation(const Napi::CallbackInfo &info); Napi::Value getTypeAllocSize(const Napi::CallbackInfo &info); + + Napi::Value getTypeAllocSizeInBits(const Napi::CallbackInfo &info); }; diff --git a/llvm-bindings.d.ts b/llvm-bindings.d.ts index cee262a..d1fc84a 100644 --- a/llvm-bindings.d.ts +++ b/llvm-bindings.d.ts @@ -1946,11 +1946,15 @@ declare namespace llvm { } class DataLayout { + public constructor(module: Module); + public constructor(desc: string); public getStringRepresentation(): string; public getTypeAllocSize(type: Type): number; + + public getTypeAllocSizeInBits(type: Type): number; } function verifyFunction(func: Function): boolean; diff --git a/src/IR/DataLayout.cpp b/src/IR/DataLayout.cpp index 8341abf..03a2542 100644 --- a/src/IR/DataLayout.cpp +++ b/src/IR/DataLayout.cpp @@ -5,7 +5,8 @@ void DataLayout::Init(Napi::Env env, Napi::Object &exports) { Napi::HandleScope scope(env); Napi::Function func = DefineClass(env, "DataLayout", { InstanceMethod("getStringRepresentation", &DataLayout::getStringRepresentation), - InstanceMethod("getTypeAllocSize", &DataLayout::getTypeAllocSize) + InstanceMethod("getTypeAllocSize", &DataLayout::getTypeAllocSize), + InstanceMethod("getTypeAllocSizeInBits", &DataLayout::getTypeAllocSizeInBits) }); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -27,10 +28,13 @@ llvm::DataLayout &DataLayout::Extract(const Napi::Value &value) { DataLayout::DataLayout(const Napi::CallbackInfo &info) : ObjectWrap(info) { Napi::Env env = info.Env(); if (!info.IsConstructCall() || info.Length() == 0 || - !info[0].IsExternal() && !info[0].IsString()) { + !Module::IsClassOf(info[0]) && !info[0].IsExternal() && !info[0].IsString()) { throw Napi::TypeError::New(env, ErrMsg::Class::DataLayout::constructor); } - if (info[0].IsExternal()) { + if (Module::IsClassOf(info[0])) { + llvm::Module *module = Module::Extract(info[0]); + dataLayout = new llvm::DataLayout(module); + } else if (info[0].IsExternal()) { auto external = info[0].As>(); dataLayout = external.Data(); } else if (info[0].IsString()) { @@ -57,3 +61,13 @@ Napi::Value DataLayout::getTypeAllocSize(const Napi::CallbackInfo &info) { } throw Napi::TypeError::New(env, ErrMsg::Class::DataLayout::getTypeAllocSize); } + +Napi::Value DataLayout::getTypeAllocSizeInBits(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + if (info.Length() == 1 && Type::IsClassOf(info[0])) { + llvm::Type *type = Type::Extract(info[0]); + auto allocSizeInBits = dataLayout->getTypeAllocSizeInBits(type); + return Napi::Number::New(env, double(allocSizeInBits.getFixedSize())); + } + throw Napi::TypeError::New(env, ErrMsg::Class::DataLayout::getTypeAllocSize); +} diff --git a/tests/IR/Type.spec.ts b/tests/IR/Type.spec.ts index 678c5e1..f7495fa 100644 --- a/tests/IR/Type.spec.ts +++ b/tests/IR/Type.spec.ts @@ -39,6 +39,7 @@ describe('Test type testers', () => { test('Test with ArrayType', () => { const context = new llvm.LLVMContext(); const irBuilder = new llvm.IRBuilder(context); + const module = new llvm.Module('testModule', context); [ llvm.ArrayType.get(irBuilder.getInt8Ty(), 17), @@ -57,12 +58,16 @@ describe('Test type testers', () => { expect(valArrayType.isStructTy()).toBe(false); expect(valArrayType.isVectorTy()).toBe(false); expect(valArrayType.isVoidTy()).toBe(false); + + expect(module.getDataLayout().getTypeAllocSize(valArrayType)).toBe(17); + expect(module.getDataLayout().getTypeAllocSizeInBits(valArrayType)).toBe(136); }); }); test('Test with StructType', () => { const context = new llvm.LLVMContext(); const irBuilder = new llvm.IRBuilder(context); + const module = new llvm.Module('testModule', context); [ llvm.StructType.create(context, [ irBuilder.getInt8Ty(), irBuilder.getInt8Ty() ], 'myStruct'), @@ -85,6 +90,12 @@ describe('Test type testers', () => { expect(valStructType.isStructTy() && valStructType.getNumElements()).toBe(2); expect(valStructType.isStructTy() && valStructType.getElementType(0).isIntegerTy(8)).toBe(true); expect(valStructType.isStructTy() && valStructType.getElementType(1).isIntegerTy(8)).toBe(true); + + expect(module.getDataLayout().getTypeAllocSize(valStructType)).toBe(2); + expect(module.getDataLayout().getTypeAllocSizeInBits(valStructType)).toBe(16); + + expect(new llvm.DataLayout(module).getTypeAllocSize(valStructType)).toBe(2); + expect(new llvm.DataLayout(module.getDataLayoutStr()).getTypeAllocSizeInBits(valStructType)).toBe(16); }); });