[dart2wasm] Throw NoSuchMethodError in unimplemented external members

New passing tests:

- co19/Language/Functions/External_Functions/not_connected_to_a_body_t01
- co19/LanguageFeatures/Abstract-external-fields/static_analysis_external_A01_t03
- co19/LanguageFeatures/Abstract-external-fields/static_analysis_external_A02_t04
- co19/LanguageFeatures/Abstract-external-fields/static_analysis_external_A03_t03
- co19/LanguageFeatures/Abstract-external-fields/static_analysis_external_A03_t06
- co19/LanguageFeatures/Abstract-external-fields/static_analysis_external_A05_t03
- language/bool/has_environment_not_new_test
- language/constructor/external_constructor_test
- language/external_abstract_fields/external_fields_test
- lib/math/random_secure_unsupported_test

Change-Id: I74a430af37d3f138387a942ef028639224c312d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/284622
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart
index 5fafd7a..7df780a 100644
--- a/pkg/dart2wasm/lib/code_generator.dart
+++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -179,10 +179,19 @@
     }
 
     if (member.isExternal) {
-      final text =
-          "Unimplemented external member $member at ${member.location}";
-      print(text);
-      b.comment(text);
+      b.comment("Unimplemented external member $member at ${member.location}");
+      if (member.isInstanceMember) {
+        b.local_get(paramLocals[0]);
+      } else {
+        b.ref_null(w.HeapType.none);
+      }
+      translator.constants.instantiateConstant(
+          function,
+          b,
+          SymbolConstant(member.name.text, null),
+          translator.classInfo[translator.symbolClass]!.nonNullableType);
+      b.call(translator.functions.getFunction(translator
+          .noSuchMethodErrorThrowUnimplementedExternalMemberError.reference));
       b.unreachable();
       b.end();
       return;
diff --git a/pkg/dart2wasm/lib/kernel_nodes.dart b/pkg/dart2wasm/lib/kernel_nodes.dart
index e31db2a..59caf8e 100644
--- a/pkg/dart2wasm/lib/kernel_nodes.dart
+++ b/pkg/dart2wasm/lib/kernel_nodes.dart
@@ -184,6 +184,9 @@
       index.getProcedure("dart:core", "Invocation", "genericMethod");
   late final Procedure noSuchMethodErrorThrowWithInvocation = index
       .getProcedure("dart:core", "NoSuchMethodError", "_throwWithInvocation");
+  late final Procedure noSuchMethodErrorThrowUnimplementedExternalMemberError =
+      index.getProcedure("dart:core", "NoSuchMethodError",
+          "_throwUnimplementedExternalMemberError");
   late final Procedure stackTraceCurrent =
       index.getProcedure("dart:core", "StackTrace", "get:current");
   late final Procedure throwNullCheckError =
diff --git a/sdk/lib/_internal/wasm/lib/errors_patch.dart b/sdk/lib/_internal/wasm/lib/errors_patch.dart
index 004cc98..ba30d82 100644
--- a/sdk/lib/_internal/wasm/lib/errors_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/errors_patch.dart
@@ -127,6 +127,12 @@
     throw NoSuchMethodError.withInvocation(receiver, invocation);
   }
 
+  @pragma("wasm:entry-point")
+  static Never _throwUnimplementedExternalMemberError(
+      Object? receiver, Symbol memberName) {
+    throw NoSuchMethodError(receiver, memberName, null, null);
+  }
+
   @patch
   String toString() {
     StringBuffer sb = StringBuffer('');