@@ -4124,6 +4124,85 @@ DART_EXPORT Dart_Handle Dart_New(Dart_Handle type,
41244124 return Api::NewHandle (T, new_object.raw ());
41254125}
41264126
4127+ static RawInstance* AllocateObject (Thread* thread, const Class& cls) {
4128+ if (!cls.is_fields_marked_nullable ()) {
4129+ // Mark all fields as nullable.
4130+ Zone* zone = thread->zone ();
4131+ Class& iterate_cls = Class::Handle (zone, cls.raw ());
4132+ Field& field = Field::Handle (zone);
4133+ Array& fields = Array::Handle (zone);
4134+ while (!iterate_cls.IsNull ()) {
4135+ ASSERT (iterate_cls.is_finalized ());
4136+ iterate_cls.set_is_fields_marked_nullable ();
4137+ fields = iterate_cls.fields ();
4138+ iterate_cls = iterate_cls.SuperClass ();
4139+ for (int field_num = 0 ; field_num < fields.Length (); field_num++) {
4140+ field ^= fields.At (field_num);
4141+ if (field.is_static ()) {
4142+ continue ;
4143+ }
4144+ field.RecordStore (Object::null_object ());
4145+ }
4146+ }
4147+ }
4148+
4149+ // Allocate an object for the given class.
4150+ return Instance::New (cls);
4151+ }
4152+
4153+ DART_EXPORT Dart_Handle Dart_Allocate (Dart_Handle type) {
4154+ DARTSCOPE (Thread::Current ());
4155+ CHECK_CALLBACK_STATE (T);
4156+
4157+ const Type& type_obj = Api::UnwrapTypeHandle (Z, type);
4158+ // Get the class to instantiate.
4159+ if (type_obj.IsNull ()) {
4160+ RETURN_TYPE_ERROR (Z, type, Type);
4161+ }
4162+ const Class& cls = Class::Handle (Z, type_obj.type_class ());
4163+ CHECK_ERROR_HANDLE (cls.VerifyEntryPoint ());
4164+ #if defined(DEBUG)
4165+ if (!cls.is_allocated () && (Dart::vm_snapshot_kind () == Snapshot::kFullAOT )) {
4166+ return Api::NewError (" Precompilation dropped '%s'" , cls.ToCString ());
4167+ }
4168+ #endif
4169+ CHECK_ERROR_HANDLE (cls.EnsureIsFinalized (T));
4170+ return Api::NewHandle (T, AllocateObject (T, cls));
4171+ }
4172+
4173+ DART_EXPORT Dart_Handle
4174+ Dart_AllocateWithNativeFields (Dart_Handle type,
4175+ intptr_t num_native_fields,
4176+ const intptr_t * native_fields) {
4177+ DARTSCOPE (Thread::Current ());
4178+ CHECK_CALLBACK_STATE (T);
4179+
4180+ const Type& type_obj = Api::UnwrapTypeHandle (Z, type);
4181+ // Get the class to instantiate.
4182+ if (type_obj.IsNull ()) {
4183+ RETURN_TYPE_ERROR (Z, type, Type);
4184+ }
4185+ if (native_fields == NULL ) {
4186+ RETURN_NULL_ERROR (native_fields);
4187+ }
4188+ const Class& cls = Class::Handle (Z, type_obj.type_class ());
4189+ CHECK_ERROR_HANDLE (cls.VerifyEntryPoint ());
4190+ #if defined(DEBUG)
4191+ if (!cls.is_allocated () && (Dart::vm_snapshot_kind () == Snapshot::kFullAOT )) {
4192+ return Api::NewError (" Precompilation dropped '%s'" , cls.ToCString ());
4193+ }
4194+ #endif
4195+ CHECK_ERROR_HANDLE (cls.EnsureIsFinalized (T));
4196+ if (num_native_fields != cls.num_native_fields ()) {
4197+ return Api::NewError (
4198+ " %s: invalid number of native fields %" Pd " passed in, expected %d" ,
4199+ CURRENT_FUNC , num_native_fields, cls.num_native_fields ());
4200+ }
4201+ const Instance& instance = Instance::Handle (Z, AllocateObject (T, cls));
4202+ instance.SetNativeFields (num_native_fields, native_fields);
4203+ return Api::NewHandle (T, instance.raw ());
4204+ }
4205+
41274206static Dart_Handle SetupArguments (Thread* thread,
41284207 int num_args,
41294208 Dart_Handle* arguments,
@@ -4150,6 +4229,83 @@ static Dart_Handle SetupArguments(Thread* thread,
41504229 return Api::Success ();
41514230}
41524231
4232+ DART_EXPORT Dart_Handle Dart_InvokeConstructor (Dart_Handle object,
4233+ Dart_Handle name,
4234+ int number_of_arguments,
4235+ Dart_Handle* arguments) {
4236+ DARTSCOPE (Thread::Current ());
4237+ API_TIMELINE_DURATION (T);
4238+ CHECK_CALLBACK_STATE (T);
4239+
4240+ if (number_of_arguments < 0 ) {
4241+ return Api::NewError (
4242+ " %s expects argument 'number_of_arguments' to be non-negative." ,
4243+ CURRENT_FUNC );
4244+ }
4245+ const Instance& instance = Api::UnwrapInstanceHandle (Z, object);
4246+ if (instance.IsNull ()) {
4247+ RETURN_TYPE_ERROR (Z, object, Instance);
4248+ }
4249+
4250+ // Since we have allocated an object it would mean that the type
4251+ // is finalized.
4252+ // TODO(asiva): How do we ensure that a constructor is not called more than
4253+ // once for the same object.
4254+
4255+ // Construct name of the constructor to invoke.
4256+ const String& constructor_name = Api::UnwrapStringHandle (Z, name);
4257+ const AbstractType& type_obj =
4258+ AbstractType::Handle (Z, instance.GetType (Heap::kNew ));
4259+ const Class& cls = Class::Handle (Z, type_obj.type_class ());
4260+ const String& class_name = String::Handle (Z, cls.Name ());
4261+ const Array& strings = Array::Handle (Z, Array::New (3 ));
4262+ strings.SetAt (0 , class_name);
4263+ strings.SetAt (1 , Symbols::Dot ());
4264+ if (constructor_name.IsNull ()) {
4265+ strings.SetAt (2 , Symbols::Empty ());
4266+ } else {
4267+ strings.SetAt (2 , constructor_name);
4268+ }
4269+ const String& dot_name = String::Handle (Z, String::ConcatAll (strings));
4270+ const TypeArguments& type_arguments =
4271+ TypeArguments::Handle (Z, type_obj.arguments ());
4272+ const Function& constructor =
4273+ Function::Handle (Z, cls.LookupFunctionAllowPrivate (dot_name));
4274+ const int kTypeArgsLen = 0 ;
4275+ const int extra_args = 1 ;
4276+ if (!constructor.IsNull () && constructor.IsGenerativeConstructor () &&
4277+ constructor.AreValidArgumentCounts (
4278+ kTypeArgsLen , number_of_arguments + extra_args, 0 , NULL )) {
4279+ CHECK_ERROR_HANDLE (constructor.VerifyCallEntryPoint ());
4280+ // Create the argument list.
4281+ // Constructors get the uninitialized object.
4282+ if (!type_arguments.IsNull ()) {
4283+ // The type arguments will be null if the class has no type
4284+ // parameters, in which case the following call would fail
4285+ // because there is no slot reserved in the object for the
4286+ // type vector.
4287+ instance.SetTypeArguments (type_arguments);
4288+ }
4289+ Dart_Handle result;
4290+ Array& args = Array::Handle (Z);
4291+ result =
4292+ SetupArguments (T, number_of_arguments, arguments, extra_args, &args);
4293+ if (!Api::IsError (result)) {
4294+ args.SetAt (0 , instance);
4295+ const Object& retval =
4296+ Object::Handle (Z, DartEntry::InvokeFunction (constructor, args));
4297+ if (retval.IsError ()) {
4298+ result = Api::NewHandle (T, retval.raw ());
4299+ } else {
4300+ result = Api::NewHandle (T, instance.raw ());
4301+ }
4302+ }
4303+ return result;
4304+ }
4305+ return Api::NewError (" %s expects argument 'name' to be a valid constructor." ,
4306+ CURRENT_FUNC );
4307+ }
4308+
41534309DART_EXPORT Dart_Handle Dart_Invoke (Dart_Handle target,
41544310 Dart_Handle name,
41554311 int number_of_arguments,
0 commit comments