Created
April 30, 2017 19:55
-
-
Save ptomato/8d112afe44f2b10972b92f4c2ae9fea0 to your computer and use it in GitHub Desktop.
how to get the lexical scope of an executed script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* g++ -g -Wno-invalid-offsetof -DDEBUG -std=c++11 -o lexical `pkg-config --cflags --libs mozjs-45` lexical.cpp */ | |
#include <iostream> | |
#include "js-config.h" | |
#include "jsapi.h" | |
#include "js/Initialization.h" | |
#include "jsfriendapi.h" | |
static JSClass global_class = { | |
"global", JSCLASS_GLOBAL_FLAGS, | |
nullptr, nullptr, nullptr, nullptr, nullptr, | |
nullptr, nullptr, nullptr, nullptr, nullptr, | |
nullptr, | |
JS_GlobalObjectTraceHook | |
}; | |
static bool | |
import1(JSContext *cx, const char *script, JS::MutableHandleObject module, | |
JS::MutableHandleObject lexical) | |
{ | |
module.set(JS_NewGlobalObject(cx, &global_class, nullptr, | |
JS::FireOnNewGlobalHook)); | |
JSAutoCompartment ac(cx, module); | |
JS::CompileOptions options(cx); | |
options.setUTF8(true); | |
JS::RootedValue dummy_retval(cx); | |
if (!JS::Evaluate(cx, options, script, strlen(script), &dummy_retval)) | |
return false; | |
lexical.set(JS_GlobalLexicalScope(module)); | |
return true; | |
} | |
static bool | |
import2(JSContext *cx, const char *script, JS::HandleObject global, | |
JS::MutableHandleObject module, JS::MutableHandleObject lexical) | |
{ | |
JS::CompileOptions options(cx); | |
options.setUTF8(true); | |
JS::RootedScript compiled_script(cx); | |
if (!JS::CompileForNonSyntacticScope(cx, options, script, strlen(script), | |
&compiled_script)) | |
return false; | |
/* This function says it should not be used */ | |
if (!js::ExecuteInGlobalAndReturnScope(cx, global, compiled_script, lexical)) | |
return false; | |
JS::RootedValue non_syntactic_variables(cx, JS_GetReservedSlot(lexical, 0)); | |
module.set(&non_syntactic_variables.toObject()); | |
return true; | |
} | |
int main(int argc, const char *argv[]) | |
{ | |
JS_Init(); | |
JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024); | |
JSContext *cx = JS_NewContext(rt, 8192); | |
{ | |
JSAutoRequest ar(cx); | |
JS::RootedObject global(cx, | |
JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook)); | |
JSAutoCompartment ac(cx, global); | |
JS_InitStandardClasses(cx, global); | |
const char *script = "var a = 1; let b = 2; const c = 3;"; | |
JS::RootedObject module(cx), lexical(cx); | |
std::cout << "---- Using ExecuteScript ----\n"; | |
if (!import1(cx, script, &module, &lexical)) | |
return 1; | |
js::DumpObject(module); | |
js::DumpObject(lexical); | |
std::cout << "--- Using ExecuteInGlobalAndReturnScope ----\n"; | |
module = nullptr; | |
lexical = nullptr; | |
if (!import2(cx, script, global, &module, &lexical)) | |
return 1; | |
js::DumpObject(module); | |
js::DumpObject(lexical); | |
} | |
JS_DestroyContext(cx); | |
JS_DestroyRuntime(rt); | |
JS_ShutDown(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---- Using ExecuteScript ---- | |
object 0x107b87060 from global 0x107b87060 [global] | |
class 0x1063682b0 global | |
flags: delegate varobj unqualified_varobj | |
proto null | |
reserved slots: | |
0 (reserved) = undefined | |
...etc... | |
154 (reserved) = undefined | |
155 (reserved) = <Block object at 0x107b88070> | |
156 (reserved) = undefined | |
...etc... | |
178 (reserved) = undefined | |
properties: | |
((js::Shape*) 0x107b86128) enumerate permanent JSString* (0x107b00940) = Latin1Char * (0x107b00948) = "a" | |
: slot 179 = 1 | |
object 0x107b88070 from global 0x107b87060 [global] | |
class 0x106cc0320 Block | |
flags: delegate | |
proto <Block object at 0x107b88040> | |
reserved slots: | |
0 (reserved) = <global object at 0x107b87060> | |
1 (reserved) = <global object at 0x107b87060> | |
properties: | |
((js::Shape*) 0x107b86150) enumerate permanent JSString* (0x107b00958) = Latin1Char * (0x107b00960) = "b" | |
: slot 2 = 2 | |
((js::Shape*) 0x107b86178) enumerate readonly permanent JSString* (0x107b00970) = Latin1Char * (0x107b00978) = "c" | |
: slot 3 = 3 | |
--- Using ExecuteInGlobalAndReturnScope ---- | |
object 0x107b63190 from global 0x107b62060 [global] | |
class 0x106cc01f8 NonSyntacticVariablesObject | |
flags: delegate varobj unqualified_varobj | |
proto null | |
reserved slots: | |
0 (reserved) = <Block object at 0x107b63070> | |
properties: | |
((js::Shape*) 0x107b83858) enumerate permanent JSString* (0x107b00940) = Latin1Char * (0x107b00948) = "a" | |
: slot 1 = 1 | |
object 0x107b631f0 from global 0x107b62060 [global] | |
class 0x106cc0320 Block | |
flags: delegate | |
proto <Block object at 0x107b631c0> | |
reserved slots: | |
0 (reserved) = <NonSyntacticVariablesObject object at 0x107b63190> | |
1 (reserved) = <global object at 0x107b62060> | |
properties: | |
((js::Shape*) 0x107b83880) enumerate permanent JSString* (0x107b00958) = Latin1Char * (0x107b00960) = "b" | |
: slot 2 = 2 | |
((js::Shape*) 0x107b838a8) enumerate readonly permanent JSString* (0x107b00970) = Latin1Char * (0x107b00978) = "c" | |
: slot 3 = 3 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment