[vm] refactor native entry and native entry type arguments

Change-Id: I03efbbf4340de1c8f23c60854ed991671ca2b647
Reviewed-on: https://dart-review.googlesource.com/c/87077
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Samir Jindel <sjindel@google.com>
diff --git a/runtime/lib/array.cc b/runtime/lib/array.cc
index 3322745..d143a98 100644
--- a/runtime/lib/array.cc
+++ b/runtime/lib/array.cc
@@ -10,19 +10,19 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(List_new, 2) {
+DEFINE_NATIVE_ENTRY(List_new, 0, 2) {
   // This function is handled by flow-graph builder.
   UNREACHABLE();
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(List_allocate, 2) {
+DEFINE_NATIVE_ENTRY(List_allocate, 0, 2) {
   // Implemented in FlowGraphBuilder::VisitNativeBody.
   UNREACHABLE();
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(List_getIndexed, 2) {
+DEFINE_NATIVE_ENTRY(List_getIndexed, 0, 2) {
   const Array& array = Array::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   if ((index.Value() < 0) || (index.Value() >= array.Length())) {
@@ -31,7 +31,7 @@
   return array.At(index.Value());
 }
 
-DEFINE_NATIVE_ENTRY(List_setIndexed, 3) {
+DEFINE_NATIVE_ENTRY(List_setIndexed, 0, 3) {
   const Array& array = Array::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   const Instance& value =
@@ -43,13 +43,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(List_getLength, 1) {
+DEFINE_NATIVE_ENTRY(List_getLength, 0, 1) {
   const Array& array = Array::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Smi::New(array.Length());
 }
 
 // ObjectArray src, int start, int count, bool needTypeArgument.
-DEFINE_NATIVE_ENTRY(List_slice, 4) {
+DEFINE_NATIVE_ENTRY(List_slice, 0, 4) {
   const Array& src = Array::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, count, arguments->NativeArgAt(2));
@@ -70,7 +70,7 @@
 }
 
 // Private factory, expects correct arguments.
-DEFINE_NATIVE_ENTRY(ImmutableList_from, 4) {
+DEFINE_NATIVE_ENTRY(ImmutableList_from, 0, 4) {
   // Ignore first argument of a thsi factory (type argument).
   const Array& from_array =
       Array::CheckedHandle(zone, arguments->NativeArgAt(1));
diff --git a/runtime/lib/async.cc b/runtime/lib/async.cc
index 2799419..5a11f34 100644
--- a/runtime/lib/async.cc
+++ b/runtime/lib/async.cc
@@ -11,7 +11,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(AsyncStarMoveNext_debuggerStepCheck, 1) {
+DEFINE_NATIVE_ENTRY(AsyncStarMoveNext_debuggerStepCheck, 0, 1) {
 #if !defined(PRODUCT)
   GET_NON_NULL_NATIVE_ARGUMENT(Closure, async_op, arguments->NativeArgAt(0));
   Debugger* debugger = isolate->debugger();
diff --git a/runtime/lib/bool.cc b/runtime/lib/bool.cc
index dc2b00f..c52fd71 100644
--- a/runtime/lib/bool.cc
+++ b/runtime/lib/bool.cc
@@ -16,7 +16,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(Bool_fromEnvironment, 3) {
+DEFINE_NATIVE_ENTRY(Bool_fromEnvironment, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
   GET_NATIVE_ARGUMENT(Bool, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
diff --git a/runtime/lib/class_id.cc b/runtime/lib/class_id.cc
index 2d9f67d..c0f5295 100644
--- a/runtime/lib/class_id.cc
+++ b/runtime/lib/class_id.cc
@@ -7,7 +7,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(ClassID_getID, 1) {
+DEFINE_NATIVE_ENTRY(ClassID_getID, 0, 1) {
   const Instance& instance =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Smi::New(instance.GetClassId());
diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
index 3f694d3..e605c05 100644
--- a/runtime/lib/date.cc
+++ b/runtime/lib/date.cc
@@ -14,7 +14,7 @@
 
 static int64_t kMaxAllowedSeconds = kMaxInt32;
 
-DEFINE_NATIVE_ENTRY(DateTime_timeZoneName, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneName, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, dart_seconds,
                                arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
@@ -25,7 +25,7 @@
   return String::New(name);
 }
 
-DEFINE_NATIVE_ENTRY(DateTime_timeZoneOffsetInSeconds, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneOffsetInSeconds, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, dart_seconds,
                                arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
@@ -36,12 +36,12 @@
   return Integer::New(offset);
 }
 
-DEFINE_NATIVE_ENTRY(DateTime_localTimeZoneAdjustmentInSeconds, 0) {
+DEFINE_NATIVE_ENTRY(DateTime_localTimeZoneAdjustmentInSeconds, 0, 0) {
   int adjustment = OS::GetLocalTimeZoneAdjustmentInSeconds();
   return Integer::New(adjustment);
 }
 
-DEFINE_NATIVE_ENTRY(DateTime_currentTimeMicros, 0) {
+DEFINE_NATIVE_ENTRY(DateTime_currentTimeMicros, 0, 0) {
   return Integer::New(OS::GetCurrentTimeMicros());
 }
 
diff --git a/runtime/lib/developer.cc b/runtime/lib/developer.cc
index e8056b4..defe884 100644
--- a/runtime/lib/developer.cc
+++ b/runtime/lib/developer.cc
@@ -19,7 +19,7 @@
 namespace dart {
 
 // Native implementations for the dart:developer library.
-DEFINE_NATIVE_ENTRY(Developer_debugger, 2) {
+DEFINE_NATIVE_ENTRY(Developer_debugger, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, when, arguments->NativeArgAt(0));
 #if !defined(PRODUCT)
   GET_NATIVE_ARGUMENT(String, msg, arguments->NativeArgAt(1));
@@ -34,7 +34,7 @@
   return when.raw();
 }
 
-DEFINE_NATIVE_ENTRY(Developer_inspect, 1) {
+DEFINE_NATIVE_ENTRY(Developer_inspect, 0, 1) {
   GET_NATIVE_ARGUMENT(Instance, inspectee, arguments->NativeArgAt(0));
 #ifndef PRODUCT
   if (FLAG_support_service) {
@@ -44,7 +44,7 @@
   return inspectee.raw();
 }
 
-DEFINE_NATIVE_ENTRY(Developer_log, 8) {
+DEFINE_NATIVE_ENTRY(Developer_log, 0, 8) {
 #if defined(PRODUCT)
   return Object::null();
 #else
@@ -66,7 +66,7 @@
 #endif  // PRODUCT
 }
 
-DEFINE_NATIVE_ENTRY(Developer_postEvent, 2) {
+DEFINE_NATIVE_ENTRY(Developer_postEvent, 0, 2) {
 #if defined(PRODUCT)
   return Object::null();
 #else
@@ -80,7 +80,7 @@
 #endif  // PRODUCT
 }
 
-DEFINE_NATIVE_ENTRY(Developer_lookupExtension, 1) {
+DEFINE_NATIVE_ENTRY(Developer_lookupExtension, 0, 1) {
 #if defined(PRODUCT)
   return Object::null();
 #else
@@ -92,7 +92,7 @@
 #endif  // PRODUCT
 }
 
-DEFINE_NATIVE_ENTRY(Developer_registerExtension, 2) {
+DEFINE_NATIVE_ENTRY(Developer_registerExtension, 0, 2) {
 #if defined(PRODUCT)
   return Object::null();
 #else
@@ -112,7 +112,7 @@
 #endif  // PRODUCT
 }
 
-DEFINE_NATIVE_ENTRY(Developer_getServiceMajorVersion, 0) {
+DEFINE_NATIVE_ENTRY(Developer_getServiceMajorVersion, 0, 0) {
 #if defined(PRODUCT)
   return Smi::New(0);
 #else
@@ -120,7 +120,7 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(Developer_getServiceMinorVersion, 0) {
+DEFINE_NATIVE_ENTRY(Developer_getServiceMinorVersion, 0, 0) {
 #if defined(PRODUCT)
   return Smi::New(0);
 #else
@@ -134,7 +134,7 @@
                                    Message::kNormalPriority));
 }
 
-DEFINE_NATIVE_ENTRY(Developer_getServerInfo, 1) {
+DEFINE_NATIVE_ENTRY(Developer_getServerInfo, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
 #if defined(PRODUCT)
   SendNull(port);
@@ -149,7 +149,7 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(Developer_webServerControl, 2) {
+DEFINE_NATIVE_ENTRY(Developer_webServerControl, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
 #if defined(PRODUCT)
   SendNull(port);
@@ -165,7 +165,7 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(Developer_getIsolateIDFromSendPort, 1) {
+DEFINE_NATIVE_ENTRY(Developer_getIsolateIDFromSendPort, 0, 1) {
 #if defined(PRODUCT)
   return Object::null();
 #else
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index eb24241..fb2f903 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -17,7 +17,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 0, 2) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   const Integer& value =
@@ -28,7 +28,7 @@
   return Double::New(value.AsDoubleValue());
 }
 
-DEFINE_NATIVE_ENTRY(Double_add, 2) {
+DEFINE_NATIVE_ENTRY(Double_add, 0, 2) {
   double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
@@ -38,7 +38,7 @@
   return Double::New(left + right);
 }
 
-DEFINE_NATIVE_ENTRY(Double_sub, 2) {
+DEFINE_NATIVE_ENTRY(Double_sub, 0, 2) {
   double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
@@ -48,7 +48,7 @@
   return Double::New(left - right);
 }
 
-DEFINE_NATIVE_ENTRY(Double_mul, 2) {
+DEFINE_NATIVE_ENTRY(Double_mul, 0, 2) {
   double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
@@ -58,7 +58,7 @@
   return Double::New(left * right);
 }
 
-DEFINE_NATIVE_ENTRY(Double_div, 2) {
+DEFINE_NATIVE_ENTRY(Double_div, 0, 2) {
   double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
@@ -85,7 +85,7 @@
   return Integer::New(ival);
 }
 
-DEFINE_NATIVE_ENTRY(Double_hashCode, 1) {
+DEFINE_NATIVE_ENTRY(Double_hashCode, 0, 1) {
   double val = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   if (FLAG_trace_intrinsified_natives) {
     OS::PrintErr("Double_hashCode %f\n", val);
@@ -102,7 +102,7 @@
   return Smi::New(((uval >> 32) ^ (uval)) & kSmiMax);
 }
 
-DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) {
+DEFINE_NATIVE_ENTRY(Double_trunc_div, 0, 2) {
   double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
@@ -113,21 +113,21 @@
                          "Result of truncating division is Infinity or NaN");
 }
 
-DEFINE_NATIVE_ENTRY(Double_modulo, 2) {
+DEFINE_NATIVE_ENTRY(Double_modulo, 0, 2) {
   double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
   return Double::New(DartModulo(left, right));
 }
 
-DEFINE_NATIVE_ENTRY(Double_remainder, 2) {
+DEFINE_NATIVE_ENTRY(Double_remainder, 0, 2) {
   double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
   return Double::New(fmod_ieee(left, right));
 }
 
-DEFINE_NATIVE_ENTRY(Double_greaterThan, 2) {
+DEFINE_NATIVE_ENTRY(Double_greaterThan, 0, 2) {
   const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
   bool result = right.IsNull() ? false : (left.value() > right.value());
@@ -138,13 +138,13 @@
   return Bool::Get(result).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Double_greaterThanFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Double_greaterThanFromInteger, 0, 2) {
   const Double& right = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
   return Bool::Get(left.AsDoubleValue() > right.value()).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Double_equal, 2) {
+DEFINE_NATIVE_ENTRY(Double_equal, 0, 2) {
   const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
   bool result = right.IsNull() ? false : (left.value() == right.value());
@@ -155,28 +155,28 @@
   return Bool::Get(result).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) {
+DEFINE_NATIVE_ENTRY(Double_equalToInteger, 0, 2) {
   const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1));
   return Bool::Get(left.value() == right.AsDoubleValue()).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Double_round, 1) {
+DEFINE_NATIVE_ENTRY(Double_round, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Double::New(round(arg.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Double_floor, 1) {
+DEFINE_NATIVE_ENTRY(Double_floor, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Double::New(floor(arg.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Double_ceil, 1) {
+DEFINE_NATIVE_ENTRY(Double_ceil, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Double::New(ceil(arg.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Double_truncate, 1) {
+DEFINE_NATIVE_ENTRY(Double_truncate, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Double::New(trunc(arg.value()));
 }
@@ -186,12 +186,12 @@
 #pragma GCC diagnostic ignored "-Wold-style-cast"
 #endif
 
-DEFINE_NATIVE_ENTRY(Double_toInt, 1) {
+DEFINE_NATIVE_ENTRY(Double_toInt, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   return DoubleToInteger(arg.value(), "Infinity or NaN toInt");
 }
 
-DEFINE_NATIVE_ENTRY(Double_parse, 3) {
+DEFINE_NATIVE_ENTRY(Double_parse, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, startValue, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, endValue, arguments->NativeArgAt(2));
@@ -210,12 +210,12 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Double_toString, 1) {
+DEFINE_NATIVE_ENTRY(Double_toString, 0, 1) {
   const Number& number = Number::CheckedHandle(zone, arguments->NativeArgAt(0));
   return number.ToString(Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 2) {
+DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 0, 2) {
   // The boundaries are exclusive.
   static const double kLowerBoundary = -1e21;
   static const double kUpperBoundary = 1e21;
@@ -234,7 +234,7 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(Double_toStringAsExponential, 2) {
+DEFINE_NATIVE_ENTRY(Double_toStringAsExponential, 0, 2) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1));
   double d = arg.value();
@@ -249,7 +249,7 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(Double_toStringAsPrecision, 2) {
+DEFINE_NATIVE_ENTRY(Double_toStringAsPrecision, 0, 2) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, precision, arguments->NativeArgAt(1));
   double d = arg.value();
@@ -263,24 +263,24 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(Double_getIsInfinite, 1) {
+DEFINE_NATIVE_ENTRY(Double_getIsInfinite, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Bool::Get(isinf(arg.value())).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Double_getIsNaN, 1) {
+DEFINE_NATIVE_ENTRY(Double_getIsNaN, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Bool::Get(isnan(arg.value())).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) {
+DEFINE_NATIVE_ENTRY(Double_getIsNegative, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   // Include negative zero, infinity.
   double dval = arg.value();
   return Bool::Get(signbit(dval) && !isnan(dval)).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Double_flipSignBit, 1) {
+DEFINE_NATIVE_ENTRY(Double_flipSignBit, 0, 1) {
   const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
   const double in_val = arg.value();
   const int64_t bits = bit_cast<int64_t, double>(in_val) ^ kSignBitDouble;
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index dc136fd..54e61eb 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -68,7 +68,7 @@
 // Arg1: index of the first token after the failed assertion.
 // Arg2: Message object or null.
 // Return value: none, throws an exception.
-DEFINE_NATIVE_ENTRY(AssertionError_throwNew, 3) {
+DEFINE_NATIVE_ENTRY(AssertionError_throwNew, 0, 3) {
   // No need to type check the arguments. This function can only be called
   // internally from the VM.
   const TokenPosition assertion_start = TokenPosition(
@@ -113,7 +113,7 @@
 // Arg2: dst type.
 // Arg3: dst name.
 // Return value: none, throws an exception.
-DEFINE_NATIVE_ENTRY(TypeError_throwNew, 4) {
+DEFINE_NATIVE_ENTRY(TypeError_throwNew, 0, 4) {
   // No need to type check the arguments. This function can only be called
   // internally from the VM.
   const TokenPosition location = TokenPosition(
@@ -134,7 +134,7 @@
 // Allocate and throw a new FallThroughError.
 // Arg0: index of the case clause token into which we fall through.
 // Return value: none, throws an exception.
-DEFINE_NATIVE_ENTRY(FallThroughError_throwNew, 1) {
+DEFINE_NATIVE_ENTRY(FallThroughError_throwNew, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_pos, arguments->NativeArgAt(0));
   TokenPosition fallthrough_pos = TokenPosition(smi_pos.Value());
 
@@ -159,7 +159,7 @@
 // Arg0: Token position of allocation statement.
 // Arg1: class name of the abstract class that cannot be instantiated.
 // Return value: none, throws an exception.
-DEFINE_NATIVE_ENTRY(AbstractClassInstantiationError_throwNew, 2) {
+DEFINE_NATIVE_ENTRY(AbstractClassInstantiationError_throwNew, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_pos, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, class_name, arguments->NativeArgAt(1));
   TokenPosition error_pos = TokenPosition(smi_pos.Value());
@@ -183,7 +183,7 @@
 }
 
 // Rethrow an error with a stacktrace.
-DEFINE_NATIVE_ENTRY(Async_rethrow, 2) {
+DEFINE_NATIVE_ENTRY(Async_rethrow, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, error, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, stacktrace, arguments->NativeArgAt(1));
   Exceptions::ReThrow(thread, error, stacktrace);
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 0a50260..4311238 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -13,7 +13,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(Function_apply, 2) {
+DEFINE_NATIVE_ENTRY(Function_apply, 0, 2) {
   const int kTypeArgsLen = 0;  // TODO(regis): Add support for generic function.
   const Array& fun_arguments =
       Array::CheckedHandle(zone, arguments->NativeArgAt(0));
@@ -30,7 +30,7 @@
   return result.raw();
 }
 
-DEFINE_NATIVE_ENTRY(Closure_equals, 2) {
+DEFINE_NATIVE_ENTRY(Closure_equals, 0, 2) {
   const Closure& receiver =
       Closure::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NATIVE_ARGUMENT(Instance, other, arguments->NativeArgAt(1));
@@ -65,13 +65,13 @@
   return Bool::False().raw();
 }
 
-DEFINE_NATIVE_ENTRY(Closure_computeHash, 1) {
+DEFINE_NATIVE_ENTRY(Closure_computeHash, 0, 1) {
   const Closure& receiver =
       Closure::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Smi::New(receiver.ComputeHash());
 }
 
-DEFINE_NATIVE_ENTRY(Closure_clone, 1) {
+DEFINE_NATIVE_ENTRY(Closure_clone, 0, 1) {
   const Closure& receiver =
       Closure::CheckedHandle(zone, arguments->NativeArgAt(0));
   const TypeArguments& instantiator_type_arguments =
diff --git a/runtime/lib/growable_array.cc b/runtime/lib/growable_array.cc
index 1d57b7a..71d9f2a 100644
--- a/runtime/lib/growable_array.cc
+++ b/runtime/lib/growable_array.cc
@@ -11,7 +11,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(GrowableList_allocate, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_allocate, 0, 2) {
   const TypeArguments& type_arguments =
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, data, arguments->NativeArgAt(1));
@@ -27,7 +27,7 @@
   return new_array.raw();
 }
 
-DEFINE_NATIVE_ENTRY(GrowableList_getIndexed, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_getIndexed, 0, 2) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
@@ -38,7 +38,7 @@
   return obj.raw();
 }
 
-DEFINE_NATIVE_ENTRY(GrowableList_setIndexed, 3) {
+DEFINE_NATIVE_ENTRY(GrowableList_setIndexed, 0, 3) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
@@ -50,19 +50,19 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(GrowableList_getLength, 1) {
+DEFINE_NATIVE_ENTRY(GrowableList_getLength, 0, 1) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Smi::New(array.Length());
 }
 
-DEFINE_NATIVE_ENTRY(GrowableList_getCapacity, 1) {
+DEFINE_NATIVE_ENTRY(GrowableList_getCapacity, 0, 1) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Smi::New(array.Capacity());
 }
 
-DEFINE_NATIVE_ENTRY(GrowableList_setLength, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_setLength, 0, 2) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));
@@ -71,7 +71,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(GrowableList_setData, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_setData, 0, 2) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, data, arguments->NativeArgAt(1));
@@ -80,13 +80,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Internal_makeListFixedLength, 1) {
+DEFINE_NATIVE_ENTRY(Internal_makeListFixedLength, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(GrowableObjectArray, array,
                                arguments->NativeArgAt(0));
   return Array::MakeFixedLength(array, /* unique = */ true);
 }
 
-DEFINE_NATIVE_ENTRY(Internal_makeFixedListUnmodifiable, 1) {
+DEFINE_NATIVE_ENTRY(Internal_makeFixedListUnmodifiable, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Array, array, arguments->NativeArgAt(0));
   array.MakeImmutable();
   return array.raw();
diff --git a/runtime/lib/identical.cc b/runtime/lib/identical.cc
index bbb47bd..c0d2b96 100644
--- a/runtime/lib/identical.cc
+++ b/runtime/lib/identical.cc
@@ -8,7 +8,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(Identical_comparison, 2) {
+DEFINE_NATIVE_ENTRY(Identical_comparison, 0, 2) {
   GET_NATIVE_ARGUMENT(Instance, a, arguments->NativeArgAt(0));
   GET_NATIVE_ARGUMENT(Instance, b, arguments->NativeArgAt(1));
   const bool is_identical = a.IsIdenticalTo(b);
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 1c8cf7c..c66299f 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -28,7 +28,7 @@
   return true;
 }
 
-DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 0, 2) {
   const Integer& right =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
@@ -41,7 +41,7 @@
   return left.BitOp(Token::kBIT_AND, right);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 0, 2) {
   const Integer& right =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
@@ -54,7 +54,7 @@
   return left.BitOp(Token::kBIT_OR, right);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 0, 2) {
   const Integer& right =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
@@ -67,7 +67,7 @@
   return left.BitOp(Token::kBIT_XOR, right);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 0, 2) {
   const Integer& right_int =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
@@ -80,7 +80,7 @@
   return left_int.ArithmeticOp(Token::kADD, right_int);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 0, 2) {
   const Integer& right_int =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
@@ -93,7 +93,7 @@
   return left_int.ArithmeticOp(Token::kSUB, right_int);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 0, 2) {
   const Integer& right_int =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
@@ -106,7 +106,7 @@
   return left_int.ArithmeticOp(Token::kMUL, right_int);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 0, 2) {
   const Integer& right_int =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
@@ -116,7 +116,7 @@
   return left_int.ArithmeticOp(Token::kTRUNCDIV, right_int);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 0, 2) {
   const Integer& right_int =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
@@ -133,7 +133,7 @@
   return left_int.ArithmeticOp(Token::kMOD, right_int);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 0, 2) {
   const Integer& right =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
@@ -146,7 +146,7 @@
   return Bool::Get(left.CompareWith(right) == 1).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 0, 2) {
   const Integer& left = Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1));
   ASSERT(CheckInteger(left));
@@ -179,12 +179,12 @@
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_parse, 1) {
+DEFINE_NATIVE_ENTRY(Integer_parse, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
   return ParseInteger(value);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 3) {
+DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
   GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
@@ -211,7 +211,7 @@
   return value.ShiftOp(kind, amount, Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_shrFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_shrFromInteger, 0, 2) {
   const Integer& amount =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
@@ -224,7 +224,7 @@
   return ShiftOperationHelper(Token::kSHR, value, amount);
 }
 
-DEFINE_NATIVE_ENTRY(Integer_shlFromInteger, 2) {
+DEFINE_NATIVE_ENTRY(Integer_shlFromInteger, 0, 2) {
   const Integer& amount =
       Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
@@ -237,7 +237,7 @@
   return ShiftOperationHelper(Token::kSHL, value, amount);
 }
 
-DEFINE_NATIVE_ENTRY(Smi_bitAndFromSmi, 2) {
+DEFINE_NATIVE_ENTRY(Smi_bitAndFromSmi, 0, 2) {
   const Smi& left = Smi::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, right, arguments->NativeArgAt(1));
   if (FLAG_trace_intrinsified_natives) {
@@ -249,7 +249,7 @@
   return Smi::New(left_value.Value() & right_value.Value());
 }
 
-DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) {
+DEFINE_NATIVE_ENTRY(Smi_bitNegate, 0, 1) {
   const Smi& operand = Smi::CheckedHandle(zone, arguments->NativeArgAt(0));
   if (FLAG_trace_intrinsified_natives) {
     OS::PrintErr("Smi_bitNegate: %s\n", operand.ToCString());
@@ -259,7 +259,7 @@
   return Smi::New(result);
 }
 
-DEFINE_NATIVE_ENTRY(Smi_bitLength, 1) {
+DEFINE_NATIVE_ENTRY(Smi_bitLength, 0, 1) {
   const Smi& operand = Smi::CheckedHandle(zone, arguments->NativeArgAt(0));
   if (FLAG_trace_intrinsified_natives) {
     OS::PrintErr("Smi_bitLength: %s\n", operand.ToCString());
@@ -272,7 +272,7 @@
 
 // Mint natives.
 
-DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) {
+DEFINE_NATIVE_ENTRY(Mint_bitNegate, 0, 1) {
   const Mint& operand = Mint::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(CheckInteger(operand));
   if (FLAG_trace_intrinsified_natives) {
@@ -282,7 +282,7 @@
   return Integer::New(result);
 }
 
-DEFINE_NATIVE_ENTRY(Mint_bitLength, 1) {
+DEFINE_NATIVE_ENTRY(Mint_bitLength, 0, 1) {
   const Mint& operand = Mint::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(CheckInteger(operand));
   if (FLAG_trace_intrinsified_natives) {
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index bd52652..608ced8 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -25,20 +25,20 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(CapabilityImpl_factory, 1) {
+DEFINE_NATIVE_ENTRY(CapabilityImpl_factory, 0, 1) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   uint64_t id = isolate->random()->NextUInt64();
   return Capability::New(id);
 }
 
-DEFINE_NATIVE_ENTRY(CapabilityImpl_equals, 2) {
+DEFINE_NATIVE_ENTRY(CapabilityImpl_equals, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Capability, recv, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Capability, other, arguments->NativeArgAt(1));
   return (recv.Id() == other.Id()) ? Bool::True().raw() : Bool::False().raw();
 }
 
-DEFINE_NATIVE_ENTRY(CapabilityImpl_get_hashcode, 1) {
+DEFINE_NATIVE_ENTRY(CapabilityImpl_get_hashcode, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Capability, cap, arguments->NativeArgAt(0));
   int64_t id = cap.Id();
   int32_t hi = static_cast<int32_t>(id >> 32);
@@ -47,36 +47,36 @@
   return Smi::New(hash);
 }
 
-DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) {
+DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 0, 1) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   Dart_Port port_id = PortMap::CreatePort(isolate->message_handler());
   return ReceivePort::New(port_id, false /* not control port */);
 }
 
-DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_id, 1) {
+DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_id, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
   return Integer::New(port.Id());
 }
 
-DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_sendport, 1) {
+DEFINE_NATIVE_ENTRY(RawReceivePortImpl_get_sendport, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
   return port.send_port();
 }
 
-DEFINE_NATIVE_ENTRY(RawReceivePortImpl_closeInternal, 1) {
+DEFINE_NATIVE_ENTRY(RawReceivePortImpl_closeInternal, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
   Dart_Port id = port.Id();
   PortMap::ClosePort(id);
   return Integer::New(id);
 }
 
-DEFINE_NATIVE_ENTRY(SendPortImpl_get_id, 1) {
+DEFINE_NATIVE_ENTRY(SendPortImpl_get_id, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   return Integer::New(port.Id());
 }
 
-DEFINE_NATIVE_ENTRY(SendPortImpl_get_hashcode, 1) {
+DEFINE_NATIVE_ENTRY(SendPortImpl_get_hashcode, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   int64_t id = port.Id();
   int32_t hi = static_cast<int32_t>(id >> 32);
@@ -85,7 +85,7 @@
   return Smi::New(hash);
 }
 
-DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 2) {
+DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   // TODO(iposva): Allow for arbitrary messages to be sent.
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
@@ -182,7 +182,7 @@
   return result;
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 10) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 10) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(2));
@@ -281,7 +281,7 @@
   return result;
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 12) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
 
@@ -371,7 +371,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) {
+DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0, 0) {
   const Array& result = Array::Handle(Array::New(3));
   result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port())));
   result.SetAt(
@@ -381,13 +381,13 @@
   return result.raw();
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0) {
+DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0, 0) {
   const Library& root_lib =
       Library::Handle(zone, isolate->object_store()->root_library());
   return root_lib.url();
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) {
+DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1));
 
diff --git a/runtime/lib/linked_hash_map.cc b/runtime/lib/linked_hash_map.cc
index cd09658..89ad2bb 100644
--- a/runtime/lib/linked_hash_map.cc
+++ b/runtime/lib/linked_hash_map.cc
@@ -12,13 +12,13 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_getIndex, 1) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_getIndex, 0, 1) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   return map.index();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_setIndex, 2) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_setIndex, 0, 2) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   const TypedData& index =
@@ -27,13 +27,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_getData, 1) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_getData, 0, 1) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   return map.data();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_setData, 2) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_setData, 0, 2) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Array& data = Array::CheckedHandle(zone, arguments->NativeArgAt(1));
@@ -41,13 +41,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_getHashMask, 1) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_getHashMask, 0, 1) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   return map.hash_mask();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_setHashMask, 2) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_setHashMask, 0, 2) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Smi& hashMask = Smi::CheckedHandle(zone, arguments->NativeArgAt(1));
@@ -55,13 +55,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_getDeletedKeys, 1) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_getDeletedKeys, 0, 1) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   return map.deleted_keys();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_setDeletedKeys, 2) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_setDeletedKeys, 0, 2) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Smi& deletedKeys = Smi::CheckedHandle(zone, arguments->NativeArgAt(1));
@@ -69,13 +69,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_getUsedData, 1) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_getUsedData, 0, 1) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   return map.used_data();
 }
 
-DEFINE_NATIVE_ENTRY(LinkedHashMap_setUsedData, 2) {
+DEFINE_NATIVE_ENTRY(LinkedHashMap_setUsedData, 0, 2) {
   const LinkedHashMap& map =
       LinkedHashMap::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Smi& usedData = Smi::CheckedHandle(zone, arguments->NativeArgAt(1));
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index e3ef926..b4a5bfd 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -13,58 +13,58 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(Math_sqrt, 1) {
+DEFINE_NATIVE_ENTRY(Math_sqrt, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(sqrt(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_sin, 1) {
+DEFINE_NATIVE_ENTRY(Math_sin, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(sin(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_cos, 1) {
+DEFINE_NATIVE_ENTRY(Math_cos, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(cos(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_tan, 1) {
+DEFINE_NATIVE_ENTRY(Math_tan, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(tan(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_asin, 1) {
+DEFINE_NATIVE_ENTRY(Math_asin, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(asin(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_acos, 1) {
+DEFINE_NATIVE_ENTRY(Math_acos, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(acos(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_atan, 1) {
+DEFINE_NATIVE_ENTRY(Math_atan, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(atan(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_atan2, 2) {
+DEFINE_NATIVE_ENTRY(Math_atan2, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand1, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand2, arguments->NativeArgAt(1));
   return Double::New(atan2_ieee(operand1.value(), operand2.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_exp, 1) {
+DEFINE_NATIVE_ENTRY(Math_exp, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(exp(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_log, 1) {
+DEFINE_NATIVE_ENTRY(Math_log, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0));
   return Double::New(log(operand.value()));
 }
 
-DEFINE_NATIVE_ENTRY(Math_doublePow, 2) {
+DEFINE_NATIVE_ENTRY(Math_doublePow, 0, 2) {
   const double operand =
       Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, exponent_object,
@@ -94,7 +94,7 @@
 //       ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & (1 << 64) - 1);
 //   _state[_kSTATE_LO] = state & (1 << 32) - 1);
 //   _state[_kSTATE_HI] = state >> 32;
-DEFINE_NATIVE_ENTRY(Random_nextState, 1) {
+DEFINE_NATIVE_ENTRY(Random_nextState, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, receiver, arguments->NativeArgAt(0));
   const TypedData& array = TypedData::Handle(GetRandomStateArray(receiver));
   const uint64_t state_lo = array.GetUint32(0);
@@ -143,7 +143,7 @@
 //   result[_kSTATE_LO] = seed & ((1 << 32) - 1);
 //   result[_kSTATE_HI] = seed >> 32;
 //   return result;
-DEFINE_NATIVE_ENTRY(Random_setupSeed, 1) {
+DEFINE_NATIVE_ENTRY(Random_setupSeed, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0));
   uint64_t seed = mix64(static_cast<uint64_t>(seed_int.AsInt64Value()));
 
@@ -153,14 +153,14 @@
   return CreateRandomState(zone, seed);
 }
 
-DEFINE_NATIVE_ENTRY(Random_initialSeed, 0) {
+DEFINE_NATIVE_ENTRY(Random_initialSeed, 0, 0) {
   Random* rnd = isolate->random();
   uint64_t seed = rnd->NextUInt32();
   seed |= (static_cast<uint64_t>(rnd->NextUInt32()) << 32);
   return CreateRandomState(zone, seed);
 }
 
-DEFINE_NATIVE_ENTRY(SecureRandom_getBytes, 1) {
+DEFINE_NATIVE_ENTRY(SecureRandom_getBytes, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, count, arguments->NativeArgAt(0));
   const intptr_t n = count.Value();
   ASSERT((n > 0) && (n <= 8));
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index d29f4f1..37756f2 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -427,7 +427,7 @@
   return CreateMirror(Symbols::_LocalLibraryDependencyMirror(), args);
 }
 
-DEFINE_NATIVE_ENTRY(LibraryMirror_fromPrefix, 1) {
+DEFINE_NATIVE_ENTRY(LibraryMirror_fromPrefix, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(LibraryPrefix, prefix,
                                arguments->NativeArgAt(0));
   const Library& deferred_lib = Library::Handle(prefix.GetLibrary(0));
@@ -437,7 +437,7 @@
   return CreateLibraryMirror(thread, deferred_lib);
 }
 
-DEFINE_NATIVE_ENTRY(LibraryMirror_libraryDependencies, 2) {
+DEFINE_NATIVE_ENTRY(LibraryMirror_libraryDependencies, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, lib_mirror, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
   const Library& lib = Library::Handle(ref.GetLibraryReferent());
@@ -597,7 +597,7 @@
   return result.Canonicalize();
 }
 
-DEFINE_NATIVE_ENTRY(MirrorSystem_libraries, 0) {
+DEFINE_NATIVE_ENTRY(MirrorSystem_libraries, 0, 0) {
   const GrowableObjectArray& libraries =
       GrowableObjectArray::Handle(zone, isolate->object_store()->libraries());
 
@@ -617,7 +617,7 @@
   return library_mirrors.raw();
 }
 
-DEFINE_NATIVE_ENTRY(MirrorSystem_isolate, 0) {
+DEFINE_NATIVE_ENTRY(MirrorSystem_isolate, 0, 0) {
   VerifyMethodKindShifts();
 
   return CreateIsolateMirror();
@@ -629,7 +629,7 @@
   Exceptions::PropagateError(error);
 }
 
-DEFINE_NATIVE_ENTRY(IsolateMirror_loadUri, 1) {
+DEFINE_NATIVE_ENTRY(IsolateMirror_loadUri, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0));
 
   if (!isolate->HasTagHandler()) {
@@ -708,7 +708,7 @@
   FATAL("Non-library from tag handler");
 }
 
-DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) {
+DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFinalized());
   ASSERT(type.HasTypeClass());
@@ -723,12 +723,12 @@
                            Object::null_instance());
 }
 
-DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 1) {
+DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   return CreateTypeMirror(type);
 }
 
-DEFINE_NATIVE_ENTRY(Mirrors_instantiateGenericType, 2) {
+DEFINE_NATIVE_ENTRY(Mirrors_instantiateGenericType, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(1));
 
@@ -779,20 +779,20 @@
   return instantiated_type.raw();
 }
 
-DEFINE_NATIVE_ENTRY(Mirrors_mangleName, 2) {
+DEFINE_NATIVE_ENTRY(Mirrors_mangleName, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
   const Library& lib = Library::Handle(ref.GetLibraryReferent());
   return lib.IsPrivate(name) ? lib.PrivateName(name) : name.raw();
 }
 
-DEFINE_NATIVE_ENTRY(MirrorReference_equals, 2) {
+DEFINE_NATIVE_ENTRY(MirrorReference_equals, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, b, arguments->NativeArgAt(1));
   return Bool::Get(a.referent() == b.referent()).raw();
 }
 
-DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 1) {
+DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
   Object& decl = Object::Handle();
   if (reflectee.IsMirrorReference()) {
@@ -836,7 +836,7 @@
   return metadata.raw();
 }
 
-DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 2) {
+DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
                                arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
@@ -847,14 +847,14 @@
   return CreateMethodMirror(func, owner_mirror, AbstractType::Handle());
 }
 
-DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 2) {
+DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
   const Function& func = Function::Handle(ref.GetFunctionReferent());
   return CreateParameterMirrorList(func, owner);
 }
 
-DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 1) {
+DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Function& func = Function::Handle(ref.GetFunctionReferent());
   ASSERT(!func.IsNull());
@@ -863,7 +863,7 @@
   return type.Canonicalize();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_libraryUri, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_libraryUri, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Class& klass = Class::Handle(ref.GetClassReferent());
   const Library& library = Library::Handle(klass.library());
@@ -871,7 +871,7 @@
   return library.url();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFinalized());
   const Class& cls = Class::Handle(type.type_class());
@@ -880,7 +880,7 @@
   return super_type.raw();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFinalized());
   const Class& cls = Class::Handle(type.type_class());
@@ -888,7 +888,7 @@
   return InstantiateType(super_type, type);
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFinalized());
   const Class& cls = Class::Handle(type.type_class());
@@ -900,7 +900,7 @@
   return cls.interfaces();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFinalized());
   const Class& cls = Class::Handle(type.type_class());
@@ -922,7 +922,7 @@
   return interfaces_inst.raw();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFinalized());
   const Class& cls = Class::Handle(type.type_class());
@@ -937,7 +937,7 @@
   return mixin_type.raw();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) {
+DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, instantiator,
                                arguments->NativeArgAt(1));
@@ -957,7 +957,7 @@
   return InstantiateType(mixin_type, instantiator);
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_members, 3) {
+DEFINE_NATIVE_ENTRY(ClassMirror_members, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
                                arguments->NativeArgAt(0));
   GET_NATIVE_ARGUMENT(AbstractType, owner_instantiator,
@@ -1005,7 +1005,7 @@
   return member_mirrors.raw();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_constructors, 3) {
+DEFINE_NATIVE_ENTRY(ClassMirror_constructors, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
                                arguments->NativeArgAt(0));
   GET_NATIVE_ARGUMENT(AbstractType, owner_instantiator,
@@ -1038,7 +1038,7 @@
   return constructor_mirrors.raw();
 }
 
-DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) {
+DEFINE_NATIVE_ENTRY(LibraryMirror_members, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
                                arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
@@ -1090,7 +1090,7 @@
   return member_mirrors.raw();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Class& klass = Class::Handle(ref.GetClassReferent());
   const Error& error = Error::Handle(zone, klass.EnsureIsFinalized(thread));
@@ -1101,7 +1101,7 @@
   return CreateTypeVariableList(klass);
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
 
   const Class& cls = Class::Handle(type.type_class());
@@ -1138,7 +1138,7 @@
   return result.raw();
 }
 
-DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) {
+DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
   Class& owner = Class::Handle(param.parameterized_class());
   AbstractType& type = AbstractType::Handle();
@@ -1156,12 +1156,12 @@
                            Instance::null_instance());
 }
 
-DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) {
+DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
   return param.bound();
 }
 
-DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 1) {
+DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFunctionType());
   const Class& cls = Class::Handle(type.type_class());
@@ -1171,7 +1171,7 @@
                              Object::null_instance());
 }
 
-DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) {
+DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 0, 5) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1183,7 +1183,7 @@
   RETURN_OR_PROPAGATE(reflectee.Invoke(function_name, args, arg_names));
 }
 
-DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) {
+DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 0, 3) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1192,7 +1192,7 @@
   RETURN_OR_PROPAGATE(reflectee.InvokeGetter(getter_name));
 }
 
-DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) {
+DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 0, 4) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1202,7 +1202,7 @@
   RETURN_OR_PROPAGATE(reflectee.InvokeSetter(setter_name, value));
 }
 
-DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 1) {
+DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
   const AbstractType& type = AbstractType::Handle(instance.GetType(Heap::kNew));
   // The static type of null is specified to be the bottom type, however, the
@@ -1210,7 +1210,7 @@
   return type.Canonicalize();
 }
 
-DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) {
+DEFINE_NATIVE_ENTRY(ClosureMirror_function, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
   ASSERT(!closure.IsNull());
 
@@ -1244,7 +1244,7 @@
   return Instance::null();
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 5) {
+DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 0, 5) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1257,7 +1257,7 @@
   RETURN_OR_PROPAGATE(klass.Invoke(function_name, args, arg_names));
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) {
+DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 0, 3) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1272,7 +1272,7 @@
   RETURN_OR_PROPAGATE(klass.InvokeGetter(getter_name, true));
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
+DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 0, 4) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1283,7 +1283,7 @@
   RETURN_OR_PROPAGATE(klass.InvokeSetter(setter_name, value));
 }
 
-DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) {
+DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 0, 5) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Class& klass = Class::Handle(ref.GetClassReferent());
   GET_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(1));
@@ -1437,7 +1437,7 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) {
+DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 0, 5) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1450,7 +1450,7 @@
   RETURN_OR_PROPAGATE(library.Invoke(function_name, args, arg_names));
 }
 
-DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 3) {
+DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 0, 3) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1460,7 +1460,7 @@
   RETURN_OR_PROPAGATE(library.InvokeGetter(getter_name, true));
 }
 
-DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) {
+DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 0, 4) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
   // with its cousins.
@@ -1471,7 +1471,7 @@
   RETURN_OR_PROPAGATE(library.InvokeSetter(setter_name, value));
 }
 
-DEFINE_NATIVE_ENTRY(MethodMirror_owner, 2) {
+DEFINE_NATIVE_ENTRY(MethodMirror_owner, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(1));
   const Function& func = Function::Handle(ref.GetFunctionReferent());
@@ -1488,14 +1488,14 @@
   return CreateClassMirror(owner, type, Bool::True(), Object::null_instance());
 }
 
-DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) {
+DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
   const Function& func = Function::Handle(ref.GetFunctionReferent());
   return CreateParameterMirrorList(func, owner);
 }
 
-DEFINE_NATIVE_ENTRY(MethodMirror_return_type, 2) {
+DEFINE_NATIVE_ENTRY(MethodMirror_return_type, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Function& func = Function::Handle(ref.GetFunctionReferent());
   GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(1));
@@ -1506,7 +1506,7 @@
   return InstantiateType(type, instantiator);
 }
 
-DEFINE_NATIVE_ENTRY(MethodMirror_source, 1) {
+DEFINE_NATIVE_ENTRY(MethodMirror_source, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Function& func = Function::Handle(ref.GetFunctionReferent());
   return func.GetSource();
@@ -1522,7 +1522,7 @@
   return CreateMirror(Symbols::_SourceLocation(), args);
 }
 
-DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 1) {
+DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
   Object& decl = Object::Handle(zone);
   if (reflectee.IsMirrorReference()) {
@@ -1600,7 +1600,7 @@
   return CreateSourceLocation(uri, from_line, from_col);
 }
 
-DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) {
+DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0));
   ASSERT(type.IsFunctionType());
   const Class& cls = Class::Handle(type.type_class());
@@ -1612,7 +1612,7 @@
   return CreateFunctionTypeMirror(referent_type);
 }
 
-DEFINE_NATIVE_ENTRY(ParameterMirror_type, 3) {
+DEFINE_NATIVE_ENTRY(ParameterMirror_type, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, pos, arguments->NativeArgAt(1));
   GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(2));
@@ -1623,7 +1623,7 @@
   return InstantiateType(type, instantiator);
 }
 
-DEFINE_NATIVE_ENTRY(VariableMirror_type, 2) {
+DEFINE_NATIVE_ENTRY(VariableMirror_type, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Field& field = Field::Handle(ref.GetFieldReferent());
   GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(1));
@@ -1631,7 +1631,7 @@
   return InstantiateType(type, instantiator);
 }
 
-DEFINE_NATIVE_ENTRY(TypeMirror_subtypeTest, 2) {
+DEFINE_NATIVE_ENTRY(TypeMirror_subtypeTest, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1));
   return Bool::Get(a.IsSubtypeOf(b, Heap::kNew)).raw();
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index ca598f3..44ef533c 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -15,7 +15,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(DartAsync_fatal, 1) {
+DEFINE_NATIVE_ENTRY(DartAsync_fatal, 0, 1) {
   // The dart:async library code entered an unrecoverable state.
   const Instance& instance =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
@@ -25,13 +25,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Object_equals, 1) {
+DEFINE_NATIVE_ENTRY(Object_equals, 0, 1) {
   // Implemented in the flow graph builder.
   UNREACHABLE();
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Object_getHash, 1) {
+DEFINE_NATIVE_ENTRY(Object_getHash, 0, 1) {
 // Please note that no handle is created for the argument.
 // This is safe since the argument is only used in a tail call.
 // The performance benefit is more than 5% when using hashCode.
@@ -44,7 +44,7 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(Object_setHash, 2) {
+DEFINE_NATIVE_ENTRY(Object_setHash, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, hash, arguments->NativeArgAt(1));
 #if defined(HASH_IN_OBJECT_HEADER)
   Object::SetCachedHash(arguments->NativeArgAt(0), hash.Value());
@@ -57,7 +57,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Object_toString, 1) {
+DEFINE_NATIVE_ENTRY(Object_toString, 0, 1) {
   const Instance& instance =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   if (instance.IsString()) {
@@ -70,7 +70,7 @@
   return String::New(c_str);
 }
 
-DEFINE_NATIVE_ENTRY(Object_runtimeType, 1) {
+DEFINE_NATIVE_ENTRY(Object_runtimeType, 0, 1) {
   const Instance& instance =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   if (instance.IsString()) {
@@ -83,7 +83,7 @@
   return instance.GetType(Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(Object_haveSameRuntimeType, 2) {
+DEFINE_NATIVE_ENTRY(Object_haveSameRuntimeType, 0, 2) {
   const Instance& left =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Instance& right =
@@ -131,7 +131,7 @@
       .raw();
 }
 
-DEFINE_NATIVE_ENTRY(Object_instanceOf, 4) {
+DEFINE_NATIVE_ENTRY(Object_instanceOf, 0, 4) {
   const Instance& instance =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   const TypeArguments& instantiator_type_arguments =
@@ -156,7 +156,7 @@
   return Bool::Get(is_instance_of).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Object_simpleInstanceOf, 2) {
+DEFINE_NATIVE_ENTRY(Object_simpleInstanceOf, 0, 2) {
   // This native is only called when the right hand side passes
   // SimpleInstanceOfType and it is a non-negative test.
   const Instance& instance =
@@ -170,13 +170,13 @@
   return Bool::Get(is_instance_of).raw();
 }
 
-DEFINE_NATIVE_ENTRY(AbstractType_toString, 1) {
+DEFINE_NATIVE_ENTRY(AbstractType_toString, 0, 1) {
   const AbstractType& type =
       AbstractType::CheckedHandle(zone, arguments->NativeArgAt(0));
   return type.UserVisibleName();
 }
 
-DEFINE_NATIVE_ENTRY(Type_getHashCode, 1) {
+DEFINE_NATIVE_ENTRY(Type_getHashCode, 0, 1) {
   const Type& type = Type::CheckedHandle(zone, arguments->NativeArgAt(0));
   intptr_t hash_val = type.Hash();
   ASSERT(hash_val > 0);
@@ -184,21 +184,21 @@
   return Smi::New(hash_val);
 }
 
-DEFINE_NATIVE_ENTRY(LibraryPrefix_invalidateDependentCode, 1) {
+DEFINE_NATIVE_ENTRY(LibraryPrefix_invalidateDependentCode, 0, 1) {
   const LibraryPrefix& prefix =
       LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
   prefix.InvalidateDependentCode();
   return Bool::Get(true).raw();
 }
 
-DEFINE_NATIVE_ENTRY(LibraryPrefix_load, 1) {
+DEFINE_NATIVE_ENTRY(LibraryPrefix_load, 0, 1) {
   const LibraryPrefix& prefix =
       LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
   bool hasCompleted = prefix.LoadLibrary();
   return Bool::Get(hasCompleted).raw();
 }
 
-DEFINE_NATIVE_ENTRY(LibraryPrefix_loadError, 1) {
+DEFINE_NATIVE_ENTRY(LibraryPrefix_loadError, 0, 1) {
   const LibraryPrefix& prefix =
       LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
   // Currently all errors are Dart instances, e.g. I/O errors
@@ -209,13 +209,13 @@
   return error.raw();
 }
 
-DEFINE_NATIVE_ENTRY(LibraryPrefix_isLoaded, 1) {
+DEFINE_NATIVE_ENTRY(LibraryPrefix_isLoaded, 0, 1) {
   const LibraryPrefix& prefix =
       LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Bool::Get(prefix.is_loaded()).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Internal_inquireIs64Bit, 0) {
+DEFINE_NATIVE_ENTRY(Internal_inquireIs64Bit, 0, 0) {
 #if defined(ARCH_IS_64_BIT)
   return Bool::True().raw();
 #else
@@ -223,7 +223,7 @@
 #endif  // defined(ARCH_IS_64_BIT)
 }
 
-DEFINE_NATIVE_ENTRY(Internal_unsafeCast, 1) {
+DEFINE_NATIVE_ENTRY(Internal_unsafeCast, 0, 1) {
   UNREACHABLE();  // Should be erased at Kernel translation time.
   return arguments->NativeArgAt(0);
 }
@@ -270,7 +270,8 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(Internal_extractTypeArguments, 2) {
+// for documentation see pkg/dart_internal/lib/extract_type_arguments.dart
+DEFINE_NATIVE_ENTRY(Internal_extractTypeArguments, 0, 2) {
   const Instance& instance =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Instance& extract =
@@ -278,11 +279,9 @@
 
   Class& interface_cls = Class::Handle(zone);
   intptr_t num_type_args = 0;
-  const TypeArguments& function_type_args =
-      TypeArguments::Handle(zone, arguments->NativeTypeArgs());
-  if (function_type_args.Length() == 1) {
+  if (arguments->NativeTypeArgCount() >= 1) {
     const AbstractType& function_type_arg =
-        AbstractType::Handle(zone, function_type_args.TypeAt(0));
+        AbstractType::Handle(zone, arguments->NativeTypeArgAt(0));
     if (function_type_arg.IsType() &&
         (function_type_arg.arguments() == TypeArguments::null())) {
       interface_cls = function_type_arg.type_class();
@@ -358,7 +357,7 @@
   return result.raw();
 }
 
-DEFINE_NATIVE_ENTRY(Internal_prependTypeArguments, 4) {
+DEFINE_NATIVE_ENTRY(Internal_prependTypeArguments, 0, 4) {
   const TypeArguments& function_type_arguments =
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
   const TypeArguments& parent_type_arguments =
@@ -373,7 +372,7 @@
 // closure.
 // Arg0: Closure object
 // Arg1: Type arguments to function
-DEFINE_NATIVE_ENTRY(Internal_boundsCheckForPartialInstantiation, 2) {
+DEFINE_NATIVE_ENTRY(Internal_boundsCheckForPartialInstantiation, 0, 2) {
   const Closure& closure =
       Closure::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Function& target = Function::Handle(zone, closure.function());
@@ -430,7 +429,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(InvocationMirror_unpackTypeArguments, 2) {
+DEFINE_NATIVE_ENTRY(InvocationMirror_unpackTypeArguments, 0, 2) {
   const TypeArguments& type_arguments =
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Smi& num_type_arguments =
@@ -453,7 +452,7 @@
   return type_list.raw();
 }
 
-DEFINE_NATIVE_ENTRY(NoSuchMethodError_existingMethodSignature, 3) {
+DEFINE_NATIVE_ENTRY(NoSuchMethodError_existingMethodSignature, 0, 3) {
   const Instance& receiver =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, method_name, arguments->NativeArgAt(1));
diff --git a/runtime/lib/profiler.cc b/runtime/lib/profiler.cc
index 009a2d3..3d6d84e 100644
--- a/runtime/lib/profiler.cc
+++ b/runtime/lib/profiler.cc
@@ -15,19 +15,19 @@
 
 // Native implementations of the profiler parts of the dart:developer library.
 
-DEFINE_NATIVE_ENTRY(UserTag_new, 2) {
+DEFINE_NATIVE_ENTRY(UserTag_new, 0, 2) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(String, tag_label, arguments->NativeArgAt(1));
   return UserTag::New(tag_label);
 }
 
-DEFINE_NATIVE_ENTRY(UserTag_label, 1) {
+DEFINE_NATIVE_ENTRY(UserTag_label, 0, 1) {
   const UserTag& self = UserTag::CheckedHandle(zone, arguments->NativeArgAt(0));
   return self.label();
 }
 
-DEFINE_NATIVE_ENTRY(UserTag_makeCurrent, 1) {
+DEFINE_NATIVE_ENTRY(UserTag_makeCurrent, 0, 1) {
   const UserTag& self = UserTag::CheckedHandle(zone, arguments->NativeArgAt(0));
   if (FLAG_trace_intrinsified_natives) {
     OS::PrintErr("UserTag_makeCurrent: %s\n", self.ToCString());
@@ -37,14 +37,14 @@
   return old.raw();
 }
 
-DEFINE_NATIVE_ENTRY(UserTag_defaultTag, 0) {
+DEFINE_NATIVE_ENTRY(UserTag_defaultTag, 0, 0) {
   if (FLAG_trace_intrinsified_natives) {
     OS::PrintErr("UserTag_defaultTag\n");
   }
   return isolate->default_tag();
 }
 
-DEFINE_NATIVE_ENTRY(Profiler_getCurrentTag, 0) {
+DEFINE_NATIVE_ENTRY(Profiler_getCurrentTag, 0, 0) {
   if (FLAG_trace_intrinsified_natives) {
     OS::PrintErr("Profiler_getCurrentTag\n");
   }
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index 8c25731..aa58c5f 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -14,7 +14,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(RegExp_factory, 4) {
+DEFINE_NATIVE_ENTRY(RegExp_factory, 0, 4) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(String, pattern, arguments->NativeArgAt(1));
@@ -35,25 +35,25 @@
   return RegExpEngine::CreateRegExp(thread, pattern, multi_line, ignore_case);
 }
 
-DEFINE_NATIVE_ENTRY(RegExp_getPattern, 1) {
+DEFINE_NATIVE_ENTRY(RegExp_getPattern, 0, 1) {
   const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
   return regexp.pattern();
 }
 
-DEFINE_NATIVE_ENTRY(RegExp_getIsMultiLine, 1) {
+DEFINE_NATIVE_ENTRY(RegExp_getIsMultiLine, 0, 1) {
   const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
   return Bool::Get(regexp.is_multi_line()).raw();
 }
 
-DEFINE_NATIVE_ENTRY(RegExp_getIsCaseSensitive, 1) {
+DEFINE_NATIVE_ENTRY(RegExp_getIsCaseSensitive, 0, 1) {
   const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
   return Bool::Get(!regexp.is_ignore_case()).raw();
 }
 
-DEFINE_NATIVE_ENTRY(RegExp_getGroupCount, 1) {
+DEFINE_NATIVE_ENTRY(RegExp_getGroupCount, 0, 1) {
   const RegExp& regexp = RegExp::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
   if (regexp.is_initialized()) {
@@ -87,12 +87,12 @@
                                                  /*sticky=*/sticky, zone);
 }
 
-DEFINE_NATIVE_ENTRY(RegExp_ExecuteMatch, 3) {
+DEFINE_NATIVE_ENTRY(RegExp_ExecuteMatch, 0, 3) {
   // This function is intrinsified. See Intrinsifier::RegExp_ExecuteMatch.
   return ExecuteMatch(zone, arguments, /*sticky=*/false);
 }
 
-DEFINE_NATIVE_ENTRY(RegExp_ExecuteMatchSticky, 3) {
+DEFINE_NATIVE_ENTRY(RegExp_ExecuteMatchSticky, 0, 3) {
   // This function is intrinsified. See Intrinsifier::RegExp_ExecuteMatchSticky.
   return ExecuteMatch(zone, arguments, /*sticky=*/true);
 }
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 41f0602..356853b 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -18,7 +18,7 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_fromDoubles, 5) {
+DEFINE_NATIVE_ENTRY(Float32x4_fromDoubles, 0, 5) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(Double, x, arguments->NativeArgAt(1));
@@ -32,7 +32,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_splat, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_splat, 0, 2) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(Double, v, arguments->NativeArgAt(1));
@@ -40,25 +40,25 @@
   return Float32x4::New(_v, _v, _v, _v);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_zero, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_zero, 0, 1) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   return Float32x4::New(0.0f, 0.0f, 0.0f, 0.0f);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_fromInt32x4Bits, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_fromInt32x4Bits, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, v, arguments->NativeArgAt(1));
   return Float32x4::New(v.value());
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_fromFloat64x2, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_fromFloat64x2, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, v, arguments->NativeArgAt(1));
   float _x = static_cast<float>(v.x());
   float _y = static_cast<float>(v.y());
   return Float32x4::New(_x, _y, 0.0f, 0.0f);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_add, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_add, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
   float _x = self.x() + other.x();
@@ -68,7 +68,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_negate, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_negate, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   float _x = -self.x();
   float _y = -self.y();
@@ -77,7 +77,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_sub, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_sub, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
   float _x = self.x() - other.x();
@@ -87,7 +87,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_mul, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_mul, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
   float _x = self.x() * other.x();
@@ -97,7 +97,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_div, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_div, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
   float _x = self.x() / other.x();
@@ -107,7 +107,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_cmplt, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_cmplt, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, b, arguments->NativeArgAt(1));
   uint32_t _x = a.x() < b.x() ? 0xFFFFFFFF : 0x0;
@@ -117,7 +117,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_cmplte, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_cmplte, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, b, arguments->NativeArgAt(1));
   uint32_t _x = a.x() <= b.x() ? 0xFFFFFFFF : 0x0;
@@ -127,7 +127,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_cmpgt, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_cmpgt, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, b, arguments->NativeArgAt(1));
   uint32_t _x = a.x() > b.x() ? 0xFFFFFFFF : 0x0;
@@ -137,7 +137,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_cmpgte, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_cmpgte, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, b, arguments->NativeArgAt(1));
   uint32_t _x = a.x() >= b.x() ? 0xFFFFFFFF : 0x0;
@@ -147,7 +147,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_cmpequal, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_cmpequal, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, b, arguments->NativeArgAt(1));
   uint32_t _x = a.x() == b.x() ? 0xFFFFFFFF : 0x0;
@@ -157,7 +157,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_cmpnequal, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_cmpnequal, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, b, arguments->NativeArgAt(1));
   uint32_t _x = a.x() != b.x() ? 0xFFFFFFFF : 0x0;
@@ -167,7 +167,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_scale, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_scale, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, scale, arguments->NativeArgAt(1));
   float _s = static_cast<float>(scale.value());
@@ -178,7 +178,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_abs, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_abs, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   float _x = fabsf(self.x());
   float _y = fabsf(self.y());
@@ -187,7 +187,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_clamp, 3) {
+DEFINE_NATIVE_ENTRY(Float32x4_clamp, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, lo, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, hi, arguments->NativeArgAt(2));
@@ -204,31 +204,31 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_getX, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_getX, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   double value = static_cast<double>(self.x());
   return Double::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_getY, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_getY, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   double value = static_cast<double>(self.y());
   return Double::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_getZ, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_getZ, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   double value = static_cast<double>(self.z());
   return Double::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_getW, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_getW, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   double value = static_cast<double>(self.w());
   return Double::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_getSignMask, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_getSignMask, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   uint32_t mx = (bit_cast<uint32_t>(self.x()) & 0x80000000) >> 31;
   uint32_t my = (bit_cast<uint32_t>(self.y()) & 0x80000000) >> 31;
@@ -238,7 +238,7 @@
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getSignMask, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getSignMask, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   uint32_t mx = (self.x() & 0x80000000) >> 31;
   uint32_t my = (self.y() & 0x80000000) >> 31;
@@ -248,7 +248,7 @@
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_shuffle, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_shuffle, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
   int64_t m = mask.AsInt64Value();
@@ -261,7 +261,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_shuffleMix, 3) {
+DEFINE_NATIVE_ENTRY(Float32x4_shuffleMix, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
@@ -276,7 +276,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_setX, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_setX, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, x, arguments->NativeArgAt(1));
   float _x = static_cast<float>(x.value());
@@ -286,7 +286,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_setY, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_setY, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, y, arguments->NativeArgAt(1));
   float _x = self.x();
@@ -296,7 +296,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_setZ, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_setZ, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, z, arguments->NativeArgAt(1));
   float _x = self.x();
@@ -306,7 +306,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_setW, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_setW, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, w, arguments->NativeArgAt(1));
   float _x = self.x();
@@ -316,7 +316,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_min, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_min, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
   float _x = self.x() < other.x() ? self.x() : other.x();
@@ -326,7 +326,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_max, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_max, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
   float _x = self.x() > other.x() ? self.x() : other.x();
@@ -336,7 +336,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_sqrt, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_sqrt, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   float _x = sqrtf(self.x());
   float _y = sqrtf(self.y());
@@ -345,7 +345,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_reciprocal, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_reciprocal, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   float _x = 1.0f / self.x();
   float _y = 1.0f / self.y();
@@ -354,7 +354,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Float32x4_reciprocalSqrt, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_reciprocalSqrt, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   float _x = sqrtf(1.0f / self.x());
   float _y = sqrtf(1.0f / self.y());
@@ -363,7 +363,7 @@
   return Float32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_fromInts, 5) {
+DEFINE_NATIVE_ENTRY(Int32x4_fromInts, 0, 5) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, x, arguments->NativeArgAt(1));
@@ -377,7 +377,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_fromBools, 5) {
+DEFINE_NATIVE_ENTRY(Int32x4_fromBools, 0, 5) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, x, arguments->NativeArgAt(1));
@@ -391,12 +391,12 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_fromFloat32x4Bits, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_fromFloat32x4Bits, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, v, arguments->NativeArgAt(1));
   return Int32x4::New(v.value());
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_or, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_or, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, other, arguments->NativeArgAt(1));
   int32_t _x = self.x() | other.x();
@@ -406,7 +406,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_and, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_and, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, other, arguments->NativeArgAt(1));
   int32_t _x = self.x() & other.x();
@@ -416,7 +416,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_xor, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_xor, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, other, arguments->NativeArgAt(1));
   int32_t _x = self.x() ^ other.x();
@@ -426,7 +426,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_add, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_add, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, other, arguments->NativeArgAt(1));
   int32_t _x = self.x() + other.x();
@@ -436,7 +436,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_sub, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_sub, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, other, arguments->NativeArgAt(1));
   int32_t _x = self.x() - other.x();
@@ -446,31 +446,31 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getX, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getX, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.x();
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getY, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getY, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.y();
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getZ, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getZ, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.z();
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getW, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getW, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.w();
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_shuffle, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_shuffle, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
   int64_t m = mask.AsInt64Value();
@@ -483,7 +483,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_shuffleMix, 3) {
+DEFINE_NATIVE_ENTRY(Int32x4_shuffleMix, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, zw, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
@@ -498,7 +498,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setX, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setX, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, x, arguments->NativeArgAt(1));
   int32_t _x = static_cast<int32_t>(x.AsInt64Value() & 0xFFFFFFFF);
@@ -508,7 +508,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setY, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setY, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, y, arguments->NativeArgAt(1));
   int32_t _x = self.x();
@@ -518,7 +518,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setZ, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setZ, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, z, arguments->NativeArgAt(1));
   int32_t _x = self.x();
@@ -528,7 +528,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setW, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setW, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, w, arguments->NativeArgAt(1));
   int32_t _x = self.x();
@@ -538,31 +538,31 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getFlagX, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getFlagX, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.x();
   return Bool::Get(value != 0).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getFlagY, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getFlagY, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.y();
   return Bool::Get(value != 0).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getFlagZ, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getFlagZ, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.z();
   return Bool::Get(value != 0).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_getFlagW, 1) {
+DEFINE_NATIVE_ENTRY(Int32x4_getFlagW, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   int32_t value = self.w();
   return Bool::Get(value != 0).raw();
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setFlagX, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setFlagX, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, flagX, arguments->NativeArgAt(1));
   int32_t _x = self.x();
@@ -573,7 +573,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setFlagY, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setFlagY, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, flagY, arguments->NativeArgAt(1));
   int32_t _x = self.x();
@@ -584,7 +584,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setFlagZ, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setFlagZ, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, flagZ, arguments->NativeArgAt(1));
   int32_t _x = self.x();
@@ -595,7 +595,7 @@
   return Int32x4::New(_x, _y, _z, _w);
 }
 
-DEFINE_NATIVE_ENTRY(Int32x4_setFlagW, 2) {
+DEFINE_NATIVE_ENTRY(Int32x4_setFlagW, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, flagW, arguments->NativeArgAt(1));
   int32_t _x = self.x();
@@ -615,7 +615,7 @@
   float32_int32(int32_t v) { u = v; }
 };
 
-DEFINE_NATIVE_ENTRY(Int32x4_select, 3) {
+DEFINE_NATIVE_ENTRY(Int32x4_select, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Int32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, tv, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, fv, arguments->NativeArgAt(2));
@@ -640,7 +640,7 @@
   return Float32x4::New(tempX.f, tempY.f, tempZ.f, tempW.f);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_fromDoubles, 3) {
+DEFINE_NATIVE_ENTRY(Float64x2_fromDoubles, 0, 3) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(Double, x, arguments->NativeArgAt(1));
@@ -648,20 +648,20 @@
   return Float64x2::New(x.value(), y.value());
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_splat, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_splat, 0, 2) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(Double, v, arguments->NativeArgAt(1));
   return Float64x2::New(v.value(), v.value());
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_zero, 1) {
+DEFINE_NATIVE_ENTRY(Float64x2_zero, 0, 1) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   return Float64x2::New(0.0, 0.0);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_fromFloat32x4, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_fromFloat32x4, 0, 2) {
   ASSERT(
       TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, v, arguments->NativeArgAt(1));
@@ -670,7 +670,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_add, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_add, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, other, arguments->NativeArgAt(1));
   double _x = self.x() + other.x();
@@ -678,14 +678,14 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_negate, 1) {
+DEFINE_NATIVE_ENTRY(Float64x2_negate, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   double _x = -self.x();
   double _y = -self.y();
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_sub, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_sub, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, other, arguments->NativeArgAt(1));
   double _x = self.x() - other.x();
@@ -693,7 +693,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_mul, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_mul, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, other, arguments->NativeArgAt(1));
   double _x = self.x() * other.x();
@@ -701,7 +701,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_div, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_div, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, other, arguments->NativeArgAt(1));
   double _x = self.x() / other.x();
@@ -709,7 +709,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_scale, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_scale, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, scale, arguments->NativeArgAt(1));
   double _s = scale.value();
@@ -718,14 +718,14 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_abs, 1) {
+DEFINE_NATIVE_ENTRY(Float64x2_abs, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   double _x = fabs(self.x());
   double _y = fabs(self.y());
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_clamp, 3) {
+DEFINE_NATIVE_ENTRY(Float64x2_clamp, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, lo, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, hi, arguments->NativeArgAt(2));
@@ -738,17 +738,17 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_getX, 1) {
+DEFINE_NATIVE_ENTRY(Float64x2_getX, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   return Double::New(self.x());
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_getY, 1) {
+DEFINE_NATIVE_ENTRY(Float64x2_getY, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   return Double::New(self.y());
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_getSignMask, 1) {
+DEFINE_NATIVE_ENTRY(Float64x2_getSignMask, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   uint32_t mx = (bit_cast<uint64_t>(self.x()) & 0x8000000000000000LL) >> 63;
   uint32_t my = (bit_cast<uint64_t>(self.y()) & 0x8000000000000000LL) >> 63;
@@ -756,7 +756,7 @@
   return Integer::New(value);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_setX, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_setX, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, x, arguments->NativeArgAt(1));
   double _x = x.value();
@@ -764,7 +764,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_setY, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_setY, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Double, y, arguments->NativeArgAt(1));
   double _x = self.x();
@@ -772,7 +772,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_min, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_min, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, other, arguments->NativeArgAt(1));
   double _x = self.x() < other.x() ? self.x() : other.x();
@@ -780,7 +780,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_max, 2) {
+DEFINE_NATIVE_ENTRY(Float64x2_max, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, other, arguments->NativeArgAt(1));
   double _x = self.x() > other.x() ? self.x() : other.x();
@@ -788,7 +788,7 @@
   return Float64x2::New(_x, _y);
 }
 
-DEFINE_NATIVE_ENTRY(Float64x2_sqrt, 1) {
+DEFINE_NATIVE_ENTRY(Float64x2_sqrt, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float64x2, self, arguments->NativeArgAt(0));
   double _x = sqrt(self.x());
   double _y = sqrt(self.y());
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index c84b78b..0a412f2 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -102,11 +102,11 @@
   return CurrentStackTrace(thread, false, 0);
 }
 
-DEFINE_NATIVE_ENTRY(StackTrace_current, 0) {
+DEFINE_NATIVE_ENTRY(StackTrace_current, 0, 0) {
   return CurrentStackTrace(thread, false);
 }
 
-DEFINE_NATIVE_ENTRY(StackTrace_asyncStackTraceHelper, 1) {
+DEFINE_NATIVE_ENTRY(StackTrace_asyncStackTraceHelper, 0, 1) {
   if (!FLAG_causal_async_stacks) {
     return Object::null();
   }
@@ -120,12 +120,12 @@
   return CurrentStackTrace(thread, true);
 }
 
-DEFINE_NATIVE_ENTRY(StackTrace_clearAsyncThreadStackTrace, 0) {
+DEFINE_NATIVE_ENTRY(StackTrace_clearAsyncThreadStackTrace, 0, 0) {
   thread->clear_async_stack_trace();
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(StackTrace_setAsyncThreadStackTrace, 1) {
+DEFINE_NATIVE_ENTRY(StackTrace_setAsyncThreadStackTrace, 0, 1) {
   if (!FLAG_causal_async_stacks) {
     return Object::null();
   }
diff --git a/runtime/lib/stopwatch.cc b/runtime/lib/stopwatch.cc
index 8adb201..d569cb6 100644
--- a/runtime/lib/stopwatch.cc
+++ b/runtime/lib/stopwatch.cc
@@ -9,11 +9,11 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(Stopwatch_now, 0) {
+DEFINE_NATIVE_ENTRY(Stopwatch_now, 0, 0) {
   return Integer::New(OS::GetCurrentMonotonicTicks());
 }
 
-DEFINE_NATIVE_ENTRY(Stopwatch_frequency, 0) {
+DEFINE_NATIVE_ENTRY(Stopwatch_frequency, 0, 0) {
   return Integer::New(OS::GetCurrentMonotonicFrequency());
 }
 
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 2aa299d..5592f20 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -16,7 +16,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(String_fromEnvironment, 3) {
+DEFINE_NATIVE_ENTRY(String_fromEnvironment, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
   GET_NATIVE_ARGUMENT(String, default_value, arguments->NativeArgAt(2));
   // Call the embedder to supply us with the environment.
@@ -28,7 +28,7 @@
   return default_value.raw();
 }
 
-DEFINE_NATIVE_ENTRY(StringBase_createFromCodePoints, 3) {
+DEFINE_NATIVE_ENTRY(StringBase_createFromCodePoints, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, list, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -89,7 +89,7 @@
   return TwoByteString::New(utf16_len, utf32_array, array_len, Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(StringBase_substringUnchecked, 3) {
+DEFINE_NATIVE_ENTRY(StringBase_substringUnchecked, 0, 3) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
@@ -160,7 +160,7 @@
   return true;
 }
 
-DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 4) {
+DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 0, 4) {
   const String& base = String::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(GrowableObjectArray, matches_growable,
                                arguments->NativeArgAt(1));
@@ -245,7 +245,7 @@
   return result.raw();
 }
 
-DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 3) {
+DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 0, 3) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(receiver.IsOneByteString());
@@ -258,7 +258,7 @@
 }
 
 // This is high-performance code.
-DEFINE_NATIVE_ENTRY(OneByteString_splitWithCharCode, 2) {
+DEFINE_NATIVE_ENTRY(OneByteString_splitWithCharCode, 0, 2) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(receiver.IsOneByteString());
@@ -286,12 +286,12 @@
   return result.raw();
 }
 
-DEFINE_NATIVE_ENTRY(OneByteString_allocate, 1) {
+DEFINE_NATIVE_ENTRY(OneByteString_allocate, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(0));
   return OneByteString::New(length_obj.Value(), Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(OneByteString_allocateFromOneByteList, 3) {
+DEFINE_NATIVE_ENTRY(OneByteString_allocateFromOneByteList, 0, 3) {
   Instance& list = Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -377,7 +377,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(OneByteString_setAt, 3) {
+DEFINE_NATIVE_ENTRY(OneByteString_setAt, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, receiver, arguments->NativeArgAt(0));
   ASSERT(receiver.IsOneByteString());
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index_obj, arguments->NativeArgAt(1));
@@ -387,7 +387,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(TwoByteString_allocateFromTwoByteList, 3) {
+DEFINE_NATIVE_ENTRY(TwoByteString_allocateFromTwoByteList, 0, 3) {
   Instance& list = Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -472,7 +472,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(String_getHashCode, 1) {
+DEFINE_NATIVE_ENTRY(String_getHashCode, 0, 1) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   intptr_t hash_val = receiver.Hash();
@@ -481,7 +481,7 @@
   return Smi::New(hash_val);
 }
 
-DEFINE_NATIVE_ENTRY(String_getLength, 1) {
+DEFINE_NATIVE_ENTRY(String_getLength, 0, 1) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Smi::New(receiver.Length());
@@ -500,7 +500,7 @@
   return 0;
 }
 
-DEFINE_NATIVE_ENTRY(String_charAt, 2) {
+DEFINE_NATIVE_ENTRY(String_charAt, 0, 2) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
@@ -509,7 +509,7 @@
 }
 
 // Returns the 16-bit UTF-16 code unit at the given index.
-DEFINE_NATIVE_ENTRY(String_codeUnitAt, 2) {
+DEFINE_NATIVE_ENTRY(String_codeUnitAt, 0, 2) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
@@ -517,28 +517,28 @@
   return Smi::New(static_cast<intptr_t>(value));
 }
 
-DEFINE_NATIVE_ENTRY(String_concat, 2) {
+DEFINE_NATIVE_ENTRY(String_concat, 0, 2) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, b, arguments->NativeArgAt(1));
   return String::Concat(receiver, b);
 }
 
-DEFINE_NATIVE_ENTRY(String_toLowerCase, 1) {
+DEFINE_NATIVE_ENTRY(String_toLowerCase, 0, 1) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!receiver.IsNull());
   return String::ToLowerCase(receiver);
 }
 
-DEFINE_NATIVE_ENTRY(String_toUpperCase, 1) {
+DEFINE_NATIVE_ENTRY(String_toUpperCase, 0, 1) {
   const String& receiver =
       String::CheckedHandle(zone, arguments->NativeArgAt(0));
   ASSERT(!receiver.IsNull());
   return String::ToUpperCase(receiver);
 }
 
-DEFINE_NATIVE_ENTRY(String_concatRange, 3) {
+DEFINE_NATIVE_ENTRY(String_concatRange, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, argument, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, end, arguments->NativeArgAt(2));
@@ -573,7 +573,7 @@
   return String::ConcatAllRange(strings, start_ix, end_ix, Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(StringBuffer_createStringFromUint16Array, 3) {
+DEFINE_NATIVE_ENTRY(StringBuffer_createStringFromUint16Array, 0, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(TypedData, codeUnits, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, isLatin1, arguments->NativeArgAt(2));
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 5fb597bb..3e68d99 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -15,7 +15,7 @@
 
 // Native implementations for the dart:developer library.
 
-DEFINE_NATIVE_ENTRY(Timeline_isDartStreamEnabled, 0) {
+DEFINE_NATIVE_ENTRY(Timeline_isDartStreamEnabled, 0, 0) {
 #ifndef PRODUCT
   if (!FLAG_support_timeline) {
     return Bool::False().raw();
@@ -27,7 +27,7 @@
   return Bool::False().raw();
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_getNextAsyncId, 0) {
+DEFINE_NATIVE_ENTRY(Timeline_getNextAsyncId, 0, 0) {
   if (!FLAG_support_timeline) {
     return Integer::New(0);
   }
@@ -38,15 +38,15 @@
   return Integer::New(recorder->GetNextAsyncId());
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) {
+DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0, 0) {
   return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_getThreadCpuClock, 0) {
+DEFINE_NATIVE_ENTRY(Timeline_getThreadCpuClock, 0, 0) {
   return Integer::New(OS::GetCurrentThreadCPUMicros(), Heap::kNew);
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 6) {
+DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 6) {
 #ifndef PRODUCT
   if (!FLAG_support_timeline) {
     return Object::null();
@@ -76,7 +76,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_reportCompleteEvent, 5) {
+DEFINE_NATIVE_ENTRY(Timeline_reportCompleteEvent, 0, 5) {
 #ifndef PRODUCT
   if (!FLAG_support_timeline) {
     return Object::null();
@@ -105,7 +105,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_reportFlowEvent, 7) {
+DEFINE_NATIVE_ENTRY(Timeline_reportFlowEvent, 0, 7) {
 #ifndef PRODUCT
   if (!FLAG_support_timeline) {
     return Object::null();
@@ -137,7 +137,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 4) {
+DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 0, 4) {
 #ifndef PRODUCT
   if (!FLAG_support_timeline) {
     return Object::null();
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index 36e480a..4a373fc 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -37,7 +37,7 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(TypedData_length, 1) {
+DEFINE_NATIVE_ENTRY(TypedData_length, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
   if (instance.IsTypedData()) {
     const TypedData& array = TypedData::Cast(instance);
@@ -105,7 +105,7 @@
   }
 }
 
-DEFINE_NATIVE_ENTRY(TypedData_setRange, 7) {
+DEFINE_NATIVE_ENTRY(TypedData_setRange, 0, 7) {
   const Instance& dst =
       Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   const Smi& dst_start = Smi::CheckedHandle(zone, arguments->NativeArgAt(1));
@@ -158,7 +158,7 @@
 //
 // Argument 0 is type arguments and is ignored.
 #define TYPED_DATA_NEW(name)                                                   \
-  DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 2) {                             \
+  DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 0, 2) {                          \
     GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));      \
     intptr_t cid = kTypedData##name##Cid;                                      \
     intptr_t len = length.Value();                                             \
@@ -172,7 +172,7 @@
 CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE)
 
 #define TYPED_DATA_GETTER(getter, object, ctor, access_size)                   \
-  DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) {                                 \
+  DEFINE_NATIVE_ENTRY(TypedData_##getter, 0, 2) {                              \
     GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance,                           \
                                  arguments->NativeArgAt(0));                   \
     GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes,                           \
@@ -197,7 +197,7 @@
 
 #define TYPED_DATA_SETTER(setter, object, get_object_value, access_size,       \
                           access_type)                                         \
-  DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) {                                 \
+  DEFINE_NATIVE_ENTRY(TypedData_##setter, 0, 3) {                              \
     GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance,                           \
                                  arguments->NativeArgAt(0));                   \
     GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes,                           \
diff --git a/runtime/lib/uri.cc b/runtime/lib/uri.cc
index 2f5dba1..4f1ef81 100644
--- a/runtime/lib/uri.cc
+++ b/runtime/lib/uri.cc
@@ -8,7 +8,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(Uri_isWindowsPlatform, 0) {
+DEFINE_NATIVE_ENTRY(Uri_isWindowsPlatform, 0, 0) {
 #if defined(HOST_OS_WINDOWS)
   return Bool::True().raw();
 #else
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index aa87514..deec036 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -78,7 +78,7 @@
 };
 #endif  // !PRODUCT
 
-DEFINE_NATIVE_ENTRY(VMService_SendIsolateServiceMessage, 2) {
+DEFINE_NATIVE_ENTRY(VMService_SendIsolateServiceMessage, 0, 2) {
 #ifndef PRODUCT
   if (!FLAG_support_service) {
     return Bool::Get(false).raw();
@@ -101,7 +101,7 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(VMService_SendRootServiceMessage, 1) {
+DEFINE_NATIVE_ENTRY(VMService_SendRootServiceMessage, 0, 1) {
 #ifndef PRODUCT
   GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0));
   if (FLAG_support_service) {
@@ -111,7 +111,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_SendObjectRootServiceMessage, 1) {
+DEFINE_NATIVE_ENTRY(VMService_SendObjectRootServiceMessage, 0, 1) {
 #ifndef PRODUCT
   GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0));
   if (FLAG_support_service) {
@@ -121,7 +121,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_OnStart, 0) {
+DEFINE_NATIVE_ENTRY(VMService_OnStart, 0, 0) {
 #ifndef PRODUCT
   if (FLAG_trace_service) {
     OS::PrintErr("vm-service: Booting dart:vmservice library.\n");
@@ -141,7 +141,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_OnExit, 0) {
+DEFINE_NATIVE_ENTRY(VMService_OnExit, 0, 0) {
 #ifndef PRODUCT
   if (FLAG_trace_service) {
     OS::PrintErr("vm-service: processed exit message.\n");
@@ -153,7 +153,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_OnServerAddressChange, 1) {
+DEFINE_NATIVE_ENTRY(VMService_OnServerAddressChange, 0, 1) {
 #ifndef PRODUCT
   if (!FLAG_support_service) {
     return Object::null();
@@ -168,7 +168,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_ListenStream, 1) {
+DEFINE_NATIVE_ENTRY(VMService_ListenStream, 0, 1) {
 #ifndef PRODUCT
   GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
   bool result = false;
@@ -181,7 +181,7 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(VMService_CancelStream, 1) {
+DEFINE_NATIVE_ENTRY(VMService_CancelStream, 0, 1) {
 #ifndef PRODUCT
   GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
   if (FLAG_support_service) {
@@ -191,7 +191,7 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0) {
+DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0, 0) {
 #ifndef PRODUCT
   if (!FLAG_support_service) {
     return Object::null();
@@ -381,7 +381,7 @@
 
 #endif
 
-DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 1) {
+DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 0, 1) {
 #ifndef PRODUCT
   if (!FLAG_support_service) {
     return Object::null();
@@ -439,7 +439,7 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(VMService_spawnUriNotify, 2) {
+DEFINE_NATIVE_ENTRY(VMService_spawnUriNotify, 0, 2) {
 #ifndef PRODUCT
   if (!FLAG_support_service) {
     return Object::null();
diff --git a/runtime/lib/weak_property.cc b/runtime/lib/weak_property.cc
index 069f77d..8715b6d 100644
--- a/runtime/lib/weak_property.cc
+++ b/runtime/lib/weak_property.cc
@@ -10,7 +10,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(WeakProperty_new, 2) {
+DEFINE_NATIVE_ENTRY(WeakProperty_new, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, key, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(1));
   const WeakProperty& weak_property = WeakProperty::Handle(WeakProperty::New());
@@ -19,19 +19,19 @@
   return weak_property.raw();
 }
 
-DEFINE_NATIVE_ENTRY(WeakProperty_getKey, 1) {
+DEFINE_NATIVE_ENTRY(WeakProperty_getKey, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
                                arguments->NativeArgAt(0));
   return weak_property.key();
 }
 
-DEFINE_NATIVE_ENTRY(WeakProperty_getValue, 1) {
+DEFINE_NATIVE_ENTRY(WeakProperty_getValue, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
                                arguments->NativeArgAt(0));
   return weak_property.value();
 }
 
-DEFINE_NATIVE_ENTRY(WeakProperty_setValue, 2) {
+DEFINE_NATIVE_ENTRY(WeakProperty_setValue, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(WeakProperty, weak_property,
                                arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(1));
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 7c2a30a..251740e 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -131,11 +131,33 @@
     return ArgAt(actual_index);
   }
 
-  RawTypeArguments* NativeTypeArgs() {
+  RawTypeArguments* NativeTypeArgs() const {
     ASSERT(ToGenericFunction());
     return TypeArguments::RawCast(ArgAt(0));
   }
 
+  int NativeTypeArgCount() const {
+    if (ToGenericFunction()) {
+      TypeArguments& type_args = TypeArguments::Handle(NativeTypeArgs());
+      if (type_args.IsNull()) {
+        // null vector represents infinite list of dynamics
+        return INT_MAX;
+      }
+      return type_args.Length();
+    }
+    return 0;
+  }
+
+  RawAbstractType* NativeTypeArgAt(int index) const {
+    ASSERT((index >= 0) && (index < NativeTypeArgCount()));
+    TypeArguments& type_args = TypeArguments::Handle(NativeTypeArgs());
+    if (type_args.IsNull()) {
+      // null vector represents infinite list of dynamics
+      return Type::dynamic_type().raw();
+    }
+    return TypeArguments::Handle(NativeTypeArgs()).TypeAt(index);
+  }
+
   void SetReturn(const Object& value) const { *retval_ = value.raw(); }
 
   RawObject* ReturnValue() const {
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index 0d7a930..b98e2f4 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -61,7 +61,7 @@
 #define SET_NATIVE_RETVAL(arguments, value) arguments->SetReturnUnsafe(value);
 #endif
 
-#define DEFINE_NATIVE_ENTRY(name, argument_count)                              \
+#define DEFINE_NATIVE_ENTRY(name, type_argument_count, argument_count)         \
   static RawObject* DN_Helper##name(Isolate* isolate, Thread* thread,          \
                                     Zone* zone, NativeArguments* arguments);   \
   void NATIVE_ENTRY_FUNCTION(name)(Dart_NativeArguments args) {                \
@@ -71,6 +71,8 @@
     /* Tell MemorySanitizer 'arguments' is initialized by generated code. */   \
     MSAN_UNPOISON(arguments, sizeof(*arguments));                              \
     ASSERT(arguments->NativeArgCount() == argument_count);                     \
+    /* Note: a longer type arguments vector may be passed */                   \
+    ASSERT(arguments->NativeTypeArgCount() >= type_argument_count);            \
     TRACE_NATIVE_CALL("%s", "" #name);                                         \
     {                                                                          \
       Thread* thread = arguments->thread();                                    \