mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 08:41:10 +00:00
[ 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:
parent
91eee195fc
commit
3d1b8b26c2
|
@ -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)`.
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue