summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/wasm/asm-wasm-stack.js
blob: be728394eacab46bd5f332d92c81ba940e0c419c (plain)
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
99
100
101
102
103
104
105
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --validate-asm --allow-natives-syntax

var filename = '(?:[^ ]+/)?test/mjsunit/wasm/asm-wasm-stack.js';
filename = filename.replace(/\//g, '[/\\\\]');

function checkPreformattedStack(e, expected_lines) {
  print('preformatted stack: ' + e.stack);
  var lines = e.stack.split('\n');
  assertEquals(expected_lines.length, lines.length);
  for (var i = 0; i < lines.length; ++i) {
    assertMatches(expected_lines[i], lines[i], 'line ' + i);
  }
}

function checkFunctionsOnCallsites(e, locations) {
  var stack = e.stack;
  print('callsite objects (size ' + stack.length + '):');
  for (var i = 0; i < stack.length; ++i) {
    var s = stack[i];
    print(
        ' [' + i + '] ' + s.getFunctionName() + ' (' + s.getFileName() + ':' +
        s.getLineNumber() + ':' + s.getColumnNumber() + ')');
  }
  assertEquals(locations.length, stack.length, 'stack size');
  for (var i = 0; i < locations.length; ++i) {
    var cs = stack[i];
    assertMatches('^' + filename + '$', cs.getFileName(), 'file name at ' + i);
    assertEquals(
        locations[i][0], cs.getFunctionName(), 'function name at ' + i);
    assertEquals(locations[i][1], cs.getLineNumber(), 'line number at ' + i);
    assertEquals(
        locations[i][2], cs.getColumnNumber(), 'column number at ' + i);
    assertNotNull(cs.getThis(), 'receiver should be global');
    assertEquals(stack[0].getThis(), cs.getThis(), 'receiver should be global');
  }
}

function throwException() {
  throw new Error('exception from JS');
}

function generateWasmFromAsmJs(stdlib, foreign, heap) {
  'use asm';
  var throwFunc = foreign.throwFunc;
  function callThrow() {
    throwFunc();
  }
  function redirectFun(i) {
    i = i|0;
    switch (i|0) {
      case 0: callThrow(); break;
      case 1: redirectFun(0); break;
      case 2: redirectFun(1); break;
    }
  }
  return redirectFun;
}

(function PreformattedStackTraceFromJS() {
  var fun = generateWasmFromAsmJs(this, {throwFunc: throwException}, undefined);
  var e = null;
  try {
    fun(0);
  } catch (ex) {
    e = ex;
  }
  assertInstanceof(e, Error, 'exception should have been thrown');
  checkPreformattedStack(e, [
    '^Error: exception from JS$',
    '^ *at throwException \\(' + filename + ':43:9\\)$',
    '^ *at callThrow \\(' + filename + ':50:5\\)$',
    '^ *at redirectFun \\(' + filename + ':55:15\\)$',
    '^ *at PreformattedStackTraceFromJS \\(' + filename + ':67:5\\)$',
    '^ *at ' + filename + ':80:3$'
  ]);
})();

// Now collect the Callsite objects instead of just a string.
Error.prepareStackTrace = function(error, frames) {
  return frames;
};

(function CallsiteObjectsFromJS() {
  var fun = generateWasmFromAsmJs(this, {throwFunc: throwException}, undefined);
  var e = null;
  try {
    fun(2);
  } catch (ex) {
    e = ex;
  }
  assertInstanceof(e, Error, 'exception should have been thrown');
  checkFunctionsOnCallsites(e, [
    ['throwException', 43, 9],         // --
    ['callThrow', 50, 5],              // --
    ['redirectFun', 55, 15],            // --
    ['redirectFun', 56, 15],            // --
    ['redirectFun', 57, 15],            // --
    ['CallsiteObjectsFromJS', 91, 5],  // --
    [null, 105, 3]
  ]);
})();