Reland "[ VM ] Removed Dart_Allocate, Dart_AllocateWithNativeFields, and Dart_InvokeConstructor from embedding API"

This reverts commit 34447c8dbb.

Reason for revert: Last Dart_AllocateWithNativeFields usage removed in Tonic

Original change's description:
> Revert "[ VM ] Removed Dart_Allocate, Dart_AllocateWithNativeFields, and Dart_InvokeConstructor from embedding API"
> 
> This reverts commit 3d1b8b26c2.
> 
> 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>

TBR=bkonyi@google.com,rmacnak@google.com,asiva@google.com,cskau@google.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Change-Id: I2ac83e1bfccccd9b626acfa4a6ac517b4f3968fb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136020
Auto-Submit: Ben Konyi <bkonyi@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi 2020-02-18 17:34:44 +00:00 committed by commit-bot@chromium.org
parent edc8bd7ec6
commit 082aece5f4
5 changed files with 9 additions and 282 deletions

View file

@ -39,6 +39,9 @@ case of `name` instead of converting them to lowercase.
### Dart VM ### Dart VM
* **Breaking Change**: Removed `Dart_Allocate`, `Dart_AllocateWithNativeFields`,
and `Dart_InvokeConstructor`. Calls to these methods should be replaced with
a single call to `Dart_New`.
* Added `Dart_TypeDynamic`, `Dart_TypeVoid` and `Dart_TypeNever`. Type dynamic * Added `Dart_TypeDynamic`, `Dart_TypeVoid` and `Dart_TypeNever`. Type dynamic
can no longer by reached by `Dart_GetType(dart:core, dynamic)`. can no longer by reached by `Dart_GetType(dart:core, dynamic)`.
* Added the following methods to the VM embedding API: * Added the following methods to the VM embedding API:

View file

@ -100,8 +100,6 @@ void RunTests(Dart_NativeArguments arguments) {
Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D")); Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D"));
CHECK(D_class); CHECK(D_class);
CHECK(Dart_Allocate(D_class));
FAIL("D.", Dart_New(D_class, Dart_Null(), 0, nullptr)); FAIL("D.", Dart_New(D_class, Dart_Null(), 0, nullptr));
CHECK(Dart_New(D_class, Dart_NewStringFromCString("defined"), 0, nullptr)); CHECK(Dart_New(D_class, Dart_NewStringFromCString("defined"), 0, nullptr));

View file

