Chromium Code Reviews| 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 "factory.h" | 5 #include "factory.h" |
| 6 | 6 |
| 7 #include "macro-assembler.h" | 7 #include "macro-assembler.h" |
| 8 #include "isolate-inl.h" | 8 #include "isolate-inl.h" |
| 9 #include "v8conversions.h" | 9 #include "v8conversions.h" |
| 10 | 10 |
| (...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1232 isolate()->js_builtins_object(), | 1232 isolate()->js_builtins_object(), |
| 1233 ARRAY_SIZE(argv), | 1233 ARRAY_SIZE(argv), |
| 1234 argv, | 1234 argv, |
| 1235 &exception).ToHandle(&result)) { | 1235 &exception).ToHandle(&result)) { |
| 1236 return exception; | 1236 return exception; |
| 1237 } | 1237 } |
| 1238 return result; | 1238 return result; |
| 1239 } | 1239 } |
| 1240 | 1240 |
| 1241 | 1241 |
| 1242 Handle<JSFunction> Factory::NewFunction(Handle<String> name, | 1242 Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype, |
| 1243 Handle<String> name, | |
| 1243 InstanceType type, | 1244 InstanceType type, |
| 1244 int instance_size, | 1245 int instance_size, |
| 1245 Handle<Code> code, | 1246 Handle<Code> code, |
| 1246 bool force_initial_map) { | 1247 bool force_initial_map) { |
| 1247 // Allocate the function | 1248 // Allocate the function |
| 1248 Handle<JSFunction> function = NewFunction(name, code, the_hole_value()); | 1249 Handle<JSFunction> function = NewFunction(name, code, maybe_prototype); |
| 1249 | 1250 |
| 1250 if (force_initial_map || | 1251 Handle<Object> prototype; |
| 1251 type != JS_OBJECT_TYPE || | 1252 if (maybe_prototype.ToHandle(&prototype) && |
| 1252 instance_size != JSObject::kHeaderSize) { | 1253 (force_initial_map || |
| 1254 type != JS_OBJECT_TYPE || | |
| 1255 instance_size != JSObject::kHeaderSize)) { | |
| 1253 Handle<Map> initial_map = NewMap(type, instance_size); | 1256 Handle<Map> initial_map = NewMap(type, instance_size); |
| 1254 Handle<JSObject> prototype = NewFunctionPrototype(function); | 1257 if (prototype->IsJSObject()) { |
| 1258 JSObject::SetLocalPropertyIgnoreAttributes( | |
| 1259 Handle<JSObject>::cast(prototype), | |
| 1260 constructor_string(), | |
| 1261 function, | |
| 1262 DONT_ENUM).Assert(); | |
| 1263 } else if (!function->shared()->is_generator()) { | |
| 1264 prototype = NewFunctionPrototype(function); | |
| 1265 } | |
| 1255 initial_map->set_prototype(*prototype); | 1266 initial_map->set_prototype(*prototype); |
| 1256 function->set_initial_map(*initial_map); | 1267 function->set_initial_map(*initial_map); |
| 1257 initial_map->set_constructor(*function); | 1268 initial_map->set_constructor(*function); |
| 1258 } else { | 1269 } else { |
| 1259 ASSERT(!function->has_initial_map()); | 1270 ASSERT(!function->has_initial_map()); |
| 1260 ASSERT(!function->has_prototype()); | 1271 ASSERT(!function->has_prototype()); |
| 1261 } | 1272 } |
| 1262 | 1273 |
| 1263 return function; | 1274 return function; |
| 1264 } | 1275 } |
| 1265 | 1276 |
| 1266 | 1277 |
| 1278 Handle<JSFunction> Factory::NewFunction(Handle<String> name, | |
| 1279 InstanceType type, | |
| 1280 int instance_size, | |
| 1281 Handle<Code> code, | |
| 1282 bool force_initial_map) { | |
| 1283 return NewFunction( | |
| 1284 the_hole_value(), name, type, instance_size, code, force_initial_map); | |
| 1285 } | |
| 1286 | |
| 1287 | |
| 1267 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name, | 1288 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name, |
| 1268 InstanceType type, | 1289 InstanceType type, |
| 1269 int instance_size, | 1290 int instance_size, |
| 1270 Handle<JSObject> prototype, | 1291 Handle<JSObject> prototype, |
| 1271 Handle<Code> code, | 1292 Handle<Code> code, |
| 1272 bool force_initial_map) { | 1293 bool force_initial_map) { |
| 1273 // Allocate the function. | 1294 // Allocate the function. |
| 1274 Handle<JSFunction> function = NewFunction(name, code, prototype); | 1295 Handle<JSFunction> function = NewFunction(name, code, prototype); |
| 1275 | 1296 |
| 1276 if (force_initial_map || | 1297 if (force_initial_map || |
| (...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2034 | 2055 |
| 2035 Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee, | 2056 Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee, |
| 2036 int length) { | 2057 int length) { |
| 2037 CALL_HEAP_FUNCTION( | 2058 CALL_HEAP_FUNCTION( |
| 2038 isolate(), | 2059 isolate(), |
| 2039 isolate()->heap()->AllocateArgumentsObject(*callee, length), JSObject); | 2060 isolate()->heap()->AllocateArgumentsObject(*callee, length), JSObject); |
| 2040 } | 2061 } |
| 2041 | 2062 |
| 2042 | 2063 |
| 2043 Handle<JSFunction> Factory::CreateApiFunction( | 2064 Handle<JSFunction> Factory::CreateApiFunction( |
| 2044 Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) { | 2065 Handle<FunctionTemplateInfo> obj, |
| 2066 Handle<Object> prototype, | |
| 2067 ApiInstanceType instance_type) { | |
| 2045 Handle<Code> code = isolate()->builtins()->HandleApiCall(); | 2068 Handle<Code> code = isolate()->builtins()->HandleApiCall(); |
| 2046 Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi(); | 2069 Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi(); |
| 2047 | 2070 |
| 2048 int internal_field_count = 0; | 2071 int internal_field_count = 0; |
| 2049 if (!obj->instance_template()->IsUndefined()) { | 2072 if (!obj->instance_template()->IsUndefined()) { |
| 2050 Handle<ObjectTemplateInfo> instance_template = | 2073 Handle<ObjectTemplateInfo> instance_template = |
| 2051 Handle<ObjectTemplateInfo>( | 2074 Handle<ObjectTemplateInfo>( |
| 2052 ObjectTemplateInfo::cast(obj->instance_template())); | 2075 ObjectTemplateInfo::cast(obj->instance_template())); |
| 2053 internal_field_count = | 2076 internal_field_count = |
| 2054 Smi::cast(instance_template->internal_field_count())->value(); | 2077 Smi::cast(instance_template->internal_field_count())->value(); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2070 case OuterGlobalObject: | 2093 case OuterGlobalObject: |
| 2071 type = JS_GLOBAL_PROXY_TYPE; | 2094 type = JS_GLOBAL_PROXY_TYPE; |
| 2072 instance_size += JSGlobalProxy::kSize; | 2095 instance_size += JSGlobalProxy::kSize; |
| 2073 break; | 2096 break; |
| 2074 default: | 2097 default: |
| 2075 UNREACHABLE(); | 2098 UNREACHABLE(); |
| 2076 type = JS_OBJECT_TYPE; // Keep the compiler happy. | 2099 type = JS_OBJECT_TYPE; // Keep the compiler happy. |
| 2077 break; | 2100 break; |
| 2078 } | 2101 } |
| 2079 | 2102 |
| 2103 MaybeHandle<Object> maybe_prototype = prototype; | |
| 2104 if (obj->remove_prototype()) maybe_prototype = MaybeHandle<Object>(); | |
| 2105 | |
| 2080 Handle<JSFunction> result = NewFunction( | 2106 Handle<JSFunction> result = NewFunction( |
| 2081 Factory::empty_string(), type, instance_size, code, true); | 2107 maybe_prototype, Factory::empty_string(), type, |
| 2108 instance_size, code, true); | |
| 2082 | 2109 |
| 2083 // Set length. | |
| 2084 result->shared()->set_length(obj->length()); | 2110 result->shared()->set_length(obj->length()); |
| 2085 | 2111 Handle<Object> class_name(obj->class_name(), isolate()); |
| 2086 // Set class name. | |
| 2087 Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate()); | |
| 2088 if (class_name->IsString()) { | 2112 if (class_name->IsString()) { |
| 2089 result->shared()->set_instance_class_name(*class_name); | 2113 result->shared()->set_instance_class_name(*class_name); |
| 2090 result->shared()->set_name(*class_name); | 2114 result->shared()->set_name(*class_name); |
| 2091 } | 2115 } |
| 2116 result->shared()->set_function_data(*obj); | |
| 2117 result->shared()->set_construct_stub(*construct_stub); | |
| 2118 result->shared()->DontAdaptArguments(); | |
| 2092 | 2119 |
| 2093 Handle<Map> map = Handle<Map>(result->initial_map()); | 2120 if (obj->remove_prototype()) return result; |
|
Igor Sheludko
2014/04/28 15:00:38
Does it make sense to put ASSERT(result->shared()-
Toon Verwaest
2014/04/29 09:41:13
Done.
| |
| 2121 // Down from here is only valid for API functions that can be used as a | |
| 2122 // constructor (don't set the "remove prototype" flag). | |
| 2123 | |
| 2124 Handle<Map> map(result->initial_map()); | |
| 2094 | 2125 |
| 2095 // Mark as undetectable if needed. | 2126 // Mark as undetectable if needed. |
| 2096 if (obj->undetectable()) { | 2127 if (obj->undetectable()) { |
| 2097 map->set_is_undetectable(); | 2128 map->set_is_undetectable(); |
| 2098 } | 2129 } |
| 2099 | 2130 |
| 2100 // Mark as hidden for the __proto__ accessor if needed. | 2131 // Mark as hidden for the __proto__ accessor if needed. |
| 2101 if (obj->hidden_prototype()) { | 2132 if (obj->hidden_prototype()) { |
| 2102 map->set_is_hidden_prototype(); | 2133 map->set_is_hidden_prototype(); |
| 2103 } | 2134 } |
| 2104 | 2135 |
| 2105 // Mark as needs_access_check if needed. | 2136 // Mark as needs_access_check if needed. |
| 2106 if (obj->needs_access_check()) { | 2137 if (obj->needs_access_check()) { |
| 2107 map->set_is_access_check_needed(true); | 2138 map->set_is_access_check_needed(true); |
| 2108 } | 2139 } |
| 2109 | 2140 |
| 2110 // Set interceptor information in the map. | 2141 // Set interceptor information in the map. |
| 2111 if (!obj->named_property_handler()->IsUndefined()) { | 2142 if (!obj->named_property_handler()->IsUndefined()) { |
| 2112 map->set_has_named_interceptor(); | 2143 map->set_has_named_interceptor(); |
| 2113 } | 2144 } |
| 2114 if (!obj->indexed_property_handler()->IsUndefined()) { | 2145 if (!obj->indexed_property_handler()->IsUndefined()) { |
| 2115 map->set_has_indexed_interceptor(); | 2146 map->set_has_indexed_interceptor(); |
| 2116 } | 2147 } |
| 2117 | 2148 |
| 2118 // Set instance call-as-function information in the map. | 2149 // Set instance call-as-function information in the map. |
| 2119 if (!obj->instance_call_handler()->IsUndefined()) { | 2150 if (!obj->instance_call_handler()->IsUndefined()) { |
| 2120 map->set_has_instance_call_handler(); | 2151 map->set_has_instance_call_handler(); |
| 2121 } | 2152 } |
| 2122 | 2153 |
| 2123 result->shared()->set_function_data(*obj); | |
| 2124 result->shared()->set_construct_stub(*construct_stub); | |
| 2125 result->shared()->DontAdaptArguments(); | |
| 2126 | |
| 2127 // Recursively copy parent instance templates' accessors, | 2154 // Recursively copy parent instance templates' accessors, |
| 2128 // 'data' may be modified. | 2155 // 'data' may be modified. |
| 2129 int max_number_of_additional_properties = 0; | 2156 int max_number_of_additional_properties = 0; |
| 2130 int max_number_of_static_properties = 0; | 2157 int max_number_of_static_properties = 0; |
| 2131 FunctionTemplateInfo* info = *obj; | 2158 FunctionTemplateInfo* info = *obj; |
| 2132 while (true) { | 2159 while (true) { |
| 2133 if (!info->instance_template()->IsUndefined()) { | 2160 if (!info->instance_template()->IsUndefined()) { |
| 2134 Object* props = | 2161 Object* props = |
| 2135 ObjectTemplateInfo::cast( | 2162 ObjectTemplateInfo::cast( |
| 2136 info->instance_template())->property_accessors(); | 2163 info->instance_template())->property_accessors(); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2294 return Handle<Object>::null(); | 2321 return Handle<Object>::null(); |
| 2295 } | 2322 } |
| 2296 | 2323 |
| 2297 | 2324 |
| 2298 Handle<Object> Factory::ToBoolean(bool value) { | 2325 Handle<Object> Factory::ToBoolean(bool value) { |
| 2299 return value ? true_value() : false_value(); | 2326 return value ? true_value() : false_value(); |
| 2300 } | 2327 } |
| 2301 | 2328 |
| 2302 | 2329 |
| 2303 } } // namespace v8::internal | 2330 } } // namespace v8::internal |
| OLD | NEW |