OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/factory.h" | 5 #include "src/factory.h" |
6 | 6 |
7 #include "src/allocation-site-scopes.h" | 7 #include "src/allocation-site-scopes.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 2218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2229 Handle<JSObject> result = NewJSObjectFromMap(map); | 2229 Handle<JSObject> result = NewJSObjectFromMap(map); |
2230 Handle<Smi> value(Smi::FromInt(length), isolate()); | 2230 Handle<Smi> value(Smi::FromInt(length), isolate()); |
2231 Object::SetProperty(result, length_string(), value, STRICT).Assert(); | 2231 Object::SetProperty(result, length_string(), value, STRICT).Assert(); |
2232 if (!strict_mode_callee) { | 2232 if (!strict_mode_callee) { |
2233 Object::SetProperty(result, callee_string(), callee, STRICT).Assert(); | 2233 Object::SetProperty(result, callee_string(), callee, STRICT).Assert(); |
2234 } | 2234 } |
2235 return result; | 2235 return result; |
2236 } | 2236 } |
2237 | 2237 |
2238 | 2238 |
2239 Handle<JSFunction> Factory::CreateApiFunction( | |
2240 Handle<FunctionTemplateInfo> obj, | |
2241 Handle<Object> prototype, | |
2242 ApiInstanceType instance_type) { | |
2243 Handle<Code> code = isolate()->builtins()->HandleApiCall(); | |
2244 Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi(); | |
2245 | |
2246 obj->set_instantiated(true); | |
2247 Handle<JSFunction> result; | |
2248 if (obj->remove_prototype()) { | |
2249 result = NewFunctionWithoutPrototype(empty_string(), code); | |
2250 } else { | |
2251 int internal_field_count = 0; | |
2252 if (!obj->instance_template()->IsUndefined()) { | |
2253 Handle<ObjectTemplateInfo> instance_template = | |
2254 Handle<ObjectTemplateInfo>( | |
2255 ObjectTemplateInfo::cast(obj->instance_template())); | |
2256 internal_field_count = | |
2257 Smi::cast(instance_template->internal_field_count())->value(); | |
2258 } | |
2259 | |
2260 // TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing | |
2261 // JSObject::GetHeaderSize. | |
2262 int instance_size = kPointerSize * internal_field_count; | |
2263 InstanceType type; | |
2264 switch (instance_type) { | |
2265 case JavaScriptObjectType: | |
2266 type = JS_OBJECT_TYPE; | |
2267 instance_size += JSObject::kHeaderSize; | |
2268 break; | |
2269 case GlobalObjectType: | |
2270 type = JS_GLOBAL_OBJECT_TYPE; | |
2271 instance_size += JSGlobalObject::kSize; | |
2272 break; | |
2273 case GlobalProxyType: | |
2274 type = JS_GLOBAL_PROXY_TYPE; | |
2275 instance_size += JSGlobalProxy::kSize; | |
2276 break; | |
2277 default: | |
2278 UNREACHABLE(); | |
2279 type = JS_OBJECT_TYPE; // Keep the compiler happy. | |
2280 break; | |
2281 } | |
2282 | |
2283 result = NewFunction(empty_string(), code, prototype, type, instance_size, | |
2284 obj->read_only_prototype(), true); | |
2285 } | |
2286 | |
2287 result->shared()->set_length(obj->length()); | |
2288 Handle<Object> class_name(obj->class_name(), isolate()); | |
2289 if (class_name->IsString()) { | |
2290 result->shared()->set_instance_class_name(*class_name); | |
2291 result->shared()->set_name(*class_name); | |
2292 } | |
2293 result->shared()->set_function_data(*obj); | |
2294 result->shared()->set_construct_stub(*construct_stub); | |
2295 result->shared()->DontAdaptArguments(); | |
2296 | |
2297 if (obj->remove_prototype()) { | |
2298 DCHECK(result->shared()->IsApiFunction()); | |
2299 DCHECK(!result->has_initial_map()); | |
2300 DCHECK(!result->has_prototype()); | |
2301 return result; | |
2302 } | |
2303 | |
2304 #ifdef DEBUG | |
2305 LookupIterator it(handle(JSObject::cast(result->prototype())), | |
2306 constructor_string(), LookupIterator::OWN_SKIP_INTERCEPTOR); | |
2307 MaybeHandle<Object> maybe_prop = Object::GetProperty(&it); | |
2308 DCHECK(it.IsFound()); | |
2309 DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result)); | |
2310 #endif | |
2311 | |
2312 // Down from here is only valid for API functions that can be used as a | |
2313 // constructor (don't set the "remove prototype" flag). | |
2314 | |
2315 Handle<Map> map(result->initial_map()); | |
2316 | |
2317 // Mark as undetectable if needed. | |
2318 if (obj->undetectable()) { | |
2319 map->set_is_undetectable(); | |
2320 } | |
2321 | |
2322 // Mark as hidden for the __proto__ accessor if needed. | |
2323 if (obj->hidden_prototype()) { | |
2324 map->set_is_hidden_prototype(); | |
2325 } | |
2326 | |
2327 // Mark as needs_access_check if needed. | |
2328 if (obj->needs_access_check()) { | |
2329 map->set_is_access_check_needed(true); | |
2330 } | |
2331 | |
2332 // Set interceptor information in the map. | |
2333 if (!obj->named_property_handler()->IsUndefined()) { | |
2334 map->set_has_named_interceptor(); | |
2335 } | |
2336 if (!obj->indexed_property_handler()->IsUndefined()) { | |
2337 map->set_has_indexed_interceptor(); | |
2338 } | |
2339 | |
2340 // Set instance call-as-function information in the map. | |
2341 if (!obj->instance_call_handler()->IsUndefined()) { | |
2342 map->set_has_instance_call_handler(); | |
2343 } | |
2344 | |
2345 // Recursively copy parent instance templates' accessors, | |
2346 // 'data' may be modified. | |
2347 int max_number_of_additional_properties = 0; | |
2348 int max_number_of_static_properties = 0; | |
2349 FunctionTemplateInfo* info = *obj; | |
2350 while (true) { | |
2351 if (!info->instance_template()->IsUndefined()) { | |
2352 Object* props = | |
2353 ObjectTemplateInfo::cast( | |
2354 info->instance_template())->property_accessors(); | |
2355 if (!props->IsUndefined()) { | |
2356 Handle<Object> props_handle(props, isolate()); | |
2357 NeanderArray props_array(props_handle); | |
2358 max_number_of_additional_properties += props_array.length(); | |
2359 } | |
2360 } | |
2361 if (!info->property_accessors()->IsUndefined()) { | |
2362 Object* props = info->property_accessors(); | |
2363 if (!props->IsUndefined()) { | |
2364 Handle<Object> props_handle(props, isolate()); | |
2365 NeanderArray props_array(props_handle); | |
2366 max_number_of_static_properties += props_array.length(); | |
2367 } | |
2368 } | |
2369 Object* parent = info->parent_template(); | |
2370 if (parent->IsUndefined()) break; | |
2371 info = FunctionTemplateInfo::cast(parent); | |
2372 } | |
2373 | |
2374 Map::EnsureDescriptorSlack(map, max_number_of_additional_properties); | |
2375 | |
2376 // Use a temporary FixedArray to acculumate static accessors | |
2377 int valid_descriptors = 0; | |
2378 Handle<FixedArray> array; | |
2379 if (max_number_of_static_properties > 0) { | |
2380 array = NewFixedArray(max_number_of_static_properties); | |
2381 } | |
2382 | |
2383 while (true) { | |
2384 // Install instance descriptors | |
2385 if (!obj->instance_template()->IsUndefined()) { | |
2386 Handle<ObjectTemplateInfo> instance = | |
2387 Handle<ObjectTemplateInfo>( | |
2388 ObjectTemplateInfo::cast(obj->instance_template()), isolate()); | |
2389 Handle<Object> props = Handle<Object>(instance->property_accessors(), | |
2390 isolate()); | |
2391 if (!props->IsUndefined()) { | |
2392 Map::AppendCallbackDescriptors(map, props); | |
2393 } | |
2394 } | |
2395 // Accumulate static accessors | |
2396 if (!obj->property_accessors()->IsUndefined()) { | |
2397 Handle<Object> props = Handle<Object>(obj->property_accessors(), | |
2398 isolate()); | |
2399 valid_descriptors = | |
2400 AccessorInfo::AppendUnique(props, array, valid_descriptors); | |
2401 } | |
2402 // Climb parent chain | |
2403 Handle<Object> parent = Handle<Object>(obj->parent_template(), isolate()); | |
2404 if (parent->IsUndefined()) break; | |
2405 obj = Handle<FunctionTemplateInfo>::cast(parent); | |
2406 } | |
2407 | |
2408 // Install accumulated static accessors | |
2409 for (int i = 0; i < valid_descriptors; i++) { | |
2410 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); | |
2411 JSObject::SetAccessor(result, accessor).Assert(); | |
2412 } | |
2413 | |
2414 DCHECK(result->shared()->IsApiFunction()); | |
2415 return result; | |
2416 } | |
2417 | |
2418 | |
2419 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context, | 2239 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context, |
2420 int number_of_properties, | 2240 int number_of_properties, |
2421 bool* is_result_from_cache) { | 2241 bool* is_result_from_cache) { |
2422 const int kMapCacheSize = 128; | 2242 const int kMapCacheSize = 128; |
2423 | 2243 |
2424 if (number_of_properties > kMapCacheSize) { | 2244 if (number_of_properties > kMapCacheSize) { |
2425 *is_result_from_cache = false; | 2245 *is_result_from_cache = false; |
2426 return Map::Create(isolate(), number_of_properties); | 2246 return Map::Create(isolate(), number_of_properties); |
2427 } | 2247 } |
2428 *is_result_from_cache = true; | 2248 *is_result_from_cache = true; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2485 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); | 2305 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); |
2486 store->set(JSRegExp::kIrregexpLatin1CodeSavedIndex, uninitialized); | 2306 store->set(JSRegExp::kIrregexpLatin1CodeSavedIndex, uninitialized); |
2487 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); | 2307 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); |
2488 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0)); | 2308 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0)); |
2489 store->set(JSRegExp::kIrregexpCaptureCountIndex, | 2309 store->set(JSRegExp::kIrregexpCaptureCountIndex, |
2490 Smi::FromInt(capture_count)); | 2310 Smi::FromInt(capture_count)); |
2491 regexp->set_data(*store); | 2311 regexp->set_data(*store); |
2492 } | 2312 } |
2493 | 2313 |
2494 | 2314 |
2495 MaybeHandle<FunctionTemplateInfo> Factory::ConfigureInstance( | |
2496 Handle<FunctionTemplateInfo> desc, Handle<JSObject> instance) { | |
2497 // Configure the instance by adding the properties specified by the | |
2498 // instance template. | |
2499 Handle<Object> instance_template(desc->instance_template(), isolate()); | |
2500 if (!instance_template->IsUndefined()) { | |
2501 RETURN_ON_EXCEPTION( | |
2502 isolate(), | |
2503 Execution::ConfigureInstance(isolate(), instance, instance_template), | |
2504 FunctionTemplateInfo); | |
2505 } | |
2506 return desc; | |
2507 } | |
2508 | |
2509 | |
2510 Handle<Object> Factory::GlobalConstantFor(Handle<String> name) { | 2315 Handle<Object> Factory::GlobalConstantFor(Handle<String> name) { |
2511 if (String::Equals(name, undefined_string())) return undefined_value(); | 2316 if (String::Equals(name, undefined_string())) return undefined_value(); |
2512 if (String::Equals(name, nan_string())) return nan_value(); | 2317 if (String::Equals(name, nan_string())) return nan_value(); |
2513 if (String::Equals(name, infinity_string())) return infinity_value(); | 2318 if (String::Equals(name, infinity_string())) return infinity_value(); |
2514 return Handle<Object>::null(); | 2319 return Handle<Object>::null(); |
2515 } | 2320 } |
2516 | 2321 |
2517 | 2322 |
2518 Handle<Object> Factory::ToBoolean(bool value) { | 2323 Handle<Object> Factory::ToBoolean(bool value) { |
2519 return value ? true_value() : false_value(); | 2324 return value ? true_value() : false_value(); |
2520 } | 2325 } |
2521 | 2326 |
2522 | 2327 |
2523 } } // namespace v8::internal | 2328 } } // namespace v8::internal |
OLD | NEW |