aboutsummaryrefslogtreecommitdiff
path: root/src/jsifier.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/jsifier.js')
-rw-r--r--src/jsifier.js93
1 files changed, 62 insertions, 31 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index b377202d..8884e24f 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -16,6 +16,8 @@ var SETJMP_LABEL = -1;
var INDENTATION = ' ';
+var functionStubSigs = {};
+
// JSifier
function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
@@ -278,7 +280,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// they would shadow similarly-named globals in the parent.
item.JS = '';
} else {
- item.JS = makeGlobalDef(item.ident);
+ item.JS = makeGlobalDef(item.ident);
}
if (!NAMED_GLOBALS && isIndexableGlobal(item.ident)) {
@@ -407,6 +409,11 @@ function JSify(data, functionsOnly, givenFunctions) {
// functionStub
substrate.addActor('FunctionStub', {
processItem: function(item) {
+ // note the signature
+ if (item.returnType && item.params) {
+ functionStubSigs[item.ident] = Functions.getSignature(item.returnType.text, item.params.map(function(arg) { return arg.type }), false);
+ }
+
function addFromLibrary(ident) {
if (ident in addedLibraryItems) return '';
addedLibraryItems[ident] = true;
@@ -658,6 +665,10 @@ function JSify(data, functionsOnly, givenFunctions) {
}
}
+ if (func.hasVarArgsCall) {
+ func.JS += INDENTATION + 'var tempVarArgs = 0;\n';
+ }
+
// Prepare the stack, if we need one. If we have other stack allocations, force the stack to be set up.
func.JS += INDENTATION + RuntimeGenerator.stackEnter(func.initialStack, func.otherStackAllocations) + ';\n';
@@ -1234,6 +1245,7 @@ function JSify(data, functionsOnly, givenFunctions) {
+ (EXCEPTION_DEBUG ? 'Module.print("Exception: " + e + ", currently at: " + (new Error().stack)); ' : '')
+ 'return null } })();';
}
+ ret = makeVarArgsCleanup(ret);
if (item.assignTo) {
ret = 'var ' + item.assignTo + ' = ' + ret;
@@ -1446,12 +1458,13 @@ function JSify(data, functionsOnly, givenFunctions) {
});
if (hasVarArgs && !useJSArgs) {
+ funcData.hasVarArgsCall = true;
if (varargs.length === 0) {
varargs = [0];
varargsTypes = ['i32'];
}
var offset = 0;
- varargs = '(tempInt=' + RuntimeGenerator.stackAlloc(varargs.length, ',') + ',' +
+ varargs = '(tempVarArgs=' + RuntimeGenerator.stackAlloc(varargs.length, ',') + ',' +
varargs.map(function(arg, i) {
var type = varargsTypes[i];
if (type == 0) return null;
@@ -1459,17 +1472,17 @@ function JSify(data, functionsOnly, givenFunctions) {
var ret;
assert(offset % Runtime.STACK_ALIGN == 0); // varargs must be aligned
if (!varargsByVals[i]) {
- ret = makeSetValue(getFastValue('tempInt', '+', offset), 0, arg, type, null, null, Runtime.STACK_ALIGN, null, ',');
+ ret = makeSetValue(getFastValue('tempVarArgs', '+', offset), 0, arg, type, null, null, Runtime.STACK_ALIGN, null, ',');
offset += Runtime.alignMemory(Runtime.getNativeFieldSize(type), Runtime.STACK_ALIGN);
} else {
var size = calcAllocatedSize(removeAllPointing(type));
- ret = makeCopyValues(getFastValue('tempInt', '+', offset), arg, size, null, null, varargsByVals[i], ',');
+ ret = makeCopyValues(getFastValue('tempVarArgs', '+', offset), arg, size, null, null, varargsByVals[i], ',');
offset += Runtime.forceAlign(size, Runtime.STACK_ALIGN);
}
return ret;
}).filter(function(arg) {
return arg !== null;
- }).join(',') + ',tempInt)';
+ }).join(',') + ',tempVarArgs)';
varargs = asmCoercion(varargs, 'i32');
}
@@ -1531,7 +1544,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// This is a call through an invoke_*, either a forced one, or a setjmp-required one
// note: no need to update argsTypes at this point
if (byPointerForced) Functions.unimplementedFunctions[callIdent] = sig;
- args.unshift(byPointerForced ? Functions.getIndex(callIdent, undefined, sig) : asmCoercion(callIdent, 'i32'));
+ args.unshift(byPointerForced ? Functions.getIndex(callIdent, sig) : asmCoercion(callIdent, 'i32'));
callIdent = 'invoke_' + sig;
}
} else if (SAFE_DYNCALLS) {
@@ -1557,10 +1570,24 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret;
}
+
+ function makeVarArgsCleanup(js) {
+ if (js.indexOf('(tempVarArgs=') >= 0) {
+ if (js[js.length-1] == ';') {
+ return js + ' STACKTOP=tempVarArgs;';
+ } else {
+ assert(js.indexOf(';') < 0);
+ return '((' + js + '), STACKTOP=tempVarArgs)';
+ }
+ }
+ return js;
+ }
+
makeFuncLineActor('getelementptr', function(item) { return finalizeLLVMFunctionCall(item) });
makeFuncLineActor('call', function(item) {
if (item.standalone && LibraryManager.isStubFunction(item.ident)) return ';';
- return makeFunctionCall(item.ident, item.params, item.funcData, item.type, false, !!item.assignTo || !item.standalone) + (item.standalone ? ';' : '');
+ var ret = makeFunctionCall(item.ident, item.params, item.funcData, item.type, false, !!item.assignTo || !item.standalone) + (item.standalone ? ';' : '');
+ return makeVarArgsCleanup(ret);
});
makeFuncLineActor('unreachable', function(item) {
@@ -1608,7 +1635,7 @@ function JSify(data, functionsOnly, givenFunctions) {
//
if (!mainPass) {
- if (phase == 'pre' && !Variables.generatedGlobalBase) {
+ if (phase == 'pre' && !Variables.generatedGlobalBase && !BUILD_AS_SHARED_LIB) {
Variables.generatedGlobalBase = true;
// Globals are done, here is the rest of static memory
assert((TARGET_LE32 && Runtime.GLOBAL_BASE == 8) || (TARGET_X86 && Runtime.GLOBAL_BASE == 4)); // this is assumed in e.g. relocations for linkable modules
@@ -1652,24 +1679,26 @@ function JSify(data, functionsOnly, givenFunctions) {
print('}\n');
if (USE_TYPED_ARRAYS == 2) {
- print('var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);\n');
- print('assert(tempDoublePtr % 8 == 0);\n');
- print('function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much\n');
- print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
- print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
- print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
- print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
- print('}\n');
- print('function copyTempDouble(ptr) {\n');
- print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
- print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
- print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
- print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
- print(' HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];\n');
- print(' HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];\n');
- print(' HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];\n');
- print(' HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];\n');
- print('}\n');
+ if (!BUILD_AS_SHARED_LIB) {
+ print('var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);\n');
+ print('assert(tempDoublePtr % 8 == 0);\n');
+ print('function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much\n');
+ print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
+ print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
+ print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
+ print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
+ print('}\n');
+ print('function copyTempDouble(ptr) {\n');
+ print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
+ print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
+ print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
+ print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
+ print(' HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];\n');
+ print(' HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];\n');
+ print(' HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];\n');
+ print(' HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];\n');
+ print('}\n');
+ }
}
}
@@ -1704,11 +1733,13 @@ function JSify(data, functionsOnly, givenFunctions) {
legalizedI64s = legalizedI64sDefault;
- print('STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);\n');
- print('staticSealed = true; // seal the static portion of memory\n');
- print('STACK_MAX = STACK_BASE + ' + TOTAL_STACK + ';\n');
- print('DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);\n');
- print('assert(DYNAMIC_BASE < TOTAL_MEMORY); // Stack must fit in TOTAL_MEMORY; allocations from here on may enlarge TOTAL_MEMORY\n');
+ if (!BUILD_AS_SHARED_LIB) {
+ print('STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);\n');
+ print('staticSealed = true; // seal the static portion of memory\n');
+ print('STACK_MAX = STACK_BASE + ' + TOTAL_STACK + ';\n');
+ print('DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);\n');
+ print('assert(DYNAMIC_BASE < TOTAL_MEMORY); // Stack must fit in TOTAL_MEMORY; allocations from here on may enlarge TOTAL_MEMORY\n');
+ }
if (asmLibraryFunctions.length > 0) {
print('// ASM_LIBRARY FUNCTIONS');