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