Skip to content

Instantly share code, notes, and snippets.

@AndreasMadsen
Last active August 29, 2015 14:05
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 AndreasMadsen/f4891f3523c70cb28abd to your computer and use it in GitHub Desktop.
Save AndreasMadsen/f4891f3523c70cb28abd to your computer and use it in GitHub Desktop.
d8 --allow-natives-syntax test.js
function foo() {
var a = true;
var b = { "prop": "you" };
var c = "Bad Ass";
var d = ["my", "life", 0];
var locals = %LocalVariabels(foo);
print(JSON.stringify(locals));
}
foo();
index 08bc92c..393cc9a 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -14552,6 +14552,61 @@ RUNTIME_FUNCTION(Runtime_GetScript) {
}
+// Get variabels in this function scope
+RUNTIME_FUNCTION(Runtime_LocalVariabels) {
+ HandleScope scope(isolate);
+
+ DCHECK(args.length() == 1);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+ // Unpack the function scope
+ v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
+ SharedFunctionInfo* shared = function->shared();
+ ScopeInfo* scope_info = shared->scope_info();
+ Object* script_obj = shared->script();
+
+ if (script_obj->IsScript()) {
+ // Search the frames for a function match
+ JavaScriptFrame* frame;
+ bool found = false;
+
+ for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
+ frame = it.frame();
+ if (frame->function() == *function.location()) {
+ found = true;
+ break;
+ }
+ }
+
+ // function is not in active scope, stop here
+ if (!found) {
+ return isolate->heap()->undefined_value();
+ }
+
+ // Build an object containing the local variables
+ Local<v8::Object> locals = v8::Object::New(v8_isolate);
+
+ int stack_local_count = scope_info->StackLocalCount();
+
+ for (int i = 0; i < stack_local_count; i++) {
+ String* name = scope_info->StackLocalName(i);
+ const char* name_buf = name->ToCString().get();
+
+ locals->Set(
+ v8::Handle<v8::Value>::Cast(reinterpret_cast<v8::Handle<v8::String>>(handle(reinterpret_cast<v8::String*>(name), isolate))),
+ v8::Handle<v8::Value>::Cast(reinterpret_cast<v8::Handle<v8::Object>>(handle(reinterpret_cast<v8::Object*>(frame->GetExpression(i)), isolate)))
+ );
+ printf("print :: name: %s\n", name_buf);
+ }
+
+ return reinterpret_cast<Object*>(*locals);
+ }
+
+ return isolate->heap()->undefined_value();
+}
@AndreasMadsen
Copy link
Author

The casting on L50-51 is completely messed up, and won't compile.
But basically we need to go
from: v8::internal::String* to v8::Handle<v8::Value>
from: v8::internal::Object* to v8::Handle<v8::Value>
or find some other way of creating an object and setting the properties.

I have confirmed that scope_info->StackLocalName(i); returns the variable name, I believe that frame->GetExpression(i) returns the variable value.

@watson
Copy link

watson commented Aug 26, 2014

@AndreasMadsen Wow, that's a lot of progress! I've not been able to get anywhere near that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment