Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: src/objects.cc

Issue 12297012: Runtime version of declarative native accessors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: round 2 Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« include/v8.h ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698