| 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 |