Add Dart_Allocate to the C++ API

This change allows us to allocate Dart objects from C++ without
invoking a constructor.  In turn, it allows us to declare Dartium DOM
types with no public generative constructor.

Note, the current constructor has to be public as dart:html Element is
subclassed by dart:svg SvgElement (and eventually by user defined
custom elements as well).  This leads to unfortunate holes such as: https://code.google.com/p/dart/issues/detail?id=11277

This should also give a modest boost in DOM perf as the existing
constructor does absolutely nothing.

BUG=11277
R=asiva@google.com

Review URL: https://codereview.chromium.org//16968006

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@24189 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
vsm@google.com 2013-06-19 15:48:23 +00:00
parent 3792e37d67
commit 9ddec8e9a1
3 changed files with 46 additions and 0 deletions

View file

@ -1752,6 +1752,16 @@ DART_EXPORT Dart_Handle Dart_New(Dart_Handle clazz,
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_Handle Dart_Allocate(Dart_Handle type);
/**
* Invokes a method or function.
*

View file

@ -2825,6 +2825,33 @@ DART_EXPORT Dart_Handle Dart_New(Dart_Handle clazz,
}
DART_EXPORT Dart_Handle Dart_Allocate(Dart_Handle type) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
CHECK_CALLBACK_STATE(isolate);
const Object& result = Object::Handle(isolate, Api::UnwrapHandle(type));
// Get the class to instantiate.
if (result.IsNull()) {
RETURN_TYPE_ERROR(isolate, type, Type);
}
Class& cls = Class::Handle(isolate);
if (result.IsType()) {
cls = Type::Cast(result).type_class();
} else if (result.IsClass()) {
// For backwards compatibility we allow class objects to be passed in
// for now. This needs to be removed once all code that uses class
// objects to invoke Dart_New is removed.
cls ^= result.raw();
} else {
RETURN_TYPE_ERROR(isolate, type, Type);
}
// Allocate an object for the given class.
return Api::NewHandle(isolate, Instance::New(cls));
}
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
Dart_Handle name,
int number_of_arguments,

View file

@ -3919,6 +3919,15 @@ TEST_CASE(New) {
EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
EXPECT_EQ(7, int_value);
// Allocate without a constructor.
result = Dart_Allocate(cls);
EXPECT_VALID(result);
instanceof = false;
EXPECT_VALID(Dart_ObjectIsType(result, cls, &instanceof));
EXPECT(instanceof);
foo = Dart_GetField(result, NewString("foo"));
EXPECT(Dart_IsNull(foo));
// Invoke the unnamed constructor with an empty string.
result = Dart_New(cls, NewString(""), 0, NULL);
EXPECT_VALID(result);