diff options
-rw-r--r-- | src/analyzer.js | 4 | ||||
-rw-r--r-- | src/jsifier.js | 24 | ||||
-rw-r--r-- | src/parseTools.js | 6 |
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) { |