[vm/kernel/bytecode] Fix arguments passing in native factory constructors

VM requires to pass null type arguments to factory constructors of
non-generic classes. This includes native implementation of native
factory constructors.

Bytecode generation for bodies of native factory constructors is fixed
to push this extra argument for NativeCall.

Change-Id: I741a783c6964da88ecd0bfd1d2ec4aa3b1868708
Reviewed-on: https://dart-review.googlesource.com/60200
Reviewed-by: Zach Anderson <zra@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov 2018-06-13 22:28:04 +00:00 committed by commit-bot@chromium.org
parent c30ce41ae6
commit 33feee3b03
3 changed files with 28 additions and 0 deletions

View file

@ -152,6 +152,11 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
if (locals.hasTypeArgsVar) {
asm.emitPush(locals.typeArgsVarIndexInFrame);
} else if (enclosingMember is Procedure &&
(enclosingMember as Procedure).isFactory) {
// Null type arguments are passed to factory constructors even if class
// is not generic. TODO(alexmarkov): Clean this up.
_genPushNull();
}
if (locals.hasReceiver) {
asm.emitPush(locals.getVarIndexInFrame(locals.receiverVar));

View file

@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// ignore_for_file: native_function_body_in_non_sdk_code
class Base<T1, T2> {
T1 t1;
T2 t2;
@ -67,6 +69,10 @@ void foo5() {
new I.test_factory2(param: 42);
}
class J {
factory J() native "agent_J";
}
main() {
foo1();
foo2();

View file

@ -1,6 +1,7 @@
library #lib;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
class Base<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic> extends core::Object {
generic-covariant-impl field self::Base::T1 t1 = null;
@ -385,6 +386,22 @@ ConstantPool {
] static factory test_factory2({dynamic param = null}) → self::I
return new self::I::•(param);
}
class J extends core::Object {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
PushConstant CP#0
NativeCall CP#1
ReturnTOS
}
ConstantPool {
[0] = Null
[1] = NativeEntry agent_J
}
] @_in::ExternalName::•("agent_J")
external static factory •() → self::J;
}
[@vm.bytecode=
Bytecode {
Entry 1