|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include <stdio.h> |
|
6 #include <stdlib.h> |
|
7 #include <string.h> |
|
8 |
|
9 #include "gdb-tests.h" |
|
10 #include "jsapi.h" |
|
11 #include "jsfriendapi.h" |
|
12 |
|
13 using namespace JS; |
|
14 |
|
15 /* The class of the global object. */ |
|
16 const JSClass global_class = { |
|
17 "global", JSCLASS_GLOBAL_FLAGS, |
|
18 JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, |
|
19 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, |
|
20 nullptr, nullptr, nullptr, nullptr, |
|
21 JS_GlobalObjectTraceHook |
|
22 }; |
|
23 |
|
24 template<typename T> |
|
25 static inline T * |
|
26 checkPtr(T *ptr) |
|
27 { |
|
28 if (! ptr) |
|
29 abort(); |
|
30 return ptr; |
|
31 } |
|
32 |
|
33 static void |
|
34 checkBool(bool success) |
|
35 { |
|
36 if (! success) |
|
37 abort(); |
|
38 } |
|
39 |
|
40 /* The error reporter callback. */ |
|
41 void reportError(JSContext *cx, const char *message, JSErrorReport *report) |
|
42 { |
|
43 fprintf(stderr, "%s:%u: %s\n", |
|
44 report->filename ? report->filename : "<no filename>", |
|
45 (unsigned int) report->lineno, |
|
46 message); |
|
47 } |
|
48 |
|
49 // prolog.py sets a breakpoint on this function; test functions can call it |
|
50 // to easily return control to GDB where desired. |
|
51 void breakpoint() { |
|
52 // If we leave this function empty, the linker will unify it with other |
|
53 // empty functions throughout SpiderMonkey. If we then set a GDB |
|
54 // breakpoint on it, that breakpoint will hit at all sorts of random |
|
55 // times. So make it perform a distinctive side effect. |
|
56 fprintf(stderr, "Called " __FILE__ ":breakpoint\n"); |
|
57 } |
|
58 |
|
59 GDBFragment *GDBFragment::allFragments = nullptr; |
|
60 |
|
61 int |
|
62 main (int argc, const char **argv) |
|
63 { |
|
64 if (!JS_Init()) return 1; |
|
65 JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024, JS_USE_HELPER_THREADS)); |
|
66 JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff); |
|
67 JS_SetNativeStackQuota(runtime, 5000000); |
|
68 |
|
69 JSContext *cx = checkPtr(JS_NewContext(runtime, 8192)); |
|
70 JS_SetErrorReporter(cx, reportError); |
|
71 |
|
72 JSAutoRequest ar(cx); |
|
73 |
|
74 /* Create the global object. */ |
|
75 JS::CompartmentOptions options; |
|
76 options.setVersion(JSVERSION_LATEST); |
|
77 RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class, |
|
78 nullptr, JS::FireOnNewGlobalHook, options))); |
|
79 js::SetDefaultObjectForContext(cx, global); |
|
80 |
|
81 JSAutoCompartment ac(cx, global); |
|
82 |
|
83 /* Populate the global object with the standard globals, |
|
84 like Object and Array. */ |
|
85 checkBool(JS_InitStandardClasses(cx, global)); |
|
86 |
|
87 argv++; |
|
88 while (*argv) { |
|
89 const char *name = *argv++; |
|
90 GDBFragment *fragment; |
|
91 for (fragment = GDBFragment::allFragments; fragment; fragment = fragment->next) { |
|
92 if (strcmp(fragment->name(), name) == 0) { |
|
93 fragment->run(cx, argv); |
|
94 break; |
|
95 } |
|
96 } |
|
97 if (!fragment) { |
|
98 fprintf(stderr, "Unrecognized fragment name: %s\n", name); |
|
99 exit(1); |
|
100 } |
|
101 } |
|
102 |
|
103 return 0; |
|
104 } |