Oh, Hi Ben.

Thanks for the tip. I have tried ScopeInfo::CopyContextLocalsToScopeObject 
but
it doesn't help. As far as I can see it is only better way of doing the "Add 
context
containing declarations" part.

Now knowing about ScopeInfo::CopyContextLocalsToScopeObject, I see now
that I should be using the MaterializeLocalScope convenience function. But
unfortunately this did not help either.

*Update patch attached. Same error.*

Den lørdag den 30. august 2014 17.16.44 UTC+2 skrev Ben Noordhuis:
>
> On Sat, Aug 30, 2014 at 1:51 PM, Andreas Madsen <[email protected] 
> <javascript:>> wrote: 
> > I'm trying to suggest a change for v8 there will extend the frame 
> objects 
> > there can be obtained using Error.prepareStackTrace, so they also have 
> > a getFunctionArguments and a getFunctionVariabels method. As this is 
> > quite useful for understanding the cause of runtime errors. 
> > 
> > See attachment for .patch file. 
> > 
> > However there is an issue in the added test. The error is caused by the 
> > optimization of the test function. I have tried to solve it using the 
> > FrameInspector but without luck. I hope someone kind can help me solve 
> > the issue. 
> > The error output can be seen below. 
> > 
> > ======================================================== 
> > ./d8 --allow-natives-syntax test/mjsunit/mjsunit.js 
> > test/mjsunit/local-variabels.js 
> > 
> > ["param_def","param_undef","inner","locals"] 
> > ["outer","deep"] 
> > ["param_def","param_undef","inner","locals"] 
> > ["outer","deep"] 
> > ["param_def","param_undef","inner","locals"] 
> > ["outer","deep"] 
> > test/mjsunit/mjsunit.js:178: Failure: expected <"outer-scope"> found 
> > <undefined> 
> >     throw new MjsUnitAssertionError(message); 
> >           ^ 
> > Error 
> >     at new MjsUnitAssertionError (test/mjsunit/mjsunit.js:31:16) 
> >     at fail (test/mjsunit/mjsunit.js:178:11) 
> >     at assertEquals (test/mjsunit/mjsunit.js:259:7) 
> >     at deep (test/mjsunit/local-variabels.js:51:39) 
> >     at test (test/mjsunit/local-variabels.js:54:3) 
> >     at test/mjsunit/local-variabels.js:60:1 
> > ======================================================== 
> > 
> > ======================================================== 
> > ./d8 --turbo-filter="*" --allow-natives-syntax test/mjsunit/mjsunit.js 
> > test/mjsunit/local-variabels.js 
> > ["param_def","param_undef","inner","locals"] 
> > ["outer","deep"] 
> > ["param_def","param_undef","inner","locals"] 
> > ["outer","deep"] 
> > ["param_def","param_undef","inner","locals"] 
> > 
> > \# 
> > \# Fatal error in ../src/deoptimizer.cc, line 151 
> > \# CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex) 
> failed 
> > \#   Value: 268435455 
> > \# 
> > 
> > ==== C stack trace =============================== 
> > 
> >  1: ?? 
> >  2: ?? 
> >  3: ?? 
> >  4: ?? 
> > ======================================================== 
>
> Hi Andreas, I didn't test it but, looking at the patch, I think 
> ScopeInfo::CopyContextLocalsToScopeObject() with |locals| as the 
> target should get you access to |outer|. 
>

-- 
-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
>From a922dca16686c8446a1f8e06501c294a7ff3f9fc Mon Sep 17 00:00:00 2001
From: Andreas Madsen <[email protected]>
Date: Tue, 26 Aug 2014 21:49:55 +0200
Subject: [PATCH] Extend frame object to include variabel info

The frame objects there can be obtained using Error.prepareStackTrace,
now also have a getFunctionArguments and a getFunctionVariabels method.

This is useful for understanding the cause of runtime errors.
---
 src/messages.js                            | 10 +++++
 src/runtime.cc                             | 42 +++++++++++++++++++++
 src/runtime.h                              |  1 +
 test/mjsunit/local-variabels.js            | 60 ++++++++++++++++++++++++++++++
 test/mjsunit/runtime-gen/localvariabels.js |  6 +++
 tools/generate-runtime-tests.py            |  6 +--
 6 files changed, 122 insertions(+), 3 deletions(-)
 create mode 100644 test/mjsunit/local-variabels.js
 create mode 100644 test/mjsunit/runtime-gen/localvariabels.js

diff --git a/src/messages.js b/src/messages.js
index c86c12d..3559793 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -801,6 +801,14 @@ function CallSiteGetFunction() {
       ? UNDEFINED : GET_PRIVATE(this, CallSiteFunctionKey);
 }
 
