1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
load(libdir + "asm.js");
load(libdir + "asserts.js");
function matchStack(stackString, stackArray)
{
var match = 0;
for (name of stackArray) {
match = stackString.indexOf(name, match);
if (match === -1)
throw name + " not found in the stack " + stack;
}
}
var stack;
function dumpStack()
{
stack = new Error().stack
}
setJitCompilerOption("ion.warmup.trigger", 10);
setJitCompilerOption("baseline.warmup.trigger", 0);
setJitCompilerOption("offthread-compilation.enable", 0);
setCachingEnabled(true);
var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f");
var f = asmLink(callFFI, null, {ffi:dumpStack});
for (var i = 0; i < 15; i++) {
stack = null;
f();
matchStack(stack, ['dumpStack', 'f']);
}
if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f");
assertEq(isAsmJSModuleLoadedFromCache(callFFI), true);
stack = null;
f();
matchStack(stack, ['dumpStack', 'f']);
}
var f1 = asmLink(callFFI, null, {ffi:dumpStack});
var f2 = asmLink(callFFI, null, {ffi:function middle() { f1() }});
stack = null;
(function outer() { f2() })();
matchStack(stack, ["dumpStack", "f", "middle", "f"]);
function returnStackDumper() { return { valueOf:function() { stack = new Error().stack } } }
var f = asmLink(callFFI, null, {ffi:returnStackDumper});
for (var i = 0; i < 15; i++) {
stack = null;
f();
matchStack(stack, ['valueOf', 'f']);
}
var caught = false;
try {
stack = null;
asmLink(asmCompile(USE_ASM + "function asmRec() { asmRec() } return asmRec"))();
} catch (e) {
caught = true;
matchStack(e.stack, ['asmRec', 'asmRec', 'asmRec', 'asmRec']);
}
assertEq(caught, true);
var caught = false;
try {
callFFI(null, {ffi:Object.defineProperty})();
} catch (e) {
caught = true;
}
assertEq(caught, true);
asmLink(callFFI, null, {ffi:eval})();
asmLink(callFFI, null, {ffi:Function})();
asmLink(callFFI, null, {ffi:Error})();
var manyCalls = asmCompile('global', 'ffis',
USE_ASM +
"var ffi=ffis.ffi;\
function f1(a,b,c,d,e,f,g,h,i,j,k) { \
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; \
ffi(); \
return (a+b+c+d+e+f+g+h+i+j+k)|0; \
} \
function f2() { \
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; \
} \
function f3() { return 13 } \
function f4(i) { \
i=i|0; \
return TBL[i&3]()|0; \
} \
var TBL=[f3, f3, f2, f3]; \
return f4;");
stack = null;
assertEq(asmLink(manyCalls, null, {ffi:dumpStack})(2), 123);
matchStack(stack, ['dumpStack', 'f1', 'f2', 'f4']);
|