diff options
author | Alon Zakai <azakai@mozilla.com> | 2010-11-26 12:08:27 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2010-11-26 12:08:27 -0800 |
commit | 749092eb2942001f1fa2f8b6fcdcbce80f1e8e37 (patch) | |
tree | 84456630d78255e8f60dd1eaeca10c0b19ed2d95 | |
parent | 2c8e0810292289eb17055a4fe793c24d72033dfb (diff) |
flatten global constants at compile time
-rw-r--r-- | src/jsifier.js | 52 | ||||
-rw-r--r-- | src/parseTools.js | 2 | ||||
-rw-r--r-- | src/postamble.js | 12 |
3 files changed, 44 insertions, 22 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 5d982395..15428e78 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -138,7 +138,7 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions) { } else { ret.push(currValue); // pad to align, unless it's a structure and already aligned - if (currValue[0] != '[') { + if (typeof currValue !== 'object') { ret = ret.concat(zeros(getNativeFieldSize(currField)-1)); } i += 1; @@ -148,28 +148,28 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions) { } // Gets an entire constant expression - function parseConst(value, type) { + function makeConst(value, type, ident) { //dprint('gconst', '//yyyyy ' + JSON.stringify(value) + ',' + type + '\n'); if (value.intertype) { - return makePointer(finalizeLLVMFunctionCall(value), null, 'ALLOC_STATIC', type); + return finalizeLLVMFunctionCall(value); } else if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) { - return makePointer(indexizeFunctions(parseNumerical(toNiceIdent(value.text))), null, 'ALLOC_STATIC', type); + return indexizeFunctions(parseNumerical(toNiceIdent(value.text))); } else if (value.text == 'zeroinitializer') { - return makePointer(JSON.stringify(makeEmptyStruct(type)), null, 'ALLOC_STATIC', type); + return makeEmptyStruct(type); } else if (value.text && value.text[0] == '"') { value.text = value.text.substr(1, value.text.length-2); - return makePointer(JSON.stringify(parseLLVMString(value.text)) + ' /* ' + value.text + '*/', null, 'ALLOC_STATIC', type); + return JSON.stringify(parseLLVMString(value.text)) + ' /* ' + value.text + '*/'; } else { // Gets an array of constant items, separated by ',' tokens function handleSegments(tokens) { //dprint('gconst', '// segggS: ' + JSON.stringify(tokens) + '\n' + '\n') // Handle a single segment (after comma separation) function handleSegment(segment) { - //dprint('gconst', '// seggg: ' + JSON.stringify(segment) + '\n' + '\n') + //dprint('// seggg: ' + JSON.stringify(segment) + '\n' + '\n') if (segment[1].text == 'null') { return '0'; } else if (segment[1].text == 'zeroinitializer') { - return JSON.stringify(makeEmptyStruct(segment[0].text)); + return makeEmptyStruct(segment[0].text); } else if (segment[1].text in searchable('bitcast', 'inttoptr', 'ptrtoint')) { // TODO: Use parse/finalizeLLVMFunctionCall var type = segment[2].item.tokens.slice(-1)[0].text; // TODO: Use this? return handleSegment(segment[2].item.tokens.slice(0, -2)); @@ -181,37 +181,55 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions) { } else if (segment[1].type == '{') { // struct var type = segment[0].text; - return '[' + alignStruct(handleSegments(segment[1].tokens), type).join(', ') + ']'; + return alignStruct(handleSegments(segment[1].tokens), type); } else if (segment[1].type == '[') { var type = segment[0].text; - return '[' + alignStruct(handleSegments(segment[1].item.tokens), type).join(', ') + ']'; + return alignStruct(handleSegments(segment[1].item.tokens), type); } else if (segment.length == 2) { - return parseNumerical(toNiceIdent(segment[1].text)); + return toNiceIdent(segment[1].text); } else if (segment[1].text === 'c') { // string var text = segment[2].text; text = text.substr(1, text.length-2); - return JSON.stringify(parseLLVMString(text)) + ' /* ' + text + '*/'; + return parseLLVMString(text); // + ' /* ' + text + '*/'; } else { throw 'Invalid segment: ' + dump(segment); } }; - return splitTokenList(tokens).map(handleSegment).map(indexizeFunctions).map(parseNumerical); + return splitTokenList(tokens).map(handleSegment).map(indexizeFunctions); } + var contents; if (value.item) { // list of items - return makePointer('[ ' + alignStruct(handleSegments(value.item.tokens), type).join(', ') + ' ]', null, 'ALLOC_STATIC', type); + contents = value.item.tokens; } else if (value.type == '{') { // struct - return makePointer('[ ' + alignStruct(handleSegments(value.tokens), type).join(', ') + ' ]', null, 'ALLOC_STATIC', type); + contents = value.tokens; } else if (value[0]) { - return makePointer('[ ' + alignStruct(handleSegments(value[0].tokens), type).join(', ') + ' ]', null, 'ALLOC_STATIC', type); + contents = value[0]; } else { throw '// failzzzzzzzzzzzzzz ' + dump(value.item) + ' ::: ' + dump(value); } + return alignStruct(handleSegments(contents), type); } } + function parseConst(value, type, ident) { + var constant = makeConst(value, type); + if (typeof constant === 'object') { + function flatten(x) { + if (typeof x !== 'object') return x; + var ret = []; + for (var i = 0; i < x.length; i++) { + ret = ret.concat(flatten(x[i])); + } + return ret; + } + constant = '[' + flatten(constant).map(function(x) { return parseNumerical(x) }).join(', ') + ']'; + } + return makePointer(constant, null, 'ALLOC_STATIC', type); + } + // globalVariable substrate.addZyme('GlobalVariable', { processItem: function(item) { @@ -229,7 +247,7 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions) { item.external ? makePointer(JSON.stringify(makeEmptyStruct(item.type)), null, 'ALLOC_STATIC', item.type) + ' /* external value? */' : - parseConst(item.value, item.type) + parseConst(item.value, item.type, item.ident) ) + ' });', __result__: true, }]; diff --git a/src/parseTools.js b/src/parseTools.js index e226b395..d2e746ca 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -380,7 +380,7 @@ function IEEEUnHex(stringy) { } function parseNumerical(value, type) { - if ((!type || type == 'double' || type == 'float') && value.substr(0,2) == '0x') { + if ((!type || type == 'double' || type == 'float') && (value.substr && value.substr(0,2) == '0x')) { // Hexadecimal double value, as the llvm docs say, // "The one non-intuitive notation for constants is the hexadecimal form of floating point constants." value = IEEEUnHex(value); diff --git a/src/postamble.js b/src/postamble.js index b9ccb69b..72233980 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -8,19 +8,23 @@ function run(args) { {{GLOBAL_VARS}} - var counter = Math.pow(globalFuncs.length,2)+1; - while (globalFuncs.length > 0 && counter >= 0) { - counter--; + var failures = 0; + while (globalFuncs.length > 0) { var func = globalFuncs.pop(); try { var x = func(); if (x == undefined) throw 'undefined'; + failures = 0; } catch (e) { + failures++; + if (failures > 2*globalFuncs.length) { + throw 'Failed to generate global values'; + } globalFuncs.unshift(func); // We will try again later. The global vars we depend on should be resolved by then } } - assert(counter > 0); + assert(globalFuncs.length === 0); var argc = args.length+1; function pad() { |