Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: src/runtime.cc

Issue 7152002: Change the representation of catch contexts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/contexts.cc ('K') | « src/runtime.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 } 607 }
608 608
609 609
610 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { 610 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
611 ASSERT(args.length() == 1); 611 ASSERT(args.length() == 1);
612 CONVERT_CHECKED(JSProxy, proxy, args[0]); 612 CONVERT_CHECKED(JSProxy, proxy, args[0]);
613 return proxy->handler(); 613 return proxy->handler();
614 } 614 }
615 615
616 616
617 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) {
618 ASSERT(args.length() == 2);
619 CONVERT_CHECKED(String, key, args[0]);
620 Object* value = args[1];
621 ASSERT(!value->IsFailure());
622 // Create a catch context extension object.
623 JSFunction* constructor =
624 isolate->context()->global_context()->
625 context_extension_function();
626 Object* object;
627 { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor);
628 if (!maybe_object->ToObject(&object)) return maybe_object;
629 }
630 // Assign the exception value to the catch variable and make sure
631 // that the catch variable is DontDelete.
632 { MaybeObject* maybe_value =
633 // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4.
634 JSObject::cast(object)->SetProperty(
635 key, value, DONT_DELETE, kNonStrictMode);
636 if (!maybe_value->ToObject(&value)) return maybe_value;
637 }
638 return object;
639 }
640
641
642 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { 617 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
643 NoHandleAllocation ha; 618 NoHandleAllocation ha;
644 ASSERT(args.length() == 1); 619 ASSERT(args.length() == 1);
645 Object* obj = args[0]; 620 Object* obj = args[0];
646 if (!obj->IsJSObject()) return isolate->heap()->null_value(); 621 if (!obj->IsJSObject()) return isolate->heap()->null_value();
647 return JSObject::cast(obj)->class_name(); 622 return JSObject::cast(obj)->class_name();
648 } 623 }
649 624
650 625
651 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { 626 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 } 1278 }
1304 } 1279 }
1305 1280
1306 } else { 1281 } else {
1307 // The property is not in the function context. It needs to be 1282 // The property is not in the function context. It needs to be
1308 // "declared" in the function context's extension context, or in the 1283 // "declared" in the function context's extension context, or in the
1309 // global context. 1284 // global context.
1310 Handle<JSObject> context_ext; 1285 Handle<JSObject> context_ext;
1311 if (context->has_extension()) { 1286 if (context->has_extension()) {
1312 // The function context's extension context exists - use it. 1287 // The function context's extension context exists - use it.
1313 context_ext = Handle<JSObject>(context->extension()); 1288 context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
1314 } else { 1289 } else {
1315 // The function context's extension context does not exists - allocate 1290 // The function context's extension context does not exists - allocate
1316 // it. 1291 // it.
1317 context_ext = isolate->factory()->NewJSObject( 1292 context_ext = isolate->factory()->NewJSObject(
1318 isolate->context_extension_function()); 1293 isolate->context_extension_function());
1319 // And store it in the extension slot. 1294 // And store it in the extension slot.
1320 context->set_extension(*context_ext); 1295 context->set_extension(*context_ext);
1321 } 1296 }
1322 ASSERT(*context_ext != NULL); 1297 ASSERT(*context_ext != NULL);
1323 1298
(...skipping 6611 matching lines...) Expand 10 before | Expand all | Expand 10 after
7935 isolate->heap()->AllocateWithContext(isolate->context(), 7910 isolate->heap()->AllocateWithContext(isolate->context(),
7936 extension_object); 7911 extension_object);
7937 if (!maybe_context->To(&context)) return maybe_context; 7912 if (!maybe_context->To(&context)) return maybe_context;
7938 isolate->set_context(context); 7913 isolate->set_context(context);
7939 return context; 7914 return context;
7940 } 7915 }
7941 7916
7942 7917
7943 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { 7918 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
7944 NoHandleAllocation ha; 7919 NoHandleAllocation ha;
7945 ASSERT(args.length() == 1); 7920 ASSERT(args.length() == 2);
7946 JSObject* extension_object = JSObject::cast(args[0]); 7921 String* name = String::cast(args[0]);
7922 Object* thrown_object = args[1];
7947 Context* context; 7923 Context* context;
7948 MaybeObject* maybe_context = 7924 MaybeObject* maybe_context =
7949 isolate->heap()->AllocateCatchContext(isolate->context(), 7925 isolate->heap()->AllocateCatchContext(isolate->context(),
7950 extension_object); 7926 name,
7927 thrown_object);
7951 if (!maybe_context->To(&context)) return maybe_context; 7928 if (!maybe_context->To(&context)) return maybe_context;
7952 isolate->set_context(context); 7929 isolate->set_context(context);
7953 return context; 7930 return context;
7954 } 7931 }
7955 7932
7956 7933
7957 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { 7934 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
7958 HandleScope scope(isolate); 7935 HandleScope scope(isolate);
7959 ASSERT(args.length() == 2); 7936 ASSERT(args.length() == 2);
7960 7937
(...skipping 2232 matching lines...) Expand 10 before | Expand all | Expand 10 after
10193 NONE, 10170 NONE,
10194 kNonStrictMode), 10171 kNonStrictMode),
10195 Handle<JSObject>()); 10172 Handle<JSObject>());
10196 } 10173 }
10197 } 10174 }
10198 10175
10199 return closure_scope; 10176 return closure_scope;
10200 } 10177 }
10201 10178
10202 10179
10180 // Create a plain JSObject which materializes the scope for the specified
10181 // catch context.
10182 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
10183 Handle<Context> context) {
10184 ASSERT(context->IsCatchContext());
10185 Handle<String> name(String::cast(context->extension()));
10186 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX));
10187 Handle<JSObject> catch_scope =
10188 isolate->factory()->NewJSObject(isolate->object_function());
Mads Ager (chromium) 2011/06/14 11:54:17 Do we really want this to be a plain JSObject. Don
Kevin Millikin (Chromium) 2011/06/14 12:06:35 I'm pretty sure this is what we want. This is an
Søren Thygesen Gjesse 2011/06/14 12:18:32 It looks fine. The objects representing the differ
10189 RETURN_IF_EMPTY_HANDLE_VALUE(
10190 isolate,
10191 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
10192 Handle<JSObject>());
10193 return catch_scope;
10194 }
10195
10196
10203 // Iterate over the actual scopes visible from a stack frame. All scopes are 10197 // Iterate over the actual scopes visible from a stack frame. All scopes are
10204 // backed by an actual context except the local scope, which is inserted 10198 // backed by an actual context except the local scope, which is inserted
10205 // "artifically" in the context chain. 10199 // "artifically" in the context chain.
10206 class ScopeIterator { 10200 class ScopeIterator {
10207 public: 10201 public:
10208 enum ScopeType { 10202 enum ScopeType {
10209 ScopeTypeGlobal = 0, 10203 ScopeTypeGlobal = 0,
10210 ScopeTypeLocal, 10204 ScopeTypeLocal,
10211 ScopeTypeWith, 10205 ScopeTypeWith,
10212 ScopeTypeClosure, 10206 ScopeTypeClosure,
10213 // Every catch block contains an implicit with block (its parameter is
10214 // a JSContextExtensionObject) that extends current scope with a variable
10215 // holding exception object. Such with blocks are treated as scopes of their
10216 // own type.
10217 ScopeTypeCatch 10207 ScopeTypeCatch
10218 }; 10208 };
10219 10209
10220 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame) 10210 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame)
10221 : isolate_(isolate), 10211 : isolate_(isolate),
10222 frame_(frame), 10212 frame_(frame),
10223 function_(JSFunction::cast(frame->function())), 10213 function_(JSFunction::cast(frame->function())),
10224 context_(Context::cast(frame->context())), 10214 context_(Context::cast(frame->context())),
10225 local_done_(false), 10215 local_done_(false),
10226 at_local_(false) { 10216 at_local_(false) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
10284 return ScopeTypeLocal; 10274 return ScopeTypeLocal;
10285 } 10275 }
10286 if (context_->IsGlobalContext()) { 10276 if (context_->IsGlobalContext()) {
10287 ASSERT(context_->global()->IsGlobalObject()); 10277 ASSERT(context_->global()->IsGlobalObject());
10288 return ScopeTypeGlobal; 10278 return ScopeTypeGlobal;
10289 } 10279 }
10290 if (context_->IsFunctionContext()) { 10280 if (context_->IsFunctionContext()) {
10291 return ScopeTypeClosure; 10281 return ScopeTypeClosure;
10292 } 10282 }
10293 ASSERT(context_->has_extension()); 10283 ASSERT(context_->has_extension());
10294 // Current scope is either an explicit with statement or a with statement 10284 if (context_->IsCatchContext()) {
10295 // implicitely generated for a catch block.
10296 // If the extension object here is a JSContextExtensionObject then
10297 // current with statement is one frome a catch block otherwise it's a
10298 // regular with statement.
10299 if (context_->extension()->IsJSContextExtensionObject()) {
10300 return ScopeTypeCatch; 10285 return ScopeTypeCatch;
10301 } 10286 }
10302 return ScopeTypeWith; 10287 return ScopeTypeWith;
10303 } 10288 }
10304 10289
10305 // Return the JavaScript object with the content of the current scope. 10290 // Return the JavaScript object with the content of the current scope.
10306 Handle<JSObject> ScopeObject() { 10291 Handle<JSObject> ScopeObject() {
10307 switch (Type()) { 10292 switch (Type()) {
10308 case ScopeIterator::ScopeTypeGlobal: 10293 case ScopeIterator::ScopeTypeGlobal:
10309 return Handle<JSObject>(CurrentContext()->global()); 10294 return Handle<JSObject>(CurrentContext()->global());
10310 break;
10311 case ScopeIterator::ScopeTypeLocal: 10295 case ScopeIterator::ScopeTypeLocal:
10312 // Materialize the content of the local scope into a JSObject. 10296 // Materialize the content of the local scope into a JSObject.
10313 return MaterializeLocalScope(isolate_, frame_); 10297 return MaterializeLocalScope(isolate_, frame_);
10314 break;
10315 case ScopeIterator::ScopeTypeWith: 10298 case ScopeIterator::ScopeTypeWith:
10299 // Return the with object.
10300 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
10316 case ScopeIterator::ScopeTypeCatch: 10301 case ScopeIterator::ScopeTypeCatch:
10317 // Return the with object. 10302 return MaterializeCatchScope(isolate_, CurrentContext());
10318 return Handle<JSObject>(CurrentContext()->extension());
10319 break;
10320 case ScopeIterator::ScopeTypeClosure: 10303 case ScopeIterator::ScopeTypeClosure:
10321 // Materialize the content of the closure scope into a JSObject. 10304 // Materialize the content of the closure scope into a JSObject.
10322 return MaterializeClosure(isolate_, CurrentContext()); 10305 return MaterializeClosure(isolate_, CurrentContext());
10323 break;
10324 } 10306 }
10325 UNREACHABLE(); 10307 UNREACHABLE();
10326 return Handle<JSObject>(); 10308 return Handle<JSObject>();
10327 } 10309 }
10328 10310
10329 // Return the context for this scope. For the local context there might not 10311 // Return the context for this scope. For the local context there might not
10330 // be an actual context. 10312 // be an actual context.
10331 Handle<Context> CurrentContext() { 10313 Handle<Context> CurrentContext() {
10332 if (at_local_ && context_->closure() != *function_) { 10314 if (at_local_ && context_->closure() != *function_) {
10333 return Handle<Context>(); 10315 return Handle<Context>();
(...skipping 10 matching lines...) Expand all
10344 CurrentContext()->Print(); 10326 CurrentContext()->Print();
10345 break; 10327 break;
10346 10328
10347 case ScopeIterator::ScopeTypeLocal: { 10329 case ScopeIterator::ScopeTypeLocal: {
10348 PrintF("Local:\n"); 10330 PrintF("Local:\n");
10349 ScopeInfo<> scope_info(function_->shared()->scope_info()); 10331 ScopeInfo<> scope_info(function_->shared()->scope_info());
10350 scope_info.Print(); 10332 scope_info.Print();
10351 if (!CurrentContext().is_null()) { 10333 if (!CurrentContext().is_null()) {
10352 CurrentContext()->Print(); 10334 CurrentContext()->Print();
10353 if (CurrentContext()->has_extension()) { 10335 if (CurrentContext()->has_extension()) {
10354 Handle<JSObject> extension = 10336 Handle<Object> extension(CurrentContext()->extension());
10355 Handle<JSObject>(CurrentContext()->extension());
10356 if (extension->IsJSContextExtensionObject()) { 10337 if (extension->IsJSContextExtensionObject()) {
10357 extension->Print(); 10338 extension->Print();
10358 } 10339 }
10359 } 10340 }
10360 } 10341 }
10361 break; 10342 break;
10362 } 10343 }
10363 10344
10364 case ScopeIterator::ScopeTypeWith: { 10345 case ScopeIterator::ScopeTypeWith:
10365 PrintF("With:\n"); 10346 PrintF("With:\n");
10366 Handle<JSObject> extension = 10347 CurrentContext()->extension()->Print();
10367 Handle<JSObject>(CurrentContext()->extension());
10368 extension->Print();
10369 break; 10348 break;
10370 }
10371 10349
10372 case ScopeIterator::ScopeTypeCatch: { 10350 case ScopeIterator::ScopeTypeCatch:
10373 PrintF("Catch:\n"); 10351 PrintF("Catch:\n");
10374 Handle<JSObject> extension = 10352 CurrentContext()->extension()->Print();
10375 Handle<JSObject>(CurrentContext()->extension()); 10353 CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
10376 extension->Print();
10377 break; 10354 break;
10378 }
10379 10355
10380 case ScopeIterator::ScopeTypeClosure: { 10356 case ScopeIterator::ScopeTypeClosure:
10381 PrintF("Closure:\n"); 10357 PrintF("Closure:\n");
10382 CurrentContext()->Print(); 10358 CurrentContext()->Print();
10383 if (CurrentContext()->has_extension()) { 10359 if (CurrentContext()->has_extension()) {
10384 Handle<JSObject> extension = 10360 Handle<Object> extension(CurrentContext()->extension());
10385 Handle<JSObject>(CurrentContext()->extension());
10386 if (extension->IsJSContextExtensionObject()) { 10361 if (extension->IsJSContextExtensionObject()) {
10387 extension->Print(); 10362 extension->Print();
10388 } 10363 }
10389 } 10364 }
10390 break; 10365 break;
10391 }
10392 10366
10393 default: 10367 default:
10394 UNREACHABLE(); 10368 UNREACHABLE();
10395 } 10369 }
10396 PrintF("\n"); 10370 PrintF("\n");
10397 } 10371 }
10398 #endif 10372 #endif
10399 10373
10400 private: 10374 private:
10401 Isolate* isolate_; 10375 Isolate* isolate_;
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
10860 Handle<Context> base) { 10834 Handle<Context> base) {
10861 // At the end of the chain. Return the base context to link to. 10835 // At the end of the chain. Return the base context to link to.
10862 if (current->IsFunctionContext() || current->IsGlobalContext()) { 10836 if (current->IsFunctionContext() || current->IsGlobalContext()) {
10863 return base; 10837 return base;
10864 } 10838 }
10865 10839
10866 // Recursively copy the with and catch contexts. 10840 // Recursively copy the with and catch contexts.
10867 HandleScope scope(isolate); 10841 HandleScope scope(isolate);
10868 Handle<Context> previous(current->previous()); 10842 Handle<Context> previous(current->previous());
10869 Handle<Context> new_previous = CopyWithContextChain(isolate, previous, base); 10843 Handle<Context> new_previous = CopyWithContextChain(isolate, previous, base);
10870 Handle<JSObject> extension(JSObject::cast(current->extension())); 10844 Handle<Context> new_current;
10871 Handle<Context> new_current = current->IsCatchContext() 10845 if (current->IsCatchContext()) {
10872 ? isolate->factory()->NewCatchContext(new_previous, extension) 10846 Handle<String> name(String::cast(current->extension()));
10873 : isolate->factory()->NewWithContext(new_previous, extension); 10847 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
10848 new_current =
10849 isolate->factory()->NewCatchContext(new_previous, name, thrown_object);
10850 } else {
10851 Handle<JSObject> extension(JSObject::cast(current->extension()));
10852 new_current =
10853 isolate->factory()->NewWithContext(new_previous, extension);
10854 }
10874 return scope.CloseAndEscape(new_current); 10855 return scope.CloseAndEscape(new_current);
10875 } 10856 }
10876 10857
10877 10858
10878 // Helper function to find or create the arguments object for 10859 // Helper function to find or create the arguments object for
10879 // Runtime_DebugEvaluate. 10860 // Runtime_DebugEvaluate.
10880 static Handle<Object> GetArgumentsObject(Isolate* isolate, 10861 static Handle<Object> GetArgumentsObject(Isolate* isolate,
10881 JavaScriptFrame* frame, 10862 JavaScriptFrame* frame,
10882 Handle<JSFunction> function, 10863 Handle<JSFunction> function,
10883 Handle<SerializedScopeInfo> scope_info, 10864 Handle<SerializedScopeInfo> scope_info,
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after
12359 } else { 12340 } else {
12360 // Handle last resort GC and make sure to allow future allocations 12341 // Handle last resort GC and make sure to allow future allocations
12361 // to grow the heap without causing GCs (if possible). 12342 // to grow the heap without causing GCs (if possible).
12362 isolate->counters()->gc_last_resort_from_js()->Increment(); 12343 isolate->counters()->gc_last_resort_from_js()->Increment();
12363 isolate->heap()->CollectAllGarbage(false); 12344 isolate->heap()->CollectAllGarbage(false);
12364 } 12345 }
12365 } 12346 }
12366 12347
12367 12348
12368 } } // namespace v8::internal 12349 } } // namespace v8::internal
OLDNEW
« src/contexts.cc ('K') | « src/runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698