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
|
#include "gdb-tests.h"
#include "jsapi.h" // sundry symbols not moved to more-specific headers yet
#include "jsfriendapi.h" // JSFunctionSpecWithHelp
#include "jit/JitOptions.h" // js::jit::JitOptions
#include "js/CallArgs.h" // JS::CallArgs, JS::CallArgsFromVp
#include "js/CompilationAndEvaluation.h" // JS::Evaluate
#include "js/CompileOptions.h" // JS::CompileOptions
#include "js/RootingAPI.h" // JS::Rooted
#include "js/SourceText.h" // JS::Source{Ownership,Text}
#include "js/Value.h" // JS::Value
#include "mozilla/Utf8.h" // mozilla::Utf8Unit
#include <stdint.h> // uint32_t
#include <string.h> // strlen
static bool Something(JSContext* cx, unsigned argc, JS::Value* vp) {
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().setInt32(23);
breakpoint();
return true;
}
// clang-format off
static const JSFunctionSpecWithHelp unwind_functions[] = {
JS_FN_HELP("something", Something, 0, 0,
"something()",
" Test function for test-unwind."),
JS_FS_HELP_END
};
// clang-format on
FRAGMENT(unwind, simple) {
using namespace JS;
JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
if (!JS_DefineFunctionsWithHelp(cx, global, unwind_functions)) {
return;
}
// Define an itercount property and use it to ensure Baseline compilation.
uint32_t threshold = js::jit::JitOptions.baselineJitWarmUpThreshold;
RootedValue val(cx, Int32Value(threshold + 10));
if (!JS_DefineProperty(cx, global, "itercount", val, 0)) {
return;
}
int line0 = __LINE__;
const char* bytes =
"\n"
"function unwindFunctionInner() {\n"
" for (var i = 0; i < itercount; i++) {}\n"
" return something();\n"
"}\n"
"\n"
"function unwindFunctionOuter() {\n"
" for (var i = 0; i < itercount; i++) {}\n"
" return unwindFunctionInner();\n"
"}\n"
"\n"
"unwindFunctionOuter();\n";
JS::CompileOptions opts(cx);
opts.setFileAndLine(__FILE__, line0 + 1);
JS::SourceText<mozilla::Utf8Unit> srcBuf;
if (!srcBuf.init(cx, bytes, strlen(bytes), JS::SourceOwnership::Borrowed)) {
return;
}
JS::Rooted<JS::Value> rval(cx);
JS::Evaluate(cx, opts, srcBuf, &rval);
}
|