Commit 19f04d16 authored by ager@chromium.org's avatar ager@chromium.org

Revert eval changes since there is a crash that I don't have the time

to fix now.

TBR=kasperl
Review URL: http://codereview.chromium.org/20458

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1302 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cafe25f2
...@@ -256,11 +256,6 @@ class CodeGenerator: public AstVisitor { ...@@ -256,11 +256,6 @@ class CodeGenerator: public AstVisitor {
MemOperand SlotOperand(Slot* slot, Register tmp); MemOperand SlotOperand(Slot* slot, Register tmp);
MemOperand ContextSlotOperandCheckExtensions(Slot* slot,
Register tmp,
Register tmp2,
Label* slow);
// Expressions // Expressions
MemOperand GlobalObject() const { MemOperand GlobalObject() const {
return ContextOperand(cp, Context::GLOBAL_INDEX); return ContextOperand(cp, Context::GLOBAL_INDEX);
...@@ -277,11 +272,6 @@ class CodeGenerator: public AstVisitor { ...@@ -277,11 +272,6 @@ class CodeGenerator: public AstVisitor {
// Read a value from a slot and leave it on top of the expression stack. // Read a value from a slot and leave it on top of the expression stack.
void LoadFromSlot(Slot* slot, TypeofState typeof_state); void LoadFromSlot(Slot* slot, TypeofState typeof_state);
void LoadFromGlobalSlotCheckExtensions(Slot* slot,
TypeofState typeof_state,
Register tmp,
Register tmp2,
Label* slow);
// Special code for typeof expressions: Unfortunately, we must // Special code for typeof expressions: Unfortunately, we must
// be careful when loading the expression in 'typeof' // be careful when loading the expression in 'typeof'
......
...@@ -267,9 +267,6 @@ class CodeGenerator: public AstVisitor { ...@@ -267,9 +267,6 @@ class CodeGenerator: public AstVisitor {
Operand SlotOperand(Slot* slot, Register tmp); Operand SlotOperand(Slot* slot, Register tmp);
Operand ContextSlotOperandCheckExtensions(Slot* slot,
Register tmp,
Label* slow);
// Expressions // Expressions
Operand GlobalObject() const { Operand GlobalObject() const {
...@@ -287,10 +284,6 @@ class CodeGenerator: public AstVisitor { ...@@ -287,10 +284,6 @@ class CodeGenerator: public AstVisitor {
// Read a value from a slot and leave it on top of the expression stack. // Read a value from a slot and leave it on top of the expression stack.
void LoadFromSlot(Slot* slot, TypeofState typeof_state); void LoadFromSlot(Slot* slot, TypeofState typeof_state);
void LoadFromGlobalSlotCheckExtensions(Slot* slot,
TypeofState typeof_state,
Register tmp,
Label* slow);
// Special code for typeof expressions: Unfortunately, we must // Special code for typeof expressions: Unfortunately, we must
// be careful when loading the expression in 'typeof' // be careful when loading the expression in 'typeof'
......
...@@ -134,12 +134,10 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, ...@@ -134,12 +134,10 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
// declared variables that were introduced through declaration nodes) // declared variables that were introduced through declaration nodes)
// must not appear here. // must not appear here.
switch (mode) { switch (mode) {
case Variable::INTERNAL: // fall through case Variable::INTERNAL : // fall through
case Variable::VAR: *attributes = NONE; break; case Variable::VAR : *attributes = NONE; break;
case Variable::CONST: *attributes = READ_ONLY; break; case Variable::CONST : *attributes = READ_ONLY; break;
case Variable::DYNAMIC: UNREACHABLE(); break; case Variable::DYNAMIC : UNREACHABLE(); break;
case Variable::DYNAMIC_GLOBAL: UNREACHABLE(); break;
case Variable::DYNAMIC_LOCAL: UNREACHABLE(); break;
case Variable::TEMPORARY: UNREACHABLE(); break; case Variable::TEMPORARY: UNREACHABLE(); break;
} }
return context; return context;
......
...@@ -139,7 +139,6 @@ Scope::Scope(Scope* outer_scope, Type type) ...@@ -139,7 +139,6 @@ Scope::Scope(Scope* outer_scope, Type type)
scope_calls_eval_(false), scope_calls_eval_(false),
outer_scope_calls_eval_(false), outer_scope_calls_eval_(false),
inner_scope_calls_eval_(false), inner_scope_calls_eval_(false),
outer_scope_is_eval_scope_(false),
force_eager_compilation_(false), force_eager_compilation_(false),
num_stack_slots_(0), num_stack_slots_(0),
num_heap_slots_(0) { num_heap_slots_(0) {
...@@ -313,8 +312,7 @@ void Scope::AllocateVariables() { ...@@ -313,8 +312,7 @@ void Scope::AllocateVariables() {
// and assume they may invoke eval themselves. Eventually we could capture // and assume they may invoke eval themselves. Eventually we could capture
// this information in the ScopeInfo and then use it here (by traversing // this information in the ScopeInfo and then use it here (by traversing
// the call chain stack, at compile time). // the call chain stack, at compile time).
bool eval_scope = is_eval_scope(); PropagateScopeInfo(is_eval_scope());
PropagateScopeInfo(eval_scope, eval_scope);
// 2) Resolve variables. // 2) Resolve variables.
Scope* global_scope = NULL; Scope* global_scope = NULL;
...@@ -444,9 +442,6 @@ void Scope::Print(int n) { ...@@ -444,9 +442,6 @@ void Scope::Print(int n) {
if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
if (outer_scope_calls_eval_) Indent(n1, "// outer scope calls 'eval'\n"); if (outer_scope_calls_eval_) Indent(n1, "// outer scope calls 'eval'\n");
if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
if (outer_scope_is_eval_scope_) {
Indent(n1, "// outer scope is 'eval' scope\n");
}
if (num_stack_slots_ > 0) { Indent(n1, "// "); if (num_stack_slots_ > 0) { Indent(n1, "// ");
PrintF("%d stack slots\n", num_stack_slots_); } PrintF("%d stack slots\n", num_stack_slots_); }
if (num_heap_slots_ > 0) { Indent(n1, "// "); if (num_heap_slots_ > 0) { Indent(n1, "// ");
...@@ -487,18 +482,20 @@ void Scope::Print(int n) { ...@@ -487,18 +482,20 @@ void Scope::Print(int n) {
#endif // DEBUG #endif // DEBUG
Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { Variable* Scope::NonLocal(Handle<String> name) {
// Space optimization: reuse existing non-local with the same name // Space optimization: reuse existing non-local with the same name.
// and mode.
for (int i = 0; i < nonlocals_.length(); i++) { for (int i = 0; i < nonlocals_.length(); i++) {
Variable* var = nonlocals_[i]; Variable* var = nonlocals_[i];
if (var->name().is_identical_to(name) && var->mode() == mode) { if (var->name().is_identical_to(name)) {
ASSERT(var->mode() == Variable::DYNAMIC);
return var; return var;
} }
} }
// Otherwise create a new non-local and add it to the list. // Otherwise create a new new-local and add it to the list.
Variable* var = new Variable(NULL, name, mode, true, false); Variable* var = new Variable(
NULL /* we don't know the scope */,
name, Variable::DYNAMIC, true, false);
nonlocals_.Add(var); nonlocals_.Add(var);
// Allocate it by giving it a dynamic lookup. // Allocate it by giving it a dynamic lookup.
...@@ -514,9 +511,7 @@ Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { ...@@ -514,9 +511,7 @@ Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
// because the variable is just a guess (and may be shadowed by another // because the variable is just a guess (and may be shadowed by another
// variable that is introduced dynamically via an 'eval' call or a 'with' // variable that is introduced dynamically via an 'eval' call or a 'with'
// statement). // statement).
Variable* Scope::LookupRecursive(Handle<String> name, Variable* Scope::LookupRecursive(Handle<String> name, bool inner_lookup) {
bool inner_lookup,
Variable** invalidated_local) {
// If we find a variable, but the current scope calls 'eval', the found // If we find a variable, but the current scope calls 'eval', the found
// variable may not be the correct one (the 'eval' may introduce a // variable may not be the correct one (the 'eval' may introduce a
// property with the same name). In that case, remember that the variable // property with the same name). In that case, remember that the variable
...@@ -547,7 +542,7 @@ Variable* Scope::LookupRecursive(Handle<String> name, ...@@ -547,7 +542,7 @@ Variable* Scope::LookupRecursive(Handle<String> name,
var = function_; var = function_;
} else if (outer_scope_ != NULL) { } else if (outer_scope_ != NULL) {
var = outer_scope_->LookupRecursive(name, true, invalidated_local); var = outer_scope_->LookupRecursive(name, true /* inner lookup */);
// We may have found a variable in an outer scope. However, if // We may have found a variable in an outer scope. However, if
// the current scope is inside a 'with', the actual variable may // the current scope is inside a 'with', the actual variable may
// be a property introduced via the 'with' statement. Then, the // be a property introduced via the 'with' statement. Then, the
...@@ -568,10 +563,8 @@ Variable* Scope::LookupRecursive(Handle<String> name, ...@@ -568,10 +563,8 @@ Variable* Scope::LookupRecursive(Handle<String> name,
var->is_accessed_from_inner_scope_ = true; var->is_accessed_from_inner_scope_ = true;
// If the variable we have found is just a guess, invalidate the result. // If the variable we have found is just a guess, invalidate the result.
if (guess) { if (guess)
*invalidated_local = var;
var = NULL; var = NULL;
}
return var; return var;
} }
...@@ -585,8 +578,7 @@ void Scope::ResolveVariable(Scope* global_scope, VariableProxy* proxy) { ...@@ -585,8 +578,7 @@ void Scope::ResolveVariable(Scope* global_scope, VariableProxy* proxy) {
if (proxy->var() != NULL) return; if (proxy->var() != NULL) return;
// Otherwise, try to resolve the variable. // Otherwise, try to resolve the variable.
Variable* invalidated_local = NULL; Variable* var = LookupRecursive(proxy->name(), false);
Variable* var = LookupRecursive(proxy->name(), false, &invalidated_local);
if (proxy->inside_with()) { if (proxy->inside_with()) {
// If we are inside a local 'with' statement, all bets are off // If we are inside a local 'with' statement, all bets are off
...@@ -595,7 +587,7 @@ void Scope::ResolveVariable(Scope* global_scope, VariableProxy* proxy) { ...@@ -595,7 +587,7 @@ void Scope::ResolveVariable(Scope* global_scope, VariableProxy* proxy) {
// Note that we must do a lookup anyway, because if we find one, // Note that we must do a lookup anyway, because if we find one,
// we must mark that variable as potentially accessed from this // we must mark that variable as potentially accessed from this
// inner scope (the property may not be in the 'with' object). // inner scope (the property may not be in the 'with' object).
var = NonLocal(proxy->name(), Variable::DYNAMIC); var = NonLocal(proxy->name());
} else { } else {
// We are not inside a local 'with' statement. // We are not inside a local 'with' statement.
...@@ -609,22 +601,11 @@ void Scope::ResolveVariable(Scope* global_scope, VariableProxy* proxy) { ...@@ -609,22 +601,11 @@ void Scope::ResolveVariable(Scope* global_scope, VariableProxy* proxy) {
// or we don't know about the outer scope (because we are // or we don't know about the outer scope (because we are
// in an eval scope). // in an eval scope).
if (!is_global_scope() && if (!is_global_scope() &&
(scope_inside_with_ || outer_scope_is_eval_scope_)) { (is_eval_scope() || outer_scope_calls_eval_ ||
// If we are inside a with statement or the code is executed scope_calls_eval_ || scope_inside_with_)) {
// using eval, we give up and look up the variable at runtime. // We must look up the variable at runtime, and we don't
var = NonLocal(proxy->name(), Variable::DYNAMIC); // know anything else.
var = NonLocal(proxy->name());
} else if (!is_global_scope() &&
(scope_calls_eval_ || outer_scope_calls_eval_)) {
// If the code is not executed using eval and there are no
// with scopes, either we have a local or a global variable
// that might be shadowed by an eval-introduced variable.
if (invalidated_local != NULL) {
var = NonLocal(proxy->name(), Variable::DYNAMIC_LOCAL);
var->set_local_if_not_shadowed(invalidated_local);
} else {
var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
}
} else { } else {
// We must have a global variable. // We must have a global variable.
...@@ -662,21 +643,15 @@ void Scope::ResolveVariablesRecursively(Scope* global_scope) { ...@@ -662,21 +643,15 @@ void Scope::ResolveVariablesRecursively(Scope* global_scope) {
} }
bool Scope::PropagateScopeInfo(bool outer_scope_calls_eval, bool Scope::PropagateScopeInfo(bool outer_scope_calls_eval) {
bool outer_scope_is_eval_scope) {
if (outer_scope_calls_eval) { if (outer_scope_calls_eval) {
outer_scope_calls_eval_ = true; outer_scope_calls_eval_ = true;
} }
if (outer_scope_is_eval_scope) { bool b = scope_calls_eval_ || outer_scope_calls_eval_;
outer_scope_is_eval_scope_ = true;
}
bool calls_eval = scope_calls_eval_ || outer_scope_calls_eval_;
bool is_eval = is_eval_scope() || outer_scope_is_eval_scope_;
for (int i = 0; i < inner_scopes_.length(); i++) { for (int i = 0; i < inner_scopes_.length(); i++) {
Scope* inner_scope = inner_scopes_[i]; Scope* inner_scope = inner_scopes_[i];
if (inner_scope->PropagateScopeInfo(calls_eval, is_eval)) { if (inner_scope->PropagateScopeInfo(b)) {
inner_scope_calls_eval_ = true; inner_scope_calls_eval_ = true;
} }
if (inner_scope->force_eager_compilation_) { if (inner_scope->force_eager_compilation_) {
......
...@@ -166,13 +166,10 @@ class Scope: public ZoneObject { ...@@ -166,13 +166,10 @@ class Scope: public ZoneObject {
bool is_function_scope() const { return type_ == FUNCTION_SCOPE; } bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
bool is_global_scope() const { return type_ == GLOBAL_SCOPE; } bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
// Information about which scopes calls eval.
bool calls_eval() const { return scope_calls_eval_; }
bool outer_scope_calls_eval() const { return outer_scope_calls_eval_; }
// The scope immediately surrounding this scope, or NULL. // The scope immediately surrounding this scope, or NULL.
Scope* outer_scope() const { return outer_scope_; } Scope* outer_scope() const { return outer_scope_; }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Accessors. // Accessors.
...@@ -293,7 +290,6 @@ class Scope: public ZoneObject { ...@@ -293,7 +290,6 @@ class Scope: public ZoneObject {
// Computed via PropagateScopeInfo. // Computed via PropagateScopeInfo.
bool outer_scope_calls_eval_; bool outer_scope_calls_eval_;
bool inner_scope_calls_eval_; bool inner_scope_calls_eval_;
bool outer_scope_is_eval_scope_;
bool force_eager_compilation_; bool force_eager_compilation_;
// Computed via AllocateVariables; function scopes only. // Computed via AllocateVariables; function scopes only.
...@@ -302,18 +298,15 @@ class Scope: public ZoneObject { ...@@ -302,18 +298,15 @@ class Scope: public ZoneObject {
// Create a non-local variable with a given name. // Create a non-local variable with a given name.
// These variables are looked up dynamically at runtime. // These variables are looked up dynamically at runtime.
Variable* NonLocal(Handle<String> name, Variable::Mode mode); Variable* NonLocal(Handle<String> name);
// Variable resolution. // Variable resolution.
Variable* LookupRecursive(Handle<String> name, Variable* LookupRecursive(Handle<String> name, bool inner_lookup);
bool inner_lookup,
Variable** invalidated_local);
void ResolveVariable(Scope* global_scope, VariableProxy* proxy); void ResolveVariable(Scope* global_scope, VariableProxy* proxy);
void ResolveVariablesRecursively(Scope* global_scope); void ResolveVariablesRecursively(Scope* global_scope);
// Scope analysis. // Scope analysis.
bool PropagateScopeInfo(bool outer_scope_calls_eval, bool PropagateScopeInfo(bool outer_scope_calls_eval);
bool outer_scope_is_eval_scope);
bool HasTrivialContext() const; bool HasTrivialContext() const;
// Predicates. // Predicates.
......
...@@ -110,8 +110,6 @@ const char* Variable::Mode2String(Mode mode) { ...@@ -110,8 +110,6 @@ const char* Variable::Mode2String(Mode mode) {
case VAR: return "VAR"; case VAR: return "VAR";
case CONST: return "CONST"; case CONST: return "CONST";
case DYNAMIC: return "DYNAMIC"; case DYNAMIC: return "DYNAMIC";
case DYNAMIC_GLOBAL: return "DYNAMIC_GLOBAL";
case DYNAMIC_LOCAL: return "DYNAMIC_LOCAL";
case INTERNAL: return "INTERNAL"; case INTERNAL: return "INTERNAL";
case TEMPORARY: return "TEMPORARY"; case TEMPORARY: return "TEMPORARY";
} }
...@@ -145,7 +143,6 @@ Variable::Variable(Scope* scope, ...@@ -145,7 +143,6 @@ Variable::Variable(Scope* scope,
mode_(mode), mode_(mode),
is_valid_LHS_(is_valid_LHS), is_valid_LHS_(is_valid_LHS),
is_this_(is_this), is_this_(is_this),
local_if_not_shadowed_(NULL),
is_accessed_from_inner_scope_(false), is_accessed_from_inner_scope_(false),
rewrite_(NULL) { rewrite_(NULL) {
// names must be canonicalized for fast equality checks // names must be canonicalized for fast equality checks
...@@ -159,4 +156,5 @@ bool Variable::is_global() const { ...@@ -159,4 +156,5 @@ bool Variable::is_global() const {
return mode_ != TEMPORARY && scope_ != NULL && scope_->is_global_scope(); return mode_ != TEMPORARY && scope_ != NULL && scope_->is_global_scope();
} }
} } // namespace v8::internal } } // namespace v8::internal
...@@ -113,27 +113,13 @@ class Variable: public ZoneObject { ...@@ -113,27 +113,13 @@ class Variable: public ZoneObject {
enum Mode { enum Mode {
// User declared variables: // User declared variables:
VAR, // declared via 'var', and 'function' declarations VAR, // declared via 'var', and 'function' declarations
CONST, // declared via 'const' declarations CONST, // declared via 'const' declarations
// Variables introduced by the compiler: // Variables introduced by the compiler:
DYNAMIC, // always require dynamic lookup (we don't know DYNAMIC, // always require dynamic lookup (we don't know the declaration)
// the declaration) INTERNAL, // like VAR, but not user-visible (may or may not be in a
// context)
DYNAMIC_GLOBAL, // requires dynamic lookup, but we know that the TEMPORARY // temporary variables (not user-visible), never in a context
// variable is global unless it has been shadowed
// by an eval-introduced variable
DYNAMIC_LOCAL, // requires dynamic lookup, but we know that the
// variable is local and where it is unless it
// has been shadowed by an eval-introduced
// variable
INTERNAL, // like VAR, but not user-visible (may or may not
// be in a context)
TEMPORARY // temporary variables (not user-visible), never
// in a context
}; };
// Printing support // Printing support
...@@ -164,24 +150,9 @@ class Variable: public ZoneObject { ...@@ -164,24 +150,9 @@ class Variable: public ZoneObject {
return !is_this() && name().is_identical_to(n); return !is_this() && name().is_identical_to(n);
} }
bool is_dynamic() const {
return (mode_ == DYNAMIC ||
mode_ == DYNAMIC_GLOBAL ||
mode_ == DYNAMIC_LOCAL);
}
bool is_global() const; bool is_global() const;
bool is_this() const { return is_this_; } bool is_this() const { return is_this_; }
Variable* local_if_not_shadowed() const {
ASSERT(mode_ == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL);
return local_if_not_shadowed_;
}
void set_local_if_not_shadowed(Variable* local) {
local_if_not_shadowed_ = local;
}
Expression* rewrite() const { return rewrite_; } Expression* rewrite() const { return rewrite_; }
Slot* slot() const; Slot* slot() const;
...@@ -197,8 +168,6 @@ class Variable: public ZoneObject { ...@@ -197,8 +168,6 @@ class Variable: public ZoneObject {
bool is_valid_LHS_; bool is_valid_LHS_;
bool is_this_; bool is_this_;
Variable* local_if_not_shadowed_;
// Usage info. // Usage info.
bool is_accessed_from_inner_scope_; // set by variable resolver bool is_accessed_from_inner_scope_; // set by variable resolver
UseCount var_uses_; // uses of the variable value UseCount var_uses_; // uses of the variable value
......
// Copyright 2009 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.
// Tests global loads from eval inside of a with statement.
var x = 27;
function test(obj, source) {
with (obj) {
eval(source);
}
}
// Test shadowing in eval scope.
test({ x: 42 }, "assertEquals(42, x)");
test({ y: 42 }, "assertEquals(27, x)");
// Test shadowing in local scope inside an eval scope.
test({ x: 42 }, "function f() { assertEquals(42, x) }; f();");
test({ y: 42 }, "function f() { assertEquals(27, x) }; f();");
// Test shadowing in local scope inside an eval scope. Deeper nesting
// this time.
test({ x: 42 }, "function f() { function g() { assertEquals(42, x) }; g() }; f();");
test({ y: 42 }, "function f() { function g() { assertEquals(27, x) }; g() }; f();");
// Test shadowing in local scope inside an eval scope with eval calls in the eval scopes.
test({ x: 42 }, "function f() { eval('1'); assertEquals(42, x) }; f();");
test({ y: 42 }, "function f() { eval('1'); assertEquals(27, x) }; f();");
// Test shadowing in local scope inside an eval scope with eval calls
// in the eval scopes. Deeper nesting this time.
test({ x: 42 }, "function f() { function g() { eval('1'); assertEquals(42, x) }; g() }; f();");
test({ y: 42 }, "function f() { function g() { eval('1'); assertEquals(27, x) }; g() }; f();");
// Copyright 2009 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.
// Tests loads of local properties from eval.
function test(source) {
var x = 27;
eval(source);
}
test("assertEquals(27, x);");
test("(function() { assertEquals(27, x) })();");
// Copyright 2009 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.
// Tests loading of properties across eval calls.
var x = 1;
// Test loading across an eval call that does not shadow variables.
function testNoShadowing() {
var y = 2;
function f() {
eval('1');
assertEquals(1, x);
assertEquals(2, y);
function g() {
assertEquals(1, x);
assertEquals(2, y);
}
g();
}
f();
}
testNoShadowing();
// Test loading across eval calls that do not shadow variables.
function testNoShadowing2() {
var y = 2;
eval('1');
function f() {
eval('1');
assertEquals(1, x);
assertEquals(2, y);
function g() {
assertEquals(1, x);
assertEquals(2, y);
}
g();
}
f();
}
testNoShadowing2();
// Test loading across an eval call that shadows variables.
function testShadowing() {
var y = 2;
function f() {
eval('var x = 3; var y = 4;');
assertEquals(3, x);
assertEquals(4, y);
function g() {
assertEquals(3, x);
assertEquals(4, y);
}
g();
}
f();
}
testShadowing();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment