| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index 28481383a5fbd846a6940deb9a1b08ee64dab56e..30966f0b2c37aef0e72fbb4360600282e87b2b44 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -8909,8 +8909,22 @@ RUNTIME_FUNCTION(Runtime_NewGlobalContext) {
|
|
|
| ASSERT(function->context() == isolate->context());
|
| ASSERT(function->context()->global_object() == result->global_object());
|
| - result->global_object()->set_global_context(*result);
|
| - return *result;
|
| + GlobalObject* global = result->global_object();
|
| + Context* first_global_context = global->global_context();
|
| + if (first_global_context->IsNativeContext()) {
|
| + // This is the first global context, insert directly.
|
| + global->set_global_context(*result);
|
| + return *result;
|
| + } else {
|
| + // Insert new context at the top of the chain of global contexts.
|
| + Context* last_global_context = first_global_context;
|
| + while (!last_global_context->previous()->IsNativeContext()) {
|
| + last_global_context = last_global_context->previous();
|
| + }
|
| + result->set_previous(last_global_context->previous());
|
| + last_global_context->set_previous(*result);
|
| + return first_global_context;
|
| + }
|
| }
|
|
|
|
|
| @@ -9785,12 +9799,13 @@ static bool TokensMatchForCompileString(Isolate* isolate) {
|
|
|
| RUNTIME_FUNCTION(Runtime_CompileString) {
|
| HandleScope scope(isolate);
|
| - ASSERT(args.length() == 2);
|
| + ASSERT(args.length() == 3);
|
| CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
|
| - CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(JSGlobalProxy, global_proxy, 1);
|
| + CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 2);
|
|
|
| // Extract native context.
|
| - Handle<Context> context(isolate->native_context());
|
| + Handle<Context> native_context(isolate->native_context());
|
|
|
| // Filter cross security context calls.
|
| if (!TokensMatchForCompileString(isolate)) {
|
| @@ -9799,10 +9814,10 @@ RUNTIME_FUNCTION(Runtime_CompileString) {
|
|
|
| // Check if native context allows code generation from
|
| // strings. Throw an exception if it doesn't.
|
| - if (context->allow_code_gen_from_strings()->IsFalse() &&
|
| - !CodeGenerationFromStringsAllowed(isolate, context)) {
|
| + if (native_context->allow_code_gen_from_strings()->IsFalse() &&
|
| + !CodeGenerationFromStringsAllowed(isolate, native_context)) {
|
| Handle<Object> error_message =
|
| - context->ErrorMessageForCodeGenerationFromStrings();
|
| + native_context->ErrorMessageForCodeGenerationFromStrings();
|
| return isolate->Throw(*isolate->factory()->NewEvalError(
|
| "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
|
| }
|
| @@ -9810,6 +9825,9 @@ RUNTIME_FUNCTION(Runtime_CompileString) {
|
| // Compile source string in the native context.
|
| ParseRestriction restriction = function_literal_only
|
| ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
|
| +//TODO: this is insecure, fix. Need to get the global context properly.
|
| + Handle<GlobalObject> global(GlobalObject::cast(global_proxy->GetPrototype()));
|
| + Handle<Context> context(global->global_context());
|
| Handle<JSFunction> fun;
|
| ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| isolate, fun,
|
| @@ -11798,6 +11816,29 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
|
| }
|
|
|
|
|
| +// Create a plain JSObject which materializes the block scope for the specified
|
| +// global context.
|
| +MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeGlobalScope(
|
| + Isolate* isolate,
|
| + Handle<Context> context) {
|
| + ASSERT(context->IsGlobalContext());
|
| + Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
|
| +
|
| + // Allocate and initialize a JSObject with all the arguments, stack locals
|
| + // heap locals and extension properties of the debugged function.
|
| + Handle<JSObject> global_scope =
|
| + isolate->factory()->NewJSObject(isolate->object_function());
|
| +
|
| + // Fill all context locals.
|
| + if (!ScopeInfo::CopyContextLocalsToScopeObject(
|
| + scope_info, context, global_scope)) {
|
| + return MaybeHandle<JSObject>();
|
| + }
|
| +
|
| + return global_scope;
|
| +}
|
| +
|
| +
|
| // Create a plain JSObject which materializes the module scope for the specified
|
| // module context.
|
| MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
|
| @@ -11827,8 +11868,10 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
|
| // which is inserted "artificially" in the context chain.
|
| class ScopeIterator {
|
| public:
|
| + // This type has to be matched by ScopeType in mirror-debugger.js
|
| enum ScopeType {
|
| - ScopeTypeGlobal = 0,
|
| + ScopeTypeNative,
|
| + ScopeTypeGlobal,
|
| ScopeTypeLocal,
|
| ScopeTypeWith,
|
| ScopeTypeClosure,
|
| @@ -11956,8 +11999,8 @@ class ScopeIterator {
|
| void Next() {
|
| ASSERT(!failed_);
|
| ScopeType scope_type = Type();
|
| - if (scope_type == ScopeTypeGlobal) {
|
| - // The global scope is always the last in the chain.
|
| + if (scope_type == ScopeTypeNative) {
|
| + // The native scope is always the last in the chain.
|
| ASSERT(context_->IsNativeContext());
|
| context_ = Handle<Context>();
|
| return;
|
| @@ -11987,7 +12030,11 @@ class ScopeIterator {
|
| ASSERT(context_->IsModuleContext());
|
| return ScopeTypeModule;
|
| case GLOBAL_SCOPE:
|
| - ASSERT(context_->IsNativeContext());
|
| + ASSERT(context_->IsNativeContext() || context_->IsGlobalContext());
|
| + return
|
| + context_->IsNativeContext() ? ScopeTypeNative : ScopeTypeGlobal;
|
| + case SCRIPT_SCOPE:
|
| + ASSERT(context_->IsGlobalContext());
|
| return ScopeTypeGlobal;
|
| case WITH_SCOPE:
|
| ASSERT(context_->IsWithContext());
|
| @@ -12005,6 +12052,9 @@ class ScopeIterator {
|
| }
|
| if (context_->IsNativeContext()) {
|
| ASSERT(context_->global_object()->IsGlobalObject());
|
| + return ScopeTypeNative;
|
| + }
|
| + if (context_->IsGlobalContext()) {
|
| return ScopeTypeGlobal;
|
| }
|
| if (context_->IsFunctionContext()) {
|
| @@ -12027,8 +12077,10 @@ class ScopeIterator {
|
| MaybeHandle<JSObject> ScopeObject() {
|
| ASSERT(!failed_);
|
| switch (Type()) {
|
| - case ScopeIterator::ScopeTypeGlobal:
|
| + case ScopeIterator::ScopeTypeNative:
|
| return Handle<JSObject>(CurrentContext()->global_object());
|
| + case ScopeIterator::ScopeTypeGlobal:
|
| + return MaterializeGlobalScope(isolate_, CurrentContext());
|
| case ScopeIterator::ScopeTypeLocal:
|
| // Materialize the content of the local scope into a JSObject.
|
| ASSERT(nested_scope_chain_.length() == 1);
|
| @@ -12054,7 +12106,10 @@ class ScopeIterator {
|
| Handle<Object> new_value) {
|
| ASSERT(!failed_);
|
| switch (Type()) {
|
| + case ScopeIterator::ScopeTypeNative:
|
| + break;
|
| case ScopeIterator::ScopeTypeGlobal:
|
| + // TODO(2399): should we implement it?
|
| break;
|
| case ScopeIterator::ScopeTypeLocal:
|
| return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
|
| @@ -12093,8 +12148,7 @@ class ScopeIterator {
|
| // be an actual context.
|
| Handle<Context> CurrentContext() {
|
| ASSERT(!failed_);
|
| - if (Type() == ScopeTypeGlobal ||
|
| - nested_scope_chain_.is_empty()) {
|
| + if (Type() == ScopeTypeNative || nested_scope_chain_.is_empty()) {
|
| return context_;
|
| } else if (nested_scope_chain_.last()->HasContext()) {
|
| return context_;
|
| @@ -12109,11 +12163,26 @@ class ScopeIterator {
|
| OFStream os(stdout);
|
| ASSERT(!failed_);
|
| switch (Type()) {
|
| + case ScopeIterator::ScopeTypeNative:
|
| + os << "Native:\n";
|
| + CurrentContext()->Print(os);
|
| + break;
|
| +
|
| case ScopeIterator::ScopeTypeGlobal:
|
| os << "Global:\n";
|
| CurrentContext()->Print(os);
|
| break;
|
|
|
| + case ScopeIterator::ScopeTypeModule:
|
| + os << "Module:\n";
|
| + CurrentContext()->Print(os);
|
| + break;
|
| +
|
| + case ScopeIterator::ScopeTypeBlock:
|
| + os << "Block:\n";
|
| + CurrentContext()->Print(os);
|
| + break;
|
| +
|
| case ScopeIterator::ScopeTypeLocal: {
|
| os << "Local:\n";
|
| function_->shared()->scope_info()->Print();
|
| @@ -12150,9 +12219,6 @@ class ScopeIterator {
|
| }
|
| }
|
| break;
|
| -
|
| - default:
|
| - UNREACHABLE();
|
| }
|
| PrintF("\n");
|
| }
|
|
|