Skip to content

Commit 76ad640

Browse files
committed
[MERGE #5351 @Cellule] Asm.js: Bytecode generator stack space
Merge pull request #5351 from Cellule:asmjs_stack Check if we have enough stack when emitting bytecode recursively. OS#17953300
2 parents 2810b5c + b35e3b1 commit 76ad640

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

lib/Runtime/Language/AsmJsByteCodeGenerator.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,11 @@ namespace Js
421421

422422
EmitExpressionInfo AsmJSByteCodeGenerator::Emit( ParseNode *pnode )
423423
{
424+
if (!ThreadContext::IsCurrentStackAvailable(Js::Constants::MinStackCompile))
425+
{
426+
throw AsmJsCompilationException(_u("Out of stack space"));
427+
}
428+
424429
if( !pnode )
425430
{
426431
return EmitExpressionInfo( AsmJsType::Void );

test/AsmJs/emit_recursive.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// Find StackOverflow constructor
7+
let StackOverflow;
8+
try {
9+
const bar = () => bar();
10+
bar();
11+
} catch (e) {
12+
StackOverflow = e.constructor;
13+
}
14+
15+
function test(n) {
16+
const str = `function asm() {
17+
"use asm"
18+
function foo() {
19+
return (${Array(n).fill("1").join("+")})|0
20+
}
21+
return foo;
22+
}
23+
`;
24+
25+
try {
26+
eval(str);
27+
const res = asm()();
28+
if (res !== n) {
29+
console.log(`Invalid result: expected ${n}. Got ${res}`);
30+
}
31+
} catch (e) {
32+
if (!(e instanceof StackOverflow)) {
33+
console.log("Expected a StackOverflow error");
34+
}
35+
}
36+
}
37+
38+
// Test with/without stackoverflow in asm.js and/or javascript
39+
for (const n of [10, 50, 100, 500, 1000, 5000]) {
40+
test(n);
41+
}
42+
43+
console.log("pass");

test/AsmJs/rlexe.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,4 +1075,9 @@
10751075
<compile-flags>-testtrace:asmjs</compile-flags>
10761076
</default>
10771077
</test>
1078+
<test>
1079+
<default>
1080+
<files>emit_recursive.js</files>
1081+
</default>
1082+
</test>
10781083
</regress-exe>

0 commit comments

Comments
 (0)