michael@0: load(libdir + "asm.js"); michael@0: load(libdir + "asserts.js"); michael@0: michael@0: function matchStack(stackString, stackArray) michael@0: { michael@0: var match = 0; michael@0: for (name of stackArray) { michael@0: match = stackString.indexOf(name, match); michael@0: if (match === -1) michael@0: throw name + " not found in the stack " + stack; michael@0: } michael@0: } michael@0: michael@0: var stack; michael@0: function dumpStack() michael@0: { michael@0: stack = new Error().stack michael@0: } michael@0: michael@0: setCachingEnabled(true); michael@0: michael@0: var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f"); michael@0: michael@0: var f = asmLink(callFFI, null, {ffi:dumpStack}); michael@0: for (var i = 0; i < 5000; i++) { michael@0: stack = null; michael@0: f(); michael@0: matchStack(stack, ['dumpStack', 'f']); michael@0: } michael@0: michael@0: if (isAsmJSCompilationAvailable() && isCachingEnabled()) { michael@0: var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f"); michael@0: assertEq(isAsmJSModuleLoadedFromCache(callFFI), true); michael@0: stack = null; michael@0: f(); michael@0: matchStack(stack, ['dumpStack', 'f']); michael@0: } michael@0: michael@0: var f1 = asmLink(callFFI, null, {ffi:dumpStack}); michael@0: var f2 = asmLink(callFFI, null, {ffi:function middle() { f1() }}); michael@0: stack = null; michael@0: (function outer() { f2() })(); michael@0: matchStack(stack, ["dumpStack", "f", "middle", "f"]); michael@0: michael@0: function returnStackDumper() { return { valueOf:function() { stack = new Error().stack } } } michael@0: var f = asmLink(callFFI, null, {ffi:returnStackDumper}); michael@0: for (var i = 0; i < 5000; i++) { michael@0: stack = null; michael@0: f(); michael@0: matchStack(stack, ['valueOf', 'f']); michael@0: } michael@0: michael@0: var caught = false; michael@0: try { michael@0: stack = null; michael@0: asmLink(asmCompile(USE_ASM + "function asmRec() { asmRec() } return asmRec"))(); michael@0: } catch (e) { michael@0: caught = true; michael@0: matchStack(e.stack, ['asmRec', 'asmRec', 'asmRec', 'asmRec']); michael@0: } michael@0: assertEq(caught, true); michael@0: michael@0: var caught = false; michael@0: try { michael@0: callFFI(null, {ffi:Object.preventExtensions})(); michael@0: } catch (e) { michael@0: caught = true; michael@0: } michael@0: assertEq(caught, true); michael@0: michael@0: asmLink(callFFI, null, {ffi:eval})(); michael@0: asmLink(callFFI, null, {ffi:Function})(); michael@0: asmLink(callFFI, null, {ffi:Error})(); michael@0: michael@0: var manyCalls = asmCompile('global', 'ffis', michael@0: USE_ASM + michael@0: "var ffi=ffis.ffi;\ michael@0: function f1(a,b,c,d,e,f,g,h,i,j,k) { \ michael@0: a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0; \ michael@0: ffi(); \ michael@0: return (a+b+c+d+e+f+g+h+i+j+k)|0; \ michael@0: } \ michael@0: function f2() { \ michael@0: return f1(1,2,3,4,5,6,7,8,f1(1,2,3,4,5,6,7,8,9,10,11)|0,10,11)|0; \ michael@0: } \ michael@0: function f3() { return 13 } \ michael@0: function f4(i) { \ michael@0: i=i|0; \ michael@0: return TBL[i&3]()|0; \ michael@0: } \ michael@0: var TBL=[f3, f3, f2, f3]; \ michael@0: return f4;"); michael@0: stack = null; michael@0: assertEq(asmLink(manyCalls, null, {ffi:dumpStack})(2), 123); michael@0: matchStack(stack, ['dumpStack', 'f1', 'f2', 'f4']);