Skip to content

Commit 34447c8

Browse files
Clement Skaucommit-bot@chromium.org
authored andcommitted
Revert "[ VM ] Removed Dart_Allocate, Dart_AllocateWithNativeFields, and Dart_InvokeConstructor from embedding API"
This reverts commit 3d1b8b2. Reason for revert: Broke Flutter HHH. Dart_AllocateWithNativeFields is still used in Tonic. Original change's description: > [ VM ] Removed Dart_Allocate, Dart_AllocateWithNativeFields, and Dart_InvokeConstructor from embedding API > > These methods are no longer necessary and all objects should be created > using Dart_New instead. > > Change-Id: If64d3e3579fc03dd1a2eb6bfec73c35e90c66d8f > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135523 > Reviewed-by: Ryan Macnak <rmacnak@google.com> TBR=bkonyi@google.com,rmacnak@google.com,asiva@google.com Change-Id: I3dca62a1db60a90bbcc78c34ae150df628cd85c8 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135642 Reviewed-by: Clement Skau <cskau@google.com> Commit-Queue: Clement Skau <cskau@google.com>
1 parent 0a8484c commit 34447c8

5 files changed

Lines changed: 282 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ used (see Issue [39627][]).
2828

2929
### Dart VM
3030

31-
* **Breaking Change**: Removed `Dart_Allocate`, `Dart_AllocateWithNativeFields`,
32-
and `Dart_InvokeConstructor`. Calls to these methods should be replaced with
33-
a single call to `Dart_New`.
3431
* Added `Dart_TypeDynamic`, `Dart_TypeVoid` and `Dart_TypeNever`. Type dynamic
3532
can no longer by reached by `Dart_GetType(dart:core, dynamic)`.
3633

