1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=99:
3 : *
4 : * Test script cloning.
5 : */
6 :
7 : #include "tests.h"
8 : #include "jsapi.h"
9 : #include "jsdbgapi.h"
10 : #include "jsxdrapi.h"
11 :
12 4 : BEGIN_TEST(test_cloneScript)
13 : {
14 : JSObject *A, *B;
15 :
16 1 : CHECK(A = createGlobal());
17 1 : CHECK(B = createGlobal());
18 :
19 : const char *source =
20 : "var i = 0;\n"
21 : "var sum = 0;\n"
22 : "while (i < 10) {\n"
23 : " sum += i;\n"
24 : " ++i;\n"
25 : "}\n"
26 1 : "(sum);\n";
27 :
28 : JSObject *obj;
29 :
30 : // compile for A
31 : {
32 2 : JSAutoEnterCompartment a;
33 1 : if (!a.enter(cx, A))
34 0 : return false;
35 :
36 : JSFunction *fun;
37 1 : CHECK(fun = JS_CompileFunction(cx, A, "f", 0, NULL, source, strlen(source), __FILE__, 1));
38 1 : CHECK(obj = JS_GetFunctionObject(fun));
39 : }
40 :
41 : // clone into B
42 : {
43 2 : JSAutoEnterCompartment b;
44 1 : if (!b.enter(cx, B))
45 0 : return false;
46 :
47 1 : CHECK(JS_CloneFunctionObject(cx, obj, B));
48 : }
49 :
50 1 : return true;
51 : }
52 1 : END_TEST(test_cloneScript)
53 :
54 : void
55 2 : DestroyPrincipals(JSPrincipals *principals)
56 : {
57 2 : delete principals;
58 2 : }
59 :
60 : struct Principals : public JSPrincipals
61 : {
62 : public:
63 2 : Principals()
64 2 : {
65 2 : refcount = 0;
66 2 : }
67 : };
68 :
69 : class AutoDropPrincipals
70 : {
71 : JSRuntime *rt;
72 : JSPrincipals *principals;
73 :
74 : public:
75 2 : AutoDropPrincipals(JSRuntime *rt, JSPrincipals *principals)
76 2 : : rt(rt), principals(principals)
77 : {
78 2 : JS_HoldPrincipals(principals);
79 2 : }
80 :
81 2 : ~AutoDropPrincipals()
82 : {
83 2 : JS_DropPrincipals(rt, principals);
84 2 : }
85 : };
86 :
87 4 : BEGIN_TEST(test_cloneScriptWithPrincipals)
88 : {
89 1 : JS_InitDestroyPrincipalsCallback(rt, DestroyPrincipals);
90 :
91 1 : JSPrincipals *principalsA = new Principals();
92 2 : AutoDropPrincipals dropA(rt, principalsA);
93 1 : JSPrincipals *principalsB = new Principals();
94 2 : AutoDropPrincipals dropB(rt, principalsB);
95 :
96 : JSObject *A, *B;
97 :
98 1 : CHECK(A = createGlobal(principalsA));
99 1 : CHECK(B = createGlobal(principalsB));
100 :
101 1 : const char *argnames[] = { "arg" };
102 1 : const char *source = "return function() { return arg; }";
103 :
104 : JSObject *obj;
105 :
106 : // Compile in A
107 : {
108 2 : JSAutoEnterCompartment a;
109 1 : if (!a.enter(cx, A))
110 0 : return false;
111 :
112 : JSFunction *fun;
113 1 : CHECK(fun = JS_CompileFunctionForPrincipals(cx, A, principalsA, "f",
114 : mozilla::ArrayLength(argnames), argnames,
115 : source, strlen(source), __FILE__, 1));
116 :
117 : JSScript *script;
118 1 : CHECK(script = JS_GetFunctionScript(cx, fun));
119 :
120 1 : CHECK(JS_GetScriptPrincipals(cx, script) == principalsA);
121 1 : CHECK(obj = JS_GetFunctionObject(fun));
122 : }
123 :
124 : // Clone into B
125 : {
126 2 : JSAutoEnterCompartment b;
127 1 : if (!b.enter(cx, B))
128 0 : return false;
129 :
130 : JSObject *cloned;
131 1 : CHECK(cloned = JS_CloneFunctionObject(cx, obj, B));
132 :
133 : JSFunction *fun;
134 1 : CHECK(fun = JS_ValueToFunction(cx, JS::ObjectValue(*cloned)));
135 :
136 : JSScript *script;
137 1 : CHECK(script = JS_GetFunctionScript(cx, fun));
138 :
139 1 : CHECK(JS_GetScriptPrincipals(cx, script) == principalsB);
140 :
141 : JS::Value v;
142 1 : JS::Value args[] = { JS::Int32Value(1) };
143 1 : CHECK(JS_CallFunctionValue(cx, B, JS::ObjectValue(*cloned), 1, args, &v));
144 1 : CHECK(v.isObject());
145 :
146 1 : JSObject *funobj = &v.toObject();
147 1 : CHECK(JS_ObjectIsFunction(cx, funobj));
148 1 : CHECK(fun = JS_ValueToFunction(cx, v));
149 1 : CHECK(script = JS_GetFunctionScript(cx, fun));
150 1 : CHECK(JS_GetScriptPrincipals(cx, script) == principalsB);
151 : }
152 :
153 1 : return true;
154 : }
155 3 : END_TEST(test_cloneScriptWithPrincipals)
|