aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jsifier.js17
-rw-r--r--src/preamble.js12
-rw-r--r--src/runtime.js14
-rw-r--r--src/utility.js2
-rw-r--r--tests/runner.py8
5 files changed, 32 insertions, 21 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 329c263d..54ab8564 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -120,7 +120,7 @@ function JSify(data) {
function parseConst(value, type) {
dprint('gconst', '//yyyyy ' + JSON.stringify(value) + ',' + type + '\n');
if (isNumberType(type) || pointingLevels(type) == 1) {
- return makePointer(parseNumerical(value.text), null, 'ALLOC_STATIC', type);
+ return makePointer(indexizeFunctions(parseNumerical(toNiceIdent(value.text))), null, 'ALLOC_STATIC', type);
} else if (value.text == 'zeroinitializer') {
return makePointer(JSON.stringify(makeEmptyStruct(type)), null, 'ALLOC_STATIC', type);
} else if (value.text && value.text[0] == '"') {
@@ -157,7 +157,7 @@ function JSify(data) {
throw 'Invalid segment: ' + dump(segment);
}
};
- return splitTokenList(tokens).map(handleSegment).map(parseNumerical).map(indexizeFunctions);
+ return splitTokenList(tokens).map(handleSegment).map(indexizeFunctions).map(parseNumerical);
}
if (value.item) {
// list of items
@@ -231,16 +231,6 @@ function JSify(data) {
},
});
- var FUNCTION_INDEX = 0;
- var FUNCTION_HASH = {};
- function getFunctionIndex(name_) {
- if (!(name_ in FUNCTION_HASH)) {
- FUNCTION_HASH[name_] = FUNCTION_INDEX;
- FUNCTION_INDEX++;
- }
- return FUNCTION_HASH[name_];
- }
-
// function reconstructor & post-JS optimizer
substrate.addZyme('FunctionReconstructor', {
funcs: {},
@@ -390,8 +380,7 @@ function JSify(data) {
// Finalize function
if (LABEL_DEBUG) func.JS += " INDENT = INDENT.substr(0, INDENT.length-2);\n";
func.JS += '}\n';
- func.JS += func.ident + '.__index__ = ' + getFunctionIndex(func.ident) + ';\n';
- func.JS += 'FUNCTION_TABLE[' + getFunctionIndex(func.ident) + '] = ' + func.ident + ';\n';
+ func.JS += func.ident + '.__index__ = Runtime.getFunctionIndex(' + func.ident + ');\n';
func.__result__ = true;
return func;
},
diff --git a/src/preamble.js b/src/preamble.js
index d0ffd974..303ece97 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -3,6 +3,9 @@
function __globalConstructor__() {
}
+// This way of accessing is faster than adding |Runtime.| everywhere
+Runtime = this;
+
// Maps ints ==> functions. This lets us pass around ints, which are
// actually pointers to functions, and we convert at call()time
FUNCTION_TABLE = [];
@@ -71,12 +74,15 @@ function Pointer_make(slab, pos, allocator) {
// Finalize
var ret = [_malloc, stackAlloc, staticAlloc][allocator ? allocator : ALLOC_STATIC](Math.max(slab.length - pos, 1));
for (var i = 0; i < slab.length - pos; i++) {
+ var curr = slab[pos + i];
+ if (typeof curr === 'function') {
+ curr = Runtime.getFunctionIndex(curr);
+ }
#if SAFE_HEAP
- SAFE_HEAP_STORE(ret + i, slab[pos + i]);
+ SAFE_HEAP_STORE(ret + i, curr);
#else
#if USE_TYPED_ARRAYS
// TODO: Check - also in non-typedarray case - for functions, and if so add |.__index__|
- var curr = slab[pos + i];
if (typeof curr === 'number' || typeof curr === 'boolean') {
IHEAP[ret + i] = curr; // TODO: optimize. Can easily detect floats, but 1.0 might look like an int...
FHEAP[ret + i] = curr;
@@ -84,7 +90,7 @@ function Pointer_make(slab, pos, allocator) {
HEAP[ret + i] = curr;
}
#else
- HEAP[ret + i] = slab[pos + i];
+ HEAP[ret + i] = curr;
#endif
#endif
}
diff --git a/src/runtime.js b/src/runtime.js
index 43a522e4..8d2df889 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -69,12 +69,24 @@ Runtime = {
stackAlloc: unInline('stackAlloc', ['size']),
staticAlloc: unInline('staticAlloc', ['size']),
alignMemory: unInline('alignMemory', ['size', 'quantum']),
+
+ FUNCTION_TABLE: [],
+ getFunctionIndex: function getFunctionIndex(func) {
+ var key = Runtime.FUNCTION_TABLE.length;
+ FUNCTION_TABLE[key] = func;
+ return key;
+ },
};
function getRuntime() {
var ret = '';
for (i in Runtime) {
- ret += Runtime[i].toString() + '\n';
+ var item = Runtime[i];
+ if (typeof item === 'function') {
+ ret += item.toString() + '\n';
+ } else {
+ ret += 'var ' + i + ' = ' + JSON.stringify(item) + ';\n';
+ }
}
return ret + '\n';
}
diff --git a/src/utility.js b/src/utility.js
index 0be6e598..c28077e8 100644
--- a/src/utility.js
+++ b/src/utility.js
@@ -224,6 +224,6 @@ function setIntersect(x, y) {
}
function isNumber(x) {
- return x == parseInt(x);
+ return x == parseFloat(x);
}
diff --git a/tests/runner.py b/tests/runner.py
index 931127c8..7356ad34 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -501,6 +501,10 @@ if 'benchmark' not in sys.argv:
int calc1() { return 26; }
int calc2() { return 90; }
typedef int (*fp_t)();
+
+ fp_t globally1 = calc1;
+ fp_t globally2 = calc2;
+
int main()
{
fp_t fp = calc1;
@@ -509,11 +513,11 @@ if 'benchmark' not in sys.argv:
fp_t fp2 = calc2;
void *vp2 = (void*)fp2;
fp_t fpb2 = (fp_t)vp2;
- printf("*%d,%d,%d,%d*\\n", fp(), fpb(), fp2(), fpb2());
+ printf("*%d,%d,%d,%d,%d,%d*\\n", fp(), fpb(), fp2(), fpb2(), globally1(), globally2());
return 0;
}
'''
- self.do_test(src, '*26,26,90,90*')
+ self.do_test(src, '*26,26,90,90,26,90*')
def test_emptyclass(self):
src = '''