OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |