[ 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>
This commit is contained in:
Ben Konyi 2020-02-12 22:48:08 +00:00
parent 91eee195fc
commit 3d1b8b26c2
5 changed files with 9 additions and 282 deletions

View file

@ -28,6 +28,9 @@ used (see Issue [39627][]).
### 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
can no longer by reached by `Dart_GetType(dart:core, dynamic)`.

View file

@ -100,8 +100,6 @@ void RunTests(Dart_NativeArguments arguments) {
Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D"));
CHECK(D_class);
CHECK(Dart_Allocate(D_class));
FAIL("D.", Dart_New(D_class, Dart_Null(), 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,
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.
*
@ -2467,32 +2441,6 @@ Dart_InvokeClosure(Dart_Handle closure,
int number_of_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.
*

View file

@ -4124,85 +4124,6 @@ DART_EXPORT Dart_Handle Dart_New(Dart_Handle type,
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,
int num_args,
Dart_Handle* arguments,
@ -4229,83 +4150,6 @@ static Dart_Handle SetupArguments(Thread* thread,
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_Handle name,
int number_of_arguments,

View file

@ -1082,7 +1082,7 @@ TEST_CASE(DartAPI_FunctionIsStatic) {
Dart_Handle klass = Dart_GetType(lib, NewString("Foo"), 0, NULL);
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"));
EXPECT_VALID(closure);
@ -4879,15 +4879,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &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.
result = Dart_New(type, Dart_EmptyString(), 0, NULL);
EXPECT_VALID(result);
@ -4899,27 +4890,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &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.
result = Dart_New(type, NewString("named"), 1, args);
EXPECT_VALID(result);
@ -4930,19 +4900,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &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.
result = Dart_New(type, NewString("_hidden"), 1, args);
EXPECT_VALID(result);
@ -4953,28 +4910,6 @@ TEST_CASE(DartAPI_New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &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.
result = Dart_New(type, NewString("multiply"), 1, args);
EXPECT_VALID(result);
@ -5640,14 +5575,13 @@ static void NativeArgumentCreate(Dart_NativeArguments args) {
Dart_Handle type = Dart_GetType(lib, NewString("MyObject"), 0, NULL);
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.
Dart_Handle obj =
Dart_AllocateWithNativeFields(type, num_native_fields, native_fields);
Dart_Handle obj = Dart_New(type, Dart_Null(), 0, nullptr);
EXPECT_VALID(obj);
EXPECT_VALID(
Dart_SetNativeInstanceField(obj, 0, kNativeArgumentNativeField1Value));
EXPECT_VALID(
Dart_SetNativeInstanceField(obj, 1, kNativeArgumentNativeField2Value));
kNativeArgumentNativeField1Value *= 2;
kNativeArgumentNativeField2Value *= 2;