Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "PerfMeasurement.h"
7 : #include "jsperf.h"
8 : #include "mozilla/ModuleUtils.h"
9 : #include "nsMemory.h"
10 : #include "mozilla/Preferences.h"
11 : #include "mozJSComponentLoader.h"
12 : #include "nsZipArchive.h"
13 : #include "xpc_make_class.h"
14 :
15 : #define JSPERF_CONTRACTID \
16 : "@mozilla.org/jsperf;1"
17 :
18 : #define JSPERF_CID \
19 : { 0x421c38e6, 0xaee0, 0x4509, \
20 : { 0xa0, 0x25, 0x13, 0x0f, 0x43, 0x78, 0x03, 0x5a } }
21 :
22 : namespace mozilla {
23 : namespace jsperf {
24 :
25 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(Module)
26 :
27 0 : NS_IMPL_ISUPPORTS(Module, nsIXPCScriptable)
28 :
29 : Module::Module() = default;
30 :
31 : Module::~Module() = default;
32 :
33 : #define XPC_MAP_CLASSNAME Module
34 : #define XPC_MAP_QUOTED_CLASSNAME "Module"
35 : #define XPC_MAP_FLAGS XPC_SCRIPTABLE_WANT_CALL
36 : #include "xpc_map_end.h"
37 :
38 : static bool
39 0 : SealObjectAndPrototype(JSContext* cx, JS::Handle<JSObject *> parent, const char* name)
40 : {
41 0 : JS::Rooted<JS::Value> prop(cx);
42 0 : if (!JS_GetProperty(cx, parent, name, &prop))
43 0 : return false;
44 :
45 0 : if (prop.isUndefined()) {
46 : // Pretend we sealed the object.
47 0 : return true;
48 : }
49 :
50 0 : JS::Rooted<JSObject*> obj(cx, prop.toObjectOrNull());
51 0 : if (!JS_GetProperty(cx, obj, "prototype", &prop))
52 0 : return false;
53 :
54 0 : JS::Rooted<JSObject*> prototype(cx, prop.toObjectOrNull());
55 0 : return JS_FreezeObject(cx, obj) && JS_FreezeObject(cx, prototype);
56 : }
57 :
58 : static bool
59 0 : InitAndSealPerfMeasurementClass(JSContext* cx, JS::Handle<JSObject*> global)
60 : {
61 : // Init the PerfMeasurement class
62 0 : if (!JS::RegisterPerfMeasurement(cx, global))
63 0 : return false;
64 :
65 : // Seal up Object, Function, and Array and their prototypes. (This single
66 : // object instance is shared amongst everyone who imports the jsperf module.)
67 0 : if (!SealObjectAndPrototype(cx, global, "Object") ||
68 0 : !SealObjectAndPrototype(cx, global, "Function") ||
69 0 : !SealObjectAndPrototype(cx, global, "Array"))
70 0 : return false;
71 :
72 : // Finally, seal the global object, for good measure. (But not recursively;
73 : // this breaks things.)
74 0 : return JS_FreezeObject(cx, global);
75 : }
76 :
77 : NS_IMETHODIMP
78 0 : Module::Call(nsIXPConnectWrappedNative* wrapper,
79 : JSContext* cx,
80 : JSObject* obj,
81 : const JS::CallArgs& args,
82 : bool* _retval)
83 : {
84 :
85 0 : mozJSComponentLoader* loader = mozJSComponentLoader::Get();
86 0 : JS::Rooted<JSObject*> targetObj(cx);
87 0 : loader->FindTargetObject(cx, &targetObj);
88 :
89 0 : *_retval = InitAndSealPerfMeasurementClass(cx, targetObj);
90 0 : return NS_OK;
91 : }
92 :
93 : } // namespace jsperf
94 : } // namespace mozilla
95 :
96 : NS_DEFINE_NAMED_CID(JSPERF_CID);
97 :
98 : static const mozilla::Module::CIDEntry kPerfCIDs[] = {
99 : { &kJSPERF_CID, false, nullptr, mozilla::jsperf::ModuleConstructor },
100 : { nullptr }
101 : };
102 :
103 : static const mozilla::Module::ContractIDEntry kPerfContracts[] = {
104 : { JSPERF_CONTRACTID, &kJSPERF_CID },
105 : { nullptr }
106 : };
107 :
108 : static const mozilla::Module kPerfModule = {
109 : mozilla::Module::kVersion,
110 : kPerfCIDs,
111 : kPerfContracts
112 : };
113 :
114 : NSMODULE_DEFN(jsperf) = &kPerfModule;
|