Skip to content

Instantly share code, notes, and snippets.

@ptomato
Created April 30, 2017 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptomato/8d112afe44f2b10972b92f4c2ae9fea0 to your computer and use it in GitHub Desktop.
Save ptomato/8d112afe44f2b10972b92f4c2ae9fea0 to your computer and use it in GitHub Desktop.
how to get the lexical scope of an executed script
/* 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;
}
---- 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