This repository was archived by the owner on Jul 12, 2023. It is now read-only.
forked from polyglot-compiler/JLang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJLangStringLitExt.java
80 lines (62 loc) · 3.21 KB
/
JLangStringLitExt.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//Copyright (C) 2018 Cornell University
package jlang.extension;
import polyglot.ast.Lang;
import polyglot.ast.Node;
import polyglot.ast.StringLit;
import polyglot.types.ParsedClassType;
import java.lang.Override;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import jlang.ast.JLangExt;
import jlang.visit.LLVMTranslator;
import static jlang.util.Constants.INTERN_STRING_FUNC;
import static org.bytedeco.javacpp.LLVM.*;
public class JLangStringLitExt extends JLangExt {
@Override
public Node leaveTranslateLLVM(LLVMTranslator v) {
StringLit n = (StringLit) node();
LLVMValueRef stringVar = translateString(n.value(), v, lang());
LLVMTypeRef internStringFuncType = v.utils.functionType(v.utils.voidType(), LLVMTypeOf(stringVar));
LLVMValueRef internString = v.utils.getFunction(INTERN_STRING_FUNC, internStringFuncType);
v.utils.buildProcCall(internString, stringVar);
v.addTranslation(n,LLVMConstBitCast(stringVar, v.utils.toLL(n.type())));
return super.leaveTranslateLLVM(v);
}
public static LLVMValueRef translateString(String obj, LLVMTranslator v, Lang l) {
char[] chars = obj.toCharArray();
int sizeOfChar= v.utils.sizeOfType(v.ts.Char());
ParsedClassType arrayType = v.ts.ArrayObject();
LLVMValueRef dvGlobal = v.dv.getDispatchVectorFor(arrayType);
LLVMValueRef length = LLVMConstInt(v.utils.intType(32), chars.length, /*sign-extend*/ 0);
LLVMValueRef elemSize = LLVMConstInt(v.utils.intType(32), sizeOfChar, /*sign-extend*/ 0);
LLVMValueRef arrStruct = v.utils.buildConstStruct(length, elemSize);
List<LLVMValueRef> charTranslated = new ArrayList<>();
LLVMValueRef sync_vars = LLVMConstNull(v.utils.i8Ptr());
for (char c : chars)
charTranslated.add(LLVMConstInt(v.utils.intType(16), c, 0));
LLVMValueRef[] structBody =
Stream.concat(Stream.of(dvGlobal, sync_vars, arrStruct), charTranslated.stream())
.toArray(LLVMValueRef[]::new);
LLVMValueRef charArray = v.utils.buildConstStruct(structBody);
String reduce = intStream(obj.getBytes()).mapToObj(b -> b + "_").reduce("", (s1, s2) -> s1 + s2);
String charVarName = "_char_arr_" + reduce;
LLVMValueRef stringLit = v.utils.getGlobal(charVarName, LLVMTypeOf(charArray));
LLVMSetLinkage(stringLit, LLVMLinkOnceODRLinkage);
LLVMSetInitializer(stringLit, charArray);
LLVMValueRef dvString = v.dv.getDispatchVectorFor(v.ts.String());
LLVMValueRef[] stringLitBody =
Stream.of(dvString, sync_vars, LLVMConstBitCast(stringLit, v.utils.toLL(arrayType)))
.toArray(LLVMValueRef[]::new);
LLVMValueRef string = v.utils.buildConstStruct(stringLitBody);
String stringVarName = "_string_lit_" + reduce;
LLVMValueRef stringVar = v.utils.getGlobal(stringVarName, LLVMTypeOf(string));
LLVMSetLinkage(stringVar, LLVMLinkOnceODRLinkage);
LLVMSetInitializer(stringVar, string);
return stringVar;
}
public static IntStream intStream(byte[] array) {
return IntStream.range(0, array.length).map(idx -> array[idx]);
}
}