Revert "Fix a bug in scope analysis."

This reverts commit revision 8838.

TBR=ricow@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/7584005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8839 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2011-08-05 09:20:08 +00:00
parent b625ce2b6b
commit 3e28347d55
8 changed files with 74 additions and 128 deletions

View File

@ -3534,13 +3534,35 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) {
}
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
BOOL_ACCESSORS(SharedFunctionInfo,
compiler_hints,
strict_mode,
kStrictModeFunction)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
name_should_print_as_anonymous,
kNameShouldPrintAsAnonymous)
BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
bool SharedFunctionInfo::native() {
return BooleanBit::get(compiler_hints(), kNative);
}
void SharedFunctionInfo::set_native(bool value) {
set_compiler_hints(BooleanBit::set(compiler_hints(),
kNative,
value));
}
bool SharedFunctionInfo::bound() {
return BooleanBit::get(compiler_hints(), kBoundFunction);
}
void SharedFunctionInfo::set_bound(bool value) {
set_compiler_hints(BooleanBit::set(compiler_hints(),
kBoundFunction,
value));
}
ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)

View File

@ -4730,13 +4730,6 @@ class SharedFunctionInfo: public HeapObject {
inline bool native();
inline void set_native(bool value);
// Indicates that the function was created by the Function function.
// Though it's anonymous, toString should treat it as if it had the name
// "anonymous". We don't set the name itself so that the system does not
// see a binding for it.
inline bool name_should_print_as_anonymous();
inline void set_name_should_print_as_anonymous(bool flag);
// Indicates whether the function is a bound function created using
// the bind function.
inline bool bound();
@ -4922,6 +4915,7 @@ class SharedFunctionInfo: public HeapObject {
// Bit positions in compiler_hints.
static const int kCodeAgeSize = 3;
static const int kCodeAgeMask = (1 << kCodeAgeSize) - 1;
static const int kBoundFunction = 9;
enum CompilerHints {
kHasOnlySimpleThisPropertyAssignments,
@ -4932,10 +4926,7 @@ class SharedFunctionInfo: public HeapObject {
kStrictModeFunction,
kUsesArguments,
kHasDuplicateParameters,
kNative,
kBoundFunction,
kNameShouldPrintAsAnonymous,
kCompilerHintsCount // Pseudo entry
kNative
};
private:
@ -4949,9 +4940,6 @@ class SharedFunctionInfo: public HeapObject {
static const int kCompilerHintsSize = kIntSize;
#endif
STATIC_ASSERT(SharedFunctionInfo::kCompilerHintsCount <=
SharedFunctionInfo::kCompilerHintsSize * kBitsPerByte);
public:
// Constants for optimizing codegen for strict mode function and
// native tests.

View File

@ -2842,11 +2842,8 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
CHECK_OK);
}
result = ParseFunctionLiteral(name,
is_strict_reserved_name,
function_token_position,
EXPRESSION,
CHECK_OK);
result = ParseFunctionLiteral(name, is_strict_reserved_name,
function_token_position, NESTED, CHECK_OK);
} else {
result = ParsePrimaryExpression(CHECK_OK);
}
@ -3415,7 +3412,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
ParseFunctionLiteral(name,
false, // reserved words are allowed here
RelocInfo::kNoPosition,
EXPRESSION,
DECLARATION,
CHECK_OK);
// Allow any number of parameters for compatiabilty with JSC.
// Specification only allows zero parameters for get and one for set.
@ -3622,23 +3619,25 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
}
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
bool name_is_strict_reserved,
int function_token_position,
FunctionLiteralType type,
bool* ok) {
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
bool has_name = !function_name.is_null();
// The function's name, empty if the function is anonymous.
if (!has_name) {
function_name = isolate()->factory()->empty_symbol();
}
bool is_named = !var_name.is_null();
// The name of a named function expression, otherwise an empty handle.
Handle<String> self_name;
if (type == EXPRESSION && function_name->length() > 0) {
self_name = function_name;
// The name associated with this function. If it's a function expression,
// this is the actual function name, otherwise this is the name of the
// variable declared and initialized with the function (expression). In
// that case, we don't have a function name (it's empty).
Handle<String> name =
is_named ? var_name : isolate()->factory()->empty_symbol();
// The function name, if any.
Handle<String> function_name = isolate()->factory()->empty_symbol();
if (is_named && (type == EXPRESSION || type == NESTED)) {
function_name = name;
}
int num_parameters = 0;
@ -3656,7 +3655,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
bool has_duplicate_parameters = false;
// Parse function body.
{ LexicalScope lexical_scope(this, scope, isolate());
top_scope_->SetScopeName(function_name);
top_scope_->SetScopeName(name);
// FormalParameterList ::
// '(' (Identifier)*[','] ')'
@ -3706,10 +3705,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
// NOTE: We create a proxy and resolve it here so that in the
// future we can change the AST to only refer to VariableProxies
// instead of Variables and Proxis as is the case now.
if (!self_name.is_null()) {
Variable* fvar = top_scope_->DeclareFunctionVar(self_name);
if (!function_name.is_null() && function_name->length() > 0) {
Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
VariableProxy* fproxy =
top_scope_->NewUnresolved(self_name, inside_with());
top_scope_->NewUnresolved(function_name, inside_with());
fproxy->BindTo(fvar);
body->Add(new(zone()) ExpressionStatement(
new(zone()) Assignment(isolate(),
@ -3740,7 +3739,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
end_pos = entry.end_pos();
if (end_pos <= function_block_pos) {
// End position greater than end of stream is safe, and hard to check.
ReportInvalidPreparseData(function_name, CHECK_OK);
ReportInvalidPreparseData(name, CHECK_OK);
}
isolate()->counters()->total_preparse_skipped()->Increment(
end_pos - function_block_pos);
@ -3770,7 +3769,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
// Validate strict mode.
if (top_scope_->is_strict_mode()) {
if (IsEvalOrArguments(function_name)) {
if (IsEvalOrArguments(name)) {
int position = function_token_position != RelocInfo::kNoPosition
? function_token_position
: (start_pos > 0 ? start_pos - 1 : start_pos);
@ -3814,7 +3813,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
FunctionLiteral* function_literal =
new(zone()) FunctionLiteral(isolate(),
function_name,
name,
scope,
body,
materialized_literal_count,
@ -3824,11 +3823,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
num_parameters,
start_pos,
end_pos,
type == EXPRESSION,
(function_name->length() > 0),
has_duplicate_parameters);
function_literal->set_function_token_position(function_token_position);
if (fni_ != NULL && !has_name) fni_->AddFunction(function_literal);
if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
return function_literal;
}

View File

@ -554,7 +554,8 @@ class Parser {
enum FunctionLiteralType {
EXPRESSION,
DECLARATION
DECLARATION,
NESTED
};
ZoneList<Expression*>* ParseArguments(bool* ok);

View File

@ -615,7 +615,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
ASSERT(args.length() == 1);
Object* obj = args[0];
return isolate->heap()->ToBoolean(obj->IsJSProxy());
return obj->IsJSProxy()
? isolate->heap()->true_value() : isolate->heap()->false_value();
}
@ -1037,7 +1038,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
ASSERT(proto->IsJSGlobalObject());
obj = JSObject::cast(proto);
}
return isolate->heap()->ToBoolean(obj->map()->is_extensible());
return obj->map()->is_extensible() ? isolate->heap()->true_value()
: isolate->heap()->false_value();
}
@ -1103,7 +1105,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
Map::cast(new_map)->set_is_access_check_needed(false);
object->set_map(Map::cast(new_map));
}
return isolate->heap()->ToBoolean(needs_access_checks);
return needs_access_checks ? isolate->heap()->true_value()
: isolate->heap()->false_value();
}
@ -1914,24 +1917,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSFunction, f, args[0]);
return isolate->heap()->ToBoolean(
f->shared()->name_should_print_as_anonymous());
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSFunction, f, args[0]);
f->shared()->set_name_should_print_as_anonymous(true);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@ -2112,7 +2097,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSFunction, f, args[0]);
return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
return f->shared()->IsApiFunction() ? isolate->heap()->true_value()
: isolate->heap()->false_value();
}
@ -2121,7 +2107,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSFunction, f, args[0]);
return isolate->heap()->ToBoolean(f->IsBuiltin());
return f->IsBuiltin() ? isolate->heap()->true_value() :
isolate->heap()->false_value();
}
@ -9993,7 +9980,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
details->set(0, *value);
details->set(1, property_details);
if (hasJavaScriptAccessors) {
details->set(2, isolate->heap()->ToBoolean(caught_exception));
details->set(2,
caught_exception ? isolate->heap()->true_value()
: isolate->heap()->false_value());
details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
}
@ -12176,7 +12165,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
#ifdef LIVE_OBJECT_LIST
CONVERT_SMI_ARG_CHECKED(id, 0);
bool success = LiveObjectList::Delete(id);
return isolate->heap()->ToBoolean(success);
return success ? isolate->heap()->true_value() :
isolate->heap()->false_value();
#else
return isolate->heap()->undefined_value();
#endif