+function CallSiteGetFunctionArguments() {
+  return GET_PRIVATE(this, CallSiteFunctionKey).arguments;
+}
+
+function CallSiteGetFunctionVariables() {
+  return %LocalVariabels(GET_PRIVATE(this, CallSiteFunctionKey));
+}
+
 function CallSiteGetFunctionName() {
   // See if the function knows its own name
   var name = GET_PRIVATE(this, CallSiteFunctionKey).name;
@@ -973,6 +981,8 @@ SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array(
   "getEvalOrigin", CallSiteGetEvalOrigin,
   "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
   "getFunction", CallSiteGetFunction,
+  "getFunctionVariabels", CallSiteGetFunctionVariables,
+  "getFunctionArguments", CallSiteGetFunctionArguments,
   "getFunctionName", CallSiteGetFunctionName,
   "getMethodName", CallSiteGetMethodName,
   "getFileName", CallSiteGetFileName,
diff --git a/src/runtime.cc b/src/runtime.cc
index c69882f..d554207 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -14559,6 +14559,48 @@ RUNTIME_FUNCTION(Runtime_GetScript) {
 }
 
 
+// Advances the iterator to the frame that matches the fuction and returns the
+// inlined frame index, or -1 if not found.
+static int FindJSFrameIndexFromFunction(JavaScriptFrameIterator* it,
+                                        JSFunction* function) {
+  for (; !it->done(); it->Advance()) {
+    List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
+    it->frame()->Summarize(&frames);
+    for (int i = frames.length() - 1; i >= 0; i--) {
+      if (*frames[i].function().location() == function) return i;
+    }
+  }
+  return -1;
+}
+
+
+// Get variabels in this function scope
+RUNTIME_FUNCTION(Runtime_LocalVariabels) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+  // Function must be in script
+  if (!function->shared()->script()->IsScript()) {
+    return isolate->heap()->null_value();
+  }
+
+  // Search the frames for a function match and create a frame inspector
+  JavaScriptFrameIterator it(isolate);
+  int inlined_jsframe_index =
+      FindJSFrameIndexFromFunction(&it, *function.location());
+  if (inlined_jsframe_index == -1) {
+    // function is not in active scope, stop here
+    return isolate->heap()->null_value();
+  }
+
+  Handle<Object> locals;
+  MaterializeLocalScope(isolate, it.frame(), inlined_jsframe_index).ToHandle(&locals);
+  return *locals.location();
+}
+
+
 // Collect the raw data for a stack trace.  Returns an array of 4
 // element segments each containing a receiver, function, code and
 // native code offset.
diff --git a/src/runtime.h b/src/runtime.h
index ef42b52..519747e 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -207,6 +207,7 @@ namespace internal {
   F(FunctionIsAPIFunction, 1, 1)                                      \
   F(FunctionIsBuiltin, 1, 1)                                          \
   F(GetScript, 1, 1)                                                  \
+  F(LocalVariabels, 1, 1)                                             \
   F(CollectStackTrace, 2, 1)                                          \
   F(GetV8Version, 0, 1)                                               \
                                                                       \
diff --git a/test/mjsunit/local-variabels.js b/test/mjsunit/local-variabels.js
new file mode 100644
index 0000000..3ef7074
--- /dev/null
+++ b/test/mjsunit/local-variabels.js
@@ -0,0 +1,60 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function hidden() { }
+
+function test() {
+  var outer = "outer-scope";
+
+  function deep(param_def, param_undef) {
+    var inner = "inner-scope";
+    var locals;
+
+    locals = %LocalVariabels(deep);
+    print(JSON.stringify(Object.keys(locals)));
+    assertEquals(4, Object.keys(locals).length);
+    assertEquals("inner-scope", locals.inner);
+    assertEquals("parameter", locals.param_def);
+    assertEquals(undefined, locals.param_undef);
+    assertEquals(undefined, locals.locals);
+
+    locals = %LocalVariabels(test);
+    print(JSON.stringify(Object.keys(locals)));
+    assertEquals(2, Object.keys(locals).length);
+    assertEquals(deep, locals.deep);
+    assertEquals("outer-scope", locals.outer);
+  }
+
+  deep("parameter");
+}
+
+test();
+test();
+%OptimizeFunctionOnNextCall(test);
+test();
diff --git a/test/mjsunit/runtime-gen/localvariabels.js b/test/mjsunit/runtime-gen/localvariabels.js
new file mode 100644
index 0000000..d8247e0
--- /dev/null
+++ b/test/mjsunit/runtime-gen/localvariabels.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony --harmony-proxies
+var _locals = new Object();
+var _function = function() {};
+%LocalVariabels(_locals, _function);
diff --git a/tools/generate-runtime-tests.py b/tools/generate-runtime-tests.py
index 50970b4..d4a45d0 100755
--- a/tools/generate-runtime-tests.py
+++ b/tools/generate-runtime-tests.py
@@ -47,11 +47,11 @@ EXPAND_MACROS = [
 # that the parser doesn't bit-rot. Change the values as needed when you add,
 # remove or change runtime functions, but make sure we don't lose our ability
 # to parse them!
-EXPECTED_FUNCTION_COUNT = 431
-EXPECTED_FUZZABLE_COUNT = 332
+EXPECTED_FUNCTION_COUNT = 432
+EXPECTED_FUZZABLE_COUNT = 333
 EXPECTED_CCTEST_COUNT = 7
 EXPECTED_UNKNOWN_COUNT = 17
-EXPECTED_BUILTINS_COUNT = 808
+EXPECTED_BUILTINS_COUNT = 810
 
 
 # Don't call these at all.
-- 
2.0.4

Reply via email to