| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/debug.h" | 9 #include "src/debug.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| 11 #include "src/runtime/runtime.h" | 11 #include "src/runtime/runtime.h" |
| 12 #include "src/runtime/runtime-utils.h" | 12 #include "src/runtime/runtime-utils.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 | 16 |
| 17 // Returns a single character string where first character equals | |
| 18 // string->Get(index). | |
| 19 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { | |
| 20 DCHECK_LT(index, static_cast<uint32_t>(string->length())); | |
| 21 Factory* factory = string->GetIsolate()->factory(); | |
| 22 return factory->LookupSingleCharacterStringFromCode( | |
| 23 String::Flatten(string)->Get(index)); | |
| 24 } | |
| 25 | |
| 26 | |
| 27 MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate, | |
| 28 Handle<Object> object, | |
| 29 uint32_t index, | |
| 30 LanguageMode language_mode) { | |
| 31 // Handle [] indexing on Strings | |
| 32 if (object->IsString() && | |
| 33 index < static_cast<uint32_t>(String::cast(*object)->length())) { | |
| 34 Handle<Object> result = GetCharAt(Handle<String>::cast(object), index); | |
| 35 if (!result->IsUndefined()) return result; | |
| 36 } | |
| 37 | |
| 38 return Object::GetElement(isolate, object, index, language_mode); | |
| 39 } | |
| 40 | |
| 41 | 17 |
| 42 MaybeHandle<Name> Runtime::ToName(Isolate* isolate, Handle<Object> key) { | 18 MaybeHandle<Name> Runtime::ToName(Isolate* isolate, Handle<Object> key) { |
| 43 if (key->IsName()) { | 19 if (key->IsName()) { |
| 44 return Handle<Name>::cast(key); | 20 return Handle<Name>::cast(key); |
| 45 } else { | 21 } else { |
| 46 Handle<Object> converted; | 22 Handle<Object> converted; |
| 47 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, | 23 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, |
| 48 Execution::ToString(isolate, key), Name); | 24 Execution::ToString(isolate, key), Name); |
| 49 return Handle<Name>::cast(converted); | 25 return Handle<Name>::cast(converted); |
| 50 } | 26 } |
| 51 } | 27 } |
| 52 | 28 |
| 53 | 29 |
| 54 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, | 30 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, |
| 55 Handle<Object> object, | 31 Handle<Object> object, |
| 56 Handle<Object> key, | 32 Handle<Object> key, |
| 57 LanguageMode language_mode) { | 33 LanguageMode language_mode) { |
| 58 if (object->IsUndefined() || object->IsNull()) { | 34 if (object->IsUndefined() || object->IsNull()) { |
| 59 THROW_NEW_ERROR( | 35 THROW_NEW_ERROR( |
| 60 isolate, | 36 isolate, |
| 61 NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object), | 37 NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object), |
| 62 Object); | 38 Object); |
| 63 } | 39 } |
| 64 | 40 |
| 65 // Check if the given key is an array index. | 41 // Check if the given key is an array index. |
| 66 uint32_t index = 0; | 42 uint32_t index = 0; |
| 67 if (key->ToArrayIndex(&index)) { | 43 if (key->ToArrayIndex(&index)) { |
| 68 return GetElementOrCharAt(isolate, object, index, language_mode); | 44 return Object::GetElement(isolate, object, index, language_mode); |
| 69 } | 45 } |
| 70 | 46 |
| 71 // Convert the key to a name - possibly by calling back into JavaScript. | 47 // Convert the key to a name - possibly by calling back into JavaScript. |
| 72 Handle<Name> name; | 48 Handle<Name> name; |
| 73 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object); | 49 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object); |
| 74 | 50 |
| 75 // Check if the name is trivially convertible to an index and get | 51 // Check if the name is trivially convertible to an index and get |
| 76 // the element if so. | 52 // the element if so. |
| 77 // TODO(verwaest): Make sure GetProperty(LookupIterator*) can handle this, and | 53 // TODO(verwaest): Make sure GetProperty(LookupIterator*) can handle this, and |
| 78 // remove the special casing here. | 54 // remove the special casing here. |
| 79 if (name->AsArrayIndex(&index)) { | 55 if (name->AsArrayIndex(&index)) { |
| 80 return GetElementOrCharAt(isolate, object, index); | 56 return Object::GetElement(isolate, object, index); |
| 81 } else { | 57 } else { |
| 82 return Object::GetProperty(object, name, language_mode); | 58 return Object::GetProperty(object, name, language_mode); |
| 83 } | 59 } |
| 84 } | 60 } |
| 85 | 61 |
| 86 | 62 |
| 87 MaybeHandle<Object> Runtime::KeyedGetObjectProperty( | 63 MaybeHandle<Object> Runtime::KeyedGetObjectProperty( |
| 88 Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj, | 64 Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj, |
| 89 LanguageMode language_mode) { | 65 LanguageMode language_mode) { |
| 90 // Fast cases for getting named properties of the receiver JSObject | 66 // Fast cases for getting named properties of the receiver JSObject |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 } else { | 122 } else { |
| 147 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || | 123 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || |
| 148 !IsFastElementsKind(elements_kind)); | 124 !IsFastElementsKind(elements_kind)); |
| 149 } | 125 } |
| 150 } | 126 } |
| 151 } else if (receiver_obj->IsString() && key_obj->IsSmi()) { | 127 } else if (receiver_obj->IsString() && key_obj->IsSmi()) { |
| 152 // Fast case for string indexing using [] with a smi index. | 128 // Fast case for string indexing using [] with a smi index. |
| 153 Handle<String> str = Handle<String>::cast(receiver_obj); | 129 Handle<String> str = Handle<String>::cast(receiver_obj); |
| 154 int index = Handle<Smi>::cast(key_obj)->value(); | 130 int index = Handle<Smi>::cast(key_obj)->value(); |
| 155 if (index >= 0 && index < str->length()) { | 131 if (index >= 0 && index < str->length()) { |
| 156 return GetCharAt(str, index); | 132 Factory* factory = isolate->factory(); |
| 133 return factory->LookupSingleCharacterStringFromCode( |
| 134 String::Flatten(str)->Get(index)); |
| 157 } | 135 } |
| 158 } | 136 } |
| 159 | 137 |
| 160 // Fall back to GetObjectProperty. | 138 // Fall back to GetObjectProperty. |
| 161 return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode); | 139 return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode); |
| 162 } | 140 } |
| 163 | 141 |
| 164 | 142 |
| 165 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, | 143 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, |
| 166 Handle<JSReceiver> receiver, | 144 Handle<JSReceiver> receiver, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 187 if (object->IsUndefined() || object->IsNull()) { | 165 if (object->IsUndefined() || object->IsNull()) { |
| 188 THROW_NEW_ERROR( | 166 THROW_NEW_ERROR( |
| 189 isolate, | 167 isolate, |
| 190 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object), | 168 NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object), |
| 191 Object); | 169 Object); |
| 192 } | 170 } |
| 193 | 171 |
| 194 // Check if the given key is an array index. | 172 // Check if the given key is an array index. |
| 195 uint32_t index = 0; | 173 uint32_t index = 0; |
| 196 if (key->ToArrayIndex(&index)) { | 174 if (key->ToArrayIndex(&index)) { |
| 197 // TODO(verwaest): Support other objects as well. | 175 return Object::SetElement(isolate, object, index, value, language_mode); |
| 198 if (!object->IsJSReceiver()) return value; | |
| 199 return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index, | |
| 200 value, language_mode); | |
| 201 } | 176 } |
| 202 | 177 |
| 203 Handle<Name> name; | 178 Handle<Name> name; |
| 204 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object); | 179 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object); |
| 205 | 180 |
| 206 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name); | 181 LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name); |
| 207 // TODO(verwaest): Support other objects as well. | |
| 208 if (it.IsElement() && !object->IsJSReceiver()) return value; | |
| 209 return Object::SetProperty(&it, value, language_mode, | 182 return Object::SetProperty(&it, value, language_mode, |
| 210 Object::MAY_BE_STORE_FROM_KEYED); | 183 Object::MAY_BE_STORE_FROM_KEYED); |
| 211 } | 184 } |
| 212 | 185 |
| 213 | 186 |
| 214 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate, | 187 MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate, |
| 215 Handle<Object> obj) { | 188 Handle<Object> obj) { |
| 216 // We don't expect access checks to be needed on JSProxy objects. | 189 // We don't expect access checks to be needed on JSProxy objects. |
| 217 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 190 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
| 218 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 191 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |
| (...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1430 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); | 1403 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); |
| 1431 | 1404 |
| 1432 RETURN_FAILURE_ON_EXCEPTION( | 1405 RETURN_FAILURE_ON_EXCEPTION( |
| 1433 isolate, | 1406 isolate, |
| 1434 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), | 1407 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), |
| 1435 setter, attrs)); | 1408 setter, attrs)); |
| 1436 return isolate->heap()->undefined_value(); | 1409 return isolate->heap()->undefined_value(); |
| 1437 } | 1410 } |
| 1438 } // namespace internal | 1411 } // namespace internal |
| 1439 } // namespace v8 | 1412 } // namespace v8 |
| OLD | NEW |