bool
MaglevGraphBuilder::TryBuildFindNonDefaultConstructorOrConstruct(
ValueNode* this_function, ValueNode* new_target,
std::pair result) {
compiler::OptionalHeapObjectRef maybe_constant = TryGetConstant(this_function);
if
(!maybe_constant)
return
false
;
compiler::MapRef function_map = maybe_constant->map(broker());
compiler::HeapObjectRef current = function_map.prototype(broker());
while
(
true
) {
if
(!current.IsJSFunction())
return
false
;
compiler::JSFunctionRef current_function = current.AsJSFunction();
if
(current_function.shared(broker()).requires_instance_members_initializer()) {
return
false
;
}
if
(current_function.context(broker()).scope_info(broker()).ClassScopeHasPrivateBrand()) {
return
false
;
}
FunctionKind kind = current_function.shared(broker()).kind();
if
(kind != FunctionKind::kDefaultDerivedConstructor) {
if
(!broker()->dependencies()->DependOnArrayIteratorProtector()) {
return
false
;
}
compiler::OptionalHeapObjectRef new_target_function = TryGetConstant(new_target);
if
(kind == FunctionKind::kDefaultBaseConstructor) {
StoreRegister(result.first, GetBooleanConstant(
true
));
ValueNode* object;
if
(new_target_function && new_target_function->IsJSFunction() &&
HasValidInitialMap(new_target_function->AsJSFunction(), current_function)) {
object = BuildAllocateFastObject(
FastObject(new_target_function->AsJSFunction(), zone(), broker()),
AllocationType::kYoung);
}
else
{
object = BuildCallBuiltin({GetConstant(current_function), new_target});
current_interpreter_frame_.get(result.first)->add_use();
object->lazy_deopt_info()->UpdateResultLocation(result.second, 1);
}
StoreRegister(result.second, object);
}
else
{
StoreRegister(result.first, GetBooleanConstant(
false
));
StoreRegister(result.second, GetConstant(current));
}
broker()->dependencies()->DependOnStablePrototypeChain(
function_map, WhereToStart::kStartAtReceiver, current_function);
return
true
;
}
current = current_function.map(broker()).prototype(broker());
}
}