runtime/bin/entrypoints_verification_test_extension.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ void RunTests(Dart_NativeArguments arguments) {
100100
Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D"));
101101
CHECK(D_class);
102102

103+
CHECK(Dart_Allocate(D_class));
104+
103105
FAIL("D.", Dart_New(D_class, Dart_Null(), 0, nullptr));
104106

105107
CHECK(Dart_New(D_class, Dart_NewStringFromCString("defined"), 0, nullptr));

runtime/include/dart_api.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,6 +2397,32 @@ Dart_New(Dart_Handle type,
23972397
int number_of_arguments,
23982398
Dart_Handle* arguments);
23992399

2400+
/**
2401+
* Allocate a new object without invoking a constructor.
2402+
*
2403+
* \param type The type of an object to be allocated.
2404+
*
2405+
* \return The new object. If an error occurs during execution, then an
2406+
* error handle is returned.
2407+
*/
2408+
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_Allocate(Dart_Handle type);
2409+
2410+
/**
2411+
* Allocate a new object without invoking a constructor, and sets specified
2412+
* native fields.
2413+
*
2414+
* \param type The type of an object to be allocated.
2415+
* \param num_native_fields The number of native fields to set.
2416+
* \param native_fields An array containing the value of native fields.
2417+
*
2418+
* \return The new object. If an error occurs during execution, then an
2419+
* error handle is returned.
2420+
*/
2421+
DART_EXPORT Dart_Handle
2422+
Dart_AllocateWithNativeFields(Dart_Handle type,
2423+
intptr_t num_native_fields,
2424+
const intptr_t* native_fields);
2425+
24002426
/**
24012427
* Invokes a method or function.
24022428
*
@@ -2441,6 +2467,32 @@ Dart_InvokeClosure(Dart_Handle closure,
24412467
int number_of_arguments,
24422468
Dart_Handle* arguments);
24432469

2470+
/**
2471+
* Invokes a Generative Constructor on an object that was previously
2472+
* allocated using Dart_Allocate/Dart_AllocateWithNativeFields.
2473+
*
2474+
* The 'target' parameter must be an object.
2475+
*
2476+
* This function ignores visibility (leading underscores in names).
2477+
*
2478+
* May generate an unhandled exception error.
2479+
*
2480+
* \param target An object.
2481+
* \param name The name of the constructor to invoke.
2482+
* Use Dart_Null() or Dart_EmptyString() to invoke the unnamed constructor.
2483+
* \param number_of_arguments Size of the arguments array.
2484+
* \param arguments An array of arguments to the function.
2485+
*
2486+
* \return If the constructor is called and completes
2487+
* successfully, then the object is returned. If an error
2488+
* occurs during execution, then an error handle is returned.
2489+
*/
2490+
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
2491+
Dart_InvokeConstructor(Dart_Handle object,
2492+
Dart_Handle name,
2493+
int number_of_arguments,
2494+
Dart_Handle* arguments);
2495+
24442496
/**
24452497
* Gets the value of a field.
24462498
*

runtime/vm/dart_api_impl.cc

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
41274206
static 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+
41534309
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
41544310
Dart_Handle name,
41554311
int number_of_arguments,

runtime/vm/dart_api_impl_test.cc

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ TEST_CASE(DartAPI_FunctionIsStatic) {
10821082
Dart_Handle klass = Dart_GetType(lib, NewString("Foo"), 0, NULL);
10831083
EXPECT_VALID(klass);
10841084

1085-
Dart_Handle instance = Dart_New(klass, Dart_Null(), 0, NULL);
1085+
Dart_Handle instance = Dart_Allocate(klass);
10861086

10871087
closure = Dart_GetField(instance, NewString("getString"));
10881088
EXPECT_VALID(closure);
@@ -4879,6 +4879,15 @@ TEST_CASE(DartAPI_New) {
48794879
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
48804880
EXPECT_EQ(7, int_value);
48814881

4882+
// Allocate without a constructor.
4883+
Dart_Handle obj = Dart_Allocate(type);
4884+
EXPECT_VALID(obj);
4885+
instanceOf = false;
4886+
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
4887+
EXPECT(instanceOf);
4888+
foo = Dart_GetField(obj, NewString("foo"));
4889+
EXPECT(Dart_IsNull(foo));
4890+
48824891
// Allocate and Invoke the unnamed constructor passing in an empty string.
48834892
result = Dart_New(type, Dart_EmptyString(), 0, NULL);
48844893
EXPECT_VALID(result);
@@ -4890,6 +4899,27 @@ TEST_CASE(DartAPI_New) {
48904899
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
48914900
EXPECT_EQ(7, int_value);
48924901

4902+
// Allocate object and invoke the unnamed constructor with an empty string.
4903+
obj = Dart_Allocate(type);
4904+
EXPECT_VALID(obj);
4905+
instanceOf = false;
4906+
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
4907+
EXPECT(instanceOf);
4908+
// Use the empty string to invoke the unnamed constructor.
4909+
result = Dart_InvokeConstructor(obj, Dart_EmptyString(), 0, NULL);
4910+
EXPECT_VALID(result);
4911+
int_value = 0;
4912+
foo = Dart_GetField(result, NewString("foo"));
4913+
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
4914+
EXPECT_EQ(7, int_value);
4915+
// use Dart_Null to invoke the unnamed constructor.
4916+
result = Dart_InvokeConstructor(obj, Dart_Null(), 0, NULL);
4917+
EXPECT_VALID(result);
4918+
int_value = 0;
4919+
foo = Dart_GetField(result, NewString("foo"));
4920+
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
4921+
EXPECT_EQ(7, int_value);
4922+
48934923
// Invoke a named constructor.
48944924
result = Dart_New(type, NewString("named"), 1, args);
48954925
EXPECT_VALID(result);
@@ -4900,6 +4930,19 @@ TEST_CASE(DartAPI_New) {
49004930
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
49014931
EXPECT_EQ(11, int_value);
49024932

4933+
// Allocate object and invoke a named constructor.
4934+
obj = Dart_Allocate(type);
4935+
EXPECT_VALID(obj);
4936+
instanceOf = false;
4937+
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
4938+
EXPECT(instanceOf);
4939+
result = Dart_InvokeConstructor(obj, NewString("named"), 1, args);
4940+
EXPECT_VALID(result);
4941+
int_value = 0;
4942+
foo = Dart_GetField(result, NewString("foo"));
4943+
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
4944+
EXPECT_EQ(11, int_value);
4945+
49034946
// Invoke a hidden named constructor.
49044947
result = Dart_New(type, NewString("_hidden"), 1, args);
49054948
EXPECT_VALID(result);
@@ -4910,6 +4953,28 @@ TEST_CASE(DartAPI_New) {
49104953
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
49114954
EXPECT_EQ(-11, int_value);
49124955

4956+
// Allocate object and invoke a hidden named constructor.
4957+
obj = Dart_Allocate(type);
4958+
EXPECT_VALID(obj);
4959+
instanceOf = false;
4960+
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
4961+
EXPECT(instanceOf);
4962+
result = Dart_InvokeConstructor(obj, NewString("_hidden"), 1, args);
4963+
EXPECT_VALID(result);
4964+
int_value = 0;
4965+
foo = Dart_GetField(result, NewString("foo"));
4966+
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
4967+
EXPECT_EQ(-11, int_value);
4968+
4969+
// Allocate object and Invoke a constructor which throws an exception.
4970+
obj = Dart_Allocate(type);
4971+
EXPECT_VALID(obj);
4972+
instanceOf = false;
4973+
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
4974+
EXPECT(instanceOf);
4975+
result = Dart_InvokeConstructor(obj, NewString("exception"), 1, args);
4976+
EXPECT_ERROR(result, "ConstructorDeath");
4977+
49134978
// Invoke a factory constructor.
49144979
result = Dart_New(type, NewString("multiply"), 1, args);
49154980
EXPECT_VALID(result);
@@ -5575,13 +5640,14 @@ static void NativeArgumentCreate(Dart_NativeArguments args) {
55755640
Dart_Handle type = Dart_GetType(lib, NewString("MyObject"), 0, NULL);
55765641
EXPECT_VALID(type);
55775642

5643+
// Allocate without a constructor.
5644+
const int num_native_fields = 2;
5645+
const intptr_t native_fields[] = {kNativeArgumentNativeField1Value,
5646+
kNativeArgumentNativeField2Value};
55785647
// Allocate and Setup native fields.
5579-
Dart_Handle obj = Dart_New(type, Dart_Null(), 0, nullptr);
5648+
Dart_Handle obj =
5649+
Dart_AllocateWithNativeFields(type, num_native_fields, native_fields);
55805650
EXPECT_VALID(obj);
5581-
EXPECT_VALID(
5582-
Dart_SetNativeInstanceField(obj, 0, kNativeArgumentNativeField1Value));
5583-
EXPECT_VALID(
5584-
Dart_SetNativeInstanceField(obj, 1, kNativeArgumentNativeField2Value));
55855651

55865652
kNativeArgumentNativeField1Value *= 2;
55875653
kNativeArgumentNativeField2Value *= 2;

0 commit comments

Comments
 (0)