OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Flags: --validate-asm --allow-natives-syntax | 5 // Flags: --validate-asm --allow-natives-syntax |
6 | 6 |
7 var filename = '(?:[^ ]+/)?test/mjsunit/wasm/asm-wasm-stack.js'; | 7 var filename = '(?:[^ ]+/)?test/mjsunit/wasm/asm-wasm-stack.js'; |
8 filename = filename.replace(/\//g, '[/\\\\]'); | 8 filename = filename.replace(/\//g, '[/\\\\]'); |
9 | 9 |
10 function checkPreformattedStack(e, expected_lines) { | 10 function checkPreformattedStack(e, expected_lines) { |
11 print('preformatted stack: ' + e.stack); | 11 print('preformatted stack: ' + e.stack); |
12 var lines = e.stack.split('\n'); | 12 var lines = e.stack.split('\n'); |
13 assertEquals(expected_lines.length, lines.length); | 13 assertEquals(expected_lines.length, lines.length); |
14 for (var i = 0; i < lines.length; ++i) { | 14 for (var i = 0; i < lines.length; ++i) { |
15 assertMatches(expected_lines[i], lines[i], 'line ' + i); | 15 assertMatches(expected_lines[i], lines[i], 'line ' + i); |
16 } | 16 } |
17 } | 17 } |
18 | 18 |
19 function checkFunctionsOnCallsites(e, locations) { | 19 function printCallsites(stack) { |
20 var stack = e.stack; | |
21 print('callsite objects (size ' + stack.length + '):'); | 20 print('callsite objects (size ' + stack.length + '):'); |
22 for (var i = 0; i < stack.length; ++i) { | 21 for (var i = 0; i < stack.length; ++i) { |
23 var s = stack[i]; | 22 var s = stack[i]; |
24 print( | 23 print( |
25 ' [' + i + '] ' + s.getFunctionName() + ' (' + s.getFileName() + ':' + | 24 ' [' + i + '] ' + s.getFunctionName() + ' (' + s.getFileName() + ':' + |
26 s.getLineNumber() + ':' + s.getColumnNumber() + ')'); | 25 s.getLineNumber() + ':' + s.getColumnNumber() + ')'); |
27 } | 26 } |
28 assertEquals(locations.length, stack.length, 'stack size'); | 27 } |
29 for (var i = 0; i < locations.length; ++i) { | 28 |
| 29 function checkCallsiteArray(stack, expected) { |
| 30 assertEquals(expected.length, stack.length, 'stack size'); |
| 31 for (var i = 0; i < expected.length; ++i) { |
30 var cs = stack[i]; | 32 var cs = stack[i]; |
31 assertMatches('^' + filename + '$', cs.getFileName(), 'file name at ' + i); | 33 assertMatches('^' + filename + '$', cs.getFileName(), 'file name at ' + i); |
32 assertEquals( | 34 assertEquals(expected[i][0], cs.getFunctionName(), 'function name at ' + i); |
33 locations[i][0], cs.getFunctionName(), 'function name at ' + i); | 35 assertEquals(expected[i][1], cs.getLineNumber(), 'line number at ' + i); |
34 assertEquals(locations[i][1], cs.getLineNumber(), 'line number at ' + i); | 36 assertEquals(expected[i][2], cs.getColumnNumber(), 'column number at ' + i); |
35 assertEquals( | |
36 locations[i][2], cs.getColumnNumber(), 'column number at ' + i); | |
37 assertNotNull(cs.getThis(), 'receiver should be global'); | 37 assertNotNull(cs.getThis(), 'receiver should be global'); |
38 assertEquals(stack[0].getThis(), cs.getThis(), 'receiver should be global'); | 38 assertEquals(stack[0].getThis(), cs.getThis(), 'receiver should be global'); |
39 } | 39 } |
40 } | 40 } |
41 | 41 |
| 42 function checkFunctionsOnCallsites(e, expected) { |
| 43 printCallsites(e.stack); |
| 44 checkCallsiteArray(e.stack, expected); |
| 45 } |
| 46 |
| 47 function checkTopFunctionsOnCallsites(e, expected) { |
| 48 printCallsites(e.stack); |
| 49 assertTrue( |
| 50 e.stack.length >= expected.length, 'expected at least ' + |
| 51 expected.length + ' callsites, got ' + e.stack.length); |
| 52 checkCallsiteArray(e.stack.slice(0, expected.length), expected); |
| 53 } |
| 54 |
42 function throwException() { | 55 function throwException() { |
43 throw new Error('exception from JS'); | 56 throw new Error('exception from JS'); |
44 } | 57 } |
45 | 58 |
46 function generateWasmFromAsmJs(stdlib, foreign, heap) { | 59 function generateWasmFromAsmJs(stdlib, foreign) { |
47 'use asm'; | 60 'use asm'; |
48 var throwFunc = foreign.throwFunc; | 61 var throwFunc = foreign.throwFunc; |
49 function callThrow() { | 62 function callThrow() { |
50 throwFunc(); | 63 throwFunc(); |
51 } | 64 } |
52 function redirectFun(i) { | 65 function redirectFun(i) { |
53 i = i|0; | 66 i = i | 0; |
54 switch (i|0) { | 67 switch (i | 0) { |
55 case 0: callThrow(); break; | 68 case 0: callThrow(); break; |
56 case 1: redirectFun(0); break; | 69 case 1: redirectFun(0); break; |
57 case 2: redirectFun(1); break; | 70 case 2: redirectFun(1); break; |
58 } | 71 } |
59 } | 72 } |
60 return redirectFun; | 73 return redirectFun; |
61 } | 74 } |
62 | 75 |
63 (function PreformattedStackTraceFromJS() { | 76 (function PreformattedStackTraceFromJS() { |
64 var fun = generateWasmFromAsmJs(this, {throwFunc: throwException}, undefined); | 77 var fun = generateWasmFromAsmJs(this, {throwFunc: throwException}); |
| 78 assertTrue(%IsWasmCode(fun)); |
65 var e = null; | 79 var e = null; |
66 try { | 80 try { |
67 fun(0); | 81 fun(0); |
68 } catch (ex) { | 82 } catch (ex) { |
69 e = ex; | 83 e = ex; |
70 } | 84 } |
71 assertInstanceof(e, Error, 'exception should have been thrown'); | 85 assertInstanceof(e, Error, 'exception should have been thrown'); |
72 checkPreformattedStack(e, [ | 86 checkPreformattedStack(e, [ |
73 '^Error: exception from JS$', | 87 '^Error: exception from JS$', |
74 '^ *at throwException \\(' + filename + ':43:9\\)$', | 88 '^ *at throwException \\(' + filename + ':56:9\\)$', |
75 '^ *at callThrow \\(' + filename + ':50:5\\)$', | 89 '^ *at callThrow \\(' + filename + ':63:5\\)$', |
76 '^ *at redirectFun \\(' + filename + ':55:15\\)$', | 90 '^ *at redirectFun \\(' + filename + ':68:15\\)$', |
77 '^ *at PreformattedStackTraceFromJS \\(' + filename + ':67:5\\)$', | 91 '^ *at PreformattedStackTraceFromJS \\(' + filename + ':81:5\\)$', |
78 '^ *at ' + filename + ':80:3$' | 92 '^ *at ' + filename + ':94:3$' |
79 ]); | 93 ]); |
80 })(); | 94 })(); |
81 | 95 |
82 // Now collect the Callsite objects instead of just a string. | 96 // Now collect the Callsite objects instead of just a string. |
83 Error.prepareStackTrace = function(error, frames) { | 97 Error.prepareStackTrace = function(error, frames) { |
84 return frames; | 98 return frames; |
85 }; | 99 }; |
86 | 100 |
87 (function CallsiteObjectsFromJS() { | 101 (function CallsiteObjectsFromJS() { |
88 var fun = generateWasmFromAsmJs(this, {throwFunc: throwException}, undefined); | 102 var fun = generateWasmFromAsmJs(this, {throwFunc: throwException}); |
| 103 assertTrue(%IsWasmCode(fun)); |
89 var e = null; | 104 var e = null; |
90 try { | 105 try { |
91 fun(2); | 106 fun(2); |
92 } catch (ex) { | 107 } catch (ex) { |
93 e = ex; | 108 e = ex; |
94 } | 109 } |
95 assertInstanceof(e, Error, 'exception should have been thrown'); | 110 assertInstanceof(e, Error, 'exception should have been thrown'); |
96 checkFunctionsOnCallsites(e, [ | 111 checkFunctionsOnCallsites(e, [ |
97 ['throwException', 43, 9], // -- | 112 ['throwException', 56, 9], // -- |
98 ['callThrow', 50, 5], // -- | 113 ['callThrow', 63, 5], // -- |
99 ['redirectFun', 55, 15], // -- | 114 ['redirectFun', 68, 15], // -- |
100 ['redirectFun', 56, 15], // -- | 115 ['redirectFun', 69, 15], // -- |
101 ['redirectFun', 57, 15], // -- | 116 ['redirectFun', 70, 15], // -- |
102 ['CallsiteObjectsFromJS', 91, 5], // -- | 117 ['CallsiteObjectsFromJS', 106, 5], // -- |
103 [null, 105, 3] | 118 [null, 120, 3] |
104 ]); | 119 ]); |
105 })(); | 120 })(); |
| 121 |
| 122 function generateOverflowWasmFromAsmJs() { |
| 123 'use asm'; |
| 124 function f(a) { |
| 125 a = a | 0; |
| 126 return f(a) | 0; |
| 127 } |
| 128 return f; |
| 129 } |
| 130 |
| 131 (function StackOverflowPosition() { |
| 132 var fun = generateOverflowWasmFromAsmJs(); |
| 133 assertTrue(%IsWasmCode(fun)); |
| 134 var e = null; |
| 135 try { |
| 136 fun(2); |
| 137 } catch (ex) { |
| 138 e = ex; |
| 139 } |
| 140 // TODO(wasm): Re-enable the check once 673297 is fixed. |
| 141 //assertInstanceof(e, RangeError, 'RangeError should have been thrown'); |
| 142 checkTopFunctionsOnCallsites(e, [ |
| 143 ['f', 124, 13], // -- |
| 144 ['f', 126, 12], // -- |
| 145 ['f', 126, 12], // -- |
| 146 ['f', 126, 12] // -- |
| 147 ]); |
| 148 })(); |
OLD | NEW |