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

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: addressed nits Created 7 years, 9 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
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698