Index: runtime/lib/object.cc |
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc |
index c6490c76f71de81de2bdccae094491046d1ddaa1..53140e1d973d4c3e0fe9e44d6ae4d8e5aa7cc406 100644 |
--- a/runtime/lib/object.cc |
+++ b/runtime/lib/object.cc |
@@ -169,6 +169,37 @@ DEFINE_NATIVE_ENTRY(Object_haveSameRuntimeType, 2) { |
} |
+DEFINE_NATIVE_ENTRY(Object_prependTypeArguments, 3) { |
+ const TypeArguments& function_type_arguments = |
+ TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)); |
+ const TypeArguments& parent_type_arguments = |
+ TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(1)); |
+ if (function_type_arguments.IsNull() && parent_type_arguments.IsNull()) { |
+ return TypeArguments::null(); |
+ } |
+ GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_len, arguments->NativeArgAt(2)); |
+ const intptr_t len = smi_len.Value(); |
+ const TypeArguments& result = |
+ TypeArguments::Handle(zone, TypeArguments::New(len, Heap::kOld)); |
+ AbstractType& type = AbstractType::Handle(zone); |
+ const intptr_t split = parent_type_arguments.IsNull() |
+ ? len - function_type_arguments.Length() |
+ : parent_type_arguments.Length(); |
+ for (intptr_t i = 0; i < split; i++) { |
+ type = parent_type_arguments.IsNull() ? Type::DynamicType() |
+ : parent_type_arguments.TypeAt(i); |
+ result.SetTypeAt(i, type); |
+ } |
+ for (intptr_t i = split; i < len; i++) { |
+ type = function_type_arguments.IsNull() |
+ ? Type::DynamicType() |
+ : function_type_arguments.TypeAt(i - split); |
+ result.SetTypeAt(i, type); |
+ } |
+ return result.Canonicalize(); |
+} |
+ |
+ |
DEFINE_NATIVE_ENTRY(Object_instanceOf, 4) { |
const Instance& instance = |
Instance::CheckedHandle(zone, arguments->NativeArgAt(0)); |