Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/objects.cc

Issue 1484473002: Fix Reflect.construct wrt proxy, generator, and non-subclass new.target (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 12188 matching lines...) Expand 10 before | Expand all | Expand 10 after
12199 } 12199 }
12200 12200
12201 } // namespace 12201 } // namespace
12202 #endif 12202 #endif
12203 12203
12204 12204
12205 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { 12205 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
12206 if (function->has_initial_map()) return; 12206 if (function->has_initial_map()) return;
12207 Isolate* isolate = function->GetIsolate(); 12207 Isolate* isolate = function->GetIsolate();
12208 12208
12209 // The constructor should be compiled for the optimization hints to be
12210 // available.
12211 Compiler::Compile(function, CLEAR_EXCEPTION);
12212
12209 // First create a new map with the size and number of in-object properties 12213 // First create a new map with the size and number of in-object properties
12210 // suggested by the function. 12214 // suggested by the function.
12211 InstanceType instance_type; 12215 InstanceType instance_type;
12212 if (function->shared()->is_generator()) { 12216 if (function->shared()->is_generator()) {
12213 instance_type = JS_GENERATOR_OBJECT_TYPE; 12217 instance_type = JS_GENERATOR_OBJECT_TYPE;
12214 } else { 12218 } else {
12215 instance_type = JS_OBJECT_TYPE; 12219 instance_type = JS_OBJECT_TYPE;
12216 } 12220 }
12217 int instance_size; 12221 int instance_size;
12218 int in_object_properties; 12222 int in_object_properties;
(...skipping 19 matching lines...) Expand all
12238 // Finally link initial map and constructor function. 12242 // Finally link initial map and constructor function.
12239 DCHECK(prototype->IsJSReceiver()); 12243 DCHECK(prototype->IsJSReceiver());
12240 JSFunction::SetInitialMap(function, map, prototype); 12244 JSFunction::SetInitialMap(function, map, prototype);
12241 12245
12242 if (!function->shared()->is_generator()) { 12246 if (!function->shared()->is_generator()) {
12243 function->StartInobjectSlackTracking(); 12247 function->StartInobjectSlackTracking();
12244 } 12248 }
12245 } 12249 }
12246 12250
12247 12251
12248 Handle<Map> JSFunction::EnsureDerivedHasInitialMap( 12252 // static
12249 Handle<JSFunction> new_target, Handle<JSFunction> constructor) { 12253 MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
12250 DCHECK(constructor->has_initial_map()); 12254 Handle<JSFunction> constructor,
12251 Isolate* isolate = constructor->GetIsolate(); 12255 Handle<JSReceiver> new_target) {
12256 EnsureHasInitialMap(constructor);
12257
12252 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate); 12258 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
12253 if (*new_target == *constructor) return constructor_initial_map; 12259 if (*new_target == *constructor) return constructor_initial_map;
12254 if (new_target->has_initial_map()) { 12260
12255 // Check that |new_target|'s initial map still in sync with 12261 if (new_target->IsJSProxy()) {
12256 // the |constructor|, otherwise we must create a new initial map for 12262 Handle<JSProxy> new_target_proxy = Handle<JSProxy>::cast(new_target);
12257 // |new_target|. 12263 Handle<Object> prototype;
12258 if (new_target->initial_map()->GetConstructor() == *constructor) { 12264 Handle<String> prototype_string = isolate->factory()->prototype_string();
12259 return handle(new_target->initial_map(), isolate); 12265 ASSIGN_RETURN_ON_EXCEPTION(
12266 isolate, prototype,
12267 JSReceiver::GetProperty(new_target_proxy, prototype_string), Map);
12268 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
12269
12270 if (!prototype->IsJSReceiver()) {
12271 Handle<Context> context;
12272 ASSIGN_RETURN_ON_EXCEPTION(
12273 isolate, context, JSProxy::GetFunctionRealm(new_target_proxy), Map);
12274 DCHECK(context->IsNativeContext());
12275 // TODO(verwaest): Use the intrinsicDefaultProto instead.
12276 prototype = handle(context->initial_object_prototype(), isolate);
12260 } 12277 }
12278
12279 if (map->prototype() != *prototype) {
12280 Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
12281 }
12282
12283 map->SetConstructor(*constructor);
12284 return map;
12261 } 12285 }
12262 12286
12263 // First create a new map with the size and number of in-object properties 12287 Handle<JSFunction> new_target_function = Handle<JSFunction>::cast(new_target);
12264 // suggested by the function.
12265 DCHECK(!new_target->shared()->is_generator());
12266 DCHECK(!constructor->shared()->is_generator());
12267 12288
12268 // Fetch or allocate prototype. 12289 // Check that |new_target_function|'s initial map still in sync with
12269 // TODO(verwaest): In case of non-instance prototype, use the 12290 // the |constructor|, otherwise we must create a new initial map for
12270 // intrinsicDefaultProto instead. 12291 // |new_target_function|.
12271 Handle<Object> prototype; 12292 if (new_target_function->has_initial_map() &&
12272 if (new_target->has_instance_prototype()) { 12293 new_target_function->initial_map()->GetConstructor() == *constructor) {
12273 prototype = handle(new_target->instance_prototype(), isolate); 12294 return handle(new_target_function->initial_map(), isolate);
12274 } else {
12275 prototype = isolate->factory()->NewFunctionPrototype(new_target);
12276 } 12295 }
12277 12296
12278 // Finally link initial map and constructor function if the original 12297 // Create a new map with the size and number of in-object properties suggested
12279 // constructor is actually a subclass constructor. 12298 // by the function.
12280 if (IsSubclassConstructor(new_target->shared()->kind())) { 12299
12300 // Link initial map and constructor function if the original constructor is
12301 // actually a subclass constructor.
12302 if (IsSubclassConstructor(new_target_function->shared()->kind())) {
12303 Handle<Object> prototype(new_target_function->instance_prototype(),
12304 isolate);
12281 InstanceType instance_type = constructor_initial_map->instance_type(); 12305 InstanceType instance_type = constructor_initial_map->instance_type();
12282 DCHECK(CanSubclassHaveInobjectProperties(instance_type)); 12306 DCHECK(CanSubclassHaveInobjectProperties(instance_type));
12283 int internal_fields = 12307 int internal_fields =
12284 JSObject::GetInternalFieldCount(*constructor_initial_map); 12308 JSObject::GetInternalFieldCount(*constructor_initial_map);
12285 int pre_allocated = constructor_initial_map->GetInObjectProperties() - 12309 int pre_allocated = constructor_initial_map->GetInObjectProperties() -
12286 constructor_initial_map->unused_property_fields(); 12310 constructor_initial_map->unused_property_fields();
12287 int instance_size; 12311 int instance_size;
12288 int in_object_properties; 12312 int in_object_properties;
12289 new_target->CalculateInstanceSizeForDerivedClass( 12313 new_target_function->CalculateInstanceSizeForDerivedClass(
12290 instance_type, internal_fields, &instance_size, &in_object_properties); 12314 instance_type, internal_fields, &instance_size, &in_object_properties);
12291 12315
12292 int unused_property_fields = in_object_properties - pre_allocated; 12316 int unused_property_fields = in_object_properties - pre_allocated;
12293 Handle<Map> map = 12317 Handle<Map> map =
12294 Map::CopyInitialMap(constructor_initial_map, instance_size, 12318 Map::CopyInitialMap(constructor_initial_map, instance_size,
12295 in_object_properties, unused_property_fields); 12319 in_object_properties, unused_property_fields);
12296 12320
12297 JSFunction::SetInitialMap(new_target, map, prototype); 12321 JSFunction::SetInitialMap(new_target_function, map, prototype);
12298 map->SetConstructor(*constructor); 12322 map->SetConstructor(*constructor);
12299 new_target->StartInobjectSlackTracking(); 12323 new_target_function->StartInobjectSlackTracking();
12300 return map;
12301
12302 } else {
12303 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
12304 DCHECK(prototype->IsJSReceiver());
12305 if (map->prototype() != *prototype) {
12306 Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
12307 }
12308 map->SetConstructor(*constructor);
12309 return map; 12324 return map;
12310 } 12325 }
12326
12327 // Fetch the prototype.
12328 Handle<Object> prototype;
12329 if (new_target_function->map()->has_non_instance_prototype()) {
12330 // TODO(verwaest): In case of non-instance prototype, use the
12331 // intrinsicDefaultProto instead.
12332 prototype = handle(new_target_function->context()
12333 ->native_context()
12334 ->initial_object_prototype());
12335 } else {
12336 // Make sure the prototype is cached on new_target_function.
12337 EnsureHasInitialMap(new_target_function);
12338 prototype = handle(new_target_function->instance_prototype(), isolate);
12339 }
12340
12341 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map);
12342 DCHECK(prototype->IsJSReceiver());
12343 if (map->prototype() != *prototype) {
12344 Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
12345 }
12346 map->SetConstructor(*constructor);
12347 return map;
12311 } 12348 }
12312 12349
12313 12350
12314 void JSFunction::PrintName(FILE* out) { 12351 void JSFunction::PrintName(FILE* out) {
12315 base::SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); 12352 base::SmartArrayPointer<char> name = shared()->DebugName()->ToCString();
12316 PrintF(out, "%s", name.get()); 12353 PrintF(out, "%s", name.get());
12317 } 12354 }
12318 12355
12319 12356
12320 // The filter is a pattern that matches function names in this way: 12357 // The filter is a pattern that matches function names in this way:
(...skipping 6326 matching lines...) Expand 10 before | Expand all | Expand 10 after
18647 if (cell->value() != *new_value) { 18684 if (cell->value() != *new_value) {
18648 cell->set_value(*new_value); 18685 cell->set_value(*new_value);
18649 Isolate* isolate = cell->GetIsolate(); 18686 Isolate* isolate = cell->GetIsolate();
18650 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18687 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18651 isolate, DependentCode::kPropertyCellChangedGroup); 18688 isolate, DependentCode::kPropertyCellChangedGroup);
18652 } 18689 }
18653 } 18690 }
18654 18691
18655 } // namespace internal 18692 } // namespace internal
18656 } // namespace v8 18693 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698