blob: 91ff93d76180aed8df3b8f42dce997e9a65c3670 [file] [log] [blame]
/* -*- 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 "tests.h"
#include "jsdbgapi.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);
JSFunction *fun;
CHECK(fun = JS_CompileFunction(cx, A, "f", 0, NULL, source, strlen(source), __FILE__, 1));
CHECK(obj = JS_GetFunctionObject(fun));
}
// clone into B
{
JSAutoCompartment b(cx, B);
CHECK(JS_CloneFunctionObject(cx, obj, B));
}
return true;
}
END_TEST(test_cloneScript)
void
DestroyPrincipals(JSPrincipals *principals)
{
delete principals;
}
struct Principals : public JSPrincipals
{
public:
Principals()
{
refcount = 0;
}
};
class AutoDropPrincipals
{
JSRuntime *rt;
JSPrincipals *principals;
public:
AutoDropPrincipals(JSRuntime *rt, JSPrincipals *principals)
: rt(rt), principals(principals)
{
JS_HoldPrincipals(principals);
}
~AutoDropPrincipals()
{
JS_DropPrincipals(rt, principals);
}
};
BEGIN_TEST(test_cloneScriptWithPrincipals)
{
JS_InitDestroyPrincipalsCallback(rt, DestroyPrincipals);
JSPrincipals *principalsA = new Principals();
AutoDropPrincipals dropA(rt, principalsA);
JSPrincipals *principalsB = new Principals();
AutoDropPrincipals dropB(rt, 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::RootedFunction fun(cx, JS_CompileFunctionForPrincipals(cx, A, principalsA, "f",
mozilla::ArrayLength(argnames), argnames,
source, strlen(source), __FILE__, 1));
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, B));
JSFunction *fun;
CHECK(fun = JS_ValueToFunction(cx, JS::ObjectValue(*cloned)));
JSScript *script;
CHECK(script = JS_GetFunctionScript(cx, fun));
CHECK(JS_GetScriptPrincipals(script) == principalsB);
JS::RootedValue v(cx);
JS::Value args[] = { JS::Int32Value(1) };
CHECK(JS_CallFunctionValue(cx, B, JS::ObjectValue(*cloned), 1, args, v.address()));
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)