summaryrefslogtreecommitdiffstats
path: root/js/src/jsapi-tests/testCloneScript.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/jsapi-tests/testCloneScript.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/jsapi-tests/testCloneScript.cpp')
-rw-r--r--js/src/jsapi-tests/testCloneScript.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/js/src/jsapi-tests/testCloneScript.cpp b/js/src/jsapi-tests/testCloneScript.cpp
new file mode 100644
index 000000000..c12831fcb
--- /dev/null
+++ b/js/src/jsapi-tests/testCloneScript.cpp
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ *
+ * Test script cloning.
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "jsfriendapi.h"
+#include "jsapi-tests/tests.h"
+
+BEGIN_TEST(test_cloneScript)
+{
+ JS::RootedObject A(cx, createGlobal());
+ JS::RootedObject B(cx, createGlobal());
+
+ CHECK(A);
+ CHECK(B);
+
+ const char* source =
+ "var i = 0;\n"
+ "var sum = 0;\n"
+ "while (i < 10) {\n"
+ " sum += i;\n"
+ " ++i;\n"
+ "}\n"
+ "(sum);\n";
+
+ JS::RootedObject obj(cx);
+
+ // compile for A
+ {
+ JSAutoCompartment a(cx, A);
+ JS::RootedFunction fun(cx);
+ JS::CompileOptions options(cx);
+ options.setFileAndLine(__FILE__, 1);
+ JS::AutoObjectVector emptyScopeChain(cx);
+ CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "f", 0, nullptr,
+ source, strlen(source), &fun));
+ CHECK(obj = JS_GetFunctionObject(fun));
+ }
+
+ // clone into B
+ {
+ JSAutoCompartment b(cx, B);
+ CHECK(JS::CloneFunctionObject(cx, obj));
+ }
+
+ return true;
+}
+END_TEST(test_cloneScript)
+
+struct Principals final : public JSPrincipals
+{
+ public:
+ Principals()
+ {
+ refcount = 0;
+ }
+
+ bool write(JSContext* cx, JSStructuredCloneWriter* writer) override {
+ MOZ_ASSERT(false, "not imlemented");
+ return false;
+ }
+};
+
+class AutoDropPrincipals
+{
+ JSContext* cx;
+ JSPrincipals* principals;
+
+ public:
+ AutoDropPrincipals(JSContext* cx, JSPrincipals* principals)
+ : cx(cx), principals(principals)
+ {
+ JS_HoldPrincipals(principals);
+ }
+
+ ~AutoDropPrincipals()
+ {
+ JS_DropPrincipals(cx, principals);
+ }
+};
+
+static void
+DestroyPrincipals(JSPrincipals* principals)
+{
+ auto p = static_cast<Principals*>(principals);
+ delete p;
+}
+
+BEGIN_TEST(test_cloneScriptWithPrincipals)
+{
+ JS_InitDestroyPrincipalsCallback(cx, DestroyPrincipals);
+
+ JSPrincipals* principalsA = new Principals();
+ AutoDropPrincipals dropA(cx, principalsA);
+ JSPrincipals* principalsB = new Principals();
+ AutoDropPrincipals dropB(cx, principalsB);
+
+ JS::RootedObject A(cx, createGlobal(principalsA));
+ JS::RootedObject B(cx, createGlobal(principalsB));
+
+ CHECK(A);
+ CHECK(B);
+
+ const char* argnames[] = { "arg" };
+ const char* source = "return function() { return arg; }";
+
+ JS::RootedObject obj(cx);
+
+ // Compile in A
+ {
+ JSAutoCompartment a(cx, A);
+ JS::CompileOptions options(cx);
+ options.setFileAndLine(__FILE__, 1);
+ JS::RootedFunction fun(cx);
+ JS::AutoObjectVector emptyScopeChain(cx);
+ JS::CompileFunction(cx, emptyScopeChain, options, "f",
+ mozilla::ArrayLength(argnames), argnames, source,
+ strlen(source), &fun);
+ CHECK(fun);
+
+ JSScript* script;
+ CHECK(script = JS_GetFunctionScript(cx, fun));
+
+ CHECK(JS_GetScriptPrincipals(script) == principalsA);
+ CHECK(obj = JS_GetFunctionObject(fun));
+ }
+
+ // Clone into B
+ {
+ JSAutoCompartment b(cx, B);
+ JS::RootedObject cloned(cx);
+ CHECK(cloned = JS::CloneFunctionObject(cx, obj));
+
+ JS::RootedFunction fun(cx);
+ JS::RootedValue clonedValue(cx, JS::ObjectValue(*cloned));
+ CHECK(fun = JS_ValueToFunction(cx, clonedValue));
+
+ JSScript* script;
+ CHECK(script = JS_GetFunctionScript(cx, fun));
+
+ CHECK(JS_GetScriptPrincipals(script) == principalsB);
+
+ JS::RootedValue v(cx);
+ JS::RootedValue arg(cx, JS::Int32Value(1));
+ CHECK(JS_CallFunctionValue(cx, B, clonedValue, JS::HandleValueArray(arg), &v));
+ CHECK(v.isObject());
+
+ JSObject* funobj = &v.toObject();
+ CHECK(JS_ObjectIsFunction(cx, funobj));
+ CHECK(fun = JS_ValueToFunction(cx, v));
+ CHECK(script = JS_GetFunctionScript(cx, fun));
+ CHECK(JS_GetScriptPrincipals(script) == principalsB);
+ }
+
+ return true;
+}
+END_TEST(test_cloneScriptWithPrincipals)