Skip to content

Commit a317ed1

Browse files
author
Micha Reiser
committed
feature(IR): Add support for float constants
1 parent 3a91726 commit a317ed1

File tree

3 files changed

+45
-16
lines changed

3 files changed

+45
-16
lines changed

llvm-node.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,22 +175,23 @@ declare namespace llvm {
175175

176176
class ConstantFP extends Constant {
177177
static get(context: LLVMContext, value: number): ConstantFP;
178+
static get(type: Type, value: string): Constant;
178179

179180
static getZeroValueForNegation(type: Type): Constant;
180181

181182
static getNegativeZero(type: Type): Constant;
182183

183184
static getNaN(type: Type): Constant;
184185

185-
static getInfinity(type: Type, negative?: boolean/* = false */): Constant;
186+
static getInfinity(type: Type, negative?: boolean /* = false */): Constant;
186187

187188
private constructor();
188189

189190
readonly value: number;
190191
}
191192

192193
class ConstantInt extends Constant {
193-
static get(context: LLVMContext, value: number|string, numBits?: number, signed?: boolean): ConstantInt;
194+
static get(context: LLVMContext, value: number | string, numBits?: number, signed?: boolean): ConstantInt;
194195

195196
static getFalse(context: LLVMContext): ConstantInt;
196197

src/ir/constant-fp.cc

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#include "llvm-context.h"
77
#include "type.h"
88

9+
#include "../util/string.h"
10+
11+
912
NAN_MODULE_INIT(ConstantFPWrapper::Init) {
1013
auto constantFp = Nan::GetFunction(Nan::New(constantFpTemplate())).ToLocalChecked();
1114
Nan::Set(target, Nan::New("ConstantFP").ToLocalChecked(), constantFp);
@@ -28,16 +31,22 @@ NAN_METHOD(ConstantFPWrapper::New) {
2831
}
2932

3033
NAN_METHOD(ConstantFPWrapper::get) {
31-
if (info.Length() != 2 || !LLVMContextWrapper::isInstance(info[0]) || !info[1]->IsNumber()) {
32-
return Nan::ThrowTypeError("get needs to be called with: context: LLVMContext, value: number");
33-
}
34-
34+
if (info.Length() == 2 && LLVMContextWrapper::isInstance(info[0]) && info[1]->IsNumber()) {
3535
auto& context = LLVMContextWrapper::FromValue(info[0])->getContext();
3636
double number = Nan::To<double>(info[1]).FromJust();
3737

38-
auto* constant = llvm::ConstantFP::get(context, llvm::APFloat { number } );
38+
auto* constant = llvm::ConstantFP::get(context, llvm::APFloat { number });
3939

40-
info.GetReturnValue().Set(ConstantFPWrapper::of(constant));
40+
return info.GetReturnValue().Set(ConstantFPWrapper::of(constant));
41+
} else if (info.Length() == 2 && TypeWrapper::isInstance(info[0]) && info[1]->IsString()) {
42+
auto type = TypeWrapper::FromValue(info[0])->getType();
43+
auto number = ToString(info[1]);
44+
auto constant = llvm::ConstantFP::get(type, number);
45+
46+
return info.GetReturnValue().Set(ConstantWrapper::of(constant));
47+
}
48+
49+
return Nan::ThrowTypeError("get called with illegal arguments");
4150
}
4251

4352
NAN_METHOD(ConstantFPWrapper::getNaN) {
@@ -95,10 +104,15 @@ NAN_METHOD(ConstantFPWrapper::getNegativeZero) {
95104
}
96105

97106
NAN_GETTER(ConstantFPWrapper::getValueAPF) {
98-
auto* wrapper = ConstantFPWrapper::FromValue(info.Holder());
99-
auto value = wrapper->getConstantFP()->getValueAPF();
107+
auto* wrapper = ConstantFPWrapper::FromValue(info.Holder());
108+
auto fp = wrapper->getConstantFP();
109+
auto value = fp->getValueAPF();
100110

111+
if (fp->getType()->isFloatTy()) {
112+
info.GetReturnValue().Set(Nan::New(value.convertToFloat()));
113+
} else {
101114
info.GetReturnValue().Set(Nan::New(value.convertToDouble()));
115+
}
102116
}
103117

104118
llvm::ConstantFP *ConstantFPWrapper::getConstantFP() {

test/ir/constant-fp.spec.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,29 @@ describe("ir/constant-fp", () => {
2222

2323
describe("get", () => {
2424
const untypedGet = llvm.ConstantFP.get as any;
25-
it("creates a new float constant", () => {
25+
it("creates a new double constant", () => {
2626
const value = llvm.ConstantFP.get(context, 10);
2727

2828
expect(value.value).toBe(10);
2929
});
3030

31+
it("creates a new fp of the given type", () => {
32+
const floatType = llvm.Type.getFloatTy(context);
33+
34+
const value = llvm.ConstantFP.get(floatType, "3");
35+
36+
expect(value.type).toEqual(floatType);
37+
expect(value).toBeInstanceOf(llvm.ConstantFP);
38+
expect((value as llvm.ConstantFP).value).toBe(3);
39+
});
40+
3141
it("throws if not called with a context as first argument", () => {
32-
expect(() => untypedGet()).toThrowError("get needs to be called with: context: LLVMContext, value: number");
33-
expect(() => untypedGet({}).toThrowError("get needs to be called with: context: LLVMContext, value: number"));
42+
expect(() => untypedGet()).toThrowError("get called with illegal arguments");
43+
expect(() => untypedGet({}).toThrowError("get called with illegal arguments"));
3444
});
3545

3646
it("throws if not called with a number as second argument", () => {
37-
expect(() => untypedGet(context, "test")).toThrowError(
38-
"get needs to be called with: context: LLVMContext, value: number"
39-
);
47+
expect(() => untypedGet(context, "test")).toThrowError("get called with illegal arguments");
4048
});
4149
});
4250

@@ -86,5 +94,11 @@ describe("ir/constant-fp", () => {
8694

8795
expect(value.value).toBe(10);
8896
});
97+
98+
it("returns NaN for a NaN value", () => {
99+
const value = llvm.ConstantFP.get(context, NaN);
100+
101+
expect(value.value).toBeNaN();
102+
});
89103
});
90104
});

0 commit comments

Comments
 (0)