OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 Name* name, | 158 Name* name, |
159 PropertyAttributes* attributes) { | 159 PropertyAttributes* attributes) { |
160 LookupResult result(name->GetIsolate()); | 160 LookupResult result(name->GetIsolate()); |
161 Lookup(name, &result); | 161 Lookup(name, &result); |
162 MaybeObject* value = GetProperty(receiver, &result, name, attributes); | 162 MaybeObject* value = GetProperty(receiver, &result, name, attributes); |
163 ASSERT(*attributes <= ABSENT); | 163 ASSERT(*attributes <= ABSENT); |
164 return value; | 164 return value; |
165 } | 165 } |
166 | 166 |
167 | 167 |
| 168 template<typename To> |
| 169 static inline To* CheckedCast(void *from) { |
| 170 uintptr_t temp = reinterpret_cast<uintptr_t>(from); |
| 171 ASSERT(temp % sizeof(To) == 0); |
| 172 return reinterpret_cast<To*>(temp); |
| 173 } |
| 174 |
| 175 |
| 176 static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor, |
| 177 char* ptr, |
| 178 Heap* heap) { |
| 179 uint32_t bitmask = descriptor.bitmask; |
| 180 uint32_t compare_value = descriptor.compare_value; |
| 181 uint32_t value; |
| 182 switch (descriptor.size) { |
| 183 case 1: |
| 184 value = static_cast<uint32_t>(*CheckedCast<uint8_t>(ptr)); |
| 185 compare_value &= 0xff; |
| 186 bitmask &= 0xff; |
| 187 break; |
| 188 case 2: |
| 189 value = static_cast<uint32_t>(*CheckedCast<uint16_t>(ptr)); |
| 190 compare_value &= 0xffff; |
| 191 bitmask &= 0xffff; |
| 192 break; |
| 193 case 4: |
| 194 value = *CheckedCast<uint32_t>(ptr); |
| 195 break; |
| 196 default: |
| 197 UNREACHABLE(); |
| 198 return NULL; |
| 199 } |
| 200 return heap->ToBoolean((bitmask & value) == (bitmask & compare_value)); |
| 201 } |
| 202 |
| 203 |
| 204 static MaybeObject* PerformCompare(const PointerCompareDescriptor& descriptor, |
| 205 char* ptr, |
| 206 Heap* heap) { |
| 207 uintptr_t compare_value = |
| 208 reinterpret_cast<uintptr_t>(descriptor.compare_value); |
| 209 uintptr_t value = *CheckedCast<uintptr_t>(ptr); |
| 210 return heap->ToBoolean(compare_value == value); |
| 211 } |
| 212 |
| 213 |
| 214 static MaybeObject* GetPrimitiveValue( |
| 215 const PrimitiveValueDescriptor& descriptor, |
| 216 char* ptr, |
| 217 Heap* heap) { |
| 218 int32_t int32_value; |
| 219 switch (descriptor.data_type) { |
| 220 case kDescriptorInt8Type: |
| 221 int32_value = *CheckedCast<int8_t>(ptr); |
| 222 break; |
| 223 case kDescriptorUint8Type: |
| 224 int32_value = *CheckedCast<uint8_t>(ptr); |
| 225 break; |
| 226 case kDescriptorInt16Type: |
| 227 int32_value = *CheckedCast<int16_t>(ptr); |
| 228 break; |
| 229 case kDescriptorUint16Type: |
| 230 int32_value = *CheckedCast<uint16_t>(ptr); |
| 231 break; |
| 232 case kDescriptorInt32Type: |
| 233 int32_value = *CheckedCast<int32_t>(ptr); |
| 234 break; |
| 235 case kDescriptorUint32Type: { |
| 236 uint32_t value = *CheckedCast<uint32_t>(ptr); |
| 237 return heap->NumberFromUint32(value); |
| 238 } |
| 239 case kDescriptorBoolType: { |
| 240 uint8_t byte = *CheckedCast<uint8_t>(ptr); |
| 241 return heap->ToBoolean(byte & (0x1 << descriptor.bool_offset)); |
| 242 } |
| 243 case kDescriptorFloatType: { |
| 244 float value = *CheckedCast<float>(ptr); |
| 245 return heap->NumberFromDouble(value); |
| 246 } |
| 247 case kDescriptorDoubleType: { |
| 248 double value = *CheckedCast<double>(ptr); |
| 249 return heap->NumberFromDouble(value); |
| 250 } |
| 251 } |
| 252 return heap->NumberFromInt32(int32_value); |
| 253 } |
| 254 |
| 255 |
| 256 static MaybeObject* GetDeclaredAccessorProperty(Object* receiver, |
| 257 DeclaredAccessorInfo* info, |
| 258 Isolate* isolate) { |
| 259 char* current = reinterpret_cast<char*>(receiver); |
| 260 DeclaredAccessorDescriptorIterator iterator(info->descriptor()); |
| 261 while (true) { |
| 262 const DeclaredAccessorDescriptorData* data = iterator.Next(); |
| 263 switch (data->type) { |
| 264 case kDescriptorReturnObject: { |
| 265 ASSERT(iterator.Complete()); |
| 266 current = *CheckedCast<char*>(current); |
| 267 return *CheckedCast<Object*>(current); |
| 268 } |
| 269 case kDescriptorPointerDereference: |
| 270 ASSERT(!iterator.Complete()); |
| 271 current = *reinterpret_cast<char**>(current); |
| 272 break; |
| 273 case kDescriptorPointerShift: |
| 274 ASSERT(!iterator.Complete()); |
| 275 current += data->pointer_shift_descriptor.byte_offset; |
| 276 break; |
| 277 case kDescriptorObjectDereference: { |
| 278 ASSERT(!iterator.Complete()); |
| 279 Object* object = CheckedCast<Object>(current); |
| 280 int field = data->object_dereference_descriptor.internal_field; |
| 281 Object* smi = JSObject::cast(object)->GetInternalField(field); |
| 282 ASSERT(smi->IsSmi()); |
| 283 current = reinterpret_cast<char*>(smi); |
| 284 break; |
| 285 } |
| 286 case kDescriptorBitmaskCompare: |
| 287 ASSERT(iterator.Complete()); |
| 288 return PerformCompare(data->bitmask_compare_descriptor, |
| 289 current, |
| 290 isolate->heap()); |
| 291 case kDescriptorPointerCompare: |
| 292 ASSERT(iterator.Complete()); |
| 293 return PerformCompare(data->pointer_compare_descriptor, |
| 294 current, |
| 295 isolate->heap()); |
| 296 case kDescriptorPrimitiveValue: |
| 297 ASSERT(iterator.Complete()); |
| 298 return GetPrimitiveValue(data->primitive_value_descriptor, |
| 299 current, |
| 300 isolate->heap()); |
| 301 } |
| 302 } |
| 303 UNREACHABLE(); |
| 304 return NULL; |
| 305 } |
| 306 |
| 307 |
168 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, | 308 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, |
169 Object* structure, | 309 Object* structure, |
170 Name* name) { | 310 Name* name) { |
171 Isolate* isolate = name->GetIsolate(); | 311 Isolate* isolate = name->GetIsolate(); |
172 // To accommodate both the old and the new api we switch on the | 312 // To accommodate both the old and the new api we switch on the |
173 // data structure used to store the callbacks. Eventually foreign | 313 // data structure used to store the callbacks. Eventually foreign |
174 // callbacks should be phased out. | 314 // callbacks should be phased out. |
175 if (structure->IsForeign()) { | 315 if (structure->IsForeign()) { |
176 AccessorDescriptor* callback = | 316 AccessorDescriptor* callback = |
177 reinterpret_cast<AccessorDescriptor*>( | 317 reinterpret_cast<AccessorDescriptor*>( |
178 Foreign::cast(structure)->foreign_address()); | 318 Foreign::cast(structure)->foreign_address()); |
179 MaybeObject* value = (callback->getter)(receiver, callback->data); | 319 MaybeObject* value = (callback->getter)(receiver, callback->data); |
180 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 320 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
181 return value; | 321 return value; |
182 } | 322 } |
183 | 323 |
184 // api style callbacks. | 324 // api style callbacks. |
185 if (structure->IsExecutableAccessorInfo()) { | 325 if (structure->IsAccessorInfo()) { |
186 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); | 326 if (!AccessorInfo::cast(structure)->IsCompatibleReceiver(receiver)) { |
187 if (!data->IsCompatibleReceiver(receiver)) { | |
188 Handle<Object> name_handle(name, isolate); | 327 Handle<Object> name_handle(name, isolate); |
189 Handle<Object> receiver_handle(receiver, isolate); | 328 Handle<Object> receiver_handle(receiver, isolate); |
190 Handle<Object> args[2] = { name_handle, receiver_handle }; | 329 Handle<Object> args[2] = { name_handle, receiver_handle }; |
191 Handle<Object> error = | 330 Handle<Object> error = |
192 isolate->factory()->NewTypeError("incompatible_method_receiver", | 331 isolate->factory()->NewTypeError("incompatible_method_receiver", |
193 HandleVector(args, | 332 HandleVector(args, |
194 ARRAY_SIZE(args))); | 333 ARRAY_SIZE(args))); |
195 return isolate->Throw(*error); | 334 return isolate->Throw(*error); |
196 } | 335 } |
197 // TODO(rossberg): Handling symbols in the API requires changing the API, | 336 // TODO(rossberg): Handling symbols in the API requires changing the API, |
198 // so we do not support it for now. | 337 // so we do not support it for now. |
199 if (name->IsSymbol()) return isolate->heap()->undefined_value(); | 338 if (name->IsSymbol()) return isolate->heap()->undefined_value(); |
| 339 if (structure->IsDeclaredAccessorInfo()) { |
| 340 return GetDeclaredAccessorProperty(receiver, |
| 341 DeclaredAccessorInfo::cast(structure), |
| 342 isolate); |
| 343 } |
| 344 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); |
200 Object* fun_obj = data->getter(); | 345 Object* fun_obj = data->getter(); |
201 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 346 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
202 if (call_fun == NULL) return isolate->heap()->undefined_value(); | 347 if (call_fun == NULL) return isolate->heap()->undefined_value(); |
203 HandleScope scope(isolate); | 348 HandleScope scope(isolate); |
204 JSObject* self = JSObject::cast(receiver); | 349 JSObject* self = JSObject::cast(receiver); |
205 Handle<String> key(String::cast(name)); | 350 Handle<String> key(String::cast(name)); |
206 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); | 351 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); |
207 CustomArguments args(isolate, data->data(), self, this); | 352 CustomArguments args(isolate, data->data(), self, this); |
208 v8::AccessorInfo info(args.end()); | 353 v8::AccessorInfo info(args.end()); |
209 v8::Handle<v8::Value> result; | 354 v8::Handle<v8::Value> result; |
(...skipping 15 matching lines...) Expand all Loading... |
225 if (structure->IsAccessorPair()) { | 370 if (structure->IsAccessorPair()) { |
226 Object* getter = AccessorPair::cast(structure)->getter(); | 371 Object* getter = AccessorPair::cast(structure)->getter(); |
227 if (getter->IsSpecFunction()) { | 372 if (getter->IsSpecFunction()) { |
228 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 373 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
229 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); | 374 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); |
230 } | 375 } |
231 // Getter is not a function. | 376 // Getter is not a function. |
232 return isolate->heap()->undefined_value(); | 377 return isolate->heap()->undefined_value(); |
233 } | 378 } |
234 | 379 |
235 // TODO(dcarney): Handle correctly. | |
236 if (structure->IsDeclaredAccessorInfo()) { | |
237 return isolate->heap()->undefined_value(); | |
238 } | |
239 | |
240 UNREACHABLE(); | 380 UNREACHABLE(); |
241 return NULL; | 381 return NULL; |
242 } | 382 } |
243 | 383 |
244 | 384 |
245 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, | 385 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, |
246 Name* name_raw) { | 386 Name* name_raw) { |
247 Isolate* isolate = GetIsolate(); | 387 Isolate* isolate = GetIsolate(); |
248 HandleScope scope(isolate); | 388 HandleScope scope(isolate); |
249 Handle<Object> receiver(receiver_raw, isolate); | 389 Handle<Object> receiver(receiver_raw, isolate); |
(...skipping 9684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9934 Object* getter = AccessorPair::cast(structure)->getter(); | 10074 Object* getter = AccessorPair::cast(structure)->getter(); |
9935 if (getter->IsSpecFunction()) { | 10075 if (getter->IsSpecFunction()) { |
9936 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 10076 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
9937 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); | 10077 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); |
9938 } | 10078 } |
9939 // Getter is not a function. | 10079 // Getter is not a function. |
9940 return isolate->heap()->undefined_value(); | 10080 return isolate->heap()->undefined_value(); |
9941 } | 10081 } |
9942 | 10082 |
9943 if (structure->IsDeclaredAccessorInfo()) { | 10083 if (structure->IsDeclaredAccessorInfo()) { |
9944 // TODO(dcarney): Handle correctly. | 10084 return GetDeclaredAccessorProperty(receiver, |
9945 return isolate->heap()->undefined_value(); | 10085 DeclaredAccessorInfo::cast(structure), |
| 10086 isolate); |
9946 } | 10087 } |
9947 | 10088 |
9948 UNREACHABLE(); | 10089 UNREACHABLE(); |
9949 return NULL; | 10090 return NULL; |
9950 } | 10091 } |
9951 | 10092 |
9952 | 10093 |
9953 MaybeObject* JSObject::SetElementWithCallback(Object* structure, | 10094 MaybeObject* JSObject::SetElementWithCallback(Object* structure, |
9954 uint32_t index, | 10095 uint32_t index, |
9955 Object* value, | 10096 Object* value, |
(...skipping 3761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13717 } | 13858 } |
13718 | 13859 |
13719 | 13860 |
13720 void ObjectHashTable::RemoveEntry(int entry) { | 13861 void ObjectHashTable::RemoveEntry(int entry) { |
13721 set_the_hole(EntryToIndex(entry)); | 13862 set_the_hole(EntryToIndex(entry)); |
13722 set_the_hole(EntryToIndex(entry) + 1); | 13863 set_the_hole(EntryToIndex(entry) + 1); |
13723 ElementRemoved(); | 13864 ElementRemoved(); |
13724 } | 13865 } |
13725 | 13866 |
13726 | 13867 |
| 13868 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( |
| 13869 DeclaredAccessorDescriptor* descriptor) |
| 13870 : array_(descriptor->serialized_data()->GetDataStartAddress()), |
| 13871 length_(descriptor->serialized_data()->length()), |
| 13872 offset_(0) { |
| 13873 } |
| 13874 |
| 13875 |
| 13876 const DeclaredAccessorDescriptorData* |
| 13877 DeclaredAccessorDescriptorIterator::Next() { |
| 13878 ASSERT(offset_ < length_); |
| 13879 uint8_t* ptr = &array_[offset_]; |
| 13880 ASSERT(reinterpret_cast<uintptr_t>(ptr) % sizeof(uintptr_t) == 0); |
| 13881 const DeclaredAccessorDescriptorData* data = |
| 13882 reinterpret_cast<const DeclaredAccessorDescriptorData*>(ptr); |
| 13883 offset_ += sizeof(*data); |
| 13884 ASSERT(offset_ <= length_); |
| 13885 return data; |
| 13886 } |
| 13887 |
| 13888 |
| 13889 Handle<DeclaredAccessorDescriptor> DeclaredAccessorDescriptor::Create( |
| 13890 Isolate* isolate, |
| 13891 const DeclaredAccessorDescriptorData& descriptor, |
| 13892 Handle<DeclaredAccessorDescriptor> previous) { |
| 13893 int previous_length = |
| 13894 previous.is_null() ? 0 : previous->serialized_data()->length(); |
| 13895 int length = sizeof(descriptor) + previous_length; |
| 13896 Handle<ByteArray> serialized_descriptor = |
| 13897 isolate->factory()->NewByteArray(length); |
| 13898 Handle<DeclaredAccessorDescriptor> value = |
| 13899 isolate->factory()->NewDeclaredAccessorDescriptor(); |
| 13900 value->set_serialized_data(*serialized_descriptor); |
| 13901 // Copy in the data. |
| 13902 { |
| 13903 AssertNoAllocation no_allocation; |
| 13904 uint8_t* array = serialized_descriptor->GetDataStartAddress(); |
| 13905 if (previous_length != 0) { |
| 13906 uint8_t* previous_array = |
| 13907 previous->serialized_data()->GetDataStartAddress(); |
| 13908 memcpy(array, previous_array, previous_length); |
| 13909 array += previous_length; |
| 13910 } |
| 13911 ASSERT(reinterpret_cast<uintptr_t>(array) % sizeof(uintptr_t) == 0); |
| 13912 DeclaredAccessorDescriptorData* data = |
| 13913 reinterpret_cast<DeclaredAccessorDescriptorData*>(array); |
| 13914 *data = descriptor; |
| 13915 } |
| 13916 return value; |
| 13917 } |
| 13918 |
| 13919 |
13727 #ifdef ENABLE_DEBUGGER_SUPPORT | 13920 #ifdef ENABLE_DEBUGGER_SUPPORT |
13728 // Check if there is a break point at this code position. | 13921 // Check if there is a break point at this code position. |
13729 bool DebugInfo::HasBreakPoint(int code_position) { | 13922 bool DebugInfo::HasBreakPoint(int code_position) { |
13730 // Get the break point info object for this code position. | 13923 // Get the break point info object for this code position. |
13731 Object* break_point_info = GetBreakPointInfo(code_position); | 13924 Object* break_point_info = GetBreakPointInfo(code_position); |
13732 | 13925 |
13733 // If there is no break point info object or no break points in the break | 13926 // If there is no break point info object or no break points in the break |
13734 // point info object there is no break point at this code position. | 13927 // point info object there is no break point at this code position. |
13735 if (break_point_info->IsUndefined()) return false; | 13928 if (break_point_info->IsUndefined()) return false; |
13736 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 13929 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14102 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 14295 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
14103 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 14296 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
14104 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 14297 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
14105 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 14298 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
14106 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 14299 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
14107 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 14300 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
14108 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 14301 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
14109 } | 14302 } |
14110 | 14303 |
14111 } } // namespace v8::internal | 14304 } } // namespace v8::internal |
OLD | NEW |