| OLD | NEW |
| 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 5013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5024 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { | 5024 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { |
| 5025 HandleScope scope(isolate); | 5025 HandleScope scope(isolate); |
| 5026 ASSERT(args.length() == 4); | 5026 ASSERT(args.length() == 4); |
| 5027 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); | 5027 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); |
| 5028 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | 5028 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
| 5029 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); | 5029 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); |
| 5030 CONVERT_SMI_ARG_CHECKED(unchecked, 3); | 5030 CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
| 5031 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5031 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 5032 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 5032 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 5033 | 5033 |
| 5034 LookupResult result(isolate); | 5034 LookupResult lookup(isolate); |
| 5035 js_object->LocalLookupRealNamedProperty(*name, &result); | 5035 js_object->LocalLookupRealNamedProperty(*name, &lookup); |
| 5036 | 5036 |
| 5037 // Special case for callback properties. | 5037 // Special case for callback properties. |
| 5038 if (result.IsPropertyCallbacks()) { | 5038 if (lookup.IsPropertyCallbacks()) { |
| 5039 Object* callback = result.GetCallbackObject(); | 5039 Handle<Object> callback(lookup.GetCallbackObject(), isolate); |
| 5040 // To be compatible with Safari we do not change the value on API objects | 5040 // To be compatible with Safari we do not change the value on API objects |
| 5041 // in Object.defineProperty(). Firefox disagrees here, and actually changes | 5041 // in Object.defineProperty(). Firefox disagrees here, and actually changes |
| 5042 // the value. | 5042 // the value. |
| 5043 if (callback->IsAccessorInfo()) { | 5043 if (callback->IsAccessorInfo()) { |
| 5044 return isolate->heap()->undefined_value(); | 5044 return isolate->heap()->undefined_value(); |
| 5045 } | 5045 } |
| 5046 // Avoid redefining foreign callback as data property, just use the stored | 5046 // Avoid redefining foreign callback as data property, just use the stored |
| 5047 // setter to update the value instead. | 5047 // setter to update the value instead. |
| 5048 // TODO(mstarzinger): So far this only works if property attributes don't | 5048 // TODO(mstarzinger): So far this only works if property attributes don't |
| 5049 // change, this should be fixed once we cleanup the underlying code. | 5049 // change, this should be fixed once we cleanup the underlying code. |
| 5050 if (callback->IsForeign() && result.GetAttributes() == attr) { | 5050 if (callback->IsForeign() && lookup.GetAttributes() == attr) { |
| 5051 Handle<Object> result_object = | 5051 Handle<Object> result_object = |
| 5052 JSObject::SetPropertyWithCallback(js_object, | 5052 JSObject::SetPropertyWithCallback(js_object, |
| 5053 handle(callback, isolate), | 5053 callback, |
| 5054 name, | 5054 name, |
| 5055 obj_value, | 5055 obj_value, |
| 5056 handle(result.holder()), | 5056 handle(lookup.holder()), |
| 5057 kStrictMode); | 5057 kStrictMode); |
| 5058 RETURN_IF_EMPTY_HANDLE(isolate, result_object); | 5058 RETURN_IF_EMPTY_HANDLE(isolate, result_object); |
| 5059 return *result_object; | 5059 return *result_object; |
| 5060 } | 5060 } |
| 5061 } | 5061 } |
| 5062 | 5062 |
| 5063 // Take special care when attributes are different and there is already | 5063 // Take special care when attributes are different and there is already |
| 5064 // a property. For simplicity we normalize the property which enables us | 5064 // a property. For simplicity we normalize the property which enables us |
| 5065 // to not worry about changing the instance_descriptor and creating a new | 5065 // to not worry about changing the instance_descriptor and creating a new |
| 5066 // map. The current version of SetObjectProperty does not handle attributes | 5066 // map. The current version of SetObjectProperty does not handle attributes |
| 5067 // correctly in the case where a property is a field and is reset with | 5067 // correctly in the case where a property is a field and is reset with |
| 5068 // new attributes. | 5068 // new attributes. |
| 5069 if (result.IsFound() && | 5069 if (lookup.IsFound() && |
| 5070 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) { | 5070 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) { |
| 5071 // New attributes - normalize to avoid writing to instance descriptor | 5071 // New attributes - normalize to avoid writing to instance descriptor |
| 5072 if (js_object->IsJSGlobalProxy()) { | 5072 if (js_object->IsJSGlobalProxy()) { |
| 5073 // Since the result is a property, the prototype will exist so | 5073 // Since the result is a property, the prototype will exist so |
| 5074 // we don't have to check for null. | 5074 // we don't have to check for null. |
| 5075 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 5075 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
| 5076 } | 5076 } |
| 5077 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 5077 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 5078 // Use IgnoreAttributes version since a readonly property may be | 5078 // Use IgnoreAttributes version since a readonly property may be |
| 5079 // overridden and SetProperty does not allow this. | 5079 // overridden and SetProperty does not allow this. |
| 5080 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( | 5080 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( |
| 5081 js_object, name, obj_value, attr); | 5081 js_object, name, obj_value, attr); |
| 5082 RETURN_IF_EMPTY_HANDLE(isolate, result); | 5082 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5083 return *result; | 5083 return *result; |
| 5084 } | 5084 } |
| 5085 | 5085 |
| 5086 return Runtime::ForceSetObjectProperty(isolate, | 5086 Handle<Object> result = Runtime::ForceSetObjectProperty(isolate, js_object, |
| 5087 js_object, | 5087 name, |
| 5088 name, | 5088 obj_value, |
| 5089 obj_value, | 5089 attr); |
| 5090 attr); | 5090 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5091 return *result; |
| 5091 } | 5092 } |
| 5092 | 5093 |
| 5093 | 5094 |
| 5094 // Return property without being observable by accessors or interceptors. | 5095 // Return property without being observable by accessors or interceptors. |
| 5095 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { | 5096 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { |
| 5096 SealHandleScope shs(isolate); | 5097 SealHandleScope shs(isolate); |
| 5097 ASSERT(args.length() == 2); | 5098 ASSERT(args.length() == 2); |
| 5098 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 5099 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
| 5099 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); | 5100 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
| 5100 LookupResult lookup(isolate); | 5101 LookupResult lookup(isolate); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5114 case INTERCEPTOR: | 5115 case INTERCEPTOR: |
| 5115 case TRANSITION: | 5116 case TRANSITION: |
| 5116 return isolate->heap()->undefined_value(); | 5117 return isolate->heap()->undefined_value(); |
| 5117 case NONEXISTENT: | 5118 case NONEXISTENT: |
| 5118 UNREACHABLE(); | 5119 UNREACHABLE(); |
| 5119 } | 5120 } |
| 5120 return isolate->heap()->undefined_value(); | 5121 return isolate->heap()->undefined_value(); |
| 5121 } | 5122 } |
| 5122 | 5123 |
| 5123 | 5124 |
| 5124 MaybeObject* Runtime::SetObjectPropertyOrFail( | 5125 Handle<Object> Runtime::SetObjectProperty(Isolate* isolate, |
| 5125 Isolate* isolate, | 5126 Handle<Object> object, |
| 5126 Handle<Object> object, | 5127 Handle<Object> key, |
| 5127 Handle<Object> key, | 5128 Handle<Object> value, |
| 5128 Handle<Object> value, | 5129 PropertyAttributes attr, |
| 5129 PropertyAttributes attr, | 5130 StrictModeFlag strict_mode) { |
| 5130 StrictModeFlag strict_mode) { | |
| 5131 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, | |
| 5132 SetObjectProperty(isolate, object, key, value, attr, strict_mode)); | |
| 5133 } | |
| 5134 | |
| 5135 | |
| 5136 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, | |
| 5137 Handle<Object> object, | |
| 5138 Handle<Object> key, | |
| 5139 Handle<Object> value, | |
| 5140 PropertyAttributes attr, | |
| 5141 StrictModeFlag strict_mode) { | |
| 5142 SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY; | 5131 SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY; |
| 5143 HandleScope scope(isolate); | |
| 5144 | 5132 |
| 5145 if (object->IsUndefined() || object->IsNull()) { | 5133 if (object->IsUndefined() || object->IsNull()) { |
| 5146 Handle<Object> args[2] = { key, object }; | 5134 Handle<Object> args[2] = { key, object }; |
| 5147 Handle<Object> error = | 5135 Handle<Object> error = |
| 5148 isolate->factory()->NewTypeError("non_object_property_store", | 5136 isolate->factory()->NewTypeError("non_object_property_store", |
| 5149 HandleVector(args, 2)); | 5137 HandleVector(args, 2)); |
| 5150 return isolate->Throw(*error); | 5138 isolate->Throw(*error); |
| 5139 return Handle<Object>(); |
| 5151 } | 5140 } |
| 5152 | 5141 |
| 5153 if (object->IsJSProxy()) { | 5142 if (object->IsJSProxy()) { |
| 5154 bool has_pending_exception = false; | 5143 bool has_pending_exception = false; |
| 5155 Handle<Object> name_object = key->IsSymbol() | 5144 Handle<Object> name_object = key->IsSymbol() |
| 5156 ? key : Execution::ToString(isolate, key, &has_pending_exception); | 5145 ? key : Execution::ToString(isolate, key, &has_pending_exception); |
| 5157 if (has_pending_exception) return Failure::Exception(); | 5146 if (has_pending_exception) return Handle<Object>(); // exception |
| 5158 Handle<Name> name = Handle<Name>::cast(name_object); | 5147 Handle<Name> name = Handle<Name>::cast(name_object); |
| 5159 Handle<Object> result = JSReceiver::SetProperty( | 5148 return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value, |
| 5160 Handle<JSProxy>::cast(object), name, value, attr, strict_mode); | 5149 attr, |
| 5161 RETURN_IF_EMPTY_HANDLE(isolate, result); | 5150 strict_mode); |
| 5162 return *result; | |
| 5163 } | 5151 } |
| 5164 | 5152 |
| 5165 // If the object isn't a JavaScript object, we ignore the store. | 5153 // If the object isn't a JavaScript object, we ignore the store. |
| 5166 if (!object->IsJSObject()) return *value; | 5154 if (!object->IsJSObject()) return value; |
| 5167 | 5155 |
| 5168 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 5156 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 5169 | 5157 |
| 5170 // Check if the given key is an array index. | 5158 // Check if the given key is an array index. |
| 5171 uint32_t index; | 5159 uint32_t index; |
| 5172 if (key->ToArrayIndex(&index)) { | 5160 if (key->ToArrayIndex(&index)) { |
| 5173 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters | 5161 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters |
| 5174 // of a string using [] notation. We need to support this too in | 5162 // of a string using [] notation. We need to support this too in |
| 5175 // JavaScript. | 5163 // JavaScript. |
| 5176 // In the case of a String object we just need to redirect the assignment to | 5164 // In the case of a String object we just need to redirect the assignment to |
| 5177 // the underlying string if the index is in range. Since the underlying | 5165 // the underlying string if the index is in range. Since the underlying |
| 5178 // string does nothing with the assignment then we can ignore such | 5166 // string does nothing with the assignment then we can ignore such |
| 5179 // assignments. | 5167 // assignments. |
| 5180 if (js_object->IsStringObjectWithCharacterAt(index)) { | 5168 if (js_object->IsStringObjectWithCharacterAt(index)) { |
| 5181 return *value; | 5169 return value; |
| 5182 } | 5170 } |
| 5183 | 5171 |
| 5184 js_object->ValidateElements(); | 5172 js_object->ValidateElements(); |
| 5185 if (js_object->HasExternalArrayElements()) { | 5173 if (js_object->HasExternalArrayElements()) { |
| 5186 if (!value->IsNumber() && !value->IsUndefined()) { | 5174 if (!value->IsNumber() && !value->IsUndefined()) { |
| 5187 bool has_exception; | 5175 bool has_exception; |
| 5188 Handle<Object> number = | 5176 Handle<Object> number = |
| 5189 Execution::ToNumber(isolate, value, &has_exception); | 5177 Execution::ToNumber(isolate, value, &has_exception); |
| 5190 if (has_exception) return Failure::Exception(); | 5178 if (has_exception) return Handle<Object>(); // exception |
| 5191 value = number; | 5179 value = number; |
| 5192 } | 5180 } |
| 5193 } | 5181 } |
| 5194 MaybeObject* result = js_object->SetElement( | 5182 Handle<Object> result = JSObject::SetElement(js_object, index, value, attr, |
| 5195 index, *value, attr, strict_mode, true, set_mode); | 5183 strict_mode, |
| 5184 true, |
| 5185 set_mode); |
| 5196 js_object->ValidateElements(); | 5186 js_object->ValidateElements(); |
| 5197 if (result->IsFailure()) return result; | 5187 return result.is_null() ? result : value; |
| 5198 return *value; | |
| 5199 } | 5188 } |
| 5200 | 5189 |
| 5201 if (key->IsName()) { | 5190 if (key->IsName()) { |
| 5202 Handle<Name> name = Handle<Name>::cast(key); | 5191 Handle<Name> name = Handle<Name>::cast(key); |
| 5203 if (name->AsArrayIndex(&index)) { | 5192 if (name->AsArrayIndex(&index)) { |
| 5204 if (js_object->HasExternalArrayElements()) { | 5193 if (js_object->HasExternalArrayElements()) { |
| 5205 if (!value->IsNumber() && !value->IsUndefined()) { | 5194 if (!value->IsNumber() && !value->IsUndefined()) { |
| 5206 bool has_exception; | 5195 bool has_exception; |
| 5207 Handle<Object> number = | 5196 Handle<Object> number = |
| 5208 Execution::ToNumber(isolate, value, &has_exception); | 5197 Execution::ToNumber(isolate, value, &has_exception); |
| 5209 if (has_exception) return Failure::Exception(); | 5198 if (has_exception) return Handle<Object>(); // exception |
| 5210 value = number; | 5199 value = number; |
| 5211 } | 5200 } |
| 5212 } | 5201 } |
| 5213 MaybeObject* result = js_object->SetElement( | 5202 return JSObject::SetElement(js_object, index, value, attr, strict_mode, |
| 5214 index, *value, attr, strict_mode, true, set_mode); | 5203 true, |
| 5215 if (result->IsFailure()) return result; | 5204 set_mode); |
| 5216 } else { | 5205 } else { |
| 5217 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); | 5206 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
| 5218 Handle<Object> result = | 5207 return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode); |
| 5219 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode); | |
| 5220 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
| 5221 } | 5208 } |
| 5222 return *value; | |
| 5223 } | 5209 } |
| 5224 | 5210 |
| 5225 // Call-back into JavaScript to convert the key to a string. | 5211 // Call-back into JavaScript to convert the key to a string. |
| 5226 bool has_pending_exception = false; | 5212 bool has_pending_exception = false; |
| 5227 Handle<Object> converted = | 5213 Handle<Object> converted = |
| 5228 Execution::ToString(isolate, key, &has_pending_exception); | 5214 Execution::ToString(isolate, key, &has_pending_exception); |
| 5229 if (has_pending_exception) return Failure::Exception(); | 5215 if (has_pending_exception) return Handle<Object>(); // exception |
| 5230 Handle<String> name = Handle<String>::cast(converted); | 5216 Handle<String> name = Handle<String>::cast(converted); |
| 5231 | 5217 |
| 5232 if (name->AsArrayIndex(&index)) { | 5218 if (name->AsArrayIndex(&index)) { |
| 5233 return js_object->SetElement( | 5219 return JSObject::SetElement(js_object, index, value, attr, strict_mode, |
| 5234 index, *value, attr, strict_mode, true, set_mode); | 5220 true, |
| 5221 set_mode); |
| 5235 } else { | 5222 } else { |
| 5236 Handle<Object> result = | 5223 return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode); |
| 5237 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode); | |
| 5238 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
| 5239 return *result; | |
| 5240 } | 5224 } |
| 5241 } | 5225 } |
| 5242 | 5226 |
| 5243 | 5227 |
| 5244 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, | 5228 Handle<Object> Runtime::ForceSetObjectProperty(Isolate* isolate, |
| 5245 Handle<JSObject> js_object, | 5229 Handle<JSObject> js_object, |
| 5246 Handle<Object> key, | 5230 Handle<Object> key, |
| 5247 Handle<Object> value, | 5231 Handle<Object> value, |
| 5248 PropertyAttributes attr) { | 5232 PropertyAttributes attr) { |
| 5249 HandleScope scope(isolate); | |
| 5250 | |
| 5251 // Check if the given key is an array index. | 5233 // Check if the given key is an array index. |
| 5252 uint32_t index; | 5234 uint32_t index; |
| 5253 if (key->ToArrayIndex(&index)) { | 5235 if (key->ToArrayIndex(&index)) { |
| 5254 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters | 5236 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters |
| 5255 // of a string using [] notation. We need to support this too in | 5237 // of a string using [] notation. We need to support this too in |
| 5256 // JavaScript. | 5238 // JavaScript. |
| 5257 // In the case of a String object we just need to redirect the assignment to | 5239 // In the case of a String object we just need to redirect the assignment to |
| 5258 // the underlying string if the index is in range. Since the underlying | 5240 // the underlying string if the index is in range. Since the underlying |
| 5259 // string does nothing with the assignment then we can ignore such | 5241 // string does nothing with the assignment then we can ignore such |
| 5260 // assignments. | 5242 // assignments. |
| 5261 if (js_object->IsStringObjectWithCharacterAt(index)) { | 5243 if (js_object->IsStringObjectWithCharacterAt(index)) { |
| 5262 return *value; | 5244 return value; |
| 5263 } | 5245 } |
| 5264 | 5246 |
| 5265 return js_object->SetElement( | 5247 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode, |
| 5266 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 5248 false, |
| 5249 DEFINE_PROPERTY); |
| 5267 } | 5250 } |
| 5268 | 5251 |
| 5269 if (key->IsName()) { | 5252 if (key->IsName()) { |
| 5270 Handle<Name> name = Handle<Name>::cast(key); | 5253 Handle<Name> name = Handle<Name>::cast(key); |
| 5271 if (name->AsArrayIndex(&index)) { | 5254 if (name->AsArrayIndex(&index)) { |
| 5272 return js_object->SetElement( | 5255 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode, |
| 5273 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 5256 false, |
| 5257 DEFINE_PROPERTY); |
| 5274 } else { | 5258 } else { |
| 5275 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); | 5259 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
| 5276 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( | 5260 return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name, |
| 5277 js_object, name, value, attr); | 5261 value, attr); |
| 5278 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
| 5279 return *result; | |
| 5280 } | 5262 } |
| 5281 } | 5263 } |
| 5282 | 5264 |
| 5283 // Call-back into JavaScript to convert the key to a string. | 5265 // Call-back into JavaScript to convert the key to a string. |
| 5284 bool has_pending_exception = false; | 5266 bool has_pending_exception = false; |
| 5285 Handle<Object> converted = | 5267 Handle<Object> converted = |
| 5286 Execution::ToString(isolate, key, &has_pending_exception); | 5268 Execution::ToString(isolate, key, &has_pending_exception); |
| 5287 if (has_pending_exception) return Failure::Exception(); | 5269 if (has_pending_exception) return Handle<Object>(); // exception |
| 5288 Handle<String> name = Handle<String>::cast(converted); | 5270 Handle<String> name = Handle<String>::cast(converted); |
| 5289 | 5271 |
| 5290 if (name->AsArrayIndex(&index)) { | 5272 if (name->AsArrayIndex(&index)) { |
| 5291 return js_object->SetElement( | 5273 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode, |
| 5292 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 5274 false, |
| 5275 DEFINE_PROPERTY); |
| 5293 } else { | 5276 } else { |
| 5294 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( | 5277 return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name, value, |
| 5295 js_object, name, value, attr); | 5278 attr); |
| 5296 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
| 5297 return *result; | |
| 5298 } | 5279 } |
| 5299 } | 5280 } |
| 5300 | 5281 |
| 5301 | 5282 |
| 5302 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, | 5283 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, |
| 5303 Handle<JSReceiver> receiver, | 5284 Handle<JSReceiver> receiver, |
| 5304 Handle<Object> key, | 5285 Handle<Object> key, |
| 5305 JSReceiver::DeleteMode mode) { | 5286 JSReceiver::DeleteMode mode) { |
| 5306 HandleScope scope(isolate); | 5287 HandleScope scope(isolate); |
| 5307 | 5288 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 5336 } | 5317 } |
| 5337 | 5318 |
| 5338 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); | 5319 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
| 5339 Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode); | 5320 Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode); |
| 5340 RETURN_IF_EMPTY_HANDLE(isolate, result); | 5321 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5341 return *result; | 5322 return *result; |
| 5342 } | 5323 } |
| 5343 | 5324 |
| 5344 | 5325 |
| 5345 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { | 5326 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { |
| 5346 SealHandleScope shs(isolate); | 5327 HandleScope scope(isolate); |
| 5347 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); | 5328 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
| 5348 | 5329 |
| 5349 Handle<Object> object = args.at<Object>(0); | 5330 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
| 5350 Handle<Object> key = args.at<Object>(1); | 5331 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); |
| 5351 Handle<Object> value = args.at<Object>(2); | 5332 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
| 5352 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); | 5333 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); |
| 5353 RUNTIME_ASSERT( | 5334 RUNTIME_ASSERT( |
| 5354 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5335 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 5355 // Compute attributes. | 5336 // Compute attributes. |
| 5356 PropertyAttributes attributes = | 5337 PropertyAttributes attributes = |
| 5357 static_cast<PropertyAttributes>(unchecked_attributes); | 5338 static_cast<PropertyAttributes>(unchecked_attributes); |
| 5358 | 5339 |
| 5359 StrictModeFlag strict_mode = kNonStrictMode; | 5340 StrictModeFlag strict_mode = kNonStrictMode; |
| 5360 if (args.length() == 5) { | 5341 if (args.length() == 5) { |
| 5361 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4); | 5342 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4); |
| 5362 strict_mode = strict_mode_flag; | 5343 strict_mode = strict_mode_flag; |
| 5363 } | 5344 } |
| 5364 | 5345 |
| 5365 return Runtime::SetObjectProperty(isolate, | 5346 Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key, |
| 5366 object, | 5347 value, |
| 5367 key, | 5348 attributes, |
| 5368 value, | 5349 strict_mode); |
| 5369 attributes, | 5350 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5370 strict_mode); | 5351 return *result; |
| 5371 } | 5352 } |
| 5372 | 5353 |
| 5373 | 5354 |
| 5374 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) { | 5355 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) { |
| 5375 HandleScope scope(isolate); | 5356 HandleScope scope(isolate); |
| 5376 RUNTIME_ASSERT(args.length() == 2); | 5357 RUNTIME_ASSERT(args.length() == 2); |
| 5377 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); | 5358 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
| 5378 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); | 5359 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); |
| 5379 JSObject::TransitionElementsKind(array, map->elements_kind()); | 5360 JSObject::TransitionElementsKind(array, map->elements_kind()); |
| 5380 return *array; | 5361 return *array; |
| 5381 } | 5362 } |
| 5382 | 5363 |
| 5383 | 5364 |
| 5384 // Set the native flag on the function. | 5365 // Set the native flag on the function. |
| 5385 // This is used to decide if we should transform null and undefined | 5366 // This is used to decide if we should transform null and undefined |
| 5386 // into the global object when doing call and apply. | 5367 // into the global object when doing call and apply. |
| 5387 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { | 5368 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { |
| 5388 SealHandleScope shs(isolate); | 5369 SealHandleScope shs(isolate); |
| 5389 RUNTIME_ASSERT(args.length() == 1); | 5370 RUNTIME_ASSERT(args.length() == 1); |
| 5390 | 5371 |
| 5391 Handle<Object> object = args.at<Object>(0); | 5372 CONVERT_ARG_CHECKED(Object, object, 0); |
| 5392 | 5373 |
| 5393 if (object->IsJSFunction()) { | 5374 if (object->IsJSFunction()) { |
| 5394 JSFunction* func = JSFunction::cast(*object); | 5375 JSFunction* func = JSFunction::cast(object); |
| 5395 func->shared()->set_native(true); | 5376 func->shared()->set_native(true); |
| 5396 } | 5377 } |
| 5397 return isolate->heap()->undefined_value(); | 5378 return isolate->heap()->undefined_value(); |
| 5398 } | 5379 } |
| 5399 | 5380 |
| 5400 | 5381 |
| 5401 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { | 5382 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { |
| 5402 HandleScope scope(isolate); | 5383 HandleScope scope(isolate); |
| 5403 RUNTIME_ASSERT(args.length() == 5); | 5384 RUNTIME_ASSERT(args.length() == 5); |
| 5404 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 5385 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6187 | 6168 |
| 6188 // Create a number object from the value. | 6169 // Create a number object from the value. |
| 6189 return isolate->heap()->NumberFromDouble(value); | 6170 return isolate->heap()->NumberFromDouble(value); |
| 6190 } | 6171 } |
| 6191 | 6172 |
| 6192 | 6173 |
| 6193 template <class Converter> | 6174 template <class Converter> |
| 6194 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( | 6175 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( |
| 6195 Isolate* isolate, | 6176 Isolate* isolate, |
| 6196 String* s, | 6177 String* s, |
| 6178 String::Encoding result_encoding, |
| 6197 int length, | 6179 int length, |
| 6198 int input_string_length, | 6180 int input_string_length, |
| 6199 unibrow::Mapping<Converter, 128>* mapping) { | 6181 unibrow::Mapping<Converter, 128>* mapping) { |
| 6200 // We try this twice, once with the assumption that the result is no longer | 6182 // We try this twice, once with the assumption that the result is no longer |
| 6201 // than the input and, if that assumption breaks, again with the exact | 6183 // than the input and, if that assumption breaks, again with the exact |
| 6202 // length. This may not be pretty, but it is nicer than what was here before | 6184 // length. This may not be pretty, but it is nicer than what was here before |
| 6203 // and I hereby claim my vaffel-is. | 6185 // and I hereby claim my vaffel-is. |
| 6204 // | 6186 // |
| 6205 // Allocate the resulting string. | 6187 // Allocate the resulting string. |
| 6206 // | 6188 // |
| 6207 // NOTE: This assumes that the upper/lower case of an ASCII | 6189 // NOTE: This assumes that the upper/lower case of an ASCII |
| 6208 // character is also ASCII. This is currently the case, but it | 6190 // character is also ASCII. This is currently the case, but it |
| 6209 // might break in the future if we implement more context and locale | 6191 // might break in the future if we implement more context and locale |
| 6210 // dependent upper/lower conversions. | 6192 // dependent upper/lower conversions. |
| 6211 Object* o; | 6193 Object* o; |
| 6212 { MaybeObject* maybe_o = s->IsOneByteRepresentation() | 6194 { MaybeObject* maybe_o = result_encoding == String::ONE_BYTE_ENCODING |
| 6213 ? isolate->heap()->AllocateRawOneByteString(length) | 6195 ? isolate->heap()->AllocateRawOneByteString(length) |
| 6214 : isolate->heap()->AllocateRawTwoByteString(length); | 6196 : isolate->heap()->AllocateRawTwoByteString(length); |
| 6215 if (!maybe_o->ToObject(&o)) return maybe_o; | 6197 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 6216 } | 6198 } |
| 6217 String* result = String::cast(o); | 6199 String* result = String::cast(o); |
| 6218 bool has_changed_character = false; | 6200 bool has_changed_character = false; |
| 6219 | 6201 |
| 6202 DisallowHeapAllocation no_gc; |
| 6203 |
| 6220 // Convert all characters to upper case, assuming that they will fit | 6204 // Convert all characters to upper case, assuming that they will fit |
| 6221 // in the buffer | 6205 // in the buffer |
| 6222 Access<ConsStringIteratorOp> op( | 6206 Access<ConsStringIteratorOp> op( |
| 6223 isolate->runtime_state()->string_iterator()); | 6207 isolate->runtime_state()->string_iterator()); |
| 6224 StringCharacterStream stream(s, op.value()); | 6208 StringCharacterStream stream(s, op.value()); |
| 6225 unibrow::uchar chars[Converter::kMaxWidth]; | 6209 unibrow::uchar chars[Converter::kMaxWidth]; |
| 6226 // We can assume that the string is not empty | 6210 // We can assume that the string is not empty |
| 6227 uc32 current = stream.GetNext(); | 6211 uc32 current = stream.GetNext(); |
| 6212 // y with umlauts is the only character that stops fitting into one-byte |
| 6213 // when converting to uppercase. |
| 6214 static const uc32 yuml_code = 0xff; |
| 6215 bool ignore_yuml = result->IsSeqTwoByteString() || Converter::kIsToLower; |
| 6228 for (int i = 0; i < length;) { | 6216 for (int i = 0; i < length;) { |
| 6229 bool has_next = stream.HasMore(); | 6217 bool has_next = stream.HasMore(); |
| 6230 uc32 next = has_next ? stream.GetNext() : 0; | 6218 uc32 next = has_next ? stream.GetNext() : 0; |
| 6231 int char_length = mapping->get(current, next, chars); | 6219 int char_length = mapping->get(current, next, chars); |
| 6232 if (char_length == 0) { | 6220 if (char_length == 0) { |
| 6233 // The case conversion of this character is the character itself. | 6221 // The case conversion of this character is the character itself. |
| 6234 result->Set(i, current); | 6222 result->Set(i, current); |
| 6235 i++; | 6223 i++; |
| 6236 } else if (char_length == 1) { | 6224 } else if (char_length == 1 && (ignore_yuml || current != yuml_code)) { |
| 6237 // Common case: converting the letter resulted in one character. | 6225 // Common case: converting the letter resulted in one character. |
| 6238 ASSERT(static_cast<uc32>(chars[0]) != current); | 6226 ASSERT(static_cast<uc32>(chars[0]) != current); |
| 6239 result->Set(i, chars[0]); | 6227 result->Set(i, chars[0]); |
| 6240 has_changed_character = true; | 6228 has_changed_character = true; |
| 6241 i++; | 6229 i++; |
| 6242 } else if (length == input_string_length) { | 6230 } else if (length == input_string_length) { |
| 6231 bool found_yuml = (current == yuml_code); |
| 6243 // We've assumed that the result would be as long as the | 6232 // We've assumed that the result would be as long as the |
| 6244 // input but here is a character that converts to several | 6233 // input but here is a character that converts to several |
| 6245 // characters. No matter, we calculate the exact length | 6234 // characters. No matter, we calculate the exact length |
| 6246 // of the result and try the whole thing again. | 6235 // of the result and try the whole thing again. |
| 6247 // | 6236 // |
| 6248 // Note that this leaves room for optimization. We could just | 6237 // Note that this leaves room for optimization. We could just |
| 6249 // memcpy what we already have to the result string. Also, | 6238 // memcpy what we already have to the result string. Also, |
| 6250 // the result string is the last object allocated we could | 6239 // the result string is the last object allocated we could |
| 6251 // "realloc" it and probably, in the vast majority of cases, | 6240 // "realloc" it and probably, in the vast majority of cases, |
| 6252 // extend the existing string to be able to hold the full | 6241 // extend the existing string to be able to hold the full |
| 6253 // result. | 6242 // result. |
| 6254 int next_length = 0; | 6243 int next_length = 0; |
| 6255 if (has_next) { | 6244 if (has_next) { |
| 6256 next_length = mapping->get(next, 0, chars); | 6245 next_length = mapping->get(next, 0, chars); |
| 6257 if (next_length == 0) next_length = 1; | 6246 if (next_length == 0) next_length = 1; |
| 6258 } | 6247 } |
| 6259 int current_length = i + char_length + next_length; | 6248 int current_length = i + char_length + next_length; |
| 6260 while (stream.HasMore()) { | 6249 while (stream.HasMore()) { |
| 6261 current = stream.GetNext(); | 6250 current = stream.GetNext(); |
| 6251 found_yuml |= (current == yuml_code); |
| 6262 // NOTE: we use 0 as the next character here because, while | 6252 // NOTE: we use 0 as the next character here because, while |
| 6263 // the next character may affect what a character converts to, | 6253 // the next character may affect what a character converts to, |
| 6264 // it does not in any case affect the length of what it convert | 6254 // it does not in any case affect the length of what it convert |
| 6265 // to. | 6255 // to. |
| 6266 int char_length = mapping->get(current, 0, chars); | 6256 int char_length = mapping->get(current, 0, chars); |
| 6267 if (char_length == 0) char_length = 1; | 6257 if (char_length == 0) char_length = 1; |
| 6268 current_length += char_length; | 6258 current_length += char_length; |
| 6269 if (current_length > Smi::kMaxValue) { | 6259 if (current_length > Smi::kMaxValue) { |
| 6270 isolate->context()->mark_out_of_memory(); | 6260 isolate->context()->mark_out_of_memory(); |
| 6271 return Failure::OutOfMemoryException(0x13); | 6261 return Failure::OutOfMemoryException(0x13); |
| 6272 } | 6262 } |
| 6273 } | 6263 } |
| 6274 // Try again with the real length. | 6264 // Try again with the real length. Return signed if we need |
| 6275 return Smi::FromInt(current_length); | 6265 // to allocate a two-byte string for y-umlaut to uppercase. |
| 6266 return (found_yuml && !ignore_yuml) ? Smi::FromInt(-current_length) |
| 6267 : Smi::FromInt(current_length); |
| 6276 } else { | 6268 } else { |
| 6277 for (int j = 0; j < char_length; j++) { | 6269 for (int j = 0; j < char_length; j++) { |
| 6278 result->Set(i, chars[j]); | 6270 result->Set(i, chars[j]); |
| 6279 i++; | 6271 i++; |
| 6280 } | 6272 } |
| 6281 has_changed_character = true; | 6273 has_changed_character = true; |
| 6282 } | 6274 } |
| 6283 current = next; | 6275 current = next; |
| 6284 } | 6276 } |
| 6285 if (has_changed_character) { | 6277 if (has_changed_character) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6311 // further simplified. | 6303 // further simplified. |
| 6312 ASSERT(0 < m && m < n); | 6304 ASSERT(0 < m && m < n); |
| 6313 // Has high bit set in every w byte less than n. | 6305 // Has high bit set in every w byte less than n. |
| 6314 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; | 6306 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; |
| 6315 // Has high bit set in every w byte greater than m. | 6307 // Has high bit set in every w byte greater than m. |
| 6316 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); | 6308 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); |
| 6317 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); | 6309 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); |
| 6318 } | 6310 } |
| 6319 | 6311 |
| 6320 | 6312 |
| 6321 enum AsciiCaseConversion { | 6313 #ifdef DEBUG |
| 6322 ASCII_TO_LOWER, | 6314 static bool CheckFastAsciiConvert(char* dst, |
| 6323 ASCII_TO_UPPER | 6315 char* src, |
| 6324 }; | 6316 int length, |
| 6317 bool changed, |
| 6318 bool is_to_lower) { |
| 6319 bool expected_changed = false; |
| 6320 for (int i = 0; i < length; i++) { |
| 6321 if (dst[i] == src[i]) continue; |
| 6322 expected_changed = true; |
| 6323 if (is_to_lower) { |
| 6324 ASSERT('A' <= src[i] && src[i] <= 'Z'); |
| 6325 ASSERT(dst[i] == src[i] + ('a' - 'A')); |
| 6326 } else { |
| 6327 ASSERT('a' <= src[i] && src[i] <= 'z'); |
| 6328 ASSERT(dst[i] == src[i] - ('a' - 'A')); |
| 6329 } |
| 6330 } |
| 6331 return (expected_changed == changed); |
| 6332 } |
| 6333 #endif |
| 6325 | 6334 |
| 6326 | 6335 |
| 6327 template <AsciiCaseConversion dir> | 6336 template<class Converter> |
| 6328 struct FastAsciiConverter { | 6337 static bool FastAsciiConvert(char* dst, |
| 6329 static bool Convert(char* dst, char* src, int length, bool* changed_out) { | 6338 char* src, |
| 6339 int length, |
| 6340 bool* changed_out) { |
| 6330 #ifdef DEBUG | 6341 #ifdef DEBUG |
| 6331 char* saved_dst = dst; | 6342 char* saved_dst = dst; |
| 6332 char* saved_src = src; | 6343 char* saved_src = src; |
| 6333 #endif | 6344 #endif |
| 6334 // We rely on the distance between upper and lower case letters | 6345 DisallowHeapAllocation no_gc; |
| 6335 // being a known power of 2. | 6346 // We rely on the distance between upper and lower case letters |
| 6336 ASSERT('a' - 'A' == (1 << 5)); | 6347 // being a known power of 2. |
| 6337 // Boundaries for the range of input characters than require conversion. | 6348 ASSERT('a' - 'A' == (1 << 5)); |
| 6338 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; | 6349 // Boundaries for the range of input characters than require conversion. |
| 6339 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; | 6350 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1; |
| 6340 bool changed = false; | 6351 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1; |
| 6341 uintptr_t or_acc = 0; | 6352 bool changed = false; |
| 6342 char* const limit = src + length; | 6353 uintptr_t or_acc = 0; |
| 6354 char* const limit = src + length; |
| 6343 #ifdef V8_HOST_CAN_READ_UNALIGNED | 6355 #ifdef V8_HOST_CAN_READ_UNALIGNED |
| 6344 // Process the prefix of the input that requires no conversion one | 6356 // Process the prefix of the input that requires no conversion one |
| 6345 // (machine) word at a time. | 6357 // (machine) word at a time. |
| 6346 while (src <= limit - sizeof(uintptr_t)) { | 6358 while (src <= limit - sizeof(uintptr_t)) { |
| 6347 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); | 6359 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
| 6348 or_acc |= w; | 6360 or_acc |= w; |
| 6349 if (AsciiRangeMask(w, lo, hi) != 0) { | 6361 if (AsciiRangeMask(w, lo, hi) != 0) { |
| 6350 changed = true; | 6362 changed = true; |
| 6351 break; | 6363 break; |
| 6352 } | |
| 6353 *reinterpret_cast<uintptr_t*>(dst) = w; | |
| 6354 src += sizeof(uintptr_t); | |
| 6355 dst += sizeof(uintptr_t); | |
| 6356 } | 6364 } |
| 6357 // Process the remainder of the input performing conversion when | 6365 *reinterpret_cast<uintptr_t*>(dst) = w; |
| 6358 // required one word at a time. | 6366 src += sizeof(uintptr_t); |
| 6359 while (src <= limit - sizeof(uintptr_t)) { | 6367 dst += sizeof(uintptr_t); |
| 6360 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); | 6368 } |
| 6361 or_acc |= w; | 6369 // Process the remainder of the input performing conversion when |
| 6362 uintptr_t m = AsciiRangeMask(w, lo, hi); | 6370 // required one word at a time. |
| 6363 // The mask has high (7th) bit set in every byte that needs | 6371 while (src <= limit - sizeof(uintptr_t)) { |
| 6364 // conversion and we know that the distance between cases is | 6372 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
| 6365 // 1 << 5. | 6373 or_acc |= w; |
| 6366 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); | 6374 uintptr_t m = AsciiRangeMask(w, lo, hi); |
| 6367 src += sizeof(uintptr_t); | 6375 // The mask has high (7th) bit set in every byte that needs |
| 6368 dst += sizeof(uintptr_t); | 6376 // conversion and we know that the distance between cases is |
| 6377 // 1 << 5. |
| 6378 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); |
| 6379 src += sizeof(uintptr_t); |
| 6380 dst += sizeof(uintptr_t); |
| 6381 } |
| 6382 #endif |
| 6383 // Process the last few bytes of the input (or the whole input if |
| 6384 // unaligned access is not supported). |
| 6385 while (src < limit) { |
| 6386 char c = *src; |
| 6387 or_acc |= c; |
| 6388 if (lo < c && c < hi) { |
| 6389 c ^= (1 << 5); |
| 6390 changed = true; |
| 6369 } | 6391 } |
| 6370 #endif | 6392 *dst = c; |
| 6371 // Process the last few bytes of the input (or the whole input if | 6393 ++src; |
| 6372 // unaligned access is not supported). | 6394 ++dst; |
| 6373 while (src < limit) { | 6395 } |
| 6374 char c = *src; | 6396 if ((or_acc & kAsciiMask) != 0) { |
| 6375 or_acc |= c; | 6397 return false; |
| 6376 if (lo < c && c < hi) { | |
| 6377 c ^= (1 << 5); | |
| 6378 changed = true; | |
| 6379 } | |
| 6380 *dst = c; | |
| 6381 ++src; | |
| 6382 ++dst; | |
| 6383 } | |
| 6384 if ((or_acc & kAsciiMask) != 0) { | |
| 6385 return false; | |
| 6386 } | |
| 6387 #ifdef DEBUG | |
| 6388 CheckConvert(saved_dst, saved_src, length, changed); | |
| 6389 #endif | |
| 6390 *changed_out = changed; | |
| 6391 return true; | |
| 6392 } | 6398 } |
| 6393 | 6399 |
| 6394 #ifdef DEBUG | 6400 ASSERT(CheckFastAsciiConvert( |
| 6395 static void CheckConvert(char* dst, char* src, int length, bool changed) { | 6401 saved_dst, saved_src, length, changed, Converter::kIsToLower)); |
| 6396 bool expected_changed = false; | |
| 6397 for (int i = 0; i < length; i++) { | |
| 6398 if (dst[i] == src[i]) continue; | |
| 6399 expected_changed = true; | |
| 6400 if (dir == ASCII_TO_LOWER) { | |
| 6401 ASSERT('A' <= src[i] && src[i] <= 'Z'); | |
| 6402 ASSERT(dst[i] == src[i] + ('a' - 'A')); | |
| 6403 } else { | |
| 6404 ASSERT(dir == ASCII_TO_UPPER); | |
| 6405 ASSERT('a' <= src[i] && src[i] <= 'z'); | |
| 6406 ASSERT(dst[i] == src[i] - ('a' - 'A')); | |
| 6407 } | |
| 6408 } | |
| 6409 ASSERT(expected_changed == changed); | |
| 6410 } | |
| 6411 #endif | |
| 6412 }; | |
| 6413 | 6402 |
| 6414 | 6403 *changed_out = changed; |
| 6415 struct ToLowerTraits { | 6404 return true; |
| 6416 typedef unibrow::ToLowercase UnibrowConverter; | 6405 } |
| 6417 | |
| 6418 typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter; | |
| 6419 }; | |
| 6420 | |
| 6421 | |
| 6422 struct ToUpperTraits { | |
| 6423 typedef unibrow::ToUppercase UnibrowConverter; | |
| 6424 | |
| 6425 typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter; | |
| 6426 }; | |
| 6427 | 6406 |
| 6428 } // namespace | 6407 } // namespace |
| 6429 | 6408 |
| 6430 | 6409 |
| 6431 template <typename ConvertTraits> | 6410 template <class Converter> |
| 6432 MUST_USE_RESULT static MaybeObject* ConvertCase( | 6411 MUST_USE_RESULT static MaybeObject* ConvertCase( |
| 6433 Arguments args, | 6412 Arguments args, |
| 6434 Isolate* isolate, | 6413 Isolate* isolate, |
| 6435 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { | 6414 unibrow::Mapping<Converter, 128>* mapping) { |
| 6436 SealHandleScope shs(isolate); | 6415 SealHandleScope shs(isolate); |
| 6437 CONVERT_ARG_CHECKED(String, s, 0); | 6416 CONVERT_ARG_CHECKED(String, s, 0); |
| 6438 s = s->TryFlattenGetString(); | 6417 s = s->TryFlattenGetString(); |
| 6439 | 6418 |
| 6440 const int length = s->length(); | 6419 const int length = s->length(); |
| 6441 // Assume that the string is not empty; we need this assumption later | 6420 // Assume that the string is not empty; we need this assumption later |
| 6442 if (length == 0) return s; | 6421 if (length == 0) return s; |
| 6443 | 6422 |
| 6444 // Simpler handling of ASCII strings. | 6423 // Simpler handling of ASCII strings. |
| 6445 // | 6424 // |
| 6446 // NOTE: This assumes that the upper/lower case of an ASCII | 6425 // NOTE: This assumes that the upper/lower case of an ASCII |
| 6447 // character is also ASCII. This is currently the case, but it | 6426 // character is also ASCII. This is currently the case, but it |
| 6448 // might break in the future if we implement more context and locale | 6427 // might break in the future if we implement more context and locale |
| 6449 // dependent upper/lower conversions. | 6428 // dependent upper/lower conversions. |
| 6450 if (s->IsSeqOneByteString()) { | 6429 if (s->IsSeqOneByteString()) { |
| 6451 Object* o; | 6430 Object* o; |
| 6452 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); | 6431 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); |
| 6453 if (!maybe_o->ToObject(&o)) return maybe_o; | 6432 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 6454 } | 6433 } |
| 6455 SeqOneByteString* result = SeqOneByteString::cast(o); | 6434 SeqOneByteString* result = SeqOneByteString::cast(o); |
| 6456 bool has_changed_character; | 6435 bool has_changed_character; |
| 6457 bool is_ascii = ConvertTraits::AsciiConverter::Convert( | 6436 bool is_ascii = FastAsciiConvert<Converter>( |
| 6458 reinterpret_cast<char*>(result->GetChars()), | 6437 reinterpret_cast<char*>(result->GetChars()), |
| 6459 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), | 6438 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), |
| 6460 length, | 6439 length, |
| 6461 &has_changed_character); | 6440 &has_changed_character); |
| 6462 // If not ASCII, we discard the result and take the 2 byte path. | 6441 // If not ASCII, we discard the result and take the 2 byte path. |
| 6463 if (is_ascii) { | 6442 if (is_ascii) { |
| 6464 return has_changed_character ? result : s; | 6443 return has_changed_character ? result : s; |
| 6465 } | 6444 } |
| 6466 } | 6445 } |
| 6467 | 6446 |
| 6447 String::Encoding result_encoding = s->IsOneByteRepresentation() |
| 6448 ? String::ONE_BYTE_ENCODING : String::TWO_BYTE_ENCODING; |
| 6468 Object* answer; | 6449 Object* answer; |
| 6469 { MaybeObject* maybe_answer = | 6450 { MaybeObject* maybe_answer = ConvertCaseHelper( |
| 6470 ConvertCaseHelper(isolate, s, length, length, mapping); | 6451 isolate, s, result_encoding, length, length, mapping); |
| 6471 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | 6452 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 6472 } | 6453 } |
| 6473 if (answer->IsSmi()) { | 6454 if (answer->IsSmi()) { |
| 6474 // Retry with correct length. | 6455 int new_length = Smi::cast(answer)->value(); |
| 6475 { MaybeObject* maybe_answer = | 6456 if (new_length < 0) { |
| 6476 ConvertCaseHelper(isolate, | 6457 result_encoding = String::TWO_BYTE_ENCODING; |
| 6477 s, Smi::cast(answer)->value(), length, mapping); | 6458 new_length = -new_length; |
| 6478 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | |
| 6479 } | 6459 } |
| 6460 MaybeObject* maybe_answer = ConvertCaseHelper( |
| 6461 isolate, s, result_encoding, new_length, length, mapping); |
| 6462 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 6480 } | 6463 } |
| 6481 return answer; | 6464 return answer; |
| 6482 } | 6465 } |
| 6483 | 6466 |
| 6484 | 6467 |
| 6485 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) { | 6468 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) { |
| 6486 return ConvertCase<ToLowerTraits>( | 6469 return ConvertCase( |
| 6487 args, isolate, isolate->runtime_state()->to_lower_mapping()); | 6470 args, isolate, isolate->runtime_state()->to_lower_mapping()); |
| 6488 } | 6471 } |
| 6489 | 6472 |
| 6490 | 6473 |
| 6491 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) { | 6474 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) { |
| 6492 return ConvertCase<ToUpperTraits>( | 6475 return ConvertCase( |
| 6493 args, isolate, isolate->runtime_state()->to_upper_mapping()); | 6476 args, isolate, isolate->runtime_state()->to_upper_mapping()); |
| 6494 } | 6477 } |
| 6495 | 6478 |
| 6496 | 6479 |
| 6497 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { | 6480 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { |
| 6498 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff; | 6481 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff; |
| 6499 } | 6482 } |
| 6500 | 6483 |
| 6501 | 6484 |
| 6502 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) { | 6485 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) { |
| (...skipping 3217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9720 CONVERT_LANGUAGE_MODE_ARG(language_mode, 3); | 9703 CONVERT_LANGUAGE_MODE_ARG(language_mode, 3); |
| 9721 ASSERT(args[4]->IsSmi()); | 9704 ASSERT(args[4]->IsSmi()); |
| 9722 return CompileGlobalEval(isolate, | 9705 return CompileGlobalEval(isolate, |
| 9723 args.at<String>(1), | 9706 args.at<String>(1), |
| 9724 args.at<Object>(2), | 9707 args.at<Object>(2), |
| 9725 language_mode, | 9708 language_mode, |
| 9726 args.smi_at(4)); | 9709 args.smi_at(4)); |
| 9727 } | 9710 } |
| 9728 | 9711 |
| 9729 | 9712 |
| 9713 // Allocate a block of memory in the given space (filled with a filler). |
| 9714 // Used as a fall-back for generated code when the space is full. |
| 9730 static MaybeObject* Allocate(Isolate* isolate, | 9715 static MaybeObject* Allocate(Isolate* isolate, |
| 9731 int size, | 9716 int size, |
| 9732 AllocationSpace space) { | 9717 AllocationSpace space) { |
| 9733 // Allocate a block of memory in the given space (filled with a filler). | 9718 Heap* heap = isolate->heap(); |
| 9734 // Use as fallback for allocation in generated code when the space | |
| 9735 // is full. | |
| 9736 SealHandleScope shs(isolate); | |
| 9737 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); | 9719 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); |
| 9738 RUNTIME_ASSERT(size > 0); | 9720 RUNTIME_ASSERT(size > 0); |
| 9739 Heap* heap = isolate->heap(); | |
| 9740 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize()); | 9721 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize()); |
| 9741 Object* allocation; | 9722 HeapObject* allocation; |
| 9742 { MaybeObject* maybe_allocation; | 9723 { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space); |
| 9743 if (space == NEW_SPACE) { | 9724 if (!maybe_allocation->To(&allocation)) return maybe_allocation; |
| 9744 maybe_allocation = heap->new_space()->AllocateRaw(size); | |
| 9745 } else { | |
| 9746 ASSERT(space == OLD_POINTER_SPACE || space == OLD_DATA_SPACE); | |
| 9747 maybe_allocation = heap->paged_space(space)->AllocateRaw(size); | |
| 9748 } | |
| 9749 if (maybe_allocation->ToObject(&allocation)) { | |
| 9750 heap->CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size); | |
| 9751 } | |
| 9752 return maybe_allocation; | |
| 9753 } | 9725 } |
| 9726 #ifdef DEBUG |
| 9727 MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address()); |
| 9728 ASSERT(chunk->owner()->identity() == space); |
| 9729 #endif |
| 9730 heap->CreateFillerObjectAt(allocation->address(), size); |
| 9731 return allocation; |
| 9754 } | 9732 } |
| 9755 | 9733 |
| 9756 | 9734 |
| 9757 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) { | 9735 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) { |
| 9758 SealHandleScope shs(isolate); | 9736 SealHandleScope shs(isolate); |
| 9759 ASSERT(args.length() == 1); | 9737 ASSERT(args.length() == 1); |
| 9760 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); | 9738 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); |
| 9761 return Allocate(isolate, size_smi->value(), NEW_SPACE); | 9739 return Allocate(isolate, size_smi->value(), NEW_SPACE); |
| 9762 } | 9740 } |
| 9763 | 9741 |
| (...skipping 1578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11342 // First fill all parameters. | 11320 // First fill all parameters. |
| 11343 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 11321 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
| 11344 Handle<Object> value(i < frame_inspector->GetParametersCount() | 11322 Handle<Object> value(i < frame_inspector->GetParametersCount() |
| 11345 ? frame_inspector->GetParameter(i) | 11323 ? frame_inspector->GetParameter(i) |
| 11346 : isolate->heap()->undefined_value(), | 11324 : isolate->heap()->undefined_value(), |
| 11347 isolate); | 11325 isolate); |
| 11348 ASSERT(!value->IsTheHole()); | 11326 ASSERT(!value->IsTheHole()); |
| 11349 | 11327 |
| 11350 RETURN_IF_EMPTY_HANDLE_VALUE( | 11328 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 11351 isolate, | 11329 isolate, |
| 11352 SetProperty(isolate, | 11330 Runtime::SetObjectProperty(isolate, |
| 11353 target, | 11331 target, |
| 11354 Handle<String>(scope_info->ParameterName(i)), | 11332 Handle<String>(scope_info->ParameterName(i)), |
| 11355 value, | 11333 value, |
| 11356 NONE, | 11334 NONE, |
| 11357 kNonStrictMode), | 11335 kNonStrictMode), |
| 11358 Handle<JSObject>()); | 11336 Handle<JSObject>()); |
| 11359 } | 11337 } |
| 11360 | 11338 |
| 11361 // Second fill all stack locals. | 11339 // Second fill all stack locals. |
| 11362 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | 11340 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
| 11363 Handle<Object> value(frame_inspector->GetExpression(i), isolate); | 11341 Handle<Object> value(frame_inspector->GetExpression(i), isolate); |
| 11364 if (value->IsTheHole()) continue; | 11342 if (value->IsTheHole()) continue; |
| 11365 | 11343 |
| 11366 RETURN_IF_EMPTY_HANDLE_VALUE( | 11344 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 11367 isolate, | 11345 isolate, |
| 11368 SetProperty(isolate, | 11346 Runtime::SetObjectProperty( |
| 11369 target, | 11347 isolate, |
| 11370 Handle<String>(scope_info->StackLocalName(i)), | 11348 target, |
| 11371 value, | 11349 Handle<String>(scope_info->StackLocalName(i)), |
| 11372 NONE, | 11350 value, |
| 11373 kNonStrictMode), | 11351 NONE, |
| 11352 kNonStrictMode), |
| 11374 Handle<JSObject>()); | 11353 Handle<JSObject>()); |
| 11375 } | 11354 } |
| 11376 | 11355 |
| 11377 return target; | 11356 return target; |
| 11378 } | 11357 } |
| 11379 | 11358 |
| 11380 | 11359 |
| 11381 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate, | 11360 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate, |
| 11382 Handle<JSObject> target, | 11361 Handle<JSObject> target, |
| 11383 Handle<JSFunction> function, | 11362 Handle<JSFunction> function, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11441 Handle<FixedArray> keys = | 11420 Handle<FixedArray> keys = |
| 11442 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); | 11421 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 11443 if (threw) return Handle<JSObject>(); | 11422 if (threw) return Handle<JSObject>(); |
| 11444 | 11423 |
| 11445 for (int i = 0; i < keys->length(); i++) { | 11424 for (int i = 0; i < keys->length(); i++) { |
| 11446 // Names of variables introduced by eval are strings. | 11425 // Names of variables introduced by eval are strings. |
| 11447 ASSERT(keys->get(i)->IsString()); | 11426 ASSERT(keys->get(i)->IsString()); |
| 11448 Handle<String> key(String::cast(keys->get(i))); | 11427 Handle<String> key(String::cast(keys->get(i))); |
| 11449 RETURN_IF_EMPTY_HANDLE_VALUE( | 11428 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 11450 isolate, | 11429 isolate, |
| 11451 SetProperty(isolate, | 11430 Runtime::SetObjectProperty(isolate, |
| 11452 target, | 11431 target, |
| 11453 key, | 11432 key, |
| 11454 GetProperty(isolate, ext, key), | 11433 GetProperty(isolate, ext, key), |
| 11455 NONE, | 11434 NONE, |
| 11456 kNonStrictMode), | 11435 kNonStrictMode), |
| 11457 Handle<JSObject>()); | 11436 Handle<JSObject>()); |
| 11458 } | 11437 } |
| 11459 } | 11438 } |
| 11460 } | 11439 } |
| 11461 | 11440 |
| 11462 return target; | 11441 return target; |
| 11463 } | 11442 } |
| 11464 | 11443 |
| 11465 | 11444 |
| 11466 static Handle<JSObject> MaterializeLocalScope( | 11445 static Handle<JSObject> MaterializeLocalScope( |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11546 | 11525 |
| 11547 // Function context extension. These are variables introduced by eval. | 11526 // Function context extension. These are variables introduced by eval. |
| 11548 if (function_context->closure() == *function) { | 11527 if (function_context->closure() == *function) { |
| 11549 if (function_context->has_extension() && | 11528 if (function_context->has_extension() && |
| 11550 !function_context->IsNativeContext()) { | 11529 !function_context->IsNativeContext()) { |
| 11551 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 11530 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
| 11552 | 11531 |
| 11553 if (JSReceiver::HasProperty(ext, variable_name)) { | 11532 if (JSReceiver::HasProperty(ext, variable_name)) { |
| 11554 // We don't expect this to do anything except replacing | 11533 // We don't expect this to do anything except replacing |
| 11555 // property value. | 11534 // property value. |
| 11556 SetProperty(isolate, | 11535 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value, |
| 11557 ext, | 11536 NONE, |
| 11558 variable_name, | 11537 kNonStrictMode); |
| 11559 new_value, | |
| 11560 NONE, | |
| 11561 kNonStrictMode); | |
| 11562 return true; | 11538 return true; |
| 11563 } | 11539 } |
| 11564 } | 11540 } |
| 11565 } | 11541 } |
| 11566 } | 11542 } |
| 11567 | 11543 |
| 11568 return default_result; | 11544 return default_result; |
| 11569 } | 11545 } |
| 11570 | 11546 |
| 11571 | 11547 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 11597 Handle<FixedArray> keys = | 11573 Handle<FixedArray> keys = |
| 11598 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); | 11574 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 11599 if (threw) return Handle<JSObject>(); | 11575 if (threw) return Handle<JSObject>(); |
| 11600 | 11576 |
| 11601 for (int i = 0; i < keys->length(); i++) { | 11577 for (int i = 0; i < keys->length(); i++) { |
| 11602 // Names of variables introduced by eval are strings. | 11578 // Names of variables introduced by eval are strings. |
| 11603 ASSERT(keys->get(i)->IsString()); | 11579 ASSERT(keys->get(i)->IsString()); |
| 11604 Handle<String> key(String::cast(keys->get(i))); | 11580 Handle<String> key(String::cast(keys->get(i))); |
| 11605 RETURN_IF_EMPTY_HANDLE_VALUE( | 11581 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 11606 isolate, | 11582 isolate, |
| 11607 SetProperty(isolate, | 11583 Runtime::SetObjectProperty(isolate, closure_scope, key, |
| 11608 closure_scope, | 11584 GetProperty(isolate, ext, key), |
| 11609 key, | 11585 NONE, |
| 11610 GetProperty(isolate, ext, key), | 11586 kNonStrictMode), |
| 11611 NONE, | |
| 11612 kNonStrictMode), | |
| 11613 Handle<JSObject>()); | 11587 Handle<JSObject>()); |
| 11614 } | 11588 } |
| 11615 } | 11589 } |
| 11616 | 11590 |
| 11617 return closure_scope; | 11591 return closure_scope; |
| 11618 } | 11592 } |
| 11619 | 11593 |
| 11620 | 11594 |
| 11621 // This method copies structure of MaterializeClosure method above. | 11595 // This method copies structure of MaterializeClosure method above. |
| 11622 static bool SetClosureVariableValue(Isolate* isolate, | 11596 static bool SetClosureVariableValue(Isolate* isolate, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 11633 isolate, scope_info, context, variable_name, new_value)) { | 11607 isolate, scope_info, context, variable_name, new_value)) { |
| 11634 return true; | 11608 return true; |
| 11635 } | 11609 } |
| 11636 | 11610 |
| 11637 // Properties from the function context extension. This will | 11611 // Properties from the function context extension. This will |
| 11638 // be variables introduced by eval. | 11612 // be variables introduced by eval. |
| 11639 if (context->has_extension()) { | 11613 if (context->has_extension()) { |
| 11640 Handle<JSObject> ext(JSObject::cast(context->extension())); | 11614 Handle<JSObject> ext(JSObject::cast(context->extension())); |
| 11641 if (JSReceiver::HasProperty(ext, variable_name)) { | 11615 if (JSReceiver::HasProperty(ext, variable_name)) { |
| 11642 // We don't expect this to do anything except replacing property value. | 11616 // We don't expect this to do anything except replacing property value. |
| 11643 SetProperty(isolate, | 11617 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value, |
| 11644 ext, | 11618 NONE, |
| 11645 variable_name, | 11619 kNonStrictMode); |
| 11646 new_value, | |
| 11647 NONE, | |
| 11648 kNonStrictMode); | |
| 11649 return true; | 11620 return true; |
| 11650 } | 11621 } |
| 11651 } | 11622 } |
| 11652 | 11623 |
| 11653 return false; | 11624 return false; |
| 11654 } | 11625 } |
| 11655 | 11626 |
| 11656 | 11627 |
| 11657 // Create a plain JSObject which materializes the scope for the specified | 11628 // Create a plain JSObject which materializes the scope for the specified |
| 11658 // catch context. | 11629 // catch context. |
| 11659 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, | 11630 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, |
| 11660 Handle<Context> context) { | 11631 Handle<Context> context) { |
| 11661 ASSERT(context->IsCatchContext()); | 11632 ASSERT(context->IsCatchContext()); |
| 11662 Handle<String> name(String::cast(context->extension())); | 11633 Handle<String> name(String::cast(context->extension())); |
| 11663 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX), | 11634 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX), |
| 11664 isolate); | 11635 isolate); |
| 11665 Handle<JSObject> catch_scope = | 11636 Handle<JSObject> catch_scope = |
| 11666 isolate->factory()->NewJSObject(isolate->object_function()); | 11637 isolate->factory()->NewJSObject(isolate->object_function()); |
| 11667 RETURN_IF_EMPTY_HANDLE_VALUE( | 11638 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 11668 isolate, | 11639 isolate, |
| 11669 SetProperty(isolate, | 11640 Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object, |
| 11670 catch_scope, | 11641 NONE, |
| 11671 name, | 11642 kNonStrictMode), |
| 11672 thrown_object, | |
| 11673 NONE, | |
| 11674 kNonStrictMode), | |
| 11675 Handle<JSObject>()); | 11643 Handle<JSObject>()); |
| 11676 return catch_scope; | 11644 return catch_scope; |
| 11677 } | 11645 } |
| 11678 | 11646 |
| 11679 | 11647 |
| 11680 static bool SetCatchVariableValue(Isolate* isolate, | 11648 static bool SetCatchVariableValue(Isolate* isolate, |
| 11681 Handle<Context> context, | 11649 Handle<Context> context, |
| 11682 Handle<String> variable_name, | 11650 Handle<String> variable_name, |
| 11683 Handle<Object> new_value) { | 11651 Handle<Object> new_value) { |
| 11684 ASSERT(context->IsCatchContext()); | 11652 ASSERT(context->IsCatchContext()); |
| (...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12682 // Skip if "arguments" is already taken. | 12650 // Skip if "arguments" is already taken. |
| 12683 if (!function->shared()->is_function() || | 12651 if (!function->shared()->is_function() || |
| 12684 JSReceiver::HasLocalProperty(target, | 12652 JSReceiver::HasLocalProperty(target, |
| 12685 isolate->factory()->arguments_string())) { | 12653 isolate->factory()->arguments_string())) { |
| 12686 return target; | 12654 return target; |
| 12687 } | 12655 } |
| 12688 | 12656 |
| 12689 // FunctionGetArguments can't throw an exception. | 12657 // FunctionGetArguments can't throw an exception. |
| 12690 Handle<JSObject> arguments = Handle<JSObject>::cast( | 12658 Handle<JSObject> arguments = Handle<JSObject>::cast( |
| 12691 Accessors::FunctionGetArguments(function)); | 12659 Accessors::FunctionGetArguments(function)); |
| 12692 SetProperty(isolate, | 12660 Runtime::SetObjectProperty(isolate, target, |
| 12693 target, | 12661 isolate->factory()->arguments_string(), |
| 12694 isolate->factory()->arguments_string(), | 12662 arguments, |
| 12695 arguments, | 12663 ::NONE, |
| 12696 ::NONE, | 12664 kNonStrictMode); |
| 12697 kNonStrictMode); | |
| 12698 return target; | 12665 return target; |
| 12699 } | 12666 } |
| 12700 | 12667 |
| 12701 | 12668 |
| 12702 // Compile and evaluate source for the given context. | 12669 // Compile and evaluate source for the given context. |
| 12703 static MaybeObject* DebugEvaluate(Isolate* isolate, | 12670 static MaybeObject* DebugEvaluate(Isolate* isolate, |
| 12704 Handle<Context> context, | 12671 Handle<Context> context, |
| 12705 Handle<Object> context_extension, | 12672 Handle<Object> context_extension, |
| 12706 Handle<Object> receiver, | 12673 Handle<Object> receiver, |
| 12707 Handle<String> source) { | 12674 Handle<String> source) { |
| (...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14838 // Handle last resort GC and make sure to allow future allocations | 14805 // Handle last resort GC and make sure to allow future allocations |
| 14839 // to grow the heap without causing GCs (if possible). | 14806 // to grow the heap without causing GCs (if possible). |
| 14840 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14807 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 14841 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14808 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 14842 "Runtime::PerformGC"); | 14809 "Runtime::PerformGC"); |
| 14843 } | 14810 } |
| 14844 } | 14811 } |
| 14845 | 14812 |
| 14846 | 14813 |
| 14847 } } // namespace v8::internal | 14814 } } // namespace v8::internal |
| OLD | NEW |