1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "mozilla/Utf8.h" // mozilla::Utf8Unit
7 #include "js/CompilationAndEvaluation.h" // JS::Compile
8 #include "js/friend/JSMEnvironment.h" // JS::ExecuteInJSMEnvironment, JS::GetJSMEnvironmentOfScriptedCaller, JS::NewJSMEnvironment
9 #include "js/PropertyAndElement.h" // JS_DefineFunctions, JS_GetProperty, JS_SetProperty
10 #include "js/PropertySpec.h"
11 #include "js/SourceText.h" // JS::Source{Ownership,Text}
12 #include "jsapi-tests/tests.h"
13 #include "util/Text.h"
14 #include "vm/EnvironmentObject.h"
15 #include "vm/EnvironmentObject-inl.h"
17 BEGIN_TEST(testExecuteInJSMEnvironment_Basic
) {
18 static const char src
[] =
19 "var output = input;\n"
25 "eval('this.e = 5');\n"
26 "(0,eval)('this.f = 6');\n"
27 "(function() { this.g = 7; })();\n"
28 "function f_h() { this.h = 8; }; f_h();\n";
30 JS::CompileOptions
options(cx
);
31 options
.setFileAndLine(__FILE__
, __LINE__
);
32 options
.setNoScriptRval(true);
33 options
.setNonSyntacticScope(true);
35 JS::SourceText
<mozilla::Utf8Unit
> srcBuf
;
36 CHECK(srcBuf
.init(cx
, src
, js_strlen(src
), JS::SourceOwnership::Borrowed
));
38 JS::RootedScript
script(cx
, JS::Compile(cx
, options
, srcBuf
));
41 JS::RootedObject
varEnv(cx
, JS::NewJSMEnvironment(cx
));
42 JS::RootedObject
lexEnv(cx
, JS_ExtensibleLexicalEnvironment(varEnv
));
43 CHECK(varEnv
&& varEnv
->is
<js::NonSyntacticVariablesObject
>());
44 CHECK(lexEnv
&& js::IsExtensibleLexicalEnvironment(lexEnv
));
45 CHECK(lexEnv
->enclosingEnvironment() == varEnv
);
47 JS::RootedValue
vi(cx
, JS::Int32Value(1000));
48 CHECK(JS_SetProperty(cx
, varEnv
, "input", vi
));
50 CHECK(JS::ExecuteInJSMEnvironment(cx
, script
, varEnv
));
52 JS::RootedValue
v(cx
);
53 CHECK(JS_GetProperty(cx
, varEnv
, "output", &v
) && v
== vi
);
54 CHECK(JS_GetProperty(cx
, varEnv
, "a", &v
) && v
== JS::Int32Value(1));
55 CHECK(JS_GetProperty(cx
, varEnv
, "b", &v
) && v
== JS::Int32Value(2));
56 CHECK(JS_GetProperty(cx
, lexEnv
, "c", &v
) && v
== JS::Int32Value(3));
57 CHECK(JS_GetProperty(cx
, varEnv
, "d", &v
) && v
== JS::Int32Value(4));
58 CHECK(JS_GetProperty(cx
, varEnv
, "e", &v
) && v
== JS::Int32Value(5));
59 // TODO: Bug 1396050 will fix this
60 // CHECK(JS_GetProperty(cx, varEnv, "f", &v) && v == JS::Int32Value(6));
61 CHECK(JS_GetProperty(cx
, varEnv
, "g", &v
) && v
== JS::Int32Value(7));
62 CHECK(JS_GetProperty(cx
, varEnv
, "h", &v
) && v
== JS::Int32Value(8));
66 END_TEST(testExecuteInJSMEnvironment_Basic
);
68 static bool test_callback(JSContext
* cx
, unsigned argc
, JS::Value
* vp
) {
69 JS::RootedObject
env(cx
, JS::GetJSMEnvironmentOfScriptedCaller(cx
));
74 JS::CallArgs args
= JS::CallArgsFromVp(argc
, vp
);
75 args
.rval().setObject(*env
);
79 static const JSFunctionSpec testFunctions
[] = {
80 JS_FN("callback", test_callback
, 0, 0), JS_FS_END
};
82 BEGIN_TEST(testExecuteInJSMEnvironment_Callback
) {
83 static const char src
[] = "var output = callback();\n";
85 CHECK(JS_DefineFunctions(cx
, global
, testFunctions
));
87 JS::CompileOptions
options(cx
);
88 options
.setFileAndLine(__FILE__
, __LINE__
);
89 options
.setNoScriptRval(true);
90 options
.setNonSyntacticScope(true);
92 JS::SourceText
<mozilla::Utf8Unit
> srcBuf
;
93 CHECK(srcBuf
.init(cx
, src
, js_strlen(src
), JS::SourceOwnership::Borrowed
));
95 JS::RootedScript
script(cx
, JS::Compile(cx
, options
, srcBuf
));
98 JS::RootedObject
nsvo(cx
, JS::NewJSMEnvironment(cx
));
100 CHECK(JS::ExecuteInJSMEnvironment(cx
, script
, nsvo
));
102 JS::RootedValue
v(cx
);
103 CHECK(JS_GetProperty(cx
, nsvo
, "output", &v
) && v
== JS::ObjectValue(*nsvo
));
107 END_TEST(testExecuteInJSMEnvironment_Callback
)