@ -2397,32 +2397,6 @@ Dart_New(Dart_Handle type,
int number_of_arguments, int number_of_arguments,
Dart_Handle* arguments); Dart_Handle* arguments);
/**
* Allocate a new object without invoking a constructor.
*
* \param type The type of an object to be allocated.
*
* \return The new object. If an error occurs during execution, then an
* error handle is returned.
*/
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_Allocate(Dart_Handle type);
/**
* Allocate a new object without invoking a constructor, and sets specified
* native fields.
*
* \param type The type of an object to be allocated.
* \param num_native_fields The number of native fields to set.
* \param native_fields An array containing the value of native fields.
*
* \return The new object. If an error occurs during execution, then an
* error handle is returned.
*/
DART_EXPORT Dart_Handle
Dart_AllocateWithNativeFields(Dart_Handle type,
intptr_t num_native_fields,
const intptr_t* native_fields);
/** /**
* Invokes a method or function. * Invokes a method or function.
* *
@ -2467,32 +2441,6 @@ Dart_InvokeClosure(Dart_Handle closure,
int number_of_arguments, int number_of_arguments,
Dart_Handle* arguments); Dart_Handle* arguments);
/**
* Invokes a Generative Constructor on an object that was previously
* allocated using Dart_Allocate/Dart_AllocateWithNativeFields.
*
* The 'target' parameter must be an object.
*
* This function ignores visibility (leading underscores in names).
*
* May generate an unhandled exception error.
*
* \param target An object.
* \param name The name of the constructor to invoke.
* Use Dart_Null() or Dart_EmptyString() to invoke the unnamed constructor.
* \param number_of_arguments Size of the arguments array.
* \param arguments An array of arguments to the function.
*
* \return If the constructor is called and completes
* successfully, then the object is returned. If an error
* occurs during execution, then an error handle is returned.
*/
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
Dart_InvokeConstructor(Dart_Handle object,
Dart_Handle name,
int number_of_arguments,
Dart_Handle* arguments);
/** /**
* Gets the value of a field. * Gets the value of a field.
* *

View file

@ -4124,85 +4124,6 @@ DART_EXPORT Dart_Handle Dart_New(Dart_Handle type,
return Api::NewHandle(T, new_object.raw()); return Api::NewHandle(T, new_object.raw());
} }
static RawInstance* AllocateObject(Thread* thread, const Class& cls) {
if (!cls.is_fields_marked_nullable()) {
// Mark all fields as nullable.
Zone* zone = thread->zone();
Class& iterate_cls = Class::Handle(zone, cls.raw());
Field& field = Field::Handle(zone);
Array& fields = Array::Handle(zone);
while (!iterate_cls.IsNull()) {
ASSERT(iterate_cls.is_finalized());
iterate_cls.set_is_fields_marked_nullable();
fields = iterate_cls.fields();
iterate_cls = iterate_cls.SuperClass();
for (int field_num = 0; field_num < fields.Length(); field_num++) {
field ^= fields.At(field_num);
if (field.is_static()) {
continue;
}
field.RecordStore(Object::null_object());
}
}
}
// Allocate an object for the given class.
return Instance::New(cls);
}
DART_EXPORT Dart_Handle Dart_Allocate(Dart_Handle type) {
DARTSCOPE(Thread::Current());
CHECK_CALLBACK_STATE(T);
const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
// Get the class to instantiate.
if (type_obj.IsNull()) {
RETURN_TYPE_ERROR(Z, type, Type);
}
const Class& cls = Class::Handle(Z, type_obj.type_class());
CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
#if defined(DEBUG)
if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
}
#endif
CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
return Api::NewHandle(T, AllocateObject(T, cls));
}
DART_EXPORT Dart_Handle
Dart_AllocateWithNativeFields(Dart_Handle type,
intptr_t num_native_fields,
const intptr_t* native_fields) {
DARTSCOPE(Thread::Current());
CHECK_CALLBACK_STATE(T);
const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
// Get the class to instantiate.
if (type_obj.IsNull()) {
RETURN_TYPE_ERROR(Z, type, Type);
}
if (native_fields == NULL) {
RETURN_NULL_ERROR(native_fields);
}
const Class& cls = Class::Handle(Z, type_obj.type_class());
CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
#if defined(DEBUG)
if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
}
#endif
CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
if (num_native_fields != cls.num_native_fields()) {
return Api::NewError(
"%s: invalid number of native fields %" Pd " passed in, expected %d",
CURRENT_FUNC, num_native_fields, cls.num_native_fields());
}
const Instance& instance = Instance::Handle(Z, AllocateObject(T, cls));
instance.SetNativeFields(num_native_fields, native_fields);
return Api::NewHandle(T, instance.raw());
}
static Dart_Handle SetupArguments(Thread* thread, static Dart_Handle SetupArguments(Thread* thread,
int num_args, int num_args,
Dart_Handle* arguments, Dart_Handle* arguments,
@ -4229,83 +4150,6 @@ static Dart_Handle SetupArguments(Thread* thread,
return Api::Success(); return Api::Success();
} }
DART_EXPORT Dart_Handle Dart_InvokeConstructor(Dart_Handle object,
Dart_Handle name,
int number_of_arguments,
Dart_Handle* arguments) {
DARTSCOPE(Thread::Current());
API_TIMELINE_DURATION(T);
CHECK_CALLBACK_STATE(T);
if (number_of_arguments < 0) {
return Api::NewError(
"%s expects argument 'number_of_arguments' to be non-negative.",
CURRENT_FUNC);
}
const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
if (instance.IsNull()) {
RETURN_TYPE_ERROR(Z, object, Instance);
}
// Since we have allocated an object it would mean that the type
// is finalized.
// TODO(asiva): How do we ensure that a constructor is not called more than
// once for the same object.
// Construct name of the constructor to invoke.
const String& constructor_name = Api::UnwrapStringHandle(Z, name);
const AbstractType& type_obj =
AbstractType::Handle(Z, instance.GetType(Heap::kNew));
const Class& cls = Class::Handle(Z, type_obj.type_class());
const String& class_name = String::Handle(Z, cls.Name());
const Array& strings = Array::Handle(Z, Array::New(3));
strings.SetAt(0, class_name);
strings.SetAt(1, Symbols::Dot());
if (constructor_name.IsNull()) {
strings.SetAt(2, Symbols::Empty());
} else {
strings.SetAt(2, constructor_name);
}
const String& dot_name = String::Handle(Z, String::ConcatAll(strings));
const TypeArguments& type_arguments =
TypeArguments::Handle(Z, type_obj.arguments());
const Function& constructor =
Function::Handle(Z, cls.LookupFunctionAllowPrivate(dot_name));
const int kTypeArgsLen = 0;
const int extra_args = 1;
if (!constructor.IsNull() && constructor.IsGenerativeConstructor() &&
constructor.AreValidArgumentCounts(
kTypeArgsLen, number_of_arguments + extra_args, 0, NULL)) {
CHECK_ERROR_HANDLE(constructor.VerifyCallEntryPoint());
// Create the argument list.
// Constructors get the uninitialized object.
if (!type_arguments.IsNull()) {
// The type arguments will be null if the class has no type
// parameters, in which case the following call would fail
// because there is no slot reserved in the object for the
// type vector.
instance.SetTypeArguments(type_arguments);
}
Dart_Handle result;
Array& args = Array::Handle(Z);
result =
SetupArguments(T, number_of_arguments, arguments, extra_args, &args);
if (!Api::IsError(result)) {
args.SetAt(0, instance);
const Object& retval =
Object::Handle(Z, DartEntry::InvokeFunction(constructor, args));
if (retval.IsError()) {
result = Api::NewHandle(T, retval.raw());
} else {
result = Api::NewHandle(T, instance.raw());
}
}
return result;
}
return Api::NewError("%s expects argument 'name' to be a valid constructor.",
CURRENT_FUNC);
}
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
Dart_Handle name, Dart_Handle name,
int number_of_arguments, int number_of_arguments,

View file

@ -1082,7 +1082,7 @@ TEST_CASE(DartAPI_FunctionIsStatic) {
Dart_Handle klass = Dart_GetType(lib, NewString("Foo"), 0, NULL); Dart_Handle klass = Dart_GetType(lib, NewString("Foo"), 0, NULL);
EXPECT_VALID(klass); EXPECT_VALID(klass);
Dart_Handle instance = Dart_Allocate(klass); Dart_Handle instance = Dart_New(klass, Dart_Null(), 0, NULL);
closure = Dart_GetField(instance, NewString("getString")); closure = Dart_GetField(instance, NewString("getString"));
EXPECT_VALID(closure); EXPECT_VALID(closure);
@ -4884,15 +4884,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value)); EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(7, int_value); EXPECT_EQ(7, int_value);
// Allocate without a constructor.
Dart_Handle obj = Dart_Allocate(type);
EXPECT_VALID(obj);
instanceOf = false;
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
EXPECT(instanceOf);
foo = Dart_GetField(obj, NewString("foo"));
EXPECT(Dart_IsNull(foo));
// Allocate and Invoke the unnamed constructor passing in an empty string. // Allocate and Invoke the unnamed constructor passing in an empty string.
result = Dart_New(type, Dart_EmptyString(), 0, NULL); result = Dart_New(type, Dart_EmptyString(), 0, NULL);
EXPECT_VALID(result); EXPECT_VALID(result);
@ -4904,27 +4895,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value)); EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(7, int_value); EXPECT_EQ(7, int_value);
// Allocate object and invoke the unnamed constructor with an empty string.
obj = Dart_Allocate(type);
EXPECT_VALID(obj);
instanceOf = false;
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
EXPECT(instanceOf);
// Use the empty string to invoke the unnamed constructor.
result = Dart_InvokeConstructor(obj, Dart_EmptyString(), 0, NULL);
EXPECT_VALID(result);
int_value = 0;
foo = Dart_GetField(result, NewString("foo"));
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(7, int_value);
// use Dart_Null to invoke the unnamed constructor.
result = Dart_InvokeConstructor(obj, Dart_Null(), 0, NULL);
EXPECT_VALID(result);
int_value = 0;
foo = Dart_GetField(result, NewString("foo"));
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(7, int_value);
// Invoke a named constructor. // Invoke a named constructor.
result = Dart_New(type, NewString("named"), 1, args); result = Dart_New(type, NewString("named"), 1, args);
EXPECT_VALID(result); EXPECT_VALID(result);
@ -4935,19 +4905,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value)); EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(11, int_value); EXPECT_EQ(11, int_value);
// Allocate object and invoke a named constructor.
obj = Dart_Allocate(type);
EXPECT_VALID(obj);
instanceOf = false;
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
EXPECT(instanceOf);
result = Dart_InvokeConstructor(obj, NewString("named"), 1, args);
EXPECT_VALID(result);
int_value = 0;
foo = Dart_GetField(result, NewString("foo"));
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(11, int_value);
// Invoke a hidden named constructor. // Invoke a hidden named constructor.
result = Dart_New(type, NewString("_hidden"), 1, args); result = Dart_New(type, NewString("_hidden"), 1, args);
EXPECT_VALID(result); EXPECT_VALID(result);
@ -4958,28 +4915,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value)); EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(-11, int_value); EXPECT_EQ(-11, int_value);
// Allocate object and invoke a hidden named constructor.
obj = Dart_Allocate(type);
EXPECT_VALID(obj);
instanceOf = false;
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
EXPECT(instanceOf);
result = Dart_InvokeConstructor(obj, NewString("_hidden"), 1, args);
EXPECT_VALID(result);
int_value = 0;
foo = Dart_GetField(result, NewString("foo"));
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(-11, int_value);
// Allocate object and Invoke a constructor which throws an exception.
obj = Dart_Allocate(type);
EXPECT_VALID(obj);
instanceOf = false;
EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceOf));
EXPECT(instanceOf);
result = Dart_InvokeConstructor(obj, NewString("exception"), 1, args);
EXPECT_ERROR(result, "ConstructorDeath");
// Invoke a factory constructor. // Invoke a factory constructor.
result = Dart_New(type, NewString("multiply"), 1, args); result = Dart_New(type, NewString("multiply"), 1, args);
EXPECT_VALID(result); EXPECT_VALID(result);
@ -5645,14 +5580,13 @@ static void NativeArgumentCreate(Dart_NativeArguments args) {
Dart_Handle type = Dart_GetType(lib, NewString("MyObject"), 0, NULL); Dart_Handle type = Dart_GetType(lib, NewString("MyObject"), 0, NULL);
EXPECT_VALID(type); EXPECT_VALID(type);
// Allocate without a constructor.
const int num_native_fields = 2;
const intptr_t native_fields[] = {kNativeArgumentNativeField1Value,
kNativeArgumentNativeField2Value};
// Allocate and Setup native fields. // Allocate and Setup native fields.
Dart_Handle obj = Dart_Handle obj = Dart_New(type, Dart_Null(), 0, nullptr);
Dart_AllocateWithNativeFields(type, num_native_fields, native_fields);
EXPECT_VALID(obj); EXPECT_VALID(obj);
EXPECT_VALID(
Dart_SetNativeInstanceField(obj, 0, kNativeArgumentNativeField1Value));
EXPECT_VALID(
Dart_SetNativeInstanceField(obj, 1, kNativeArgumentNativeField2Value));
kNativeArgumentNativeField1Value *= 2; kNativeArgumentNativeField1Value *= 2;
kNativeArgumentNativeField2Value *= 2; kNativeArgumentNativeField2Value *= 2;