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 |