Chromium Code Reviews| 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 String* name, | 156 String* name, |
| 157 PropertyAttributes* attributes) { | 157 PropertyAttributes* attributes) { |
| 158 LookupResult result(name->GetIsolate()); | 158 LookupResult result(name->GetIsolate()); |
| 159 Lookup(name, &result); | 159 Lookup(name, &result); |
| 160 MaybeObject* value = GetProperty(receiver, &result, name, attributes); | 160 MaybeObject* value = GetProperty(receiver, &result, name, attributes); |
| 161 ASSERT(*attributes <= ABSENT); | 161 ASSERT(*attributes <= ABSENT); |
| 162 return value; | 162 return value; |
| 163 } | 163 } |
| 164 | 164 |
| 165 | 165 |
| 166 template<typename To> | |
| 167 static inline To* CheckedCast(void *from) { | |
| 168 uintptr_t temp = reinterpret_cast<uintptr_t>(from); | |
| 169 ASSERT(temp % sizeof(To) == 0); | |
| 170 return reinterpret_cast<To*>(temp); | |
| 171 } | |
| 172 | |
| 173 | |
| 174 static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor, | |
| 175 char* ptr, | |
| 176 Isolate* isolate) { | |
|
Sven Panne
2013/03/07 08:18:48
Passing just the Heap, not the Isolate in its full
| |
| 177 uint32_t bitmask = descriptor.bitmask; | |
| 178 uint32_t compare_value = descriptor.compare_value; | |
| 179 uint32_t value; | |
| 180 switch (descriptor.size) { | |
| 181 case 1: | |
| 182 value = static_cast<uint32_t>(*CheckedCast<uint8_t>(ptr)); | |
| 183 compare_value &= 0xff; | |
| 184 bitmask &= 0xff; | |
| 185 break; | |
| 186 case 2: | |
| 187 value = static_cast<uint32_t>(*CheckedCast<uint16_t>(ptr)); | |
| 188 compare_value &= 0xffff; | |
| 189 bitmask &= 0xffff; | |
| 190 break; | |
| 191 case 4: | |
| 192 value = *CheckedCast<uint32_t>(ptr); | |
| 193 break; | |
| 194 default: | |
| 195 UNREACHABLE(); | |
| 196 return NULL; | |
| 197 } | |
| 198 bool result = (bitmask & value) == (bitmask & compare_value); | |
| 199 return result ? isolate->heap()->true_value() | |
|
Sven Panne
2013/03/07 08:18:48
return isolate->heap()->ToBoolean(result);
| |
| 200 : isolate->heap()->false_value(); | |
| 201 } | |
| 202 | |
| 203 | |
| 204 static MaybeObject* PerformCompare(const PointerCompareDescriptor& descriptor, | |
| 205 char* ptr, | |
| 206 Isolate* isolate) { | |
| 207 uintptr_t compare_value = | |
| 208 reinterpret_cast<uintptr_t>(descriptor.compare_value); | |
| 209 uintptr_t value = *CheckedCast<uintptr_t>(ptr); | |
| 210 bool result = compare_value == value; | |
| 211 return result ? isolate->heap()->true_value() | |
|
Sven Panne
2013/03/07 08:18:48
See above
| |
| 212 : isolate->heap()->false_value(); | |
| 213 } | |
| 214 | |
| 215 | |
| 216 static MaybeObject* GetPrimitiveValue( | |
| 217 const PrimitiveValueDescriptor& descriptor, | |
| 218 char* ptr, | |
| 219 Isolate* isolate) { | |
| 220 int32_t int32_value; | |
| 221 switch (descriptor.data_type) { | |
| 222 case kDescriptorInt8Type: | |
| 223 int32_value = *CheckedCast<int8_t>(ptr); | |
| 224 break; | |
| 225 case kDescriptorUint8Type: | |
| 226 int32_value = *CheckedCast<uint8_t>(ptr); | |
| 227 break; | |
| 228 case kDescriptorInt16Type: | |
| 229 int32_value = *CheckedCast<int16_t>(ptr); | |
| 230 break; | |
| 231 case kDescriptorUint16Type: | |
| 232 int32_value = *CheckedCast<uint16_t>(ptr); | |
| 233 break; | |
| 234 case kDescriptorInt32Type: | |
| 235 int32_value = *CheckedCast<int32_t>(ptr); | |
| 236 break; | |
| 237 case kDescriptorUint32Type: { | |
| 238 uint32_t value = *CheckedCast<uint32_t>(ptr); | |
| 239 return isolate->heap()->NumberFromUint32(value); | |
| 240 } | |
| 241 case kDescriptorBoolType: { | |
| 242 uint8_t byte = *CheckedCast<uint8_t>(ptr); | |
| 243 bool result = byte & (0x1 << descriptor.bool_offset); | |
| 244 return result ? isolate->heap()->true_value() | |
|
Sven Panne
2013/03/07 08:18:48
See above
| |
| 245 : isolate->heap()->false_value(); | |
| 246 } | |
| 247 case kDescriptorFloatType: { | |
| 248 float value = *CheckedCast<float>(ptr); | |
| 249 return isolate->heap()->NumberFromDouble(value); | |
| 250 } | |
| 251 case kDescriptorDoubleType: { | |
| 252 double value = *CheckedCast<double>(ptr); | |
| 253 return isolate->heap()->NumberFromDouble(value); | |
| 254 } | |
| 255 } | |
| 256 return isolate->heap()->NumberFromInt32(int32_value); | |
| 257 } | |
| 258 | |
| 259 | |
| 260 static MaybeObject* GetDeclaredAccessorProperty(Object* receiver, | |
| 261 DeclaredAccessorInfo* info, | |
| 262 Isolate* isolate) { | |
| 263 char* current = reinterpret_cast<char*>(receiver); | |
| 264 DeclaredAccessorDescriptorIterator iterator(info->descriptor()); | |
| 265 while (true) { | |
| 266 const DeclaredAccessorDescriptorData* data = iterator.Next(); | |
| 267 switch (data->type) { | |
| 268 case kDescriptorReturnObject: { | |
| 269 ASSERT(iterator.Complete()); | |
| 270 current = *CheckedCast<char*>(current); | |
| 271 return *CheckedCast<Object*>(current); | |
| 272 } | |
| 273 case kDescriptorPointerDereference: | |
| 274 ASSERT(!iterator.Complete()); | |
| 275 current = *reinterpret_cast<char**>(current); | |
| 276 break; | |
| 277 case kDescriptorPointerShift: | |
| 278 ASSERT(!iterator.Complete()); | |
| 279 current += data->pointer_shift_descriptor.byte_offset; | |
| 280 break; | |
| 281 case kDescriptorObjectDereference: { | |
| 282 ASSERT(!iterator.Complete()); | |
| 283 Object* object = CheckedCast<Object>(current); | |
| 284 int field = data->object_dereference_descriptor.internal_field; | |
| 285 Object* smi = JSObject::cast(object)->GetInternalField(field); | |
| 286 ASSERT(smi->IsSmi()); | |
| 287 current = reinterpret_cast<char*>(smi); | |
| 288 break; | |
| 289 } | |
| 290 case kDescriptorBitmaskCompare: | |
| 291 ASSERT(iterator.Complete()); | |
| 292 return PerformCompare(data->bitmask_compare_descriptor, | |
| 293 current, | |
| 294 isolate); | |
| 295 case kDescriptorPointerCompare: | |
| 296 ASSERT(iterator.Complete()); | |
| 297 return PerformCompare(data->pointer_compare_descriptor, | |
| 298 current, | |
| 299 isolate); | |
| 300 case kDescriptorPrimitiveValue: | |
| 301 ASSERT(iterator.Complete()); | |
| 302 return GetPrimitiveValue(data->primitive_value_descriptor, | |
| 303 current, | |
| 304 isolate); | |
| 305 } | |
| 306 } | |
| 307 UNREACHABLE(); | |
| 308 return NULL; | |
| 309 } | |
| 310 | |
| 311 | |
| 166 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, | 312 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, |
| 167 Object* structure, | 313 Object* structure, |
| 168 String* name) { | 314 String* name) { |
| 169 Isolate* isolate = name->GetIsolate(); | 315 Isolate* isolate = name->GetIsolate(); |
| 170 // To accommodate both the old and the new api we switch on the | 316 // To accommodate both the old and the new api we switch on the |
| 171 // data structure used to store the callbacks. Eventually foreign | 317 // data structure used to store the callbacks. Eventually foreign |
| 172 // callbacks should be phased out. | 318 // callbacks should be phased out. |
| 173 if (structure->IsForeign()) { | 319 if (structure->IsForeign()) { |
| 174 AccessorDescriptor* callback = | 320 AccessorDescriptor* callback = |
| 175 reinterpret_cast<AccessorDescriptor*>( | 321 reinterpret_cast<AccessorDescriptor*>( |
| 176 Foreign::cast(structure)->foreign_address()); | 322 Foreign::cast(structure)->foreign_address()); |
| 177 MaybeObject* value = (callback->getter)(receiver, callback->data); | 323 MaybeObject* value = (callback->getter)(receiver, callback->data); |
| 178 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 324 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 179 return value; | 325 return value; |
| 180 } | 326 } |
| 181 | 327 |
| 182 // api style callbacks. | 328 // api style callbacks. |
| 183 if (structure->IsExecutableAccessorInfo()) { | 329 if (structure->IsAccessorInfo()) { |
| 184 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); | 330 if (!AccessorInfo::cast(structure)->IsCompatibleReceiver(receiver)) { |
| 185 if (!data->IsCompatibleReceiver(receiver)) { | |
| 186 Handle<Object> name_handle(name); | 331 Handle<Object> name_handle(name); |
| 187 Handle<Object> receiver_handle(receiver); | 332 Handle<Object> receiver_handle(receiver); |
| 188 Handle<Object> args[2] = { name_handle, receiver_handle }; | 333 Handle<Object> args[2] = { name_handle, receiver_handle }; |
| 189 Handle<Object> error = | 334 Handle<Object> error = |
| 190 isolate->factory()->NewTypeError("incompatible_method_receiver", | 335 isolate->factory()->NewTypeError("incompatible_method_receiver", |
| 191 HandleVector(args, | 336 HandleVector(args, |
| 192 ARRAY_SIZE(args))); | 337 ARRAY_SIZE(args))); |
| 193 return isolate->Throw(*error); | 338 return isolate->Throw(*error); |
| 194 } | 339 } |
| 340 if (structure->IsDeclaredAccessorInfo()) { | |
| 341 return GetDeclaredAccessorProperty(receiver, | |
| 342 DeclaredAccessorInfo::cast(structure), | |
| 343 isolate); | |
| 344 } | |
| 345 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); | |
| 195 Object* fun_obj = data->getter(); | 346 Object* fun_obj = data->getter(); |
| 196 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 347 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
| 197 if (call_fun == NULL) return isolate->heap()->undefined_value(); | 348 if (call_fun == NULL) return isolate->heap()->undefined_value(); |
| 198 HandleScope scope(isolate); | 349 HandleScope scope(isolate); |
| 199 JSObject* self = JSObject::cast(receiver); | 350 JSObject* self = JSObject::cast(receiver); |
| 200 Handle<String> key(name); | 351 Handle<String> key(name); |
| 201 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); | 352 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); |
| 202 CustomArguments args(isolate, data->data(), self, this); | 353 CustomArguments args(isolate, data->data(), self, this); |
| 203 v8::AccessorInfo info(args.end()); | 354 v8::AccessorInfo info(args.end()); |
| 204 v8::Handle<v8::Value> result; | 355 v8::Handle<v8::Value> result; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 220 if (structure->IsAccessorPair()) { | 371 if (structure->IsAccessorPair()) { |
| 221 Object* getter = AccessorPair::cast(structure)->getter(); | 372 Object* getter = AccessorPair::cast(structure)->getter(); |
| 222 if (getter->IsSpecFunction()) { | 373 if (getter->IsSpecFunction()) { |
| 223 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 374 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 224 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); | 375 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); |
| 225 } | 376 } |
| 226 // Getter is not a function. | 377 // Getter is not a function. |
| 227 return isolate->heap()->undefined_value(); | 378 return isolate->heap()->undefined_value(); |
| 228 } | 379 } |
| 229 | 380 |
| 230 // TODO(dcarney): Handle correctly. | |
| 231 if (structure->IsDeclaredAccessorInfo()) { | |
| 232 return isolate->heap()->undefined_value(); | |
| 233 } | |
| 234 | |
| 235 UNREACHABLE(); | 381 UNREACHABLE(); |
| 236 return NULL; | 382 return NULL; |
| 237 } | 383 } |
| 238 | 384 |
| 239 | 385 |
| 240 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, | 386 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, |
| 241 String* name_raw) { | 387 String* name_raw) { |
| 242 Isolate* isolate = GetIsolate(); | 388 Isolate* isolate = GetIsolate(); |
| 243 HandleScope scope(isolate); | 389 HandleScope scope(isolate); |
| 244 Handle<Object> receiver(receiver_raw); | 390 Handle<Object> receiver(receiver_raw); |
| (...skipping 9531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9776 Object* getter = AccessorPair::cast(structure)->getter(); | 9922 Object* getter = AccessorPair::cast(structure)->getter(); |
| 9777 if (getter->IsSpecFunction()) { | 9923 if (getter->IsSpecFunction()) { |
| 9778 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 9924 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 9779 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); | 9925 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); |
| 9780 } | 9926 } |
| 9781 // Getter is not a function. | 9927 // Getter is not a function. |
| 9782 return isolate->heap()->undefined_value(); | 9928 return isolate->heap()->undefined_value(); |
| 9783 } | 9929 } |
| 9784 | 9930 |
| 9785 if (structure->IsDeclaredAccessorInfo()) { | 9931 if (structure->IsDeclaredAccessorInfo()) { |
| 9786 // TODO(dcarney): Handle correctly. | 9932 return GetDeclaredAccessorProperty(receiver, |
| 9787 return isolate->heap()->undefined_value(); | 9933 DeclaredAccessorInfo::cast(structure), |
| 9934 isolate); | |
| 9788 } | 9935 } |
| 9789 | 9936 |
| 9790 UNREACHABLE(); | 9937 UNREACHABLE(); |
| 9791 return NULL; | 9938 return NULL; |
| 9792 } | 9939 } |
| 9793 | 9940 |
| 9794 | 9941 |
| 9795 MaybeObject* JSObject::SetElementWithCallback(Object* structure, | 9942 MaybeObject* JSObject::SetElementWithCallback(Object* structure, |
| 9796 uint32_t index, | 9943 uint32_t index, |
| 9797 Object* value, | 9944 Object* value, |
| (...skipping 3742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13540 } | 13687 } |
| 13541 | 13688 |
| 13542 | 13689 |
| 13543 void ObjectHashTable::RemoveEntry(int entry) { | 13690 void ObjectHashTable::RemoveEntry(int entry) { |
| 13544 set_the_hole(EntryToIndex(entry)); | 13691 set_the_hole(EntryToIndex(entry)); |
| 13545 set_the_hole(EntryToIndex(entry) + 1); | 13692 set_the_hole(EntryToIndex(entry) + 1); |
| 13546 ElementRemoved(); | 13693 ElementRemoved(); |
| 13547 } | 13694 } |
| 13548 | 13695 |
| 13549 | 13696 |
| 13697 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( | |
| 13698 DeclaredAccessorDescriptor* descriptor) | |
| 13699 : array_(descriptor->serialized_data()->GetDataStartAddress()), | |
| 13700 length_(descriptor->serialized_data()->length()), | |
| 13701 offset_(0) { | |
| 13702 } | |
| 13703 | |
| 13704 | |
| 13705 const DeclaredAccessorDescriptorData* | |
| 13706 DeclaredAccessorDescriptorIterator::Next() { | |
| 13707 ASSERT(offset_ < length_); | |
| 13708 uint8_t* ptr = &array_[offset_]; | |
| 13709 ASSERT(reinterpret_cast<uintptr_t>(ptr) % sizeof(uintptr_t) == 0); | |
| 13710 const DeclaredAccessorDescriptorData* data = | |
| 13711 reinterpret_cast<const DeclaredAccessorDescriptorData*>(ptr); | |
| 13712 offset_ += sizeof(*data); | |
| 13713 ASSERT(offset_ <= length_); | |
| 13714 return data; | |
| 13715 } | |
| 13716 | |
| 13717 | |
| 13718 Handle<DeclaredAccessorDescriptor> DeclaredAccessorDescriptor::Create( | |
| 13719 Isolate* isolate, | |
| 13720 const DeclaredAccessorDescriptorData& descriptor, | |
| 13721 Handle<DeclaredAccessorDescriptor> previous) { | |
| 13722 int previous_length = | |
| 13723 previous.is_null() ? 0 : previous->serialized_data()->length(); | |
| 13724 int length = sizeof(descriptor) + previous_length; | |
| 13725 Handle<ByteArray> serialized_descriptor = | |
| 13726 isolate->factory()->NewByteArray(length); | |
| 13727 Handle<DeclaredAccessorDescriptor> value = | |
| 13728 isolate->factory()->NewDeclaredAccessorDescriptor(); | |
| 13729 value->set_serialized_data(*serialized_descriptor); | |
| 13730 // Copy in the data. | |
| 13731 { | |
| 13732 AssertNoAllocation no_allocation; | |
| 13733 uint8_t* array = serialized_descriptor->GetDataStartAddress(); | |
| 13734 if (previous_length != 0) { | |
| 13735 uint8_t* previous_array = | |
| 13736 previous->serialized_data()->GetDataStartAddress(); | |
| 13737 memcpy(array, previous_array, previous_length); | |
| 13738 array += previous_length; | |
| 13739 } | |
| 13740 ASSERT(reinterpret_cast<uintptr_t>(array) % sizeof(uintptr_t) == 0); | |
| 13741 DeclaredAccessorDescriptorData* data = | |
| 13742 reinterpret_cast<DeclaredAccessorDescriptorData*>(array); | |
| 13743 *data = descriptor; | |
| 13744 } | |
| 13745 return value; | |
| 13746 } | |
| 13747 | |
| 13748 | |
| 13550 #ifdef ENABLE_DEBUGGER_SUPPORT | 13749 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 13551 // Check if there is a break point at this code position. | 13750 // Check if there is a break point at this code position. |
| 13552 bool DebugInfo::HasBreakPoint(int code_position) { | 13751 bool DebugInfo::HasBreakPoint(int code_position) { |
| 13553 // Get the break point info object for this code position. | 13752 // Get the break point info object for this code position. |
| 13554 Object* break_point_info = GetBreakPointInfo(code_position); | 13753 Object* break_point_info = GetBreakPointInfo(code_position); |
| 13555 | 13754 |
| 13556 // If there is no break point info object or no break points in the break | 13755 // If there is no break point info object or no break points in the break |
| 13557 // point info object there is no break point at this code position. | 13756 // point info object there is no break point at this code position. |
| 13558 if (break_point_info->IsUndefined()) return false; | 13757 if (break_point_info->IsUndefined()) return false; |
| 13559 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 13758 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13923 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 14122 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13924 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 14123 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13925 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 14124 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13926 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 14125 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13927 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 14126 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13928 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 14127 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13929 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 14128 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13930 } | 14129 } |
| 13931 | 14130 |
| 13932 } } // namespace v8::internal | 14131 } } // namespace v8::internal |
| OLD | NEW |