michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "gdb-tests.h" michael@0: #include "jsapi.h" michael@0: #include "jsfriendapi.h" michael@0: michael@0: using namespace JS; michael@0: michael@0: /* The class of the global object. */ michael@0: const JSClass global_class = { michael@0: "global", JSCLASS_GLOBAL_FLAGS, michael@0: JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, michael@0: JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, michael@0: nullptr, nullptr, nullptr, nullptr, michael@0: JS_GlobalObjectTraceHook michael@0: }; michael@0: michael@0: template michael@0: static inline T * michael@0: checkPtr(T *ptr) michael@0: { michael@0: if (! ptr) michael@0: abort(); michael@0: return ptr; michael@0: } michael@0: michael@0: static void michael@0: checkBool(bool success) michael@0: { michael@0: if (! success) michael@0: abort(); michael@0: } michael@0: michael@0: /* The error reporter callback. */ michael@0: void reportError(JSContext *cx, const char *message, JSErrorReport *report) michael@0: { michael@0: fprintf(stderr, "%s:%u: %s\n", michael@0: report->filename ? report->filename : "", michael@0: (unsigned int) report->lineno, michael@0: message); michael@0: } michael@0: michael@0: // prolog.py sets a breakpoint on this function; test functions can call it michael@0: // to easily return control to GDB where desired. michael@0: void breakpoint() { michael@0: // If we leave this function empty, the linker will unify it with other michael@0: // empty functions throughout SpiderMonkey. If we then set a GDB michael@0: // breakpoint on it, that breakpoint will hit at all sorts of random michael@0: // times. So make it perform a distinctive side effect. michael@0: fprintf(stderr, "Called " __FILE__ ":breakpoint\n"); michael@0: } michael@0: michael@0: GDBFragment *GDBFragment::allFragments = nullptr; michael@0: michael@0: int michael@0: main (int argc, const char **argv) michael@0: { michael@0: if (!JS_Init()) return 1; michael@0: JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024, JS_USE_HELPER_THREADS)); michael@0: JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff); michael@0: JS_SetNativeStackQuota(runtime, 5000000); michael@0: michael@0: JSContext *cx = checkPtr(JS_NewContext(runtime, 8192)); michael@0: JS_SetErrorReporter(cx, reportError); michael@0: michael@0: JSAutoRequest ar(cx); michael@0: michael@0: /* Create the global object. */ michael@0: JS::CompartmentOptions options; michael@0: options.setVersion(JSVERSION_LATEST); michael@0: RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class, michael@0: nullptr, JS::FireOnNewGlobalHook, options))); michael@0: js::SetDefaultObjectForContext(cx, global); michael@0: michael@0: JSAutoCompartment ac(cx, global); michael@0: michael@0: /* Populate the global object with the standard globals, michael@0: like Object and Array. */ michael@0: checkBool(JS_InitStandardClasses(cx, global)); michael@0: michael@0: argv++; michael@0: while (*argv) { michael@0: const char *name = *argv++; michael@0: GDBFragment *fragment; michael@0: for (fragment = GDBFragment::allFragments; fragment; fragment = fragment->next) { michael@0: if (strcmp(fragment->name(), name) == 0) { michael@0: fragment->run(cx, argv); michael@0: break; michael@0: } michael@0: } michael@0: if (!fragment) { michael@0: fprintf(stderr, "Unrecognized fragment name: %s\n", name); michael@0: exit(1); michael@0: } michael@0: } michael@0: michael@0: return 0; michael@0: }