[vm] Fix Dart_GetNativeFieldsOfArgument when passed an object with no native fields.
Bug: https://github.com/flutter/flutter/issues/64598 Change-Id: I90325e5eecc7a7fca2cb76894ce1830c93c05388 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/160185 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
d5b9dcb00c
commit
ae37f48796
@@ -36,7 +36,7 @@ static Dart_NativeFunction native_resolver(Dart_Handle name,
|
||||
bool* auto_setup_scope) {
|
||||
ASSERT(auto_setup_scope);
|
||||
*auto_setup_scope = false;
|
||||
return reinterpret_cast<Dart_NativeFunction>(&NativeFunc);
|
||||
return NativeFunc;
|
||||
}
|
||||
|
||||
TEST_CASE(StackMapGC) {
|
||||
|
||||
@@ -33,7 +33,7 @@ static Dart_NativeFunction NoopNativeLookup(Dart_Handle name,
|
||||
bool* auto_setup_scope) {
|
||||
ASSERT(auto_setup_scope != nullptr);
|
||||
*auto_setup_scope = false;
|
||||
return reinterpret_cast<Dart_NativeFunction>(&NoopNative);
|
||||
return NoopNative;
|
||||
}
|
||||
|
||||
// Flatten all non-captured LocalVariables from the given scope and its children
|
||||
|
||||
+22
-16
@@ -653,23 +653,29 @@ bool Api::GetNativeFieldsOfArgument(NativeArguments* arguments,
|
||||
intptr_t* field_values) {
|
||||
NoSafepointScope no_safepoint_scope;
|
||||
ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
|
||||
if (raw_obj->IsHeapObject()) {
|
||||
intptr_t cid = raw_obj->GetClassId();
|
||||
if (cid >= kNumPredefinedCids) {
|
||||
TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
|
||||
ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
|
||||
if (native_fields == TypedData::null()) {
|
||||
memset(field_values, 0, (num_fields * sizeof(field_values[0])));
|
||||
} else if (num_fields == Smi::Value(native_fields->ptr()->length_)) {
|
||||
intptr_t* native_values =
|
||||
bit_cast<intptr_t*, uint8_t*>(native_fields->ptr()->data());
|
||||
memmove(field_values, native_values,
|
||||
(num_fields * sizeof(field_values[0])));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
intptr_t cid = raw_obj->GetClassIdMayBeSmi();
|
||||
int class_num_fields = arguments->thread()
|
||||
->isolate()
|
||||
->class_table()
|
||||
->At(cid)
|
||||
->ptr()
|
||||
->num_native_fields_;
|
||||
if (num_fields != class_num_fields) {
|
||||
// No native fields or mismatched native field count.
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
|
||||
ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
|
||||
if (native_fields == TypedData::null()) {
|
||||
// Native fields not initialized.
|
||||
memset(field_values, 0, (num_fields * sizeof(field_values[0])));
|
||||
return true;
|
||||
}
|
||||
ASSERT(class_num_fields == Smi::Value(native_fields->ptr()->length_));
|
||||
intptr_t* native_values =
|
||||
reinterpret_cast<intptr_t*>(native_fields->ptr()->data());
|
||||
memmove(field_values, native_values, (num_fields * sizeof(field_values[0])));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Api::SetWeakHandleReturnValue(NativeArguments* args,
|
||||
|
||||
@@ -538,7 +538,7 @@ static Dart_NativeFunction CurrentStackTraceNativeLookup(
|
||||
bool* auto_setup_scope) {
|
||||
ASSERT(auto_setup_scope != NULL);
|
||||
*auto_setup_scope = true;
|
||||
return reinterpret_cast<Dart_NativeFunction>(&CurrentStackTraceNative);
|
||||
return CurrentStackTraceNative;
|
||||
}
|
||||
|
||||
TEST_CASE(DartAPI_CurrentStackTraceInfo) {
|
||||
@@ -687,7 +687,7 @@ static Dart_NativeFunction PropagateError_native_lookup(
|
||||
bool* auto_setup_scope) {
|
||||
ASSERT(auto_setup_scope != NULL);
|
||||
*auto_setup_scope = true;
|
||||
return reinterpret_cast<Dart_NativeFunction>(&PropagateErrorNative);
|
||||
return PropagateErrorNative;
|
||||
}
|
||||
|
||||
TEST_CASE(DartAPI_PropagateCompileTimeError) {
|
||||
@@ -4995,7 +4995,7 @@ static Dart_NativeFunction native_field_lookup(Dart_Handle name,
|
||||
bool* auto_setup_scope) {
|
||||
ASSERT(auto_setup_scope != NULL);
|
||||
*auto_setup_scope = false;
|
||||
return reinterpret_cast<Dart_NativeFunction>(&NativeFieldLookup);
|
||||
return NativeFieldLookup;
|
||||
}
|
||||
|
||||
TEST_CASE(DartAPI_InjectNativeFields2) {
|
||||
@@ -5139,6 +5139,15 @@ void TestNativeFieldsAccess_access(Dart_NativeArguments args) {
|
||||
EXPECT_EQ(0, field_values[1]);
|
||||
}
|
||||
|
||||
void TestNativeFieldsAccess_invalidAccess(Dart_NativeArguments args) {
|
||||
intptr_t field_values[kTestNumNativeFields];
|
||||
Dart_Handle result = Dart_GetNativeFieldsOfArgument(
|
||||
args, 0, kTestNumNativeFields, field_values);
|
||||
EXPECT_ERROR(result,
|
||||
"Dart_GetNativeFieldsOfArgument: "
|
||||
"expected 0 'num_fields' but was passed in 2");
|
||||
}
|
||||
|
||||
static Dart_NativeFunction TestNativeFieldsAccess_lookup(Dart_Handle name,
|
||||
int argument_count,
|
||||
bool* auto_scope) {
|
||||
@@ -5152,10 +5161,12 @@ static Dart_NativeFunction TestNativeFieldsAccess_lookup(Dart_Handle name,
|
||||
const char* function_name = obj.ToCString();
|
||||
ASSERT(function_name != NULL);
|
||||
if (strcmp(function_name, "TestNativeFieldsAccess_init") == 0) {
|
||||
return reinterpret_cast<Dart_NativeFunction>(&TestNativeFieldsAccess_init);
|
||||
return TestNativeFieldsAccess_init;
|
||||
} else if (strcmp(function_name, "TestNativeFieldsAccess_access") == 0) {
|
||||
return reinterpret_cast<Dart_NativeFunction>(
|
||||
&TestNativeFieldsAccess_access);
|
||||
return TestNativeFieldsAccess_access;
|
||||
} else if (strcmp(function_name, "TestNativeFieldsAccess_invalidAccess") ==
|
||||
0) {
|
||||
return TestNativeFieldsAccess_invalidAccess;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@@ -5178,10 +5189,15 @@ TEST_CASE(DartAPI_TestNativeFieldsAccess) {
|
||||
" int%s accessNativeFlds(int%s i) native "
|
||||
"'TestNativeFieldsAccess_access';\n"
|
||||
"}\n"
|
||||
"class NoNativeFields {\n"
|
||||
" int neitherATypedDataNorNull = 0;\n"
|
||||
" invalidAccess() native 'TestNativeFieldsAccess_invalidAccess';\n"
|
||||
"}\n"
|
||||
"NativeFields testMain() {\n"
|
||||
" NativeFields obj = new NativeFields(10, 20);\n"
|
||||
" obj.initNativeFlds();\n"
|
||||
" obj.accessNativeFlds(null);\n"
|
||||
" new NoNativeFields().invalidAccess();\n"
|
||||
" return obj;\n"
|
||||
"}\n",
|
||||
nullable_tag, nullable_tag, nullable_tag, nullable_tag),
|
||||
@@ -6394,7 +6410,7 @@ static Dart_NativeFunction native_lookup(Dart_Handle name,
|
||||
bool* auto_setup_scope) {
|
||||
ASSERT(auto_setup_scope != NULL);
|
||||
*auto_setup_scope = true;
|
||||
return reinterpret_cast<Dart_NativeFunction>(&ExceptionNative);
|
||||
return ExceptionNative;
|
||||
}
|
||||
|
||||
TEST_CASE(DartAPI_ThrowException) {
|
||||
@@ -6557,9 +6573,9 @@ static Dart_NativeFunction native_args_lookup(Dart_Handle name,
|
||||
const char* function_name = obj.ToCString();
|
||||
ASSERT(function_name != NULL);
|
||||
if (strcmp(function_name, "NativeArgument_Create") == 0) {
|
||||
return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentCreate);
|
||||
return NativeArgumentCreate;
|
||||
} else if (strcmp(function_name, "NativeArgument_Access") == 0) {
|
||||
return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentAccess);
|
||||
return NativeArgumentAccess;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -6618,7 +6634,7 @@ static Dart_NativeFunction gnac_lookup(Dart_Handle name,
|
||||
bool* auto_setup_scope) {
|
||||
ASSERT(auto_setup_scope != NULL);
|
||||
*auto_setup_scope = true;
|
||||
return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentCounter);
|
||||
return NativeArgumentCounter;
|
||||
}
|
||||
|
||||
TEST_CASE(DartAPI_GetNativeArgumentCount) {
|
||||
|
||||
@@ -806,6 +806,7 @@ class ClassLayout : public ObjectLayout {
|
||||
friend class SnapshotReader;
|
||||
friend class InstanceSerializationCluster;
|
||||
friend class CidRewriteVisitor;
|
||||
friend class Api;
|
||||
};
|
||||
|
||||
class PatchClassLayout : public ObjectLayout {
|
||||
|
||||
Reference in New Issue
Block a user