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

Side by Side Diff: src/objects.cc

Issue 10703103: Fix unhandlified code calling Harmony Proxy traps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Andreas Rossberg. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-2219.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2812 matching lines...) Expand 10 before | Expand all | Expand 10 after
2823 } 2823 }
2824 trap = Handle<Object>(derived); 2824 trap = Handle<Object>(derived);
2825 } 2825 }
2826 2826
2827 bool threw; 2827 bool threw;
2828 return Execution::Call(trap, handler, argc, argv, &threw); 2828 return Execution::Call(trap, handler, argc, argv, &threw);
2829 } 2829 }
2830 2830
2831 2831
2832 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, 2832 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
2833 String* name, 2833 String* name_raw,
2834 Object* value, 2834 Object* value_raw,
2835 PropertyAttributes attributes, 2835 PropertyAttributes attributes,
2836 StrictModeFlag strict_mode, 2836 StrictModeFlag strict_mode,
2837 StoreFromKeyed store_mode) { 2837 StoreFromKeyed store_mode) {
2838 Heap* heap = GetHeap(); 2838 Heap* heap = GetHeap();
2839 // Make sure that the top context does not change when doing callbacks or 2839 // Make sure that the top context does not change when doing callbacks or
2840 // interceptor calls. 2840 // interceptor calls.
2841 AssertNoContextChange ncc; 2841 AssertNoContextChange ncc;
2842 2842
2843 // Optimization for 2-byte strings often used as keys in a decompression 2843 // Optimization for 2-byte strings often used as keys in a decompression
2844 // dictionary. We make these short keys into symbols to avoid constantly 2844 // dictionary. We make these short keys into symbols to avoid constantly
2845 // reallocating them. 2845 // reallocating them.
2846 if (!name->IsSymbol() && name->length() <= 2) { 2846 if (!name_raw->IsSymbol() && name_raw->length() <= 2) {
2847 Object* symbol_version; 2847 Object* symbol_version;
2848 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name); 2848 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name_raw);
2849 if (maybe_symbol_version->ToObject(&symbol_version)) { 2849 if (maybe_symbol_version->ToObject(&symbol_version)) {
2850 name = String::cast(symbol_version); 2850 name_raw = String::cast(symbol_version);
2851 } 2851 }
2852 } 2852 }
2853 } 2853 }
2854 2854
2855 // Check access rights if needed. 2855 // Check access rights if needed.
2856 if (IsAccessCheckNeeded()) { 2856 if (IsAccessCheckNeeded()) {
2857 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { 2857 if (!heap->isolate()->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) {
2858 return SetPropertyWithFailedAccessCheck( 2858 return SetPropertyWithFailedAccessCheck(
2859 result, name, value, true, strict_mode); 2859 result, name_raw, value_raw, true, strict_mode);
2860 } 2860 }
2861 } 2861 }
2862 2862
2863 if (IsJSGlobalProxy()) { 2863 if (IsJSGlobalProxy()) {
2864 Object* proto = GetPrototype(); 2864 Object* proto = GetPrototype();
2865 if (proto->IsNull()) return value; 2865 if (proto->IsNull()) return value_raw;
2866 ASSERT(proto->IsJSGlobalObject()); 2866 ASSERT(proto->IsJSGlobalObject());
2867 return JSObject::cast(proto)->SetPropertyForResult( 2867 return JSObject::cast(proto)->SetPropertyForResult(
2868 result, name, value, attributes, strict_mode, store_mode); 2868 result, name_raw, value_raw, attributes, strict_mode, store_mode);
2869 } 2869 }
2870 2870
2871 if (!result->IsProperty() && !IsJSContextExtensionObject()) { 2871 // From this point on everything needs to be handlified, because
2872 // SetPropertyViaPrototypes might call back into JavaScript.
2873 Handle<JSObject> self(this);
2874 Handle<String> name(name_raw);
2875 Handle<Object> value(value_raw);
2876
2877 if (!result->IsProperty() && !self->IsJSContextExtensionObject()) {
2872 bool done = false; 2878 bool done = false;
2873 MaybeObject* result_object = 2879 MaybeObject* result_object = self->SetPropertyViaPrototypes(
2874 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); 2880 *name, *value, attributes, strict_mode, &done);
2875 if (done) return result_object; 2881 if (done) return result_object;
2876 } 2882 }
2877 2883
2878 if (!result->IsFound()) { 2884 if (!result->IsFound()) {
2879 // Neither properties nor transitions found. 2885 // Neither properties nor transitions found.
2880 return AddProperty(name, value, attributes, strict_mode, store_mode); 2886 return self->AddProperty(
2887 *name, *value, attributes, strict_mode, store_mode);
2881 } 2888 }
2882 if (result->IsReadOnly() && result->IsProperty()) { 2889 if (result->IsReadOnly() && result->IsProperty()) {
2883 if (strict_mode == kStrictMode) { 2890 if (strict_mode == kStrictMode) {
2884 Handle<JSObject> self(this); 2891 Handle<Object> args[] = { name, self };
2885 Handle<String> hname(name);
2886 Handle<Object> args[] = { hname, self };
2887 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( 2892 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError(
2888 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 2893 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
2889 } else { 2894 } else {
2890 return value; 2895 return *value;
2891 } 2896 }
2892 } 2897 }
2893 // This is a real property that is not read-only, or it is a 2898 // This is a real property that is not read-only, or it is a
2894 // transition or null descriptor and there are no setters in the prototypes. 2899 // transition or null descriptor and there are no setters in the prototypes.
2895 switch (result->type()) { 2900 switch (result->type()) {
2896 case NORMAL: 2901 case NORMAL:
2897 return SetNormalizedProperty(result, value); 2902 return self->SetNormalizedProperty(result, *value);
2898 case FIELD: 2903 case FIELD:
2899 return FastPropertyAtPut(result->GetFieldIndex(), value); 2904 return self->FastPropertyAtPut(result->GetFieldIndex(), *value);
2900 case MAP_TRANSITION: 2905 case MAP_TRANSITION:
2901 if (attributes == result->GetAttributes()) { 2906 if (attributes == result->GetAttributes()) {
2902 // Only use map transition if the attributes match. 2907 // Only use map transition if the attributes match.
2903 return AddFastPropertyUsingMap(result->GetTransitionMap(), 2908 return self->AddFastPropertyUsingMap(result->GetTransitionMap(),
2904 name, 2909 *name,
2905 value); 2910 *value);
2906 } 2911 }
2907 return ConvertDescriptorToField(name, value, attributes); 2912 return self->ConvertDescriptorToField(*name, *value, attributes);
2908 case CONSTANT_FUNCTION: 2913 case CONSTANT_FUNCTION:
2909 // Only replace the function if necessary. 2914 // Only replace the function if necessary.
2910 if (value == result->GetConstantFunction()) return value; 2915 if (*value == result->GetConstantFunction()) return *value;
2911 // Preserve the attributes of this existing property. 2916 // Preserve the attributes of this existing property.
2912 attributes = result->GetAttributes(); 2917 attributes = result->GetAttributes();
2913 return ConvertDescriptorToField(name, value, attributes); 2918 return self->ConvertDescriptorToField(*name, *value, attributes);
2914 case CALLBACKS: { 2919 case CALLBACKS: {
2915 Object* callback_object = result->GetCallbackObject(); 2920 Object* callback_object = result->GetCallbackObject();
2916 if (callback_object->IsAccessorPair() && 2921 if (callback_object->IsAccessorPair() &&
2917 !AccessorPair::cast(callback_object)->ContainsAccessor()) { 2922 !AccessorPair::cast(callback_object)->ContainsAccessor()) {
2918 return ConvertDescriptorToField(name, value, attributes); 2923 return self->ConvertDescriptorToField(*name, *value, attributes);
2919 } 2924 }
2920 return SetPropertyWithCallback(callback_object, 2925 return self->SetPropertyWithCallback(callback_object,
2921 name, 2926 *name,
2922 value, 2927 *value,
2923 result->holder(), 2928 result->holder(),
2924 strict_mode); 2929 strict_mode);
2925 } 2930 }
2926 case INTERCEPTOR: 2931 case INTERCEPTOR:
2927 return SetPropertyWithInterceptor(name, value, attributes, strict_mode); 2932 return self->SetPropertyWithInterceptor(*name,
2933 *value,
2934 attributes,
2935 strict_mode);
2928 case CONSTANT_TRANSITION: { 2936 case CONSTANT_TRANSITION: {
2929 // If the same constant function is being added we can simply 2937 // If the same constant function is being added we can simply
2930 // transition to the target map. 2938 // transition to the target map.
2931 Map* target_map = result->GetTransitionMap(); 2939 Map* target_map = result->GetTransitionMap();
2932 DescriptorArray* target_descriptors = target_map->instance_descriptors(); 2940 DescriptorArray* target_descriptors = target_map->instance_descriptors();
2933 int number = target_descriptors->SearchWithCache(name); 2941 int number = target_descriptors->SearchWithCache(*name);
2934 ASSERT(number != DescriptorArray::kNotFound); 2942 ASSERT(number != DescriptorArray::kNotFound);
2935 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); 2943 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION);
2936 JSFunction* function = 2944 JSFunction* function =
2937 JSFunction::cast(target_descriptors->GetValue(number)); 2945 JSFunction::cast(target_descriptors->GetValue(number));
2938 if (value == function) { 2946 if (*value == function) {
2939 set_map(target_map); 2947 self->set_map(target_map);
2940 return value; 2948 return *value;
2941 } 2949 }
2942 // Otherwise, replace with a MAP_TRANSITION to a new map with a 2950 // Otherwise, replace with a MAP_TRANSITION to a new map with a
2943 // FIELD, even if the value is a constant function. 2951 // FIELD, even if the value is a constant function.
2944 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); 2952 return self->ConvertDescriptorToFieldAndMapTransition(*name,
2953 *value,
2954 attributes);
2945 } 2955 }
2946 case HANDLER: 2956 case HANDLER:
2947 case NONEXISTENT: 2957 case NONEXISTENT:
2948 UNREACHABLE(); 2958 UNREACHABLE();
2949 return value; 2959 return *value;
2950 } 2960 }
2951 UNREACHABLE(); // keep the compiler happy 2961 UNREACHABLE(); // keep the compiler happy
2952 return value; 2962 return *value;
2953 } 2963 }
2954 2964
2955 2965
2956 // Set a real local property, even if it is READ_ONLY. If the property is not 2966 // Set a real local property, even if it is READ_ONLY. If the property is not
2957 // present, add it with attributes NONE. This code is an exact clone of 2967 // present, add it with attributes NONE. This code is an exact clone of
2958 // SetProperty, with the check for IsReadOnly and the check for a 2968 // SetProperty, with the check for IsReadOnly and the check for a
2959 // callback setter removed. The two lines looking up the LookupResult 2969 // callback setter removed. The two lines looking up the LookupResult
2960 // result are also added. If one of the functions is changed, the other 2970 // result are also added. If one of the functions is changed, the other
2961 // should be. 2971 // should be.
2962 // Note that this method cannot be used to set the prototype of a function 2972 // Note that this method cannot be used to set the prototype of a function
(...skipping 10414 matching lines...) Expand 10 before | Expand all | Expand 10 after
13377 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13387 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13378 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13388 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13379 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13389 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13380 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13390 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13381 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13391 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13382 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13392 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13383 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13393 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13384 } 13394 }
13385 13395
13386 } } // namespace v8::internal 13396 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-2219.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698