From 80b092de04121c247fbf42ef459a0da85e8dcfe5 Mon Sep 17 00:00:00 2001 From: Alexander Markov Date: Thu, 12 Sep 2024 14:52:58 +0000 Subject: [PATCH] [dart2bytecode] Throw exception instead of crashing when external member is called TEST=ci Change-Id: I60a598dd5f8ac05a4f5f3283d257c2c6a74490e1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384820 Reviewed-by: Slava Egorov Commit-Queue: Alexander Markov --- pkg/dart2bytecode/lib/bytecode_generator.dart | 27 ++++++++++++++----- tests/language/language.status | 2 -- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/pkg/dart2bytecode/lib/bytecode_generator.dart b/pkg/dart2bytecode/lib/bytecode_generator.dart index 468f8a3b690..66eca8de6f2 100644 --- a/pkg/dart2bytecode/lib/bytecode_generator.dart +++ b/pkg/dart2bytecode/lib/bytecode_generator.dart @@ -808,7 +808,7 @@ class BytecodeGenerator extends RecursiveVisitor { _genConstructorInitializers(node); } if (node.isExternal) { - _unimplemented(node, 'external member'); + _genNoSuchMethodForExternal(node); } else { _generateNode(node.function?.body); // BytecodeAssembler eliminates this bytecode if it is unreachable. @@ -939,6 +939,9 @@ class BytecodeGenerator extends RecursiveVisitor { late Procedure throwNewAssertionError = libraryIndex.getProcedure('dart:core', '_AssertionError', '_throwNew'); + late Procedure throwNewNoSuchMethodError = + libraryIndex.getProcedure('dart:core', 'NoSuchMethodError', '_throwNew'); + late Procedure allocateInvocationMirror = libraryIndex.getProcedure( 'dart:core', '_InvocationMirror', '_allocateInvocationMirror'); @@ -2726,6 +2729,22 @@ class BytecodeGenerator extends RecursiveVisitor { _genDirectCall(target, objectTable.getArgDescHandle(2), 2); } + void _genNoSuchMethodForExternal(Member node) { + if (node.isInstanceMember) { + _genPushReceiver(); // receiver. + } else { + asm.emitPushNull(); + } + asm.emitPushConstant(cp.addString(node.name.text)); // memberName. + asm.emitPushInt(0); // invocationType. + asm.emitPushInt(0); // typeArgumentsLength. + asm.emitPushNull(); // typeArguments. + asm.emitPushNull(); // arguments. + asm.emitPushNull(); // argumentNames. + _genDirectCall( + throwNewNoSuchMethodError, objectTable.getArgDescHandle(7), 7); + } + @override void defaultTreeNode(Node node) => throw new UnsupportedOperationError( 'Unsupported node ${node.runtimeType}'); @@ -4433,12 +4452,6 @@ class BytecodeGenerator extends RecursiveVisitor { throw 'Unexpected ${enclosingFunction!.dartAsyncMarker}'; } } - - void _unimplemented(TreeNode node, String what) { - print('Unimplemented $what at ${node.location}'); - asm.emitTrap(); - asm.isUnreachable = false; - } } class UnsupportedOperationError { diff --git a/tests/language/language.status b/tests/language/language.status index c4008bd7eb3..e07152f3239 100644 --- a/tests/language/language.status +++ b/tests/language/language.status @@ -33,8 +33,6 @@ switch/case_warn_test: Skip # Analyzer only, see language_analyzer2.status [ $compiler == dart2bytecode ] class_modifiers/trans_legacy/legacy_superdeclaration_test: Crash const/inference_test: Crash -constructor/external_constructor_test: Crash -external_abstract_fields/external_fields_test: Crash final/syntax_test/08: Crash regress/regress45763_test: Crash vm/reflect_core_vm_test: Crash