| 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 7867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7878 | 7878 |
| 7879 static inline MaybeObject* Unhole(Heap* heap, | 7879 static inline MaybeObject* Unhole(Heap* heap, |
| 7880 MaybeObject* x, | 7880 MaybeObject* x, |
| 7881 PropertyAttributes attributes) { | 7881 PropertyAttributes attributes) { |
| 7882 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); | 7882 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); |
| 7883 USE(attributes); | 7883 USE(attributes); |
| 7884 return x->IsTheHole() ? heap->undefined_value() : x; | 7884 return x->IsTheHole() ? heap->undefined_value() : x; |
| 7885 } | 7885 } |
| 7886 | 7886 |
| 7887 | 7887 |
| 7888 static JSObject* ComputeReceiverForNonGlobal(Isolate* isolate, | 7888 static Object* ComputeReceiverForNonGlobal(Isolate* isolate, |
| 7889 JSObject* holder) { | 7889 JSObject* holder) { |
| 7890 ASSERT(!holder->IsGlobalObject()); | 7890 ASSERT(!holder->IsGlobalObject()); |
| 7891 Context* top = isolate->context(); | 7891 Context* top = isolate->context(); |
| 7892 // Get the context extension function. | 7892 // Get the context extension function. |
| 7893 JSFunction* context_extension_function = | 7893 JSFunction* context_extension_function = |
| 7894 top->global_context()->context_extension_function(); | 7894 top->global_context()->context_extension_function(); |
| 7895 // If the holder isn't a context extension object, we just return it | 7895 // If the holder isn't a context extension object, we just return it |
| 7896 // as the receiver. This allows arguments objects to be used as | 7896 // as the receiver. This allows arguments objects to be used as |
| 7897 // receivers, but only if they are put in the context scope chain | 7897 // receivers, but only if they are put in the context scope chain |
| 7898 // explicitly via a with-statement. | 7898 // explicitly via a with-statement. |
| 7899 Object* constructor = holder->map()->constructor(); | 7899 Object* constructor = holder->map()->constructor(); |
| 7900 if (constructor != context_extension_function) return holder; | 7900 if (constructor != context_extension_function) return holder; |
| 7901 // Fall back to using the global object as the receiver if the | 7901 // Fall back to using the global object as the implicit receiver if |
| 7902 // property turns out to be a local variable allocated in a context | 7902 // the property turns out to be a local variable allocated in a |
| 7903 // extension object - introduced via eval. | 7903 // context extension object - introduced via eval. Implicit global |
| 7904 return top->global()->global_receiver(); | 7904 // receivers are indicated with the hole value. |
| 7905 return isolate->heap()->the_hole_value(); |
| 7905 } | 7906 } |
| 7906 | 7907 |
| 7907 | 7908 |
| 7908 static ObjectPair LoadContextSlotHelper(Arguments args, | 7909 static ObjectPair LoadContextSlotHelper(Arguments args, |
| 7909 Isolate* isolate, | 7910 Isolate* isolate, |
| 7910 bool throw_error) { | 7911 bool throw_error) { |
| 7911 HandleScope scope(isolate); | 7912 HandleScope scope(isolate); |
| 7912 ASSERT_EQ(2, args.length()); | 7913 ASSERT_EQ(2, args.length()); |
| 7913 | 7914 |
| 7914 if (!args[0]->IsContext() || !args[1]->IsString()) { | 7915 if (!args[0]->IsContext() || !args[1]->IsString()) { |
| 7915 return MakePair(isolate->ThrowIllegalOperation(), NULL); | 7916 return MakePair(isolate->ThrowIllegalOperation(), NULL); |
| 7916 } | 7917 } |
| 7917 Handle<Context> context = args.at<Context>(0); | 7918 Handle<Context> context = args.at<Context>(0); |
| 7918 Handle<String> name = args.at<String>(1); | 7919 Handle<String> name = args.at<String>(1); |
| 7919 | 7920 |
| 7920 int index; | 7921 int index; |
| 7921 PropertyAttributes attributes; | 7922 PropertyAttributes attributes; |
| 7922 ContextLookupFlags flags = FOLLOW_CHAINS; | 7923 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 7923 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); | 7924 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); |
| 7924 | 7925 |
| 7925 // If the index is non-negative, the slot has been found in a local | 7926 // If the index is non-negative, the slot has been found in a local |
| 7926 // variable or a parameter. Read it from the context object or the | 7927 // variable or a parameter. Read it from the context object or the |
| 7927 // arguments object. | 7928 // arguments object. |
| 7928 if (index >= 0) { | 7929 if (index >= 0) { |
| 7929 // If the "property" we were looking for is a local variable or an | 7930 // If the "property" we were looking for is a local variable or an |
| 7930 // argument in a context, the receiver is the global object; see | 7931 // argument in a context, the receiver is the global object; see |
| 7931 // ECMA-262, 3rd., 10.1.6 and 10.2.3. | 7932 // ECMA-262, 3rd., 10.1.6 and 10.2.3. |
| 7932 // GetElement below can cause GC. | 7933 // |
| 7933 Handle<JSObject> receiver( | 7934 // Use the hole as the receiver to signal that the receiver is |
| 7934 isolate->context()->global()->global_receiver()); | 7935 // implicit and that the global receiver should be used. |
| 7936 Handle<Object> receiver = isolate->factory()->the_hole_value(); |
| 7935 MaybeObject* value = (holder->IsContext()) | 7937 MaybeObject* value = (holder->IsContext()) |
| 7936 ? Context::cast(*holder)->get(index) | 7938 ? Context::cast(*holder)->get(index) |
| 7937 : JSObject::cast(*holder)->GetElement(index); | 7939 : JSObject::cast(*holder)->GetElement(index); |
| 7938 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); | 7940 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); |
| 7939 } | 7941 } |
| 7940 | 7942 |
| 7941 // If the holder is found, we read the property from it. | 7943 // If the holder is found, we read the property from it. |
| 7942 if (!holder.is_null() && holder->IsJSObject()) { | 7944 if (!holder.is_null() && holder->IsJSObject()) { |
| 7943 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); | 7945 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); |
| 7944 JSObject* object = JSObject::cast(*holder); | 7946 JSObject* object = JSObject::cast(*holder); |
| 7945 JSObject* receiver; | 7947 Object* receiver; |
| 7946 if (object->IsGlobalObject()) { | 7948 if (object->IsGlobalObject()) { |
| 7947 receiver = GlobalObject::cast(object)->global_receiver(); | 7949 receiver = GlobalObject::cast(object)->global_receiver(); |
| 7948 } else if (context->is_exception_holder(*holder)) { | 7950 } else if (context->is_exception_holder(*holder)) { |
| 7949 receiver = isolate->context()->global()->global_receiver(); | 7951 // Use the hole as the receiver to signal that the receiver is |
| 7952 // implicit and that the global receiver should be used. |
| 7953 receiver = isolate->heap()->the_hole_value(); |
| 7950 } else { | 7954 } else { |
| 7951 receiver = ComputeReceiverForNonGlobal(isolate, object); | 7955 receiver = ComputeReceiverForNonGlobal(isolate, object); |
| 7952 } | 7956 } |
| 7953 | 7957 |
| 7954 // GetProperty below can cause GC. | 7958 // GetProperty below can cause GC. |
| 7955 Handle<JSObject> receiver_handle(receiver); | 7959 Handle<Object> receiver_handle(receiver); |
| 7956 | 7960 |
| 7957 // No need to unhole the value here. This is taken care of by the | 7961 // No need to unhole the value here. This is taken care of by the |
| 7958 // GetProperty function. | 7962 // GetProperty function. |
| 7959 MaybeObject* value = object->GetProperty(*name); | 7963 MaybeObject* value = object->GetProperty(*name); |
| 7960 return MakePair(value, *receiver_handle); | 7964 return MakePair(value, *receiver_handle); |
| 7961 } | 7965 } |
| 7962 | 7966 |
| 7963 if (throw_error) { | 7967 if (throw_error) { |
| 7964 // The property doesn't exist - throw exception. | 7968 // The property doesn't exist - throw exception. |
| 7965 Handle<Object> reference_error = | 7969 Handle<Object> reference_error = |
| 7966 isolate->factory()->NewReferenceError("not_defined", | 7970 isolate->factory()->NewReferenceError("not_defined", |
| 7967 HandleVector(&name, 1)); | 7971 HandleVector(&name, 1)); |
| 7968 return MakePair(isolate->Throw(*reference_error), NULL); | 7972 return MakePair(isolate->Throw(*reference_error), NULL); |
| 7969 } else { | 7973 } else { |
| 7970 // The property doesn't exist - return undefined | 7974 // The property doesn't exist - return undefined. |
| 7971 return MakePair(isolate->heap()->undefined_value(), | 7975 return MakePair(isolate->heap()->undefined_value(), |
| 7972 isolate->heap()->undefined_value()); | 7976 isolate->heap()->undefined_value()); |
| 7973 } | 7977 } |
| 7974 } | 7978 } |
| 7975 | 7979 |
| 7976 | 7980 |
| 7977 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) { | 7981 RUNTIME_FUNCTION(ObjectPair, Runtime_LoadContextSlot) { |
| 7978 return LoadContextSlotHelper(args, isolate, true); | 7982 return LoadContextSlotHelper(args, isolate, true); |
| 7979 } | 7983 } |
| 7980 | 7984 |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8472 Handle<Object> reference_error = | 8476 Handle<Object> reference_error = |
| 8473 isolate->factory()->NewReferenceError("not_defined", | 8477 isolate->factory()->NewReferenceError("not_defined", |
| 8474 HandleVector(&name, 1)); | 8478 HandleVector(&name, 1)); |
| 8475 return MakePair(isolate->Throw(*reference_error), NULL); | 8479 return MakePair(isolate->Throw(*reference_error), NULL); |
| 8476 } | 8480 } |
| 8477 | 8481 |
| 8478 if (!context->IsGlobalContext()) { | 8482 if (!context->IsGlobalContext()) { |
| 8479 // 'eval' is not bound in the global context. Just call the function | 8483 // 'eval' is not bound in the global context. Just call the function |
| 8480 // with the given arguments. This is not necessarily the global eval. | 8484 // with the given arguments. This is not necessarily the global eval. |
| 8481 if (receiver->IsContext() || receiver->IsJSContextExtensionObject()) { | 8485 if (receiver->IsContext() || receiver->IsJSContextExtensionObject()) { |
| 8482 receiver = Handle<JSObject>( | 8486 receiver = isolate->factory()->the_hole_value(); |
| 8483 isolate->context()->global()->global_receiver(), isolate); | |
| 8484 } | 8487 } |
| 8485 return MakePair(*callee, *receiver); | 8488 return MakePair(*callee, *receiver); |
| 8486 } | 8489 } |
| 8487 | 8490 |
| 8488 // 'eval' is bound in the global context, but it may have been overwritten. | 8491 // 'eval' is bound in the global context, but it may have been overwritten. |
| 8489 // Compare it to the builtin 'GlobalEval' function to make sure. | 8492 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 8490 if (*callee != isolate->global_context()->global_eval_fun() || | 8493 if (*callee != isolate->global_context()->global_eval_fun() || |
| 8491 !args[1]->IsString()) { | 8494 !args[1]->IsString()) { |
| 8492 return MakePair(*callee, | 8495 return MakePair(*callee, isolate->heap()->the_hole_value()); |
| 8493 isolate->context()->global()->global_receiver()); | |
| 8494 } | 8496 } |
| 8495 | 8497 |
| 8496 ASSERT(args[3]->IsSmi()); | 8498 ASSERT(args[3]->IsSmi()); |
| 8497 return CompileGlobalEval(isolate, | 8499 return CompileGlobalEval(isolate, |
| 8498 args.at<String>(1), | 8500 args.at<String>(1), |
| 8499 args.at<Object>(2), | 8501 args.at<Object>(2), |
| 8500 static_cast<StrictModeFlag>( | 8502 static_cast<StrictModeFlag>( |
| 8501 Smi::cast(args[3])->value())); | 8503 Smi::cast(args[3])->value())); |
| 8502 } | 8504 } |
| 8503 | 8505 |
| 8504 | 8506 |
| 8505 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { | 8507 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { |
| 8506 ASSERT(args.length() == 4); | 8508 ASSERT(args.length() == 4); |
| 8507 | 8509 |
| 8508 HandleScope scope(isolate); | 8510 HandleScope scope(isolate); |
| 8509 Handle<Object> callee = args.at<Object>(0); | 8511 Handle<Object> callee = args.at<Object>(0); |
| 8510 | 8512 |
| 8511 // 'eval' is bound in the global context, but it may have been overwritten. | 8513 // 'eval' is bound in the global context, but it may have been overwritten. |
| 8512 // Compare it to the builtin 'GlobalEval' function to make sure. | 8514 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 8513 if (*callee != isolate->global_context()->global_eval_fun() || | 8515 if (*callee != isolate->global_context()->global_eval_fun() || |
| 8514 !args[1]->IsString()) { | 8516 !args[1]->IsString()) { |
| 8515 return MakePair(*callee, | 8517 return MakePair(*callee, isolate->heap()->the_hole_value()); |
| 8516 isolate->context()->global()->global_receiver()); | |
| 8517 } | 8518 } |
| 8518 | 8519 |
| 8519 ASSERT(args[3]->IsSmi()); | 8520 ASSERT(args[3]->IsSmi()); |
| 8520 return CompileGlobalEval(isolate, | 8521 return CompileGlobalEval(isolate, |
| 8521 args.at<String>(1), | 8522 args.at<String>(1), |
| 8522 args.at<Object>(2), | 8523 args.at<Object>(2), |
| 8523 static_cast<StrictModeFlag>( | 8524 static_cast<StrictModeFlag>( |
| 8524 Smi::cast(args[3])->value())); | 8525 Smi::cast(args[3])->value())); |
| 8525 } | 8526 } |
| 8526 | 8527 |
| (...skipping 3689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12216 } else { | 12217 } else { |
| 12217 // Handle last resort GC and make sure to allow future allocations | 12218 // Handle last resort GC and make sure to allow future allocations |
| 12218 // to grow the heap without causing GCs (if possible). | 12219 // to grow the heap without causing GCs (if possible). |
| 12219 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12220 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 12220 isolate->heap()->CollectAllGarbage(false); | 12221 isolate->heap()->CollectAllGarbage(false); |
| 12221 } | 12222 } |
| 12222 } | 12223 } |
| 12223 | 12224 |
| 12224 | 12225 |
| 12225 } } // namespace v8::internal | 12226 } } // namespace v8::internal |
| OLD | NEW |