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 |