View File

@ -214,8 +214,6 @@ namespace internal {
F(FunctionSetReadOnlyPrototype, 1, 1) \
F(FunctionGetName, 1, 1) \
F(FunctionSetName, 2, 1) \
F(FunctionNameShouldPrintAsAnonymous, 1, 1) \
F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1) \
F(FunctionSetBound, 1, 1) \
F(FunctionRemovePrototype, 1, 1) \
F(FunctionGetSourceCode, 1, 1) \

View File

@ -1,4 +1,4 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2006-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:
@ -1428,9 +1428,7 @@ function FunctionSourceString(func) {
}
}
var name = %FunctionNameShouldPrintAsAnonymous(func)
? 'anonymous'
: %FunctionGetName(func);
var name = %FunctionGetName(func);
return 'function ' + name + source;
}
@ -1525,7 +1523,7 @@ function NewFunction(arg1) { // length == 1
// The call to SetNewFunctionAttributes will ensure the prototype
// property of the resulting function is enumerable (ECMA262, 15.3.5.2).
var f = %CompileString(source)();
%FunctionMarkNameShouldPrintAsAnonymous(f);
%FunctionSetName(f, "anonymous");
return %SetNewFunctionAttributes(f);
}

View File

@ -1,50 +0,0 @@
// Copyright 2011 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
// Regression test for a bug in recompilation of anonymous functions inside
// catch. We would incorrectly hoist them outside the catch in some cases.
function f() {
try {
throw 0;
} catch (e) {
try {
var x = { a: 'hest' };
x.m = function (e) { return x.a; };
} catch (e) {
}
}
return x;
}
var o = f();
assertEquals('hest', o.m());
assertEquals('hest', o.m());
assertEquals('hest', o.m());
%OptimizeFunctionOnNextCall(o.m);
assertEquals('hest', o.m());