Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Unified Diff: runtime/vm/dart_api_impl_test.cc

Issue 1850653003: Provide ability to patch external functions in a class that has already been finalized. The follow… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code-review Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/dart_api_impl_test.cc
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 2bda3205765245de180e0814cb5f0ba69d1a73b3..6cbf9f304bcb0e9fffca1b619ae1ee4a76c99630 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
#include "bin/builtin.h"
+#include "vm/compiler.h"
#include "include/dart_api.h"
#include "include/dart_mirrors_api.h"
#include "include/dart_native_api.h"
@@ -9853,6 +9854,164 @@ TEST_CASE(Timeline_Dart_EmbedderTimelineStartStopRecording) {
EXPECT(stop_called);
}
+
+TEST_CASE(Dart_LoadLibraryPatch_1) {
+ const char* kScriptChars1 =
+ "class A {\n"
+ " int foo() { return 10; }\n"
+ " external int zoo();\n"
+ " external static int moo();\n"
+ "}\n"
+ "main() { new A().foo(); }\n"
+ "foozoo() { new A().zoo(); }\n"
+ "foomoo() { A.moo(); }\n";
+
+ const char* kScriptChars2 =
+ "patch class A {\n"
+ " /* patch */ int zoo() { return 1; }\n"
+ " /* patch */ static int moo() { return 1; }\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+ Dart_Handle result = Dart_Invoke(lib,
+ NewString("main"),
+ 0,
+ NULL);
+ EXPECT_VALID(result);
+ Dart_Handle url = NewString("test-lib-patch");
+ Dart_Handle source = NewString(kScriptChars2);
+ result = Dart_LibraryLoadPatch(lib, url, source);
+ EXPECT_VALID(result);
+ result = Dart_FinalizeLoading(false);
+ EXPECT_VALID(result);
+ result = Dart_Invoke(lib,
+ NewString("foozoo"),
+ 0,
+ NULL);
+ EXPECT_VALID(result);
+ result = Dart_Invoke(lib,
+ NewString("foomoo"),
+ 0,
+ NULL);
+ EXPECT_VALID(result);
+}
+
+
+TEST_CASE(Dart_LoadLibraryPatch_Error1) {
+ const char* kScriptChars1 =
+ "class A {\n"
+ " int foo() { return 10; }\n"
+ " external int zoo();\n"
+ "}\n"
+ "main() { new A().foo(); }\n"
+ "foozoo() { new A().zoo(); }\n";
+
+ const char* kScriptChars2 =
+ "patch class A {\n"
+ " /* patch */ int zoo() { return 1; }\n"
+ " /* patch */ int fld1;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+ Dart_Handle result = Dart_Invoke(lib,
+ NewString("main"),
+ 0,
+ NULL);
+ EXPECT_VALID(result);
+ Dart_Handle url = NewString("test-lib-patch");
+ Dart_Handle source = NewString(kScriptChars2);
+ // We don't expect to be able to patch in this case as new fields
+ // are being added.
+ result = Dart_LibraryLoadPatch(lib, url, source);
+ EXPECT_VALID(result);
+ result = Dart_FinalizeLoading(false);
+ EXPECT_VALID(result);
+ result = Dart_Invoke(lib,
+ NewString("foozoo"),
+ 0,
+ NULL);
+ EXPECT(Dart_IsError(result));
+}
+
+
+TEST_CASE(Dart_LoadLibraryPatch_Error2) {
+ const char* kScriptChars1 =
+ "class A {\n"
+ " int foo() { return 10; }\n"
+ " int zoo() { return 20; }\n"
+ "}\n"
+ "main() { new A().foo(); }\n"
+ "foozoo() { new A().zoo(); }\n";
+
+ const char* kScriptChars2 =
+ "patch class A {\n"
+ " /* patch */ int zoo() { return 1; }\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+ Dart_Handle result = Dart_Invoke(lib,
+ NewString("main"),
+ 0,
+ NULL);
+ EXPECT_VALID(result);
+ Dart_Handle url = NewString("test-lib-patch");
+ Dart_Handle source = NewString(kScriptChars2);
+ // We don't expect to be able to patch in this case as a non external
+ // method is being patched.
+ result = Dart_LibraryLoadPatch(lib, url, source);
+ EXPECT_VALID(result);
+ result = Dart_FinalizeLoading(false);
+ EXPECT_VALID(result);
+ result = Dart_Invoke(lib,
+ NewString("foozoo"),
+ 0,
+ NULL);
+ EXPECT(Dart_IsError(result));
+ OS::Print("Patched class executed\n");
+}
+
+
+TEST_CASE(Dart_LoadLibraryPatch_Error3) {
+ const char* kScriptChars1 =
+ "class A {\n"
+ " int foo() { return 10; }\n"
+ " external int zoo();\n"
+ "}\n"
+ "main() { new A().foo(); }\n"
+ "foozoo() { new A().zoo(); }\n";
+
+ const char* kScriptChars2 =
+ "patch class A {\n"
+ " /* patch */ int zoo() { return 1; }\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
+ Dart_Handle result = Dart_Invoke(lib,
+ NewString("main"),
+ 0,
+ NULL);
+ // We invoke the foozoo method to ensure that code for 'zoo' is generated
+ // which throws NoSuchMethod.
+ result = Dart_Invoke(lib,
+ NewString("foozoo"),
+ 0,
+ NULL);
+ EXPECT(Dart_IsError(result));
+ Dart_Handle url = NewString("test-lib-patch");
+ Dart_Handle source = NewString(kScriptChars2);
+ // We don't expect to be able to patch in this case as the function being
+ // patched has already executed.
+ result = Dart_LibraryLoadPatch(lib, url, source);
+ EXPECT_VALID(result);
+ result = Dart_FinalizeLoading(false);
+ EXPECT_VALID(result);
+ result = Dart_Invoke(lib,
+ NewString("foozoo"),
+ 0,
+ NULL);
+ EXPECT(Dart_IsError(result));
+}
+
#endif // !PRODUCT
} // namespace dart
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698