OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/api-natives.h" | 5 #include "src/api-natives.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
9 #include "src/lookup.h" | 9 #include "src/lookup.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 Handle<TemplateInfoT> data, | 177 Handle<TemplateInfoT> data, |
178 bool is_hidden_prototype) { | 178 bool is_hidden_prototype) { |
179 HandleScope scope(isolate); | 179 HandleScope scope(isolate); |
180 // Disable access checks while instantiating the object. | 180 // Disable access checks while instantiating the object. |
181 AccessCheckDisableScope access_check_scope(isolate, obj); | 181 AccessCheckDisableScope access_check_scope(isolate, obj); |
182 | 182 |
183 // Walk the inheritance chain and copy all accessors to current object. | 183 // Walk the inheritance chain and copy all accessors to current object. |
184 int max_number_of_properties = 0; | 184 int max_number_of_properties = 0; |
185 TemplateInfoT* info = *data; | 185 TemplateInfoT* info = *data; |
186 while (info != nullptr) { | 186 while (info != nullptr) { |
187 if (!info->property_accessors()->IsUndefined(isolate)) { | 187 Object* props = info->property_accessors(); |
188 Object* props = info->property_accessors(); | 188 if (!props->IsUndefined(isolate)) { |
189 if (!props->IsUndefined(isolate)) { | 189 max_number_of_properties += TemplateList::cast(props)->length(); |
190 Handle<Object> props_handle(props, isolate); | |
191 NeanderArray props_array(props_handle); | |
192 max_number_of_properties += props_array.length(); | |
193 } | |
194 } | 190 } |
195 info = info->GetParent(isolate); | 191 info = info->GetParent(isolate); |
196 } | 192 } |
197 | 193 |
198 if (max_number_of_properties > 0) { | 194 if (max_number_of_properties > 0) { |
199 int valid_descriptors = 0; | 195 int valid_descriptors = 0; |
200 // Use a temporary FixedArray to accumulate unique accessors. | 196 // Use a temporary FixedArray to accumulate unique accessors. |
201 Handle<FixedArray> array = | 197 Handle<FixedArray> array = |
202 isolate->factory()->NewFixedArray(max_number_of_properties); | 198 isolate->factory()->NewFixedArray(max_number_of_properties); |
203 | 199 |
204 info = *data; | 200 info = *data; |
205 while (info != nullptr) { | 201 while (info != nullptr) { |
206 // Accumulate accessors. | 202 // Accumulate accessors. |
207 if (!info->property_accessors()->IsUndefined(isolate)) { | 203 Object* maybe_properties = info->property_accessors(); |
208 Handle<Object> props(info->property_accessors(), isolate); | 204 if (!maybe_properties->IsUndefined(isolate)) { |
209 valid_descriptors = | 205 valid_descriptors = AccessorInfo::AppendUnique( |
210 AccessorInfo::AppendUnique(props, array, valid_descriptors); | 206 handle(maybe_properties, isolate), array, valid_descriptors); |
211 } | 207 } |
212 info = info->GetParent(isolate); | 208 info = info->GetParent(isolate); |
213 } | 209 } |
214 | 210 |
215 // Install accumulated accessors. | 211 // Install accumulated accessors. |
216 for (int i = 0; i < valid_descriptors; i++) { | 212 for (int i = 0; i < valid_descriptors; i++) { |
217 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); | 213 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); |
218 JSObject::SetAccessor(obj, accessor).Assert(); | 214 JSObject::SetAccessor(obj, accessor).Assert(); |
219 } | 215 } |
220 } | 216 } |
221 | 217 |
222 auto property_list = handle(data->property_list(), isolate); | 218 Object* maybe_property_list = data->property_list(); |
223 if (property_list->IsUndefined(isolate)) return obj; | 219 if (maybe_property_list->IsUndefined(isolate)) return obj; |
224 // TODO(dcarney): just use a FixedArray here. | 220 Handle<TemplateList> properties(TemplateList::cast(maybe_property_list), |
225 NeanderArray properties(property_list); | 221 isolate); |
226 if (properties.length() == 0) return obj; | 222 if (properties->length() == 0) return obj; |
227 | 223 |
228 int i = 0; | 224 int i = 0; |
229 for (int c = 0; c < data->number_of_properties(); c++) { | 225 for (int c = 0; c < data->number_of_properties(); c++) { |
230 auto name = handle(Name::cast(properties.get(i++)), isolate); | 226 auto name = handle(Name::cast(properties->get(i++)), isolate); |
231 Object* bit = properties.get(i++); | 227 Object* bit = properties->get(i++); |
232 if (bit->IsSmi()) { | 228 if (bit->IsSmi()) { |
233 PropertyDetails details(Smi::cast(bit)); | 229 PropertyDetails details(Smi::cast(bit)); |
234 PropertyAttributes attributes = details.attributes(); | 230 PropertyAttributes attributes = details.attributes(); |
235 PropertyKind kind = details.kind(); | 231 PropertyKind kind = details.kind(); |
236 | 232 |
237 if (kind == kData) { | 233 if (kind == kData) { |
238 auto prop_data = handle(properties.get(i++), isolate); | 234 auto prop_data = handle(properties->get(i++), isolate); |
239 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, | 235 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, |
240 prop_data, attributes), | 236 prop_data, attributes), |
241 JSObject); | 237 JSObject); |
242 } else { | 238 } else { |
243 auto getter = handle(properties.get(i++), isolate); | 239 auto getter = handle(properties->get(i++), isolate); |
244 auto setter = handle(properties.get(i++), isolate); | 240 auto setter = handle(properties->get(i++), isolate); |
245 RETURN_ON_EXCEPTION( | 241 RETURN_ON_EXCEPTION( |
246 isolate, DefineAccessorProperty(isolate, obj, name, getter, setter, | 242 isolate, DefineAccessorProperty(isolate, obj, name, getter, setter, |
247 attributes, is_hidden_prototype), | 243 attributes, is_hidden_prototype), |
248 JSObject); | 244 JSObject); |
249 } | 245 } |
250 } else { | 246 } else { |
251 // Intrinsic data property --- Get appropriate value from the current | 247 // Intrinsic data property --- Get appropriate value from the current |
252 // context. | 248 // context. |
253 PropertyDetails details(Smi::cast(properties.get(i++))); | 249 PropertyDetails details(Smi::cast(properties->get(i++))); |
254 PropertyAttributes attributes = details.attributes(); | 250 PropertyAttributes attributes = details.attributes(); |
255 DCHECK_EQ(kData, details.kind()); | 251 DCHECK_EQ(kData, details.kind()); |
256 | 252 |
257 v8::Intrinsic intrinsic = | 253 v8::Intrinsic intrinsic = |
258 static_cast<v8::Intrinsic>(Smi::cast(properties.get(i++))->value()); | 254 static_cast<v8::Intrinsic>(Smi::cast(properties->get(i++))->value()); |
259 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); | 255 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); |
260 | 256 |
261 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, | 257 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, |
262 prop_data, attributes), | 258 prop_data, attributes), |
263 JSObject); | 259 JSObject); |
264 } | 260 } |
265 } | 261 } |
266 return obj; | 262 return obj; |
267 } | 263 } |
268 | 264 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 UncacheTemplateInstantiation(isolate, serial_number); | 462 UncacheTemplateInstantiation(isolate, serial_number); |
467 } | 463 } |
468 return MaybeHandle<JSFunction>(); | 464 return MaybeHandle<JSFunction>(); |
469 } | 465 } |
470 return function; | 466 return function; |
471 } | 467 } |
472 | 468 |
473 | 469 |
474 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, | 470 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, |
475 int length, Handle<Object>* data) { | 471 int length, Handle<Object>* data) { |
476 auto list = handle(templ->property_list(), isolate); | 472 Object* maybe_list = templ->property_list(); |
477 if (list->IsUndefined(isolate)) { | 473 Handle<TemplateList> list; |
478 list = NeanderArray(isolate).value(); | 474 if (maybe_list->IsUndefined(isolate)) { |
479 templ->set_property_list(*list); | 475 list = TemplateList::New(isolate, length); |
| 476 } else { |
| 477 list = handle(TemplateList::cast(maybe_list), isolate); |
480 } | 478 } |
481 templ->set_number_of_properties(templ->number_of_properties() + 1); | 479 templ->set_number_of_properties(templ->number_of_properties() + 1); |
482 NeanderArray array(list); | |
483 for (int i = 0; i < length; i++) { | 480 for (int i = 0; i < length; i++) { |
484 Handle<Object> value = | 481 Handle<Object> value = |
485 data[i].is_null() | 482 data[i].is_null() |
486 ? Handle<Object>::cast(isolate->factory()->undefined_value()) | 483 ? Handle<Object>::cast(isolate->factory()->undefined_value()) |
487 : data[i]; | 484 : data[i]; |
488 array.add(isolate, value); | 485 list = TemplateList::Add(isolate, list, value); |
489 } | 486 } |
| 487 templ->set_property_list(*list); |
490 } | 488 } |
491 | 489 |
492 } // namespace | 490 } // namespace |
493 | 491 |
494 | 492 |
495 MaybeHandle<JSFunction> ApiNatives::InstantiateFunction( | 493 MaybeHandle<JSFunction> ApiNatives::InstantiateFunction( |
496 Handle<FunctionTemplateInfo> data) { | 494 Handle<FunctionTemplateInfo> data) { |
497 Isolate* isolate = data->GetIsolate(); | 495 Isolate* isolate = data->GetIsolate(); |
498 InvokeScope invoke_scope(isolate); | 496 InvokeScope invoke_scope(isolate); |
499 return ::v8::internal::InstantiateFunction(isolate, data); | 497 return ::v8::internal::InstantiateFunction(isolate, data); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 PropertyDetails details(attributes, ACCESSOR, 0, PropertyCellType::kNoCell); | 568 PropertyDetails details(attributes, ACCESSOR, 0, PropertyCellType::kNoCell); |
571 auto details_handle = handle(details.AsSmi(), isolate); | 569 auto details_handle = handle(details.AsSmi(), isolate); |
572 Handle<Object> data[kSize] = {name, details_handle, getter, setter}; | 570 Handle<Object> data[kSize] = {name, details_handle, getter, setter}; |
573 AddPropertyToPropertyList(isolate, info, kSize, data); | 571 AddPropertyToPropertyList(isolate, info, kSize, data); |
574 } | 572 } |
575 | 573 |
576 | 574 |
577 void ApiNatives::AddNativeDataProperty(Isolate* isolate, | 575 void ApiNatives::AddNativeDataProperty(Isolate* isolate, |
578 Handle<TemplateInfo> info, | 576 Handle<TemplateInfo> info, |
579 Handle<AccessorInfo> property) { | 577 Handle<AccessorInfo> property) { |
580 auto list = handle(info->property_accessors(), isolate); | 578 Object* maybe_list = info->property_accessors(); |
581 if (list->IsUndefined(isolate)) { | 579 Handle<TemplateList> list; |
582 list = NeanderArray(isolate).value(); | 580 if (maybe_list->IsUndefined(isolate)) { |
583 info->set_property_accessors(*list); | 581 list = TemplateList::New(isolate, 1); |
| 582 } else { |
| 583 list = handle(TemplateList::cast(maybe_list), isolate); |
584 } | 584 } |
585 NeanderArray array(list); | 585 list = TemplateList::Add(isolate, list, property); |
586 array.add(isolate, property); | 586 info->set_property_accessors(*list); |
587 } | 587 } |
588 | 588 |
589 | 589 |
590 Handle<JSFunction> ApiNatives::CreateApiFunction( | 590 Handle<JSFunction> ApiNatives::CreateApiFunction( |
591 Isolate* isolate, Handle<FunctionTemplateInfo> obj, | 591 Isolate* isolate, Handle<FunctionTemplateInfo> obj, |
592 Handle<Object> prototype, ApiInstanceType instance_type) { | 592 Handle<Object> prototype, ApiInstanceType instance_type) { |
593 Handle<SharedFunctionInfo> shared = | 593 Handle<SharedFunctionInfo> shared = |
594 FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj); | 594 FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate, obj); |
595 Handle<JSFunction> result = | 595 Handle<JSFunction> result = |
596 isolate->factory()->NewFunctionFromSharedFunctionInfo( | 596 isolate->factory()->NewFunctionFromSharedFunctionInfo( |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 if (!obj->instance_call_handler()->IsUndefined(isolate)) { | 683 if (!obj->instance_call_handler()->IsUndefined(isolate)) { |
684 map->set_is_callable(); | 684 map->set_is_callable(); |
685 map->set_is_constructor(true); | 685 map->set_is_constructor(true); |
686 } | 686 } |
687 | 687 |
688 return result; | 688 return result; |
689 } | 689 } |
690 | 690 |
691 } // namespace internal | 691 } // namespace internal |
692 } // namespace v8 | 692 } // namespace v8 |
OLD | NEW |