[VM runtime] Implement support for _extractTypeArguments in the VM (fixes #31805).

Update status files.

This cl includes implementing these two features on all platforms:
1) Support calling generic functions via DartEntry::InvokeFunction().
2) Support native generic functions. These are currently allowed, but type
   arguments are ignored, and therefore not accessible from the C++ side.

Change-Id: Id39e8ca46c2ba1ba3d46946c16712a8572ff64ea
Reviewed-on: https://dart-review.googlesource.com/34023
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Régis Crelier
2018-01-12 21:32:20 +00:00
committed by commit-bot@chromium.org
parent d539c78af1
commit 0c2793b3db
19 changed files with 254 additions and 53 deletions
+2 -7
View File
@@ -25,13 +25,8 @@ List<T> makeFixedListUnmodifiable<T>(List<T> fixedLengthList)
native "Internal_makeFixedListUnmodifiable";
@patch
Object extractTypeArguments<T>(T instance, Function extract) {
// TODO(31371): Implement this correctly for Dart 2.0.
// In Dart 1.0, instantiating the generic with dynamic (which this does),
// gives you an object that can be used anywhere a more specific type is
// expected, so this works for now.
return extract();
}
Object extractTypeArguments<T>(T instance, Function extract)
native "Internal_extractTypeArguments";
class VMLibraryHooks {
// Example: "dart:isolate _Timer._factory"
+138
View File
@@ -311,6 +311,144 @@ DEFINE_NATIVE_ENTRY(Internal_inquireIs64Bit, 0) {
#endif // defined(ARCH_IS_64_BIT)
}
static bool ExtractInterfaceTypeArgs(Zone* zone,
const Class& instance_cls,
const TypeArguments& instance_type_args,
const Class& interface_cls,
TypeArguments* interface_type_args) {
Class& cur_cls = Class::Handle(zone, instance_cls.raw());
// The following code is a specialization of Class::TypeTestNonRecursive().
Array& interfaces = Array::Handle(zone);
AbstractType& interface = AbstractType::Handle(zone);
Class& cur_interface_cls = Class::Handle(zone);
TypeArguments& cur_interface_type_args = TypeArguments::Handle(zone);
Error& error = Error::Handle(zone);
while (true) {
// Additional subtyping rules related to 'FutureOr' are not applied.
if (cur_cls.raw() == interface_cls.raw()) {
*interface_type_args = instance_type_args.raw();
return true;
}
interfaces = cur_cls.interfaces();
for (intptr_t i = 0; i < interfaces.Length(); i++) {
interface ^= interfaces.At(i);
ASSERT(interface.IsFinalized() && !interface.IsMalbounded());
cur_interface_cls = interface.type_class();
cur_interface_type_args = interface.arguments();
if (!cur_interface_type_args.IsNull() &&
!cur_interface_type_args.IsInstantiated()) {
error = Error::null();
cur_interface_type_args = cur_interface_type_args.InstantiateFrom(
instance_type_args, Object::null_type_arguments(), kNoneFree,
&error, NULL, NULL, Heap::kNew);
if (!error.IsNull()) {
continue; // Another interface may work better.
}
}
if (ExtractInterfaceTypeArgs(zone, cur_interface_cls,
cur_interface_type_args, interface_cls,
interface_type_args)) {
return true;
}
}
cur_cls = cur_cls.SuperClass();
if (cur_cls.IsNull()) {
return false;
}
}
}
DEFINE_NATIVE_ENTRY(Internal_extractTypeArguments, 2) {
const Instance& instance =
Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
const Instance& extract =
Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
Class& interface_cls = Class::Handle(zone);
intptr_t num_type_args = 0; // Remains 0 when executing Dart 1.0 code.
// TODO(regis): Check for strong mode too?
if (Isolate::Current()->reify_generic_functions()) {
const TypeArguments& function_type_args =
TypeArguments::Handle(zone, arguments->NativeTypeArgs());
if (function_type_args.Length() == 1) {
const AbstractType& function_type_arg =
AbstractType::Handle(zone, function_type_args.TypeAt(0));
if (function_type_arg.IsType() &&
(function_type_arg.arguments() == TypeArguments::null())) {
interface_cls = function_type_arg.type_class();
num_type_args = interface_cls.NumTypeParameters();
}
}
if (num_type_args == 0) {
Exceptions::ThrowArgumentError(String::Handle(
zone,
String::New(
"single function type argument must specify a generic class")));
}
}
if (instance.IsNull()) {
Exceptions::ThrowArgumentError(instance);
}
// Function 'extract' must be generic and accept the same number of type args,
// unless we execute Dart 1.0 code.
if (extract.IsNull() || !extract.IsClosure() ||
((num_type_args > 0) && // Dart 1.0 if num_type_args == 0.
(Function::Handle(zone, Closure::Cast(extract).function())
.NumTypeParameters() != num_type_args))) {
Exceptions::ThrowArgumentError(String::Handle(
zone,
String::New("argument 'extract' is not a generic function or not one "
"accepting the correct number of type arguments")));
}
TypeArguments& extracted_type_args = TypeArguments::Handle(zone);
if (num_type_args > 0) {
// The passed instance must implement interface_cls.
TypeArguments& interface_type_args = TypeArguments::Handle(zone);
interface_type_args = TypeArguments::New(num_type_args);
Class& instance_cls = Class::Handle(zone, instance.clazz());
TypeArguments& instance_type_args = TypeArguments::Handle(zone);
if (instance_cls.NumTypeArguments() > 0) {
instance_type_args = instance.GetTypeArguments();
}
if (!ExtractInterfaceTypeArgs(zone, instance_cls, instance_type_args,
interface_cls, &interface_type_args)) {
Exceptions::ThrowArgumentError(String::Handle(
zone, String::New("type of argument 'instance' is not a subtype of "
"the function type argument")));
}
if (!interface_type_args.IsNull()) {
extracted_type_args = TypeArguments::New(num_type_args);
const intptr_t offset = interface_cls.NumTypeArguments() - num_type_args;
AbstractType& type_arg = AbstractType::Handle(zone);
for (intptr_t i = 0; i < num_type_args; i++) {
type_arg = interface_type_args.TypeAt(offset + i);
extracted_type_args.SetTypeAt(i, type_arg);
}
extracted_type_args = extracted_type_args.Canonicalize(); // Can be null.
}
}
// Call the closure 'extract'.
Array& args_desc = Array::Handle(zone);
Array& args = Array::Handle(zone);
if (extracted_type_args.IsNull()) {
args_desc = ArgumentsDescriptor::New(0, 1);
args = Array::New(1);
args.SetAt(0, extract);
} else {
args_desc = ArgumentsDescriptor::New(num_type_args, 1);
args = Array::New(2);
args.SetAt(0, extracted_type_args);
args.SetAt(1, extract);
}
const Object& result =
Object::Handle(zone, DartEntry::InvokeClosure(args, args_desc));
if (result.IsError()) {
Exceptions::PropagateError(Error::Cast(result));
UNREACHABLE();
}
return result.raw();
}
DEFINE_NATIVE_ENTRY(Internal_prependTypeArguments, 3) {
const TypeArguments& function_type_arguments =
TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
+1
View File
@@ -314,6 +314,7 @@ namespace dart {
V(Internal_makeListFixedLength, 1) \
V(Internal_makeFixedListUnmodifiable, 1) \
V(Internal_inquireIs64Bit, 0) \
V(Internal_extractTypeArguments, 2) \
V(Internal_prependTypeArguments, 3) \
V(InvocationMirror_decodePositionalCountEntry, 1) \
V(InvocationMirror_decodeTypeArgsLenEntry, 1) \
+5 -1
View File
@@ -880,7 +880,11 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const Register result = locs()->out(0).reg();
// All arguments are already @SP due to preceding PushArgument()s.
ASSERT(ArgumentCount() == function().NumParameters());
ASSERT(ArgumentCount() == function().NumParameters() +
(function().IsGeneric() &&
Isolate::Current()->reify_generic_functions())
? 1
: 0);
// Push the result place holder initialized to NULL.
__ PushObject(Object::null_object());
+5 -1
View File
@@ -769,7 +769,11 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const Register result = locs()->out(0).reg();
// All arguments are already @SP due to preceding PushArgument()s.
ASSERT(ArgumentCount() == function().NumParameters());
ASSERT(ArgumentCount() == function().NumParameters() +
(function().IsGeneric() &&
Isolate::Current()->reify_generic_functions())
? 1
: 0);
// Push the result place holder initialized to NULL.
__ PushObject(Object::null_object());
+5 -1
View File
@@ -818,7 +818,11 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
// All arguments are already @ESP due to preceding PushArgument()s.
ASSERT(ArgumentCount() == function().NumParameters());
ASSERT(ArgumentCount() == function().NumParameters() +
(function().IsGeneric() &&
Isolate::Current()->reify_generic_functions())
? 1
: 0);
// Push the result place holder initialized to NULL.
__ PushObject(Object::null_object());
+5 -1
View File
@@ -784,7 +784,11 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
// All arguments are already @RSP due to preceding PushArgument()s.
ASSERT(ArgumentCount() == function().NumParameters());
ASSERT(ArgumentCount() == function().NumParameters() +
(function().IsGeneric() &&
Isolate::Current()->reify_generic_functions())
? 1
: 0);
// Push the result place holder initialized to NULL.
__ PushObject(Object::null_object());
@@ -3318,15 +3318,24 @@ void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
const ParsedFunction& pf = owner_->parsed_function();
const String& name = String::ZoneHandle(Z, function.native_name());
ZoneGrowableArray<PushArgumentInstr*>& args =
*new (Z) ZoneGrowableArray<PushArgumentInstr*>(function.NumParameters());
const intptr_t num_params = function.NumParameters();
ZoneGrowableArray<PushArgumentInstr*>* args = NULL;
if (function.IsGeneric() && owner()->isolate()->reify_generic_functions()) {
args = new (Z) ZoneGrowableArray<PushArgumentInstr*>(1 + num_params);
LocalVariable* type_args = pf.RawTypeArgumentsVariable();
ASSERT(type_args != NULL);
Value* value = Bind(new (Z) LoadLocalInstr(*type_args, node->token_pos()));
args->Add(PushArgument(value));
} else {
args = new (Z) ZoneGrowableArray<PushArgumentInstr*>(num_params);
}
for (intptr_t i = 0; i < function.NumParameters(); ++i) {
LocalVariable* parameter = pf.RawParameterVariable(i);
Value* value = Bind(new (Z) LoadLocalInstr(*parameter, node->token_pos()));
args.Add(PushArgument(value));
args->Add(PushArgument(value));
}
NativeCallInstr* native_call = new (Z) NativeCallInstr(
&name, &function, FLAG_link_natives_lazily, node->token_pos(), &args);
&name, &function, FLAG_link_natives_lazily, node->token_pos(), args);
ReturnDefinition(native_call);
}
+11 -1
View File
@@ -1397,7 +1397,12 @@ Fragment BaseFlowGraphBuilder::NullConstant() {
Fragment FlowGraphBuilder::NativeCall(const String* name,
const Function* function) {
InlineBailout("kernel::FlowGraphBuilder::NativeCall");
ArgumentArray arguments = GetArguments(function->NumParameters());
const intptr_t num_args =
function->NumParameters() +
((function->IsGeneric() && Isolate::Current()->reify_generic_functions())
? 1
: 0);
ArgumentArray arguments = GetArguments(num_args);
NativeCallInstr* call =
new (Z) NativeCallInstr(name, function, FLAG_link_natives_lazily,
TokenPosition::kNoSource, arguments);
@@ -2015,6 +2020,11 @@ Fragment FlowGraphBuilder::NativeFunctionBody(intptr_t first_positional_offset,
break;
default: {
String& name = String::ZoneHandle(Z, function.native_name());
if (function.IsGeneric() &&
Isolate::Current()->reify_generic_functions()) {
body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
body += PushArgument();
}
for (intptr_t i = 0; i < function.NumParameters(); ++i) {
body += LoadLocal(parsed_function_->RawParameterVariable(i));
body += PushArgument();
-5
View File
@@ -112,11 +112,6 @@ RawObject* DartEntry::InvokeFunction(const Function& function,
Zone* zone = thread->zone();
ASSERT(thread->IsMutatorThread());
ScopedIsolateStackLimits stack_limit(thread, current_sp);
if (ArgumentsDescriptor(arguments_descriptor).TypeArgsLen() > 0) {
const String& message = String::Handle(String::New(
"Unsupported invocation of Dart generic function with type arguments"));
return ApiError::New(message);
}
if (!function.HasCode()) {
const Object& result =
Object::Handle(zone, Compiler::CompileFunction(thread, function));
+37 -9
View File
@@ -77,8 +77,11 @@ void VerifyOnTransition();
// following signature:
// void function_name(NativeArguments arguments);
// Inside the function, arguments are accessed as follows:
// const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0));
// const Smi& arg1 = Smi::CheckedHandle(arguments.ArgAt(1));
// const Instance& arg0 = Instance::CheckedHandle(arguments.NativeArgAt(0));
// const Smi& arg1 = Smi::CheckedHandle(arguments.NativeArgAt(1));
// If the function is generic, type arguments are accessed as follows:
// const TypeArguments& type_args =
// TypeArguments::Handle(arguments.NativeTypeArgs());
// The return value is set as follows:
// arguments.SetReturn(result);
// NOTE: Since we pass 'this' as a pass-by-value argument in the stubs we don't
@@ -87,6 +90,8 @@ void VerifyOnTransition();
class NativeArguments {
public:
Thread* thread() const { return thread_; }
// Includes type arguments vector.
int ArgCount() const { return ArgcBits::decode(argc_tag_); }
RawObject* ArgAt(int index) const {
@@ -103,6 +108,7 @@ class NativeArguments {
return *arg_ptr;
}
// Does not include hidden type arguments vector.
int NativeArgCount() const {
int function_bits = FunctionBits::decode(argc_tag_);
return ArgCount() - NumHiddenArgs(function_bits);
@@ -110,9 +116,11 @@ class NativeArguments {
RawObject* NativeArg0() const {
int function_bits = FunctionBits::decode(argc_tag_);
if (function_bits == (kClosureFunctionBit | kInstanceFunctionBit)) {
if ((function_bits & (kClosureFunctionBit | kInstanceFunctionBit)) ==
(kClosureFunctionBit | kInstanceFunctionBit)) {
// Retrieve the receiver from the context.
const Object& closure = Object::Handle(ArgAt(0));
const int closure_index = (function_bits & kGenericFunctionBit) ? 1 : 0;
const Object& closure = Object::Handle(ArgAt(closure_index));
const Context& context =
Context::Handle(Closure::Cast(closure).context());
return context.At(0);
@@ -130,6 +138,11 @@ class NativeArguments {
return ArgAt(actual_index);
}
RawTypeArguments* NativeTypeArgs() {
ASSERT(ToGenericFunction());
return TypeArguments::RawCast(ArgAt(0));
}
void SetReturn(const Object& value) const { *retval_ = value.raw(); }
RawObject* ReturnValue() const {
@@ -166,7 +179,7 @@ class NativeArguments {
static int ComputeArgcTag(const Function& function) {
ASSERT(function.is_native());
ASSERT(!function.IsGenerativeConstructor()); // Not supported.
int tag = ArgcBits::encode(function.NumParameters());
int argc = function.NumParameters();
int function_bits = 0;
if (!function.is_static()) {
function_bits |= kInstanceFunctionBit;
@@ -174,6 +187,11 @@ class NativeArguments {
if (function.IsClosureFunction()) {
function_bits |= kClosureFunctionBit;
}
if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
function_bits |= kGenericFunctionBit;
argc++;
}
int tag = ArgcBits::encode(argc);
tag = FunctionBits::update(function_bits, tag);
return tag;
}
@@ -182,12 +200,13 @@ class NativeArguments {
enum {
kInstanceFunctionBit = 1,
kClosureFunctionBit = 2,
kGenericFunctionBit = 4,
};
enum ArgcTagBits {
kArgcBit = 0,
kArgcSize = 24,
kFunctionBit = 24,
kFunctionSize = 2,
kFunctionSize = 3,
};
class ArgcBits : public BitField<intptr_t, int32_t, kArgcBit, kArgcSize> {};
class FunctionBits
@@ -221,15 +240,24 @@ class NativeArguments {
return (FunctionBits::decode(argc_tag_) & kClosureFunctionBit);
}
// Returns true if the arguments are those of a generic function call.
bool ToGenericFunction() const {
return (FunctionBits::decode(argc_tag_) & kGenericFunctionBit);
}
int NumHiddenArgs(int function_bits) const {
int num_hidden_args = 0;
// For static closure functions, the closure at index 0 is hidden.
// In the instance closure function case, the receiver is accessed from
// the context and the closure at index 0 is hidden, so the apparent
// argument count remains unchanged.
if (function_bits == kClosureFunctionBit) {
return 1;
if ((function_bits & kClosureFunctionBit) == kClosureFunctionBit) {
num_hidden_args++;
}
return 0;
if ((function_bits & kGenericFunctionBit) == kGenericFunctionBit) {
num_hidden_args++;
}
return num_hidden_args;
}
Thread* thread_; // Current thread pointer.
-1
View File
@@ -1324,7 +1324,6 @@ RawObject* Simulator::Call(const Code& code,
// Load argument descriptor.
argdesc_ = arguments_descriptor.raw();
ASSERT(ArgumentsDescriptor(arguments_descriptor).TypeArgsLen() == 0);
// Ready to start executing bytecode. Load entry point and corresponding
// object pool.
+4 -2
View File
@@ -822,9 +822,11 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
// Load arguments descriptor array into R4, which is passed to Dart code.
__ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
// No need to check for type args, disallowed by DartEntry::InvokeFunction.
// Load number of arguments into R9.
// Load number of arguments into R9 and adjust count for type arguments.
__ ldr(R3, FieldAddress(R4, ArgumentsDescriptor::type_args_len_offset()));
__ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
__ cmp(R3, Operand(0));
__ AddImmediate(R9, R9, Smi::RawValue(1), NE); // Include the type arguments.
__ SmiUntag(R9);
// Compute address of 'arguments array' data area into R2.
+5 -2
View File
@@ -868,9 +868,12 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
// Load arguments descriptor array into R4, which is passed to Dart code.
__ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle);
// No need to check for type args, disallowed by DartEntry::InvokeFunction.
// Load number of arguments into S5.
// Load number of arguments into R5 and adjust count for type arguments.
__ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset());
__ LoadFieldFromOffset(R3, R4, ArgumentsDescriptor::type_args_len_offset());
__ AddImmediate(TMP, R5, 1); // Include the type arguments.
__ cmp(R3, Operand(0));
__ csinc(R5, R5, TMP, EQ); // R5 <- (R3 == 0) ? R5 : TMP + 1 (R5 : R5 + 2).
__ SmiUntag(R5);
// Compute address of 'arguments array' data area into R2.
+10 -6
View File
@@ -739,9 +739,16 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
__ movl(EDX, Address(EBP, kArgumentsDescOffset));
__ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle));
// No need to check for type args, disallowed by DartEntry::InvokeFunction.
// Load number of arguments into EBX.
// Load number of arguments into EBX and adjust count for type arguments.
__ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
__ cmpl(FieldAddress(EDX, ArgumentsDescriptor::type_args_len_offset()),
Immediate(0));
Label args_count_ok;
__ j(EQUAL, &args_count_ok, Assembler::kNearJump);
__ addl(EBX, Immediate(Smi::RawValue(1))); // Include the type arguments.
__ Bind(&args_count_ok);
// Save number of arguments as Smi on stack, replacing ArgumentsDesc.
__ movl(Address(EBP, kArgumentsDescOffset), EBX);
__ SmiUntag(EBX);
// Set up arguments for the dart call.
@@ -769,11 +776,8 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
__ movl(EAX, Address(EAX, VMHandles::kOffsetOfRawPtrInHandle));
__ call(FieldAddress(EAX, Code::entry_point_offset()));
// Reread the arguments descriptor array to obtain the number of passed
// arguments.
// Read the saved number of passed arguments as Smi.
__ movl(EDX, Address(EBP, kArgumentsDescOffset));
__ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle));
__ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
// Get rid of arguments pushed on the stack.
__ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi.
+13 -8
View File
@@ -756,7 +756,7 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
// | saved PC (return to DartEntry::InvokeFunction) |
const intptr_t kInitialOffset = 2;
// Save arguments descriptor array.
// Save arguments descriptor array, later replaced by Smi argument count.
const intptr_t kArgumentsDescOffset = -(kInitialOffset)*kWordSize;
__ pushq(kArgDescReg);
@@ -807,9 +807,16 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
// Push arguments. At this point we only need to preserve kTargetCodeReg.
ASSERT(kTargetCodeReg != RDX);
// No need to check for type args, disallowed by DartEntry::InvokeFunction.
// Load number of arguments into RBX.
// Load number of arguments into RBX and adjust count for type arguments.
__ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
__ cmpq(FieldAddress(R10, ArgumentsDescriptor::type_args_len_offset()),
Immediate(0));
Label args_count_ok;
__ j(EQUAL, &args_count_ok, Assembler::kNearJump);
__ addq(RBX, Immediate(Smi::RawValue(1))); // Include the type arguments.
__ Bind(&args_count_ok);
// Save number of arguments as Smi on stack, replacing saved ArgumentsDesc.
__ movq(Address(RBP, kArgumentsDescOffset), RBX);
__ SmiUntag(RBX);
// Compute address of 'arguments array' data area into RDX.
@@ -835,11 +842,9 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
__ movq(kTargetCodeReg, FieldAddress(CODE_REG, Code::entry_point_offset()));
__ call(kTargetCodeReg); // R10 is the arguments descriptor array.
// Read the saved arguments descriptor array to obtain the number of passed
// arguments.
__ movq(kArgDescReg, Address(RBP, kArgumentsDescOffset));
__ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle));
__ movq(RDX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
// Read the saved number of passed arguments as Smi.
__ movq(RDX, Address(RBP, kArgumentsDescOffset));
// Get rid of arguments pushed on the stack.
__ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi.
@@ -414,7 +414,6 @@ example_constructor_test: Fail, OK
external_test/10: MissingRuntimeError # KernelVM bug: Unbound external.
external_test/13: MissingRuntimeError # KernelVM bug: Unbound external.
external_test/20: MissingRuntimeError # KernelVM bug: Unbound external.
extract_type_arguments_test: RuntimeError # Issue 31371
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
factory2_test/03: MissingCompileTimeError
@@ -1239,7 +1238,6 @@ external_test/10: MissingRuntimeError # KernelVM bug: Unbound external.
external_test/13: MissingRuntimeError # KernelVM bug: Unbound external.
external_test/20: MissingRuntimeError # KernelVM bug: Unbound external.
external_test/24: Pass, CompileTimeError # Started to pass after switching to batch-mode.
extract_type_arguments_test: RuntimeError # Issue 31371
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
factory2_test/03: MissingCompileTimeError
@@ -282,7 +282,6 @@ export_ambiguous_main_negative_test: Fail # Issue 14763
export_ambiguous_main_negative_test: Skip # Issue 29895
export_ambiguous_main_test: Crash
export_double_same_main_test: Skip # Issue 29895
extract_type_arguments_test: RuntimeError # Issue 31371
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
factory1_test/00: MissingCompileTimeError
-1
View File
@@ -310,7 +310,6 @@ empty_block_case_test: MissingCompileTimeError
enum_private_test/02: MissingCompileTimeError
error_stacktrace_test/00: MissingCompileTimeError
export_ambiguous_main_test: MissingCompileTimeError
extract_type_arguments_test: RuntimeError # Issue 31371
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
factory1_test/00: MissingCompileTimeError