aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analyzer.js4
-rw-r--r--src/jsifier.js24
-rw-r--r--src/parseTools.js6
3 files changed, 32 insertions, 2 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 4af7cbc5..4582f0b1 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -257,13 +257,15 @@ function analyzer(data) {
// Decision time
+ var pointedType = removePointing(variable.type);
if (variable.origin == 'getelementptr') {
// Use our implementation that emulates pointers etc.
variable.impl = VAR_EMULATED;
} else if (OPTIMIZE && variable.pointingLevels === 0 && !variable.hasAddrTaken) {
// A simple int value, can be implemented as a native variable
variable.impl = VAR_NATIVE;
- } else if (OPTIMIZE && variable.origin === 'alloca' && !variable.hasAddrTaken && !variable.hasValueTaken) {
+ } else if (OPTIMIZE && variable.origin === 'alloca' && !variable.hasAddrTaken && !variable.hasValueTaken &&
+ (Runtime.isNumberType(pointedType) || Runtime.isPointerType(pointedType))) {
// A pointer to a value which is only accessible through this pointer. Basically
// a local value on the stack, which nothing fancy is done on. So we can
// optimize away the pointing altogether, and just have a native variable
diff --git a/src/jsifier.js b/src/jsifier.js
index 2f79b18c..3b878efe 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -57,6 +57,15 @@ function JSify(data) {
}
function makeGetValue(ptr, pos, noNeedFirst, type) {
+ if (isStructType(type)) {
+ var typeData = TYPES[type];
+ var ret = [];
+ for (var i = 0; i < typeData.fields.length; i++) {
+ ret.push('f' + i + ': ' + makeGetValue(ptr, pos + typeData.flatIndexes[i], noNeedFirst, typeData.fields[i]));
+ }
+ return '{ ' + ret.join(', ') + ' }';
+ }
+
return makeGetSlab(ptr, type) + '[' + calcFastOffset(ptr, pos, noNeedFirst) + ']';
}
@@ -68,6 +77,15 @@ function JSify(data) {
}
function makeSetValue(ptr, pos, value, noNeedFirst, type) {
+ if (isStructType(type)) {
+ var typeData = TYPES[type];
+ var ret = [];
+ for (var i = 0; i < typeData.fields.length; i++) {
+ ret.push(makeSetValue(ptr, pos + typeData.flatIndexes[i], value[i], noNeedFirst, typeData.fields[i]));
+ }
+ return ret.join('; ');
+ }
+
value = indexizeFunctions(value);
var offset = calcFastOffset(ptr, pos, noNeedFirst);
if (SAFE_HEAP) {
@@ -808,8 +826,12 @@ function JSify(data) {
function finalizeLLVMParameter(param) {
if (param.intertype in PARSABLE_LLVM_FUNCTIONS) {
return finalizeLLVMFunctionCall(param);
- } else {
+ } else if (param.intertype == 'value') {
return parseNumerical(param.ident);
+ } else if (param.intertype == 'structvalue') {
+ return param.values.map(finalizeLLVMParameter);
+ } else {
+ throw 'invalid llvm parameter: ' + param.intertype;
}
}
diff --git a/src/parseTools.js b/src/parseTools.js
index 4d6ae564..668eb56b 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -290,6 +290,12 @@ function parseLLVMSegment(segment) {
ident: segment[0].text,
type: isType(segment[0].text) ? segment[0].text : '?',
};
+ } else if (segment[1].type == '{') {
+ return {
+ intertype: 'structvalue',
+ values: splitTokenList(segment[1].tokens).map(parseLLVMSegment),
+ type: segment[0].text,
+ };
} else if (segment[0].text in PARSABLE_LLVM_FUNCTIONS) {
return parseLLVMFunctionCall([{text: '?'}].concat(segment));
} else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) {