1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/gdb/gdb-tests.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,104 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include <stdio.h> 1.9 +#include <stdlib.h> 1.10 +#include <string.h> 1.11 + 1.12 +#include "gdb-tests.h" 1.13 +#include "jsapi.h" 1.14 +#include "jsfriendapi.h" 1.15 + 1.16 +using namespace JS; 1.17 + 1.18 +/* The class of the global object. */ 1.19 +const JSClass global_class = { 1.20 + "global", JSCLASS_GLOBAL_FLAGS, 1.21 + JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, 1.22 + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, 1.23 + nullptr, nullptr, nullptr, nullptr, 1.24 + JS_GlobalObjectTraceHook 1.25 +}; 1.26 + 1.27 +template<typename T> 1.28 +static inline T * 1.29 +checkPtr(T *ptr) 1.30 +{ 1.31 + if (! ptr) 1.32 + abort(); 1.33 + return ptr; 1.34 +} 1.35 + 1.36 +static void 1.37 +checkBool(bool success) 1.38 +{ 1.39 + if (! success) 1.40 + abort(); 1.41 +} 1.42 + 1.43 +/* The error reporter callback. */ 1.44 +void reportError(JSContext *cx, const char *message, JSErrorReport *report) 1.45 +{ 1.46 + fprintf(stderr, "%s:%u: %s\n", 1.47 + report->filename ? report->filename : "<no filename>", 1.48 + (unsigned int) report->lineno, 1.49 + message); 1.50 +} 1.51 + 1.52 +// prolog.py sets a breakpoint on this function; test functions can call it 1.53 +// to easily return control to GDB where desired. 1.54 +void breakpoint() { 1.55 + // If we leave this function empty, the linker will unify it with other 1.56 + // empty functions throughout SpiderMonkey. If we then set a GDB 1.57 + // breakpoint on it, that breakpoint will hit at all sorts of random 1.58 + // times. So make it perform a distinctive side effect. 1.59 + fprintf(stderr, "Called " __FILE__ ":breakpoint\n"); 1.60 +} 1.61 + 1.62 +GDBFragment *GDBFragment::allFragments = nullptr; 1.63 + 1.64 +int 1.65 +main (int argc, const char **argv) 1.66 +{ 1.67 + if (!JS_Init()) return 1; 1.68 + JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024, JS_USE_HELPER_THREADS)); 1.69 + JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff); 1.70 + JS_SetNativeStackQuota(runtime, 5000000); 1.71 + 1.72 + JSContext *cx = checkPtr(JS_NewContext(runtime, 8192)); 1.73 + JS_SetErrorReporter(cx, reportError); 1.74 + 1.75 + JSAutoRequest ar(cx); 1.76 + 1.77 + /* Create the global object. */ 1.78 + JS::CompartmentOptions options; 1.79 + options.setVersion(JSVERSION_LATEST); 1.80 + RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class, 1.81 + nullptr, JS::FireOnNewGlobalHook, options))); 1.82 + js::SetDefaultObjectForContext(cx, global); 1.83 + 1.84 + JSAutoCompartment ac(cx, global); 1.85 + 1.86 + /* Populate the global object with the standard globals, 1.87 + like Object and Array. */ 1.88 + checkBool(JS_InitStandardClasses(cx, global)); 1.89 + 1.90 + argv++; 1.91 + while (*argv) { 1.92 + const char *name = *argv++; 1.93 + GDBFragment *fragment; 1.94 + for (fragment = GDBFragment::allFragments; fragment; fragment = fragment->next) { 1.95 + if (strcmp(fragment->name(), name) == 0) { 1.96 + fragment->run(cx, argv); 1.97 + break; 1.98 + } 1.99 + } 1.100 + if (!fragment) { 1.101 + fprintf(stderr, "Unrecognized fragment name: %s\n", name); 1.102 + exit(1); 1.103 + } 1.104 + } 1.105 + 1.106 + return 0; 1.107 +}