OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 MaybeObject* maybe = GetHeap()->Uint32ToString(index); | 512 MaybeObject* maybe = GetHeap()->Uint32ToString(index); |
513 if (!maybe->To<String>(&name)) return maybe; | 513 if (!maybe->To<String>(&name)) return maybe; |
514 return GetPropertyWithHandler(receiver, name); | 514 return GetPropertyWithHandler(receiver, name); |
515 } | 515 } |
516 | 516 |
517 | 517 |
518 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, | 518 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, |
519 Handle<JSReceiver> receiver, | 519 Handle<JSReceiver> receiver, |
520 uint32_t index, | 520 uint32_t index, |
521 Handle<Object> value, | 521 Handle<Object> value, |
522 StrictModeFlag strict_mode) { | 522 StrictMode strict_mode) { |
523 Isolate* isolate = proxy->GetIsolate(); | 523 Isolate* isolate = proxy->GetIsolate(); |
524 Handle<String> name = isolate->factory()->Uint32ToString(index); | 524 Handle<String> name = isolate->factory()->Uint32ToString(index); |
525 return SetPropertyWithHandler( | 525 return SetPropertyWithHandler( |
526 proxy, receiver, name, value, NONE, strict_mode); | 526 proxy, receiver, name, value, NONE, strict_mode); |
527 } | 527 } |
528 | 528 |
529 | 529 |
530 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { | 530 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { |
531 Isolate* isolate = proxy->GetIsolate(); | 531 Isolate* isolate = proxy->GetIsolate(); |
532 Handle<String> name = isolate->factory()->Uint32ToString(index); | 532 Handle<String> name = isolate->factory()->Uint32ToString(index); |
(...skipping 1604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2137 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 2137 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
2138 Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details); | 2138 Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details); |
2139 if (*dict != *result) object->set_properties(*result); | 2139 if (*dict != *result) object->set_properties(*result); |
2140 } | 2140 } |
2141 | 2141 |
2142 | 2142 |
2143 Handle<Object> JSObject::AddProperty(Handle<JSObject> object, | 2143 Handle<Object> JSObject::AddProperty(Handle<JSObject> object, |
2144 Handle<Name> name, | 2144 Handle<Name> name, |
2145 Handle<Object> value, | 2145 Handle<Object> value, |
2146 PropertyAttributes attributes, | 2146 PropertyAttributes attributes, |
2147 StrictModeFlag strict_mode, | 2147 StrictMode strict_mode, |
2148 JSReceiver::StoreFromKeyed store_mode, | 2148 JSReceiver::StoreFromKeyed store_mode, |
2149 ExtensibilityCheck extensibility_check, | 2149 ExtensibilityCheck extensibility_check, |
2150 ValueType value_type, | 2150 ValueType value_type, |
2151 StoreMode mode, | 2151 StoreMode mode, |
2152 TransitionFlag transition_flag) { | 2152 TransitionFlag transition_flag) { |
2153 ASSERT(!object->IsJSGlobalProxy()); | 2153 ASSERT(!object->IsJSGlobalProxy()); |
2154 Isolate* isolate = object->GetIsolate(); | 2154 Isolate* isolate = object->GetIsolate(); |
2155 | 2155 |
2156 if (!name->IsUniqueName()) { | 2156 if (!name->IsUniqueName()) { |
2157 name = isolate->factory()->InternalizeString( | 2157 name = isolate->factory()->InternalizeString( |
2158 Handle<String>::cast(name)); | 2158 Handle<String>::cast(name)); |
2159 } | 2159 } |
2160 | 2160 |
2161 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 2161 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
2162 !object->map()->is_extensible()) { | 2162 !object->map()->is_extensible()) { |
2163 if (strict_mode == kSloppyMode) { | 2163 if (strict_mode == SLOPPY) { |
2164 return value; | 2164 return value; |
2165 } else { | 2165 } else { |
2166 Handle<Object> args[1] = { name }; | 2166 Handle<Object> args[1] = { name }; |
2167 Handle<Object> error = isolate->factory()->NewTypeError( | 2167 Handle<Object> error = isolate->factory()->NewTypeError( |
2168 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 2168 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
2169 isolate->Throw(*error); | 2169 isolate->Throw(*error); |
2170 return Handle<Object>(); | 2170 return Handle<Object>(); |
2171 } | 2171 } |
2172 } | 2172 } |
2173 | 2173 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2226 &threw); | 2226 &threw); |
2227 ASSERT(!threw); | 2227 ASSERT(!threw); |
2228 } | 2228 } |
2229 | 2229 |
2230 | 2230 |
2231 Handle<Object> JSObject::SetPropertyPostInterceptor( | 2231 Handle<Object> JSObject::SetPropertyPostInterceptor( |
2232 Handle<JSObject> object, | 2232 Handle<JSObject> object, |
2233 Handle<Name> name, | 2233 Handle<Name> name, |
2234 Handle<Object> value, | 2234 Handle<Object> value, |
2235 PropertyAttributes attributes, | 2235 PropertyAttributes attributes, |
2236 StrictModeFlag strict_mode) { | 2236 StrictMode strict_mode) { |
2237 // Check local property, ignore interceptor. | 2237 // Check local property, ignore interceptor. |
2238 LookupResult result(object->GetIsolate()); | 2238 LookupResult result(object->GetIsolate()); |
2239 object->LocalLookupRealNamedProperty(*name, &result); | 2239 object->LocalLookupRealNamedProperty(*name, &result); |
2240 if (!result.IsFound()) { | 2240 if (!result.IsFound()) { |
2241 object->map()->LookupTransition(*object, *name, &result); | 2241 object->map()->LookupTransition(*object, *name, &result); |
2242 } | 2242 } |
2243 if (result.IsFound()) { | 2243 if (result.IsFound()) { |
2244 // An existing property or a map transition was found. Use set property to | 2244 // An existing property or a map transition was found. Use set property to |
2245 // handle all these cases. | 2245 // handle all these cases. |
2246 return SetPropertyForResult(object, &result, name, value, attributes, | 2246 return SetPropertyForResult(object, &result, name, value, attributes, |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2841 | 2841 |
2842 return handle(updated); | 2842 return handle(updated); |
2843 } | 2843 } |
2844 | 2844 |
2845 | 2845 |
2846 Handle<Object> JSObject::SetPropertyWithInterceptor( | 2846 Handle<Object> JSObject::SetPropertyWithInterceptor( |
2847 Handle<JSObject> object, | 2847 Handle<JSObject> object, |
2848 Handle<Name> name, | 2848 Handle<Name> name, |
2849 Handle<Object> value, | 2849 Handle<Object> value, |
2850 PropertyAttributes attributes, | 2850 PropertyAttributes attributes, |
2851 StrictModeFlag strict_mode) { | 2851 StrictMode strict_mode) { |
2852 // TODO(rossberg): Support symbols in the API. | 2852 // TODO(rossberg): Support symbols in the API. |
2853 if (name->IsSymbol()) return value; | 2853 if (name->IsSymbol()) return value; |
2854 Isolate* isolate = object->GetIsolate(); | 2854 Isolate* isolate = object->GetIsolate(); |
2855 Handle<String> name_string = Handle<String>::cast(name); | 2855 Handle<String> name_string = Handle<String>::cast(name); |
2856 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | 2856 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
2857 if (!interceptor->setter()->IsUndefined()) { | 2857 if (!interceptor->setter()->IsUndefined()) { |
2858 LOG(isolate, | 2858 LOG(isolate, |
2859 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); | 2859 ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); |
2860 PropertyCallbackArguments args( | 2860 PropertyCallbackArguments args( |
2861 isolate, interceptor->data(), *object, *object); | 2861 isolate, interceptor->data(), *object, *object); |
(...skipping 11 matching lines...) Expand all Loading... |
2873 SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); | 2873 SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); |
2874 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 2874 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
2875 return result; | 2875 return result; |
2876 } | 2876 } |
2877 | 2877 |
2878 | 2878 |
2879 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 2879 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
2880 Handle<Name> name, | 2880 Handle<Name> name, |
2881 Handle<Object> value, | 2881 Handle<Object> value, |
2882 PropertyAttributes attributes, | 2882 PropertyAttributes attributes, |
2883 StrictModeFlag strict_mode, | 2883 StrictMode strict_mode, |
2884 StoreFromKeyed store_mode) { | 2884 StoreFromKeyed store_mode) { |
2885 LookupResult result(object->GetIsolate()); | 2885 LookupResult result(object->GetIsolate()); |
2886 object->LocalLookup(*name, &result, true); | 2886 object->LocalLookup(*name, &result, true); |
2887 if (!result.IsFound()) { | 2887 if (!result.IsFound()) { |
2888 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); | 2888 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); |
2889 } | 2889 } |
2890 return SetProperty(object, &result, name, value, attributes, strict_mode, | 2890 return SetProperty(object, &result, name, value, attributes, strict_mode, |
2891 store_mode); | 2891 store_mode); |
2892 } | 2892 } |
2893 | 2893 |
2894 | 2894 |
2895 Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object, | 2895 Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object, |
2896 Handle<Object> structure, | 2896 Handle<Object> structure, |
2897 Handle<Name> name, | 2897 Handle<Name> name, |
2898 Handle<Object> value, | 2898 Handle<Object> value, |
2899 Handle<JSObject> holder, | 2899 Handle<JSObject> holder, |
2900 StrictModeFlag strict_mode) { | 2900 StrictMode strict_mode) { |
2901 Isolate* isolate = object->GetIsolate(); | 2901 Isolate* isolate = object->GetIsolate(); |
2902 | 2902 |
2903 // We should never get here to initialize a const with the hole | 2903 // We should never get here to initialize a const with the hole |
2904 // value since a const declaration would conflict with the setter. | 2904 // value since a const declaration would conflict with the setter. |
2905 ASSERT(!value->IsTheHole()); | 2905 ASSERT(!value->IsTheHole()); |
2906 | 2906 |
2907 // To accommodate both the old and the new api we switch on the | 2907 // To accommodate both the old and the new api we switch on the |
2908 // data structure used to store the callbacks. Eventually foreign | 2908 // data structure used to store the callbacks. Eventually foreign |
2909 // callbacks should be phased out. | 2909 // callbacks should be phased out. |
2910 if (structure->IsForeign()) { | 2910 if (structure->IsForeign()) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2949 return value; | 2949 return value; |
2950 } | 2950 } |
2951 | 2951 |
2952 if (structure->IsAccessorPair()) { | 2952 if (structure->IsAccessorPair()) { |
2953 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 2953 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
2954 if (setter->IsSpecFunction()) { | 2954 if (setter->IsSpecFunction()) { |
2955 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 2955 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
2956 return SetPropertyWithDefinedSetter( | 2956 return SetPropertyWithDefinedSetter( |
2957 object, Handle<JSReceiver>::cast(setter), value); | 2957 object, Handle<JSReceiver>::cast(setter), value); |
2958 } else { | 2958 } else { |
2959 if (strict_mode == kSloppyMode) { | 2959 if (strict_mode == SLOPPY) return value; |
2960 return value; | |
2961 } | |
2962 Handle<Object> args[2] = { name, holder }; | 2960 Handle<Object> args[2] = { name, holder }; |
2963 Handle<Object> error = | 2961 Handle<Object> error = |
2964 isolate->factory()->NewTypeError("no_setter_in_callback", | 2962 isolate->factory()->NewTypeError("no_setter_in_callback", |
2965 HandleVector(args, 2)); | 2963 HandleVector(args, 2)); |
2966 isolate->Throw(*error); | 2964 isolate->Throw(*error); |
2967 return Handle<Object>(); | 2965 return Handle<Object>(); |
2968 } | 2966 } |
2969 } | 2967 } |
2970 | 2968 |
2971 // TODO(dcarney): Handle correctly. | 2969 // TODO(dcarney): Handle correctly. |
(...skipping 30 matching lines...) Expand all Loading... |
3002 if (has_pending_exception) return Handle<Object>(); | 3000 if (has_pending_exception) return Handle<Object>(); |
3003 return value; | 3001 return value; |
3004 } | 3002 } |
3005 | 3003 |
3006 | 3004 |
3007 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( | 3005 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
3008 Handle<JSObject> object, | 3006 Handle<JSObject> object, |
3009 uint32_t index, | 3007 uint32_t index, |
3010 Handle<Object> value, | 3008 Handle<Object> value, |
3011 bool* found, | 3009 bool* found, |
3012 StrictModeFlag strict_mode) { | 3010 StrictMode strict_mode) { |
3013 Isolate *isolate = object->GetIsolate(); | 3011 Isolate *isolate = object->GetIsolate(); |
3014 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); | 3012 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); |
3015 !proto->IsNull(); | 3013 !proto->IsNull(); |
3016 proto = handle(proto->GetPrototype(isolate), isolate)) { | 3014 proto = handle(proto->GetPrototype(isolate), isolate)) { |
3017 if (proto->IsJSProxy()) { | 3015 if (proto->IsJSProxy()) { |
3018 return JSProxy::SetPropertyViaPrototypesWithHandler( | 3016 return JSProxy::SetPropertyViaPrototypesWithHandler( |
3019 Handle<JSProxy>::cast(proto), | 3017 Handle<JSProxy>::cast(proto), |
3020 object, | 3018 object, |
3021 isolate->factory()->Uint32ToString(index), // name | 3019 isolate->factory()->Uint32ToString(index), // name |
3022 value, | 3020 value, |
(...skipping 19 matching lines...) Expand all Loading... |
3042 } | 3040 } |
3043 *found = false; | 3041 *found = false; |
3044 return isolate->factory()->the_hole_value(); | 3042 return isolate->factory()->the_hole_value(); |
3045 } | 3043 } |
3046 | 3044 |
3047 | 3045 |
3048 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, | 3046 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
3049 Handle<Name> name, | 3047 Handle<Name> name, |
3050 Handle<Object> value, | 3048 Handle<Object> value, |
3051 PropertyAttributes attributes, | 3049 PropertyAttributes attributes, |
3052 StrictModeFlag strict_mode, | 3050 StrictMode strict_mode, |
3053 bool* done) { | 3051 bool* done) { |
3054 Isolate* isolate = object->GetIsolate(); | 3052 Isolate* isolate = object->GetIsolate(); |
3055 | 3053 |
3056 *done = false; | 3054 *done = false; |
3057 // We could not find a local property so let's check whether there is an | 3055 // We could not find a local property so let's check whether there is an |
3058 // accessor that wants to handle the property, or whether the property is | 3056 // accessor that wants to handle the property, or whether the property is |
3059 // read-only on the prototype chain. | 3057 // read-only on the prototype chain. |
3060 LookupResult result(isolate); | 3058 LookupResult result(isolate); |
3061 object->LookupRealNamedPropertyInPrototypes(*name, &result); | 3059 object->LookupRealNamedPropertyInPrototypes(*name, &result); |
3062 if (result.IsFound()) { | 3060 if (result.IsFound()) { |
(...skipping 23 matching lines...) Expand all Loading... |
3086 } | 3084 } |
3087 case TRANSITION: | 3085 case TRANSITION: |
3088 case NONEXISTENT: | 3086 case NONEXISTENT: |
3089 UNREACHABLE(); | 3087 UNREACHABLE(); |
3090 break; | 3088 break; |
3091 } | 3089 } |
3092 } | 3090 } |
3093 | 3091 |
3094 // If we get here with *done true, we have encountered a read-only property. | 3092 // If we get here with *done true, we have encountered a read-only property. |
3095 if (*done) { | 3093 if (*done) { |
3096 if (strict_mode == kSloppyMode) return value; | 3094 if (strict_mode == SLOPPY) return value; |
3097 Handle<Object> args[] = { name, object }; | 3095 Handle<Object> args[] = { name, object }; |
3098 Handle<Object> error = isolate->factory()->NewTypeError( | 3096 Handle<Object> error = isolate->factory()->NewTypeError( |
3099 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3097 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
3100 isolate->Throw(*error); | 3098 isolate->Throw(*error); |
3101 return Handle<Object>(); | 3099 return Handle<Object>(); |
3102 } | 3100 } |
3103 return isolate->factory()->the_hole_value(); | 3101 return isolate->factory()->the_hole_value(); |
3104 } | 3102 } |
3105 | 3103 |
3106 | 3104 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3454 } | 3452 } |
3455 | 3453 |
3456 | 3454 |
3457 // We only need to deal with CALLBACKS and INTERCEPTORS | 3455 // We only need to deal with CALLBACKS and INTERCEPTORS |
3458 Handle<Object> JSObject::SetPropertyWithFailedAccessCheck( | 3456 Handle<Object> JSObject::SetPropertyWithFailedAccessCheck( |
3459 Handle<JSObject> object, | 3457 Handle<JSObject> object, |
3460 LookupResult* result, | 3458 LookupResult* result, |
3461 Handle<Name> name, | 3459 Handle<Name> name, |
3462 Handle<Object> value, | 3460 Handle<Object> value, |
3463 bool check_prototype, | 3461 bool check_prototype, |
3464 StrictModeFlag strict_mode) { | 3462 StrictMode strict_mode) { |
3465 if (check_prototype && !result->IsProperty()) { | 3463 if (check_prototype && !result->IsProperty()) { |
3466 object->LookupRealNamedPropertyInPrototypes(*name, result); | 3464 object->LookupRealNamedPropertyInPrototypes(*name, result); |
3467 } | 3465 } |
3468 | 3466 |
3469 if (result->IsProperty()) { | 3467 if (result->IsProperty()) { |
3470 if (!result->IsReadOnly()) { | 3468 if (!result->IsReadOnly()) { |
3471 switch (result->type()) { | 3469 switch (result->type()) { |
3472 case CALLBACKS: { | 3470 case CALLBACKS: { |
3473 Object* obj = result->GetCallbackObject(); | 3471 Object* obj = result->GetCallbackObject(); |
3474 if (obj->IsAccessorInfo()) { | 3472 if (obj->IsAccessorInfo()) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3521 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 3519 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
3522 return value; | 3520 return value; |
3523 } | 3521 } |
3524 | 3522 |
3525 | 3523 |
3526 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 3524 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
3527 LookupResult* result, | 3525 LookupResult* result, |
3528 Handle<Name> key, | 3526 Handle<Name> key, |
3529 Handle<Object> value, | 3527 Handle<Object> value, |
3530 PropertyAttributes attributes, | 3528 PropertyAttributes attributes, |
3531 StrictModeFlag strict_mode, | 3529 StrictMode strict_mode, |
3532 StoreFromKeyed store_mode) { | 3530 StoreFromKeyed store_mode) { |
3533 if (result->IsHandler()) { | 3531 if (result->IsHandler()) { |
3534 return JSProxy::SetPropertyWithHandler(handle(result->proxy()), | 3532 return JSProxy::SetPropertyWithHandler(handle(result->proxy()), |
3535 object, key, value, attributes, strict_mode); | 3533 object, key, value, attributes, strict_mode); |
3536 } else { | 3534 } else { |
3537 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object), | 3535 return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object), |
3538 result, key, value, attributes, strict_mode, store_mode); | 3536 result, key, value, attributes, strict_mode, store_mode); |
3539 } | 3537 } |
3540 } | 3538 } |
3541 | 3539 |
(...skipping 11 matching lines...) Expand all Loading... |
3553 | 3551 |
3554 return result->BooleanValue(); | 3552 return result->BooleanValue(); |
3555 } | 3553 } |
3556 | 3554 |
3557 | 3555 |
3558 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, | 3556 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, |
3559 Handle<JSReceiver> receiver, | 3557 Handle<JSReceiver> receiver, |
3560 Handle<Name> name, | 3558 Handle<Name> name, |
3561 Handle<Object> value, | 3559 Handle<Object> value, |
3562 PropertyAttributes attributes, | 3560 PropertyAttributes attributes, |
3563 StrictModeFlag strict_mode) { | 3561 StrictMode strict_mode) { |
3564 Isolate* isolate = proxy->GetIsolate(); | 3562 Isolate* isolate = proxy->GetIsolate(); |
3565 | 3563 |
3566 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3564 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
3567 if (name->IsSymbol()) return value; | 3565 if (name->IsSymbol()) return value; |
3568 | 3566 |
3569 Handle<Object> args[] = { receiver, name, value }; | 3567 Handle<Object> args[] = { receiver, name, value }; |
3570 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); | 3568 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); |
3571 if (isolate->has_pending_exception()) return Handle<Object>(); | 3569 if (isolate->has_pending_exception()) return Handle<Object>(); |
3572 | 3570 |
3573 return value; | 3571 return value; |
3574 } | 3572 } |
3575 | 3573 |
3576 | 3574 |
3577 Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( | 3575 Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( |
3578 Handle<JSProxy> proxy, | 3576 Handle<JSProxy> proxy, |
3579 Handle<JSReceiver> receiver, | 3577 Handle<JSReceiver> receiver, |
3580 Handle<Name> name, | 3578 Handle<Name> name, |
3581 Handle<Object> value, | 3579 Handle<Object> value, |
3582 PropertyAttributes attributes, | 3580 PropertyAttributes attributes, |
3583 StrictModeFlag strict_mode, | 3581 StrictMode strict_mode, |
3584 bool* done) { | 3582 bool* done) { |
3585 Isolate* isolate = proxy->GetIsolate(); | 3583 Isolate* isolate = proxy->GetIsolate(); |
3586 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. | 3584 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. |
3587 | 3585 |
3588 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3586 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
3589 if (name->IsSymbol()) { | 3587 if (name->IsSymbol()) { |
3590 *done = false; | 3588 *done = false; |
3591 return isolate->factory()->the_hole_value(); | 3589 return isolate->factory()->the_hole_value(); |
3592 } | 3590 } |
3593 | 3591 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3641 if (hasWritable->IsTrue()) { | 3639 if (hasWritable->IsTrue()) { |
3642 Handle<String> writable_name = | 3640 Handle<String> writable_name = |
3643 isolate->factory()->InternalizeOneByteString( | 3641 isolate->factory()->InternalizeOneByteString( |
3644 STATIC_ASCII_VECTOR("writable_")); | 3642 STATIC_ASCII_VECTOR("writable_")); |
3645 Handle<Object> writable( | 3643 Handle<Object> writable( |
3646 v8::internal::GetProperty(isolate, desc, writable_name)); | 3644 v8::internal::GetProperty(isolate, desc, writable_name)); |
3647 ASSERT(!isolate->has_pending_exception()); | 3645 ASSERT(!isolate->has_pending_exception()); |
3648 ASSERT(writable->IsTrue() || writable->IsFalse()); | 3646 ASSERT(writable->IsTrue() || writable->IsFalse()); |
3649 *done = writable->IsFalse(); | 3647 *done = writable->IsFalse(); |
3650 if (!*done) return isolate->factory()->the_hole_value(); | 3648 if (!*done) return isolate->factory()->the_hole_value(); |
3651 if (strict_mode == kSloppyMode) return value; | 3649 if (strict_mode == SLOPPY) return value; |
3652 Handle<Object> args[] = { name, receiver }; | 3650 Handle<Object> args[] = { name, receiver }; |
3653 Handle<Object> error = isolate->factory()->NewTypeError( | 3651 Handle<Object> error = isolate->factory()->NewTypeError( |
3654 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3652 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
3655 isolate->Throw(*error); | 3653 isolate->Throw(*error); |
3656 return Handle<Object>(); | 3654 return Handle<Object>(); |
3657 } | 3655 } |
3658 | 3656 |
3659 // We have an AccessorDescriptor. | 3657 // We have an AccessorDescriptor. |
3660 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( | 3658 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( |
3661 STATIC_ASCII_VECTOR("set_")); | 3659 STATIC_ASCII_VECTOR("set_")); |
3662 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name)); | 3660 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name)); |
3663 ASSERT(!isolate->has_pending_exception()); | 3661 ASSERT(!isolate->has_pending_exception()); |
3664 if (!setter->IsUndefined()) { | 3662 if (!setter->IsUndefined()) { |
3665 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3663 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
3666 return SetPropertyWithDefinedSetter( | 3664 return SetPropertyWithDefinedSetter( |
3667 receiver, Handle<JSReceiver>::cast(setter), value); | 3665 receiver, Handle<JSReceiver>::cast(setter), value); |
3668 } | 3666 } |
3669 | 3667 |
3670 if (strict_mode == kSloppyMode) return value; | 3668 if (strict_mode == SLOPPY) return value; |
3671 Handle<Object> args2[] = { name, proxy }; | 3669 Handle<Object> args2[] = { name, proxy }; |
3672 Handle<Object> error = isolate->factory()->NewTypeError( | 3670 Handle<Object> error = isolate->factory()->NewTypeError( |
3673 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | 3671 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); |
3674 isolate->Throw(*error); | 3672 isolate->Throw(*error); |
3675 return Handle<Object>(); | 3673 return Handle<Object>(); |
3676 } | 3674 } |
3677 | 3675 |
3678 | 3676 |
3679 Handle<Object> JSProxy::DeletePropertyWithHandler( | 3677 Handle<Object> JSProxy::DeletePropertyWithHandler( |
3680 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { | 3678 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3910 int descriptor = transition_map->LastAdded(); | 3908 int descriptor = transition_map->LastAdded(); |
3911 | 3909 |
3912 DescriptorArray* descriptors = transition_map->instance_descriptors(); | 3910 DescriptorArray* descriptors = transition_map->instance_descriptors(); |
3913 PropertyDetails details = descriptors->GetDetails(descriptor); | 3911 PropertyDetails details = descriptors->GetDetails(descriptor); |
3914 | 3912 |
3915 if (details.type() == CALLBACKS || attributes != details.attributes()) { | 3913 if (details.type() == CALLBACKS || attributes != details.attributes()) { |
3916 // AddProperty will either normalize the object, or create a new fast copy | 3914 // AddProperty will either normalize the object, or create a new fast copy |
3917 // of the map. If we get a fast copy of the map, all field representations | 3915 // of the map. If we get a fast copy of the map, all field representations |
3918 // will be tagged since the transition is omitted. | 3916 // will be tagged since the transition is omitted. |
3919 return JSObject::AddProperty( | 3917 return JSObject::AddProperty( |
3920 object, name, value, attributes, kSloppyMode, | 3918 object, name, value, attributes, SLOPPY, |
3921 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 3919 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
3922 JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 3920 JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
3923 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 3921 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
3924 } | 3922 } |
3925 | 3923 |
3926 // Keep the target CONSTANT if the same value is stored. | 3924 // Keep the target CONSTANT if the same value is stored. |
3927 // TODO(verwaest): Also support keeping the placeholder | 3925 // TODO(verwaest): Also support keeping the placeholder |
3928 // (value->IsUninitialized) as constant. | 3926 // (value->IsUninitialized) as constant. |
3929 if (details.type() == CONSTANT && | 3927 if (details.type() == CONSTANT && |
3930 descriptors->GetValue(descriptor) == *value) { | 3928 descriptors->GetValue(descriptor) == *value) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4022 ConvertAndSetLocalProperty(lookup, name, value, attributes); | 4020 ConvertAndSetLocalProperty(lookup, name, value, attributes); |
4023 } | 4021 } |
4024 } | 4022 } |
4025 | 4023 |
4026 | 4024 |
4027 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object, | 4025 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object, |
4028 LookupResult* lookup, | 4026 LookupResult* lookup, |
4029 Handle<Name> name, | 4027 Handle<Name> name, |
4030 Handle<Object> value, | 4028 Handle<Object> value, |
4031 PropertyAttributes attributes, | 4029 PropertyAttributes attributes, |
4032 StrictModeFlag strict_mode, | 4030 StrictMode strict_mode, |
4033 StoreFromKeyed store_mode) { | 4031 StoreFromKeyed store_mode) { |
4034 Isolate* isolate = object->GetIsolate(); | 4032 Isolate* isolate = object->GetIsolate(); |
4035 | 4033 |
4036 // Make sure that the top context does not change when doing callbacks or | 4034 // Make sure that the top context does not change when doing callbacks or |
4037 // interceptor calls. | 4035 // interceptor calls. |
4038 AssertNoContextChange ncc(isolate); | 4036 AssertNoContextChange ncc(isolate); |
4039 | 4037 |
4040 // Optimization for 2-byte strings often used as keys in a decompression | 4038 // Optimization for 2-byte strings often used as keys in a decompression |
4041 // dictionary. We internalize these short keys to avoid constantly | 4039 // dictionary. We internalize these short keys to avoid constantly |
4042 // reallocating them. | 4040 // reallocating them. |
(...skipping 28 matching lines...) Expand all Loading... |
4071 if (done) return result_object; | 4069 if (done) return result_object; |
4072 } | 4070 } |
4073 | 4071 |
4074 if (!lookup->IsFound()) { | 4072 if (!lookup->IsFound()) { |
4075 // Neither properties nor transitions found. | 4073 // Neither properties nor transitions found. |
4076 return AddProperty( | 4074 return AddProperty( |
4077 object, name, value, attributes, strict_mode, store_mode); | 4075 object, name, value, attributes, strict_mode, store_mode); |
4078 } | 4076 } |
4079 | 4077 |
4080 if (lookup->IsProperty() && lookup->IsReadOnly()) { | 4078 if (lookup->IsProperty() && lookup->IsReadOnly()) { |
4081 if (strict_mode == kStrictMode) { | 4079 if (strict_mode == STRICT) { |
4082 Handle<Object> args[] = { name, object }; | 4080 Handle<Object> args[] = { name, object }; |
4083 Handle<Object> error = isolate->factory()->NewTypeError( | 4081 Handle<Object> error = isolate->factory()->NewTypeError( |
4084 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 4082 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
4085 isolate->Throw(*error); | 4083 isolate->Throw(*error); |
4086 return Handle<Object>(); | 4084 return Handle<Object>(); |
4087 } else { | 4085 } else { |
4088 return value; | 4086 return value; |
4089 } | 4087 } |
4090 } | 4088 } |
4091 | 4089 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4177 LookupResult lookup(isolate); | 4175 LookupResult lookup(isolate); |
4178 object->LocalLookup(*name, &lookup, true); | 4176 object->LocalLookup(*name, &lookup, true); |
4179 if (!lookup.IsFound()) { | 4177 if (!lookup.IsFound()) { |
4180 object->map()->LookupTransition(*object, *name, &lookup); | 4178 object->map()->LookupTransition(*object, *name, &lookup); |
4181 } | 4179 } |
4182 | 4180 |
4183 // Check access rights if needed. | 4181 // Check access rights if needed. |
4184 if (object->IsAccessCheckNeeded()) { | 4182 if (object->IsAccessCheckNeeded()) { |
4185 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { | 4183 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
4186 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, | 4184 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value, |
4187 false, kSloppyMode); | 4185 false, SLOPPY); |
4188 } | 4186 } |
4189 } | 4187 } |
4190 | 4188 |
4191 if (object->IsJSGlobalProxy()) { | 4189 if (object->IsJSGlobalProxy()) { |
4192 Handle<Object> proto(object->GetPrototype(), isolate); | 4190 Handle<Object> proto(object->GetPrototype(), isolate); |
4193 if (proto->IsNull()) return value; | 4191 if (proto->IsNull()) return value; |
4194 ASSERT(proto->IsJSGlobalObject()); | 4192 ASSERT(proto->IsJSGlobalObject()); |
4195 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), | 4193 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), |
4196 name, value, attributes, value_type, mode, extensibility_check); | 4194 name, value, attributes, value_type, mode, extensibility_check); |
4197 } | 4195 } |
4198 | 4196 |
4199 if (lookup.IsFound() && | 4197 if (lookup.IsFound() && |
4200 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { | 4198 (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { |
4201 object->LocalLookupRealNamedProperty(*name, &lookup); | 4199 object->LocalLookupRealNamedProperty(*name, &lookup); |
4202 } | 4200 } |
4203 | 4201 |
4204 // Check for accessor in prototype chain removed here in clone. | 4202 // Check for accessor in prototype chain removed here in clone. |
4205 if (!lookup.IsFound()) { | 4203 if (!lookup.IsFound()) { |
4206 object->map()->LookupTransition(*object, *name, &lookup); | 4204 object->map()->LookupTransition(*object, *name, &lookup); |
4207 TransitionFlag flag = lookup.IsFound() | 4205 TransitionFlag flag = lookup.IsFound() |
4208 ? OMIT_TRANSITION : INSERT_TRANSITION; | 4206 ? OMIT_TRANSITION : INSERT_TRANSITION; |
4209 // Neither properties nor transitions found. | 4207 // Neither properties nor transitions found. |
4210 return AddProperty(object, name, value, attributes, kSloppyMode, | 4208 return AddProperty(object, name, value, attributes, SLOPPY, |
4211 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); | 4209 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); |
4212 } | 4210 } |
4213 | 4211 |
4214 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 4212 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
4215 PropertyAttributes old_attributes = ABSENT; | 4213 PropertyAttributes old_attributes = ABSENT; |
4216 bool is_observed = FLAG_harmony_observation && | 4214 bool is_observed = FLAG_harmony_observation && |
4217 object->map()->is_observed() && | 4215 object->map()->is_observed() && |
4218 *name != isolate->heap()->hidden_string(); | 4216 *name != isolate->heap()->hidden_string(); |
4219 if (is_observed && lookup.IsProperty()) { | 4217 if (is_observed && lookup.IsProperty()) { |
4220 if (lookup.IsDataProperty()) old_value = | 4218 if (lookup.IsDataProperty()) old_value = |
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5405 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; | 5403 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; |
5406 break; | 5404 break; |
5407 } | 5405 } |
5408 } | 5406 } |
5409 | 5407 |
5410 // For functions check the context. | 5408 // For functions check the context. |
5411 if (IsJSFunction()) { | 5409 if (IsJSFunction()) { |
5412 // Get the constructor function for arguments array. | 5410 // Get the constructor function for arguments array. |
5413 JSObject* arguments_boilerplate = | 5411 JSObject* arguments_boilerplate = |
5414 heap->isolate()->context()->native_context()-> | 5412 heap->isolate()->context()->native_context()-> |
5415 arguments_boilerplate(); | 5413 sloppy_arguments_boilerplate(); |
5416 JSFunction* arguments_function = | 5414 JSFunction* arguments_function = |
5417 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 5415 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
5418 | 5416 |
5419 // Get the context and don't check if it is the native context. | 5417 // Get the context and don't check if it is the native context. |
5420 JSFunction* f = JSFunction::cast(this); | 5418 JSFunction* f = JSFunction::cast(this); |
5421 Context* context = f->context(); | 5419 Context* context = f->context(); |
5422 if (context->IsNativeContext()) { | 5420 if (context->IsNativeContext()) { |
5423 return false; | 5421 return false; |
5424 } | 5422 } |
5425 | 5423 |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5789 Handle<Object> value( | 5787 Handle<Object> value( |
5790 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), | 5788 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), |
5791 isolate); | 5789 isolate); |
5792 if (value->IsJSObject()) { | 5790 if (value->IsJSObject()) { |
5793 Handle<JSObject> result = VisitElementOrProperty( | 5791 Handle<JSObject> result = VisitElementOrProperty( |
5794 copy, Handle<JSObject>::cast(value)); | 5792 copy, Handle<JSObject>::cast(value)); |
5795 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5793 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
5796 if (copying) { | 5794 if (copying) { |
5797 // Creating object copy for literals. No strict mode needed. | 5795 // Creating object copy for literals. No strict mode needed. |
5798 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( | 5796 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( |
5799 copy, key_string, result, NONE, kSloppyMode)); | 5797 copy, key_string, result, NONE, SLOPPY)); |
5800 } | 5798 } |
5801 } | 5799 } |
5802 } | 5800 } |
5803 } | 5801 } |
5804 | 5802 |
5805 // Deep copy local elements. | 5803 // Deep copy local elements. |
5806 // Pixel elements cannot be created using an object literal. | 5804 // Pixel elements cannot be created using an object literal. |
5807 ASSERT(!copy->HasExternalArrayElements()); | 5805 ASSERT(!copy->HasExternalArrayElements()); |
5808 switch (kind) { | 5806 switch (kind) { |
5809 case FAST_SMI_ELEMENTS: | 5807 case FAST_SMI_ELEMENTS: |
(...skipping 3983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9793 } else { | 9791 } else { |
9794 function->map()->set_non_instance_prototype(false); | 9792 function->map()->set_non_instance_prototype(false); |
9795 } | 9793 } |
9796 | 9794 |
9797 return SetInstancePrototype(function, construct_prototype); | 9795 return SetInstancePrototype(function, construct_prototype); |
9798 } | 9796 } |
9799 | 9797 |
9800 | 9798 |
9801 void JSFunction::RemovePrototype() { | 9799 void JSFunction::RemovePrototype() { |
9802 Context* native_context = context()->native_context(); | 9800 Context* native_context = context()->native_context(); |
9803 Map* no_prototype_map = shared()->is_sloppy_mode() | 9801 Map* no_prototype_map = shared()->strict_mode() == SLOPPY |
9804 ? native_context->function_without_prototype_map() | 9802 ? native_context->sloppy_function_without_prototype_map() |
9805 : native_context->strict_mode_function_without_prototype_map(); | 9803 : native_context->strict_function_without_prototype_map(); |
9806 | 9804 |
9807 if (map() == no_prototype_map) return; | 9805 if (map() == no_prototype_map) return; |
9808 | 9806 |
9809 ASSERT(map() == (shared()->is_sloppy_mode() | 9807 ASSERT(map() == (shared()->strict_mode() == SLOPPY |
9810 ? native_context->function_map() | 9808 ? native_context->sloppy_function_map() |
9811 : native_context->strict_mode_function_map())); | 9809 : native_context->strict_function_map())); |
9812 | 9810 |
9813 set_map(no_prototype_map); | 9811 set_map(no_prototype_map); |
9814 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); | 9812 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); |
9815 } | 9813 } |
9816 | 9814 |
9817 | 9815 |
9818 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { | 9816 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { |
9819 if (function->has_initial_map()) return; | 9817 if (function->has_initial_map()) return; |
9820 Isolate* isolate = function->GetIsolate(); | 9818 Isolate* isolate = function->GetIsolate(); |
9821 | 9819 |
(...skipping 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11063 return NULL; | 11061 return NULL; |
11064 } | 11062 } |
11065 | 11063 |
11066 | 11064 |
11067 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { | 11065 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { |
11068 PrintF(out, "extra_ic_state = "); | 11066 PrintF(out, "extra_ic_state = "); |
11069 const char* name = NULL; | 11067 const char* name = NULL; |
11070 switch (kind) { | 11068 switch (kind) { |
11071 case STORE_IC: | 11069 case STORE_IC: |
11072 case KEYED_STORE_IC: | 11070 case KEYED_STORE_IC: |
11073 if (extra == kStrictMode) { | 11071 if (extra == STRICT) name = "STRICT"; |
11074 name = "STRICT"; | |
11075 } | |
11076 break; | 11072 break; |
11077 default: | 11073 default: |
11078 break; | 11074 break; |
11079 } | 11075 } |
11080 if (name != NULL) { | 11076 if (name != NULL) { |
11081 PrintF(out, "%s\n", name); | 11077 PrintF(out, "%s\n", name); |
11082 } else { | 11078 } else { |
11083 PrintF(out, "%d\n", extra); | 11079 PrintF(out, "%d\n", extra); |
11084 } | 11080 } |
11085 } | 11081 } |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11475 | 11471 |
11476 EndPerformSplice(self); | 11472 EndPerformSplice(self); |
11477 | 11473 |
11478 uint32_t index = Min(old_length, new_length); | 11474 uint32_t index = Min(old_length, new_length); |
11479 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 11475 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
11480 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; | 11476 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
11481 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 11477 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
11482 if (delete_count > 0) { | 11478 if (delete_count > 0) { |
11483 for (int i = indices.length() - 1; i >= 0; i--) { | 11479 for (int i = indices.length() - 1; i >= 0; i--) { |
11484 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, | 11480 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, |
11485 kSloppyMode); | 11481 SLOPPY); |
11486 } | 11482 } |
11487 | 11483 |
11488 SetProperty(deleted, isolate->factory()->length_string(), | 11484 SetProperty(deleted, isolate->factory()->length_string(), |
11489 isolate->factory()->NewNumberFromUint(delete_count), | 11485 isolate->factory()->NewNumberFromUint(delete_count), |
11490 NONE, kSloppyMode); | 11486 NONE, SLOPPY); |
11491 } | 11487 } |
11492 | 11488 |
11493 EnqueueSpliceRecord(self, index, deleted, add_count); | 11489 EnqueueSpliceRecord(self, index, deleted, add_count); |
11494 | 11490 |
11495 return *hresult; | 11491 return *hresult; |
11496 } | 11492 } |
11497 | 11493 |
11498 | 11494 |
11499 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, | 11495 Handle<Map> Map::GetPrototypeTransition(Handle<Map> map, |
11500 Handle<Object> prototype) { | 11496 Handle<Object> prototype) { |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11919 | 11915 |
11920 return GetElementsAccessor()->GetAccessorPair(this, this, index); | 11916 return GetElementsAccessor()->GetAccessorPair(this, this, index); |
11921 } | 11917 } |
11922 | 11918 |
11923 | 11919 |
11924 Handle<Object> JSObject::SetElementWithInterceptor( | 11920 Handle<Object> JSObject::SetElementWithInterceptor( |
11925 Handle<JSObject> object, | 11921 Handle<JSObject> object, |
11926 uint32_t index, | 11922 uint32_t index, |
11927 Handle<Object> value, | 11923 Handle<Object> value, |
11928 PropertyAttributes attributes, | 11924 PropertyAttributes attributes, |
11929 StrictModeFlag strict_mode, | 11925 StrictMode strict_mode, |
11930 bool check_prototype, | 11926 bool check_prototype, |
11931 SetPropertyMode set_mode) { | 11927 SetPropertyMode set_mode) { |
11932 Isolate* isolate = object->GetIsolate(); | 11928 Isolate* isolate = object->GetIsolate(); |
11933 | 11929 |
11934 // Make sure that the top context does not change when doing | 11930 // Make sure that the top context does not change when doing |
11935 // callbacks or interceptor calls. | 11931 // callbacks or interceptor calls. |
11936 AssertNoContextChange ncc(isolate); | 11932 AssertNoContextChange ncc(isolate); |
11937 | 11933 |
11938 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); | 11934 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
11939 if (!interceptor->setter()->IsUndefined()) { | 11935 if (!interceptor->setter()->IsUndefined()) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12007 UNREACHABLE(); | 12003 UNREACHABLE(); |
12008 return NULL; | 12004 return NULL; |
12009 } | 12005 } |
12010 | 12006 |
12011 | 12007 |
12012 Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, | 12008 Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, |
12013 Handle<Object> structure, | 12009 Handle<Object> structure, |
12014 uint32_t index, | 12010 uint32_t index, |
12015 Handle<Object> value, | 12011 Handle<Object> value, |
12016 Handle<JSObject> holder, | 12012 Handle<JSObject> holder, |
12017 StrictModeFlag strict_mode) { | 12013 StrictMode strict_mode) { |
12018 Isolate* isolate = object->GetIsolate(); | 12014 Isolate* isolate = object->GetIsolate(); |
12019 | 12015 |
12020 // We should never get here to initialize a const with the hole | 12016 // We should never get here to initialize a const with the hole |
12021 // value since a const declaration would conflict with the setter. | 12017 // value since a const declaration would conflict with the setter. |
12022 ASSERT(!value->IsTheHole()); | 12018 ASSERT(!value->IsTheHole()); |
12023 | 12019 |
12024 // To accommodate both the old and the new api we switch on the | 12020 // To accommodate both the old and the new api we switch on the |
12025 // data structure used to store the callbacks. Eventually foreign | 12021 // data structure used to store the callbacks. Eventually foreign |
12026 // callbacks should be phased out. | 12022 // callbacks should be phased out. |
12027 ASSERT(!structure->IsForeign()); | 12023 ASSERT(!structure->IsForeign()); |
(...skipping 18 matching lines...) Expand all Loading... |
12046 return value; | 12042 return value; |
12047 } | 12043 } |
12048 | 12044 |
12049 if (structure->IsAccessorPair()) { | 12045 if (structure->IsAccessorPair()) { |
12050 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 12046 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
12051 if (setter->IsSpecFunction()) { | 12047 if (setter->IsSpecFunction()) { |
12052 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 12048 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
12053 return SetPropertyWithDefinedSetter( | 12049 return SetPropertyWithDefinedSetter( |
12054 object, Handle<JSReceiver>::cast(setter), value); | 12050 object, Handle<JSReceiver>::cast(setter), value); |
12055 } else { | 12051 } else { |
12056 if (strict_mode == kSloppyMode) { | 12052 if (strict_mode == SLOPPY) return value; |
12057 return value; | |
12058 } | |
12059 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); | 12053 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
12060 Handle<Object> args[2] = { key, holder }; | 12054 Handle<Object> args[2] = { key, holder }; |
12061 Handle<Object> error = isolate->factory()->NewTypeError( | 12055 Handle<Object> error = isolate->factory()->NewTypeError( |
12062 "no_setter_in_callback", HandleVector(args, 2)); | 12056 "no_setter_in_callback", HandleVector(args, 2)); |
12063 isolate->Throw(*error); | 12057 isolate->Throw(*error); |
12064 return Handle<Object>(); | 12058 return Handle<Object>(); |
12065 } | 12059 } |
12066 } | 12060 } |
12067 | 12061 |
12068 // TODO(dcarney): Handle correctly. | 12062 // TODO(dcarney): Handle correctly. |
(...skipping 27 matching lines...) Expand all Loading... |
12096 return arguments->IsDictionary(); | 12090 return arguments->IsDictionary(); |
12097 } | 12091 } |
12098 | 12092 |
12099 | 12093 |
12100 // Adding n elements in fast case is O(n*n). | 12094 // Adding n elements in fast case is O(n*n). |
12101 // Note: revisit design to have dual undefined values to capture absent | 12095 // Note: revisit design to have dual undefined values to capture absent |
12102 // elements. | 12096 // elements. |
12103 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object, | 12097 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object, |
12104 uint32_t index, | 12098 uint32_t index, |
12105 Handle<Object> value, | 12099 Handle<Object> value, |
12106 StrictModeFlag strict_mode, | 12100 StrictMode strict_mode, |
12107 bool check_prototype) { | 12101 bool check_prototype) { |
12108 ASSERT(object->HasFastSmiOrObjectElements() || | 12102 ASSERT(object->HasFastSmiOrObjectElements() || |
12109 object->HasFastArgumentsElements()); | 12103 object->HasFastArgumentsElements()); |
12110 | 12104 |
12111 Isolate* isolate = object->GetIsolate(); | 12105 Isolate* isolate = object->GetIsolate(); |
12112 | 12106 |
12113 // Array optimizations rely on the prototype lookups of Array objects always | 12107 // Array optimizations rely on the prototype lookups of Array objects always |
12114 // returning undefined. If there is a store to the initial prototype object, | 12108 // returning undefined. If there is a store to the initial prototype object, |
12115 // make sure all of these optimizations are invalidated. | 12109 // make sure all of these optimizations are invalidated. |
12116 if (isolate->is_initial_object_prototype(*object) || | 12110 if (isolate->is_initial_object_prototype(*object) || |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12225 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); | 12219 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
12226 } | 12220 } |
12227 return value; | 12221 return value; |
12228 } | 12222 } |
12229 | 12223 |
12230 | 12224 |
12231 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object, | 12225 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object, |
12232 uint32_t index, | 12226 uint32_t index, |
12233 Handle<Object> value, | 12227 Handle<Object> value, |
12234 PropertyAttributes attributes, | 12228 PropertyAttributes attributes, |
12235 StrictModeFlag strict_mode, | 12229 StrictMode strict_mode, |
12236 bool check_prototype, | 12230 bool check_prototype, |
12237 SetPropertyMode set_mode) { | 12231 SetPropertyMode set_mode) { |
12238 ASSERT(object->HasDictionaryElements() || | 12232 ASSERT(object->HasDictionaryElements() || |
12239 object->HasDictionaryArgumentsElements()); | 12233 object->HasDictionaryArgumentsElements()); |
12240 Isolate* isolate = object->GetIsolate(); | 12234 Isolate* isolate = object->GetIsolate(); |
12241 | 12235 |
12242 // Insert element in the dictionary. | 12236 // Insert element in the dictionary. |
12243 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 12237 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
12244 bool is_arguments = | 12238 bool is_arguments = |
12245 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); | 12239 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); |
(...skipping 11 matching lines...) Expand all Loading... |
12257 } else { | 12251 } else { |
12258 dictionary->UpdateMaxNumberKey(index); | 12252 dictionary->UpdateMaxNumberKey(index); |
12259 // If a value has not been initialized we allow writing to it even if it | 12253 // If a value has not been initialized we allow writing to it even if it |
12260 // is read-only (a declared const that has not been initialized). If a | 12254 // is read-only (a declared const that has not been initialized). If a |
12261 // value is being defined we skip attribute checks completely. | 12255 // value is being defined we skip attribute checks completely. |
12262 if (set_mode == DEFINE_PROPERTY) { | 12256 if (set_mode == DEFINE_PROPERTY) { |
12263 details = PropertyDetails( | 12257 details = PropertyDetails( |
12264 attributes, NORMAL, details.dictionary_index()); | 12258 attributes, NORMAL, details.dictionary_index()); |
12265 dictionary->DetailsAtPut(entry, details); | 12259 dictionary->DetailsAtPut(entry, details); |
12266 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12260 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
12267 if (strict_mode == kSloppyMode) { | 12261 if (strict_mode == SLOPPY) { |
12268 return isolate->factory()->undefined_value(); | 12262 return isolate->factory()->undefined_value(); |
12269 } else { | 12263 } else { |
12270 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12264 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12271 Handle<Object> args[2] = { number, object }; | 12265 Handle<Object> args[2] = { number, object }; |
12272 Handle<Object> error = | 12266 Handle<Object> error = |
12273 isolate->factory()->NewTypeError("strict_read_only_property", | 12267 isolate->factory()->NewTypeError("strict_read_only_property", |
12274 HandleVector(args, 2)); | 12268 HandleVector(args, 2)); |
12275 isolate->Throw(*error); | 12269 isolate->Throw(*error); |
12276 return Handle<Object>(); | 12270 return Handle<Object>(); |
12277 } | 12271 } |
(...skipping 17 matching lines...) Expand all Loading... |
12295 if (check_prototype) { | 12289 if (check_prototype) { |
12296 bool found; | 12290 bool found; |
12297 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, | 12291 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
12298 index, value, &found, strict_mode); | 12292 index, value, &found, strict_mode); |
12299 if (found) return result; | 12293 if (found) return result; |
12300 } | 12294 } |
12301 | 12295 |
12302 // When we set the is_extensible flag to false we always force the | 12296 // When we set the is_extensible flag to false we always force the |
12303 // element into dictionary mode (and force them to stay there). | 12297 // element into dictionary mode (and force them to stay there). |
12304 if (!object->map()->is_extensible()) { | 12298 if (!object->map()->is_extensible()) { |
12305 if (strict_mode == kSloppyMode) { | 12299 if (strict_mode == SLOPPY) { |
12306 return isolate->factory()->undefined_value(); | 12300 return isolate->factory()->undefined_value(); |
12307 } else { | 12301 } else { |
12308 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12302 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12309 Handle<String> name = isolate->factory()->NumberToString(number); | 12303 Handle<String> name = isolate->factory()->NumberToString(number); |
12310 Handle<Object> args[1] = { name }; | 12304 Handle<Object> args[1] = { name }; |
12311 Handle<Object> error = | 12305 Handle<Object> error = |
12312 isolate->factory()->NewTypeError("object_not_extensible", | 12306 isolate->factory()->NewTypeError("object_not_extensible", |
12313 HandleVector(args, 1)); | 12307 HandleVector(args, 1)); |
12314 isolate->Throw(*error); | 12308 isolate->Throw(*error); |
12315 return Handle<Object>(); | 12309 return Handle<Object>(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12368 } | 12362 } |
12369 #endif | 12363 #endif |
12370 } | 12364 } |
12371 return value; | 12365 return value; |
12372 } | 12366 } |
12373 | 12367 |
12374 Handle<Object> JSObject::SetFastDoubleElement( | 12368 Handle<Object> JSObject::SetFastDoubleElement( |
12375 Handle<JSObject> object, | 12369 Handle<JSObject> object, |
12376 uint32_t index, | 12370 uint32_t index, |
12377 Handle<Object> value, | 12371 Handle<Object> value, |
12378 StrictModeFlag strict_mode, | 12372 StrictMode strict_mode, |
12379 bool check_prototype) { | 12373 bool check_prototype) { |
12380 ASSERT(object->HasFastDoubleElements()); | 12374 ASSERT(object->HasFastDoubleElements()); |
12381 | 12375 |
12382 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); | 12376 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); |
12383 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); | 12377 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); |
12384 | 12378 |
12385 // If storing to an element that isn't in the array, pass the store request | 12379 // If storing to an element that isn't in the array, pass the store request |
12386 // up the prototype chain before storing in the receiver's elements. | 12380 // up the prototype chain before storing in the receiver's elements. |
12387 if (check_prototype && | 12381 if (check_prototype && |
12388 (index >= elms_length || | 12382 (index >= elms_length || |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12465 NormalizeElements(object); | 12459 NormalizeElements(object); |
12466 ASSERT(object->HasDictionaryElements()); | 12460 ASSERT(object->HasDictionaryElements()); |
12467 return SetElement(object, index, value, NONE, strict_mode, check_prototype); | 12461 return SetElement(object, index, value, NONE, strict_mode, check_prototype); |
12468 } | 12462 } |
12469 | 12463 |
12470 | 12464 |
12471 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12465 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
12472 uint32_t index, | 12466 uint32_t index, |
12473 Handle<Object> value, | 12467 Handle<Object> value, |
12474 PropertyAttributes attributes, | 12468 PropertyAttributes attributes, |
12475 StrictModeFlag strict_mode) { | 12469 StrictMode strict_mode) { |
12476 if (object->IsJSProxy()) { | 12470 if (object->IsJSProxy()) { |
12477 return JSProxy::SetElementWithHandler( | 12471 return JSProxy::SetElementWithHandler( |
12478 Handle<JSProxy>::cast(object), object, index, value, strict_mode); | 12472 Handle<JSProxy>::cast(object), object, index, value, strict_mode); |
12479 } | 12473 } |
12480 return JSObject::SetElement( | 12474 return JSObject::SetElement( |
12481 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); | 12475 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); |
12482 } | 12476 } |
12483 | 12477 |
12484 | 12478 |
12485 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 12479 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
12486 uint32_t index, | 12480 uint32_t index, |
12487 Handle<Object> value, | 12481 Handle<Object> value, |
12488 StrictModeFlag strict_mode) { | 12482 StrictMode strict_mode) { |
12489 ASSERT(!object->HasExternalArrayElements()); | 12483 ASSERT(!object->HasExternalArrayElements()); |
12490 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); | 12484 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); |
12491 } | 12485 } |
12492 | 12486 |
12493 | 12487 |
12494 Handle<Object> JSObject::SetElement(Handle<JSObject> object, | 12488 Handle<Object> JSObject::SetElement(Handle<JSObject> object, |
12495 uint32_t index, | 12489 uint32_t index, |
12496 Handle<Object> value, | 12490 Handle<Object> value, |
12497 PropertyAttributes attributes, | 12491 PropertyAttributes attributes, |
12498 StrictModeFlag strict_mode, | 12492 StrictMode strict_mode, |
12499 bool check_prototype, | 12493 bool check_prototype, |
12500 SetPropertyMode set_mode) { | 12494 SetPropertyMode set_mode) { |
12501 Isolate* isolate = object->GetIsolate(); | 12495 Isolate* isolate = object->GetIsolate(); |
12502 | 12496 |
12503 if (object->HasExternalArrayElements()) { | 12497 if (object->HasExternalArrayElements()) { |
12504 if (!value->IsNumber() && !value->IsUndefined()) { | 12498 if (!value->IsNumber() && !value->IsUndefined()) { |
12505 bool has_exception; | 12499 bool has_exception; |
12506 Handle<Object> number = | 12500 Handle<Object> number = |
12507 Execution::ToNumber(isolate, value, &has_exception); | 12501 Execution::ToNumber(isolate, value, &has_exception); |
12508 if (has_exception) return Handle<Object>(); | 12502 if (has_exception) return Handle<Object>(); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12621 | 12615 |
12622 return result; | 12616 return result; |
12623 } | 12617 } |
12624 | 12618 |
12625 | 12619 |
12626 Handle<Object> JSObject::SetElementWithoutInterceptor( | 12620 Handle<Object> JSObject::SetElementWithoutInterceptor( |
12627 Handle<JSObject> object, | 12621 Handle<JSObject> object, |
12628 uint32_t index, | 12622 uint32_t index, |
12629 Handle<Object> value, | 12623 Handle<Object> value, |
12630 PropertyAttributes attributes, | 12624 PropertyAttributes attributes, |
12631 StrictModeFlag strict_mode, | 12625 StrictMode strict_mode, |
12632 bool check_prototype, | 12626 bool check_prototype, |
12633 SetPropertyMode set_mode) { | 12627 SetPropertyMode set_mode) { |
12634 ASSERT(object->HasDictionaryElements() || | 12628 ASSERT(object->HasDictionaryElements() || |
12635 object->HasDictionaryArgumentsElements() || | 12629 object->HasDictionaryArgumentsElements() || |
12636 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | 12630 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); |
12637 Isolate* isolate = object->GetIsolate(); | 12631 Isolate* isolate = object->GetIsolate(); |
12638 if (FLAG_trace_external_array_abuse && | 12632 if (FLAG_trace_external_array_abuse && |
12639 IsExternalArrayElementsKind(object->GetElementsKind())) { | 12633 IsExternalArrayElementsKind(object->GetElementsKind())) { |
12640 CheckArrayAbuse(*object, "external elements write", index); | 12634 CheckArrayAbuse(*object, "external elements write", index); |
12641 } | 12635 } |
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13706 String* string_; | 13700 String* string_; |
13707 uint32_t hash_; | 13701 uint32_t hash_; |
13708 }; | 13702 }; |
13709 | 13703 |
13710 | 13704 |
13711 // StringSharedKeys are used as keys in the eval cache. | 13705 // StringSharedKeys are used as keys in the eval cache. |
13712 class StringSharedKey : public HashTableKey { | 13706 class StringSharedKey : public HashTableKey { |
13713 public: | 13707 public: |
13714 StringSharedKey(String* source, | 13708 StringSharedKey(String* source, |
13715 SharedFunctionInfo* shared, | 13709 SharedFunctionInfo* shared, |
13716 LanguageMode language_mode, | 13710 StrictMode strict_mode, |
13717 int scope_position) | 13711 int scope_position) |
13718 : source_(source), | 13712 : source_(source), |
13719 shared_(shared), | 13713 shared_(shared), |
13720 language_mode_(language_mode), | 13714 strict_mode_(strict_mode), |
13721 scope_position_(scope_position) { } | 13715 scope_position_(scope_position) { } |
13722 | 13716 |
13723 bool IsMatch(Object* other) { | 13717 bool IsMatch(Object* other) { |
13724 if (!other->IsFixedArray()) return false; | 13718 if (!other->IsFixedArray()) return false; |
13725 FixedArray* other_array = FixedArray::cast(other); | 13719 FixedArray* other_array = FixedArray::cast(other); |
13726 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 13720 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
13727 if (shared != shared_) return false; | 13721 if (shared != shared_) return false; |
13728 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 13722 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
13729 ASSERT(language_unchecked == SLOPPY_MODE || | 13723 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
13730 language_unchecked == STRICT_MODE || | 13724 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
13731 language_unchecked == EXTENDED_MODE); | 13725 if (strict_mode != strict_mode_) return false; |
13732 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | |
13733 if (language_mode != language_mode_) return false; | |
13734 int scope_position = Smi::cast(other_array->get(3))->value(); | 13726 int scope_position = Smi::cast(other_array->get(3))->value(); |
13735 if (scope_position != scope_position_) return false; | 13727 if (scope_position != scope_position_) return false; |
13736 String* source = String::cast(other_array->get(1)); | 13728 String* source = String::cast(other_array->get(1)); |
13737 return source->Equals(source_); | 13729 return source->Equals(source_); |
13738 } | 13730 } |
13739 | 13731 |
13740 static uint32_t StringSharedHashHelper(String* source, | 13732 static uint32_t StringSharedHashHelper(String* source, |
13741 SharedFunctionInfo* shared, | 13733 SharedFunctionInfo* shared, |
13742 LanguageMode language_mode, | 13734 StrictMode strict_mode, |
13743 int scope_position) { | 13735 int scope_position) { |
13744 uint32_t hash = source->Hash(); | 13736 uint32_t hash = source->Hash(); |
13745 if (shared->HasSourceCode()) { | 13737 if (shared->HasSourceCode()) { |
13746 // Instead of using the SharedFunctionInfo pointer in the hash | 13738 // Instead of using the SharedFunctionInfo pointer in the hash |
13747 // code computation, we use a combination of the hash of the | 13739 // code computation, we use a combination of the hash of the |
13748 // script source code and the start position of the calling scope. | 13740 // script source code and the start position of the calling scope. |
13749 // We do this to ensure that the cache entries can survive garbage | 13741 // We do this to ensure that the cache entries can survive garbage |
13750 // collection. | 13742 // collection. |
13751 Script* script = Script::cast(shared->script()); | 13743 Script* script = Script::cast(shared->script()); |
13752 hash ^= String::cast(script->source())->Hash(); | 13744 hash ^= String::cast(script->source())->Hash(); |
13753 if (language_mode == STRICT_MODE) hash ^= 0x8000; | 13745 if (strict_mode == STRICT) hash ^= 0x8000; |
13754 if (language_mode == EXTENDED_MODE) hash ^= 0x0080; | |
13755 hash += scope_position; | 13746 hash += scope_position; |
13756 } | 13747 } |
13757 return hash; | 13748 return hash; |
13758 } | 13749 } |
13759 | 13750 |
13760 uint32_t Hash() { | 13751 uint32_t Hash() { |
13761 return StringSharedHashHelper( | 13752 return StringSharedHashHelper( |
13762 source_, shared_, language_mode_, scope_position_); | 13753 source_, shared_, strict_mode_, scope_position_); |
13763 } | 13754 } |
13764 | 13755 |
13765 uint32_t HashForObject(Object* obj) { | 13756 uint32_t HashForObject(Object* obj) { |
13766 FixedArray* other_array = FixedArray::cast(obj); | 13757 FixedArray* other_array = FixedArray::cast(obj); |
13767 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 13758 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
13768 String* source = String::cast(other_array->get(1)); | 13759 String* source = String::cast(other_array->get(1)); |
13769 int language_unchecked = Smi::cast(other_array->get(2))->value(); | 13760 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
13770 ASSERT(language_unchecked == SLOPPY_MODE || | 13761 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
13771 language_unchecked == STRICT_MODE || | 13762 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
13772 language_unchecked == EXTENDED_MODE); | |
13773 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked); | |
13774 int scope_position = Smi::cast(other_array->get(3))->value(); | 13763 int scope_position = Smi::cast(other_array->get(3))->value(); |
13775 return StringSharedHashHelper( | 13764 return StringSharedHashHelper( |
13776 source, shared, language_mode, scope_position); | 13765 source, shared, strict_mode, scope_position); |
13777 } | 13766 } |
13778 | 13767 |
13779 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { | 13768 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { |
13780 Object* obj; | 13769 Object* obj; |
13781 { MaybeObject* maybe_obj = heap->AllocateFixedArray(4); | 13770 { MaybeObject* maybe_obj = heap->AllocateFixedArray(4); |
13782 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13771 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
13783 } | 13772 } |
13784 FixedArray* other_array = FixedArray::cast(obj); | 13773 FixedArray* other_array = FixedArray::cast(obj); |
13785 other_array->set(0, shared_); | 13774 other_array->set(0, shared_); |
13786 other_array->set(1, source_); | 13775 other_array->set(1, source_); |
13787 other_array->set(2, Smi::FromInt(language_mode_)); | 13776 other_array->set(2, Smi::FromInt(strict_mode_)); |
13788 other_array->set(3, Smi::FromInt(scope_position_)); | 13777 other_array->set(3, Smi::FromInt(scope_position_)); |
13789 return other_array; | 13778 return other_array; |
13790 } | 13779 } |
13791 | 13780 |
13792 private: | 13781 private: |
13793 String* source_; | 13782 String* source_; |
13794 SharedFunctionInfo* shared_; | 13783 SharedFunctionInfo* shared_; |
13795 LanguageMode language_mode_; | 13784 StrictMode strict_mode_; |
13796 int scope_position_; | 13785 int scope_position_; |
13797 }; | 13786 }; |
13798 | 13787 |
13799 | 13788 |
13800 // RegExpKey carries the source and flags of a regular expression as key. | 13789 // RegExpKey carries the source and flags of a regular expression as key. |
13801 class RegExpKey : public HashTableKey { | 13790 class RegExpKey : public HashTableKey { |
13802 public: | 13791 public: |
13803 RegExpKey(String* string, JSRegExp::Flags flags) | 13792 RegExpKey(String* string, JSRegExp::Flags flags) |
13804 : string_(string), | 13793 : string_(string), |
13805 flags_(Smi::FromInt(flags.value())) { } | 13794 flags_(Smi::FromInt(flags.value())) { } |
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14978 | 14967 |
14979 // Add the new string and return it along with the string table. | 14968 // Add the new string and return it along with the string table. |
14980 entry = table->FindInsertionEntry(key->Hash()); | 14969 entry = table->FindInsertionEntry(key->Hash()); |
14981 table->set(EntryToIndex(entry), string); | 14970 table->set(EntryToIndex(entry), string); |
14982 table->ElementAdded(); | 14971 table->ElementAdded(); |
14983 *s = string; | 14972 *s = string; |
14984 return table; | 14973 return table; |
14985 } | 14974 } |
14986 | 14975 |
14987 | 14976 |
14988 // The key for the script compilation cache is dependent on the mode flags, | |
14989 // because they change the global language mode and thus binding behaviour. | |
14990 // If flags change at some point, we must ensure that we do not hit the cache | |
14991 // for code compiled with different settings. | |
14992 static LanguageMode CurrentGlobalLanguageMode() { | |
14993 return FLAG_use_strict | |
14994 ? (FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE) | |
14995 : SLOPPY_MODE; | |
14996 } | |
14997 | |
14998 | |
14999 Object* CompilationCacheTable::Lookup(String* src, Context* context) { | 14977 Object* CompilationCacheTable::Lookup(String* src, Context* context) { |
15000 SharedFunctionInfo* shared = context->closure()->shared(); | 14978 SharedFunctionInfo* shared = context->closure()->shared(); |
15001 StringSharedKey key(src, | 14979 StringSharedKey key(src, |
15002 shared, | 14980 shared, |
15003 CurrentGlobalLanguageMode(), | 14981 FLAG_use_strict ? STRICT : SLOPPY, |
15004 RelocInfo::kNoPosition); | 14982 RelocInfo::kNoPosition); |
15005 int entry = FindEntry(&key); | 14983 int entry = FindEntry(&key); |
15006 if (entry == kNotFound) return GetHeap()->undefined_value(); | 14984 if (entry == kNotFound) return GetHeap()->undefined_value(); |
15007 return get(EntryToIndex(entry) + 1); | 14985 return get(EntryToIndex(entry) + 1); |
15008 } | 14986 } |
15009 | 14987 |
15010 | 14988 |
15011 Object* CompilationCacheTable::LookupEval(String* src, | 14989 Object* CompilationCacheTable::LookupEval(String* src, |
15012 Context* context, | 14990 Context* context, |
15013 LanguageMode language_mode, | 14991 StrictMode strict_mode, |
15014 int scope_position) { | 14992 int scope_position) { |
15015 StringSharedKey key(src, | 14993 StringSharedKey key(src, |
15016 context->closure()->shared(), | 14994 context->closure()->shared(), |
15017 language_mode, | 14995 strict_mode, |
15018 scope_position); | 14996 scope_position); |
15019 int entry = FindEntry(&key); | 14997 int entry = FindEntry(&key); |
15020 if (entry == kNotFound) return GetHeap()->undefined_value(); | 14998 if (entry == kNotFound) return GetHeap()->undefined_value(); |
15021 return get(EntryToIndex(entry) + 1); | 14999 return get(EntryToIndex(entry) + 1); |
15022 } | 15000 } |
15023 | 15001 |
15024 | 15002 |
15025 Object* CompilationCacheTable::LookupRegExp(String* src, | 15003 Object* CompilationCacheTable::LookupRegExp(String* src, |
15026 JSRegExp::Flags flags) { | 15004 JSRegExp::Flags flags) { |
15027 RegExpKey key(src, flags); | 15005 RegExpKey key(src, flags); |
15028 int entry = FindEntry(&key); | 15006 int entry = FindEntry(&key); |
15029 if (entry == kNotFound) return GetHeap()->undefined_value(); | 15007 if (entry == kNotFound) return GetHeap()->undefined_value(); |
15030 return get(EntryToIndex(entry) + 1); | 15008 return get(EntryToIndex(entry) + 1); |
15031 } | 15009 } |
15032 | 15010 |
15033 | 15011 |
15034 MaybeObject* CompilationCacheTable::Put(String* src, | 15012 MaybeObject* CompilationCacheTable::Put(String* src, |
15035 Context* context, | 15013 Context* context, |
15036 Object* value) { | 15014 Object* value) { |
15037 SharedFunctionInfo* shared = context->closure()->shared(); | 15015 SharedFunctionInfo* shared = context->closure()->shared(); |
15038 StringSharedKey key(src, | 15016 StringSharedKey key(src, |
15039 shared, | 15017 shared, |
15040 CurrentGlobalLanguageMode(), | 15018 FLAG_use_strict ? STRICT : SLOPPY, |
15041 RelocInfo::kNoPosition); | 15019 RelocInfo::kNoPosition); |
15042 CompilationCacheTable* cache; | 15020 CompilationCacheTable* cache; |
15043 MaybeObject* maybe_cache = EnsureCapacity(1, &key); | 15021 MaybeObject* maybe_cache = EnsureCapacity(1, &key); |
15044 if (!maybe_cache->To(&cache)) return maybe_cache; | 15022 if (!maybe_cache->To(&cache)) return maybe_cache; |
15045 | 15023 |
15046 Object* k; | 15024 Object* k; |
15047 MaybeObject* maybe_k = key.AsObject(GetHeap()); | 15025 MaybeObject* maybe_k = key.AsObject(GetHeap()); |
15048 if (!maybe_k->To(&k)) return maybe_k; | 15026 if (!maybe_k->To(&k)) return maybe_k; |
15049 | 15027 |
15050 int entry = cache->FindInsertionEntry(key.Hash()); | 15028 int entry = cache->FindInsertionEntry(key.Hash()); |
15051 cache->set(EntryToIndex(entry), k); | 15029 cache->set(EntryToIndex(entry), k); |
15052 cache->set(EntryToIndex(entry) + 1, value); | 15030 cache->set(EntryToIndex(entry) + 1, value); |
15053 cache->ElementAdded(); | 15031 cache->ElementAdded(); |
15054 return cache; | 15032 return cache; |
15055 } | 15033 } |
15056 | 15034 |
15057 | 15035 |
15058 MaybeObject* CompilationCacheTable::PutEval(String* src, | 15036 MaybeObject* CompilationCacheTable::PutEval(String* src, |
15059 Context* context, | 15037 Context* context, |
15060 SharedFunctionInfo* value, | 15038 SharedFunctionInfo* value, |
15061 int scope_position) { | 15039 int scope_position) { |
15062 StringSharedKey key(src, | 15040 StringSharedKey key(src, |
15063 context->closure()->shared(), | 15041 context->closure()->shared(), |
15064 value->language_mode(), | 15042 value->strict_mode(), |
15065 scope_position); | 15043 scope_position); |
15066 Object* obj; | 15044 Object* obj; |
15067 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 15045 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
15068 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15046 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
15069 } | 15047 } |
15070 | 15048 |
15071 CompilationCacheTable* cache = | 15049 CompilationCacheTable* cache = |
15072 reinterpret_cast<CompilationCacheTable*>(obj); | 15050 reinterpret_cast<CompilationCacheTable*>(obj); |
15073 int entry = cache->FindInsertionEntry(key.Hash()); | 15051 int entry = cache->FindInsertionEntry(key.Hash()); |
15074 | 15052 |
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16480 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16458 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16481 static const char* error_messages_[] = { | 16459 static const char* error_messages_[] = { |
16482 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16460 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16483 }; | 16461 }; |
16484 #undef ERROR_MESSAGES_TEXTS | 16462 #undef ERROR_MESSAGES_TEXTS |
16485 return error_messages_[reason]; | 16463 return error_messages_[reason]; |
16486 } | 16464 } |
16487 | 16465 |
16488 | 16466 |
16489 } } // namespace v8::internal | 16467 } } // namespace v8::internal |
OLD | NEW |