| Index: src/ast/scopes.cc
|
| diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
|
| index a99cbfaa4d349197abcd8bc86343e73360cca631..76c393f8e861e2d032a2905903c0c05fd4970f17 100644
|
| --- a/src/ast/scopes.cc
|
| +++ b/src/ast/scopes.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "src/ast/scopes.h"
|
|
|
| +#include <set>
|
| +
|
| #include "src/accessors.h"
|
| #include "src/bootstrapper.h"
|
| #include "src/messages.h"
|
| @@ -204,7 +206,8 @@ void Scope::SetDefaults() {
|
|
|
| Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
|
| Context* context, Scope* script_scope,
|
| - AstValueFactory* ast_value_factory) {
|
| + AstValueFactory* ast_value_factory,
|
| + DeserializationMode deserialization_mode) {
|
| // Reconstruct the outer scope chain from a closure's context chain.
|
| Scope* current_scope = NULL;
|
| Scope* innermost_scope = NULL;
|
| @@ -239,6 +242,9 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
|
| new (zone) Scope(zone, current_scope,
|
| ast_value_factory->GetString(handle(name, isolate)));
|
| }
|
| + if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) {
|
| + current_scope->DeserializeScopeInfo(isolate, ast_value_factory);
|
| + }
|
| if (innermost_scope == NULL) innermost_scope = current_scope;
|
| context = context->previous();
|
| }
|
| @@ -248,6 +254,78 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
|
| return (innermost_scope == NULL) ? script_scope : innermost_scope;
|
| }
|
|
|
| +void Scope::DeserializeScopeInfo(Isolate* isolate,
|
| + AstValueFactory* ast_value_factory) {
|
| + if (scope_info_.is_null()) return;
|
| +
|
| + DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
|
| +
|
| + std::set<const AstRawString*> names_seen;
|
| + // Internalize context local & globals variables.
|
| + for (int var = 0; var < scope_info_->ContextLocalCount() +
|
| + scope_info_->ContextGlobalCount();
|
| + ++var) {
|
| + Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate);
|
| + const AstRawString* name = ast_value_factory->GetString(name_handle);
|
| + if (!names_seen.insert(name).second) continue;
|
| + int index = Context::MIN_CONTEXT_SLOTS + var;
|
| + VariableMode mode = scope_info_->ContextLocalMode(var);
|
| + InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var);
|
| + MaybeAssignedFlag maybe_assigned_flag =
|
| + scope_info_->ContextLocalMaybeAssignedFlag(var);
|
| + VariableLocation location = var < scope_info_->ContextLocalCount()
|
| + ? VariableLocation::CONTEXT
|
| + : VariableLocation::GLOBAL;
|
| + Variable::Kind kind = Variable::NORMAL;
|
| + if (index == scope_info_->ReceiverContextSlotIndex()) {
|
| + kind = Variable::THIS;
|
| + }
|
| +
|
| + Variable* result = variables_.Declare(this, name, mode, kind, init_flag,
|
| + maybe_assigned_flag);
|
| + result->AllocateTo(location, index);
|
| + }
|
| +
|
| + // We must read parameters from the end since for multiply declared
|
| + // parameters the value of the last declaration of that parameter is used
|
| + // inside a function (and thus we need to look at the last index). Was bug#
|
| + // 1110337.
|
| + for (int index = scope_info_->ParameterCount() - 1; index >= 0; --index) {
|
| + Handle<String> name_handle(scope_info_->ParameterName(index), isolate);
|
| + const AstRawString* name = ast_value_factory->GetString(name_handle);
|
| + if (!names_seen.insert(name).second) continue;
|
| +
|
| + VariableMode mode = DYNAMIC;
|
| + InitializationFlag init_flag = kCreatedInitialized;
|
| + MaybeAssignedFlag maybe_assigned_flag = kMaybeAssigned;
|
| + VariableLocation location = VariableLocation::LOOKUP;
|
| + Variable::Kind kind = Variable::NORMAL;
|
| +
|
| + Variable* result = variables_.Declare(this, name, mode, kind, init_flag,
|
| + maybe_assigned_flag);
|
| + result->AllocateTo(location, index);
|
| + }
|
| +
|
| + // Internalize function proxy for this scope.
|
| + if (scope_info_->HasFunctionName()) {
|
| + AstNodeFactory factory(ast_value_factory);
|
| + Handle<String> name_handle(scope_info_->FunctionName(), isolate);
|
| + const AstRawString* name = ast_value_factory->GetString(name_handle);
|
| + VariableMode mode;
|
| + int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode);
|
| + if (index >= 0) {
|
| + Variable* result = new (zone())
|
| + Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized);
|
| + VariableProxy* proxy = factory.NewVariableProxy(result);
|
| + VariableDeclaration* declaration =
|
| + factory.NewVariableDeclaration(proxy, mode, this, kNoSourcePosition);
|
| + DeclareFunctionVar(declaration);
|
| + result->AllocateTo(VariableLocation::CONTEXT, index);
|
| + }
|
| + }
|
| +
|
| + scope_info_ = Handle<ScopeInfo>::null();
|
| +}
|
|
|
| bool Scope::Analyze(ParseInfo* info) {
|
| DCHECK(info->literal() != NULL);
|
|
|