Chromium Code Reviews| 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 |