From 888abb1bfd5be1cf185037285d963151a8584901 Mon Sep 17 00:00:00 2001 From: "ager@chromium.org" Date: Thu, 11 Sep 2008 13:00:30 +0000 Subject: [PATCH] Fix bug in function context slot lookup. There were two problems: we read at the wrong index in the scope information and we forgot to add Context::MIN_CONTEXT_SLOTS to the index. This fixes issue 24. Review URL: http://codereview.chromium.org/1938 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@279 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/log.cc | 2 +- src/log.h | 2 +- src/scopeinfo.cc | 11 +++++--- test/mjsunit/with-function-expression.js | 36 ++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 test/mjsunit/with-function-expression.js diff --git a/src/log.cc b/src/log.cc index a9600d654..92d18d0b8 100644 --- a/src/log.cc +++ b/src/log.cc @@ -434,7 +434,7 @@ void Logger::RegExpExecEvent(Handle regexp, fprintf(logfile_, "regexp-run,"); LogRegExpSource(regexp); - fprintf(logfile_, ",0x%08x,%d..%d\n", + fprintf(logfile_, ",0x%08x,%d..%d\n", input_string->Hash(), start_index, input_string->length()); #endif } diff --git a/src/log.h b/src/log.h index e481447b4..1e67fe948 100644 --- a/src/log.h +++ b/src/log.h @@ -54,7 +54,7 @@ namespace v8 { namespace internal { // is off. --log-gc implies --log. // // --log-regexp -// Log creation and use of regular expressions, Default is off. +// Log creation and use of regular expressions, Default is off. // --log-regexp implies --log. // // --logfile diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc index b51cb986f..64706b5eb 100644 --- a/src/scopeinfo.cc +++ b/src/scopeinfo.cc @@ -484,10 +484,13 @@ int ScopeInfo::FunctionContextSlotIndex(Code* code, String* name) { ASSERT(name->IsSymbol()); if (code->sinfo_size() > 0) { Object** p = &Memory::Object_at(code->sinfo_start()); - if (*p++ == name) { - int n; - ReadInt(p, &n); // n = number of context slots - return n -1; // the function context slot is the last entry + if (*p == name) { + p = ContextEntriesAddr(code); + int n; // number of context slots + ReadInt(p, &n); + ASSERT(n != 0); + // The function context slot is the last entry. + return n + Context::MIN_CONTEXT_SLOTS - 1; } } return -1; diff --git a/test/mjsunit/with-function-expression.js b/test/mjsunit/with-function-expression.js new file mode 100644 index 000000000..17de8175d --- /dev/null +++ b/test/mjsunit/with-function-expression.js @@ -0,0 +1,36 @@ +// Copyright 2008 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. + +var source = "(function x() { with({}) { return '' + x; } })()"; + +// Don't throw exceptions. +assertDoesNotThrow(source); + +// Check that the return value is a function. Use regexp to avoid +// depending on the exact printing of the function. +var regexp = /function/; +var res = assertTrue(eval(source).match(regexp) == 'function'); -- 2.34.1