diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-04-13 17:20:16 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-04-13 17:21:18 -0700 |
commit | 9e59c98c81fa207665428b7e3f84b48e1fb0f902 (patch) | |
tree | d12145faab8fcdb4e50d9f9362ef48ed9ab26c48 /src/parseTools.js | |
parent | 234819df4c3425fbb4f5d77afe83fdaf246bf648 (diff) |
refactor library-needing code out of jsifier
Diffstat (limited to 'src/parseTools.js')
-rw-r--r-- | src/parseTools.js | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index 94ea4f46..5954749a 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -589,3 +589,129 @@ function correctRoundings() { return CORRECT_ROUNDINGS === 1 || correctSpecificRounding(); } + +// See makeSetValue +function makeGetValue(ptr, pos, type, noNeedFirst) { + if (isStructType(type)) { + var typeData = Types.types[type]; + var ret = []; + for (var i = 0; i < typeData.fields.length; i++) { + ret.push('f' + i + ': ' + makeGetValue(ptr, pos + typeData.flatIndexes[i], typeData.fields[i], noNeedFirst)); + } + return '{ ' + ret.join(', ') + ' }'; + } + + var offset = calcFastOffset(ptr, pos, noNeedFirst); + if (SAFE_HEAP) { + if (type !== 'null') type = '"' + safeQuote(type) + '"'; + return 'SAFE_HEAP_LOAD(' + offset + ', ' + type + ')'; + } else { + return makeGetSlabs(ptr, type)[0] + '[' + offset + ']'; + } +} + +function indexizeFunctions(value) { // TODO: Also check for other functions (externals, library, etc.) + if (value in Functions.currFunctions) { + value = Functions.getIndex(value); // Store integer value + } + return value; +} + +//! @param ptr The pointer. Used to find both the slab and the offset in that slab. If the pointer +//! is just an integer, then this is almost redundant, but in general the pointer type +//! may in the future include information about which slab as well. So, for now it is +//! possible to put |0| here, but if a pointer is available, that is more future-proof. +//! @param pos The position in that slab - the offset. Added to any offset in the pointer itself. +//! @param value The value to set. +//! @param type A string defining the type. Used to find the slab (IHEAP, FHEAP, etc.). +//! 'null' means, in the context of SAFE_HEAP, that we should accept all types; +//! which means we should write to all slabs, ignore type differences if any on reads, etc. +//! @param noNeedFirst Whether to ignore the offset in the pointer itself. +function makeSetValue(ptr, pos, value, type, noNeedFirst) { + if (isStructType(type)) { + var typeData = Types.types[type]; + var ret = []; + for (var i = 0; i < typeData.fields.length; i++) { + ret.push(makeSetValue(ptr, pos + typeData.flatIndexes[i], value[i], typeData.fields[i], noNeedFirst)); + } + return ret.join('; '); + } + + value = indexizeFunctions(value); + var offset = calcFastOffset(ptr, pos, noNeedFirst); + if (SAFE_HEAP) { + if (type !== 'null') type = '"' + safeQuote(type) + '"'; + return 'SAFE_HEAP_STORE(' + offset + ', ' + value + ', ' + type + ');'; + } else { + return makeGetSlabs(ptr, type, true).map(function(slab) { return slab + '[' + offset + ']=' + value }).join('; ') + ';'; + } +} + +function makeCopyValue(dest, destPos, src, srcPos, type, modifier) { + if (type !== 'null') { + return makeSetValue(dest, destPos, makeGetValue(src, srcPos, type) + (modifier || ''), type); + } + // Null is special-cased: We copy over all heaps + return 'IHEAP[' + dest + '+' + destPos + '] = IHEAP[' + src + '+' + srcPos + ']; ' + + 'FHEAP[' + dest + '+' + destPos + '] = FHEAP[' + src + '+' + srcPos + ']; ' + + (SAFE_HEAP ? 'SAFE_HEAP_COPY_HISTORY(' + dest + ' + ' + destPos + ', ' + src + ' + ' + srcPos + ')' : ''); +} + +// Given two values and an operation, returns the result of that operation. +// Tries to do as much as possible at compile time. +function getFastValue(a, op, b) { + if (isNumber(a) && isNumber(b)) { + return eval(a + op + b); + } + if (op == '*') { + if (!a) a = 1; + if (!b) b = 1; + if (a == 0 || b == 0) { + return 0; + } else if (a == 1) { + return b; + } else if (b == 1) { + return a; + } + } else if (op in set('+', '-')) { + if (!a) a = 0; + if (!b) b = 0; + if (a == 0) { + return b; + } else if (b == 0) { + return a; + } + } + return a + op + b; +} + +function calcFastOffset(ptr, pos, noNeedFirst) { + var offset = noNeedFirst ? '0' : makeGetPos(ptr); + return getFastValue(offset, '+', pos); +} + +function makeGetPos(ptr) { + return ptr; +} + +function makePointer(slab, pos, allocator, type) { // type is FFU + if (slab in set('HEAP', 'IHEAP', 'FHEAP')) return pos; + return 'Pointer_make(' + slab + ', ' + (pos ? pos : 0) + (allocator ? ', ' + allocator : '') + ')'; +} + +function makeGetSlabs(ptr, type, allowMultiple) { + assert(type); + if (!USE_TYPED_ARRAYS) { + return ['HEAP']; + } else { + if (type in Runtime.FLOAT_TYPES || type === 'int64') { + return ['FHEAP']; + } else if (type in Runtime.INT_TYPES || isPointerType(type)) { + return ['IHEAP']; + } else { + assert(allowMultiple, 'Unknown slab type and !allowMultiple: ' + type); + return ['IHEAP', 'FHEAP']; // unknown, so assign to both typed arrays + } + } +} + |