Skip to content

Commit

Permalink
Version 3.6.0-192.0.dev
Browse files Browse the repository at this point in the history
Merge 3f17f33 into dev
  • Loading branch information
Dart CI committed Aug 28, 2024
2 parents bc3dad1 + 3f17f33 commit 1f6c1df
Show file tree
Hide file tree
Showing 15 changed files with 196 additions and 9 deletions.
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ if (is_fuchsia) {
"tests/ffi/abi_specific_int_test.dart",
"tests/ffi/abi_test.dart",
"tests/ffi/address_of_array_generated_test.dart",
"tests/ffi/address_of_cast_test.dart",
"tests/ffi/address_of_struct_generated_test.dart",
"tests/ffi/address_of_test.dart",
"tests/ffi/address_of_typeddata_generated_test.dart",
Expand Down
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ vars = {
"material_color_utilities_rev": "799b6ba2f3f1c28c67cc7e0b4f18e0c7d7f3c03e",
"mime_rev": "11fec7d6df509a4efd554051cc27e3bf82df9c96",
"mockito_rev": "eb4d1daa20c105c94ac29689c1975f0850fa18f2",
"native_rev": "7efefec16509ed38544a8af999b9e85694586bc7", # mosum@ and dacoharkes@ are rolling breaking changes manually while the assets features are in experimental.
"native_rev": "87e8f924f06458ccba11dda7edc26d607c663d60", # dart-native-interop-team@ is rolling breaking changes manually while the assets features are in experimental.
"package_config_rev": "76934c2ca25922ec72909bbff7dfbddaf0d02bd9",
"path_rev": "e969f42ed112dd702a9453beb9df6c12ae2d3805",
"pool_rev": "924fb04353cec915d927f9f1aed88e2eda92b98a",
Expand Down
10 changes: 10 additions & 0 deletions pkg/dart2bytecode/lib/assembler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -755,4 +755,14 @@ class BytecodeAssembler {
void emitJumpIfInitialized(Label label) {
_emitJumpInstruction(Opcode.kJumpIfInitialized, label);
}

@pragma('vm:prefer-inline')
void emitAllocateRecord(int rd) {
_emitInstructionD(Opcode.kAllocateRecord, rd);
}

@pragma('vm:prefer-inline')
void emitLoadRecordField(int rd) {
_emitInstructionD(Opcode.kLoadRecordField, rd);
}
}
28 changes: 25 additions & 3 deletions pkg/dart2bytecode/lib/bytecode_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4252,17 +4252,39 @@ class BytecodeGenerator extends RecursiveVisitor {

@override
void visitRecordIndexGet(RecordIndexGet node) {
_unimplemented(node, 'RecordIndexGet');
_generateNode(node.receiver);
asm.emitLoadRecordField(node.index);
}

@override
void visitRecordNameGet(RecordNameGet node) {
_unimplemented(node, 'RecordNameGet');
final type = node.receiverType;
final namedFields = type.named;
final name = node.name;
int fieldIndex = -1;
for (int i = 0; i < namedFields.length; ++i) {
if (namedFields[i].name == name) {
fieldIndex = type.positional.length + i;
break;
}
}
if (fieldIndex < 0) {
throw 'Unable to find record field "$name" in $type';
}
_generateNode(node.receiver);
asm.emitLoadRecordField(fieldIndex);
}

@override
void visitRecordLiteral(RecordLiteral node) {
_unimplemented(node, 'RecordLiteral');
assert(!node.isConst);
for (final expr in node.positional) {
_generateNode(expr);
}
for (final expr in node.named) {
_generateNode(expr.value);
}
asm.emitAllocateRecord(cp.addType(node.recordType));
}

@override
Expand Down
10 changes: 10 additions & 0 deletions pkg/dart2bytecode/lib/dbc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ enum Opcode {
kCompareDoubleLt,
kCompareDoubleGe,
kCompareDoubleLe,

// Records
kAllocateRecord,
kAllocateRecord_Wide,
kLoadRecordField,
kLoadRecordField_Wide,
}

/// Compact variants of opcodes are always even.
Expand Down Expand Up @@ -456,6 +462,10 @@ const Map<Opcode, Format> BytecodeFormats = const {
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kCompareDoubleLe: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kAllocateRecord: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
Opcode.kLoadRecordField: const Format(
Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
};

// Should match constant in runtime/vm/stack_frame_kbc.h.
Expand Down
18 changes: 18 additions & 0 deletions pkg/dart2bytecode/lib/object_table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ enum ConstTag {
kString,
kMap,
kSet,
kRecord,
}

enum TypeTag {
Expand Down Expand Up @@ -1405,6 +1406,7 @@ class _ConstObjectHandle extends ObjectHandle {
}
break;
case ConstTag.kList:
case ConstTag.kRecord:
case ConstTag.kMap:
case ConstTag.kSet:
{
Expand Down Expand Up @@ -1461,6 +1463,7 @@ class _ConstObjectHandle extends ObjectHandle {
reader.readPackedObject(), reader.readPackedObject())));
break;
case ConstTag.kList:
case ConstTag.kRecord:
case ConstTag.kMap:
case ConstTag.kSet:
type = reader.readPackedObject();
Expand Down Expand Up @@ -1503,6 +1506,7 @@ class _ConstObjectHandle extends ObjectHandle {
}
break;
case ConstTag.kList:
case ConstTag.kRecord:
case ConstTag.kMap:
case ConstTag.kSet:
{
Expand Down Expand Up @@ -1579,6 +1583,7 @@ class _ConstObjectHandle extends ObjectHandle {
_combineHashes(type.hashCode, mapHashCode(fieldValues));
}
case ConstTag.kList:
case ConstTag.kRecord:
case ConstTag.kMap:
case ConstTag.kSet:
{
Expand Down Expand Up @@ -1610,6 +1615,7 @@ class _ConstObjectHandle extends ObjectHandle {
case ConstTag.kInstance:
return this.type == other.type && mapEquals(this.value, other.value);
case ConstTag.kList:
case ConstTag.kRecord:
case ConstTag.kMap:
case ConstTag.kSet:
return this.type == other.type && listEquals(this.value, other.value);
Expand All @@ -1634,6 +1640,8 @@ class _ConstObjectHandle extends ObjectHandle {
return 'const $type $value';
case ConstTag.kList:
return 'const List<$type> $value';
case ConstTag.kRecord:
return 'const Record<$type> $value';
case ConstTag.kMap:
return 'const Map<$type> $value';
case ConstTag.kSet:
Expand Down Expand Up @@ -2382,6 +2390,16 @@ class _NodeVisitor extends VisitorDefault<ObjectHandle?>
objectTable.getHandles(node.entries),
objectTable.getHandle(node.typeArgument)));

@override
ObjectHandle? visitRecordConstant(RecordConstant node) =>
objectTable.getOrAddObject(new _ConstObjectHandle(
ConstTag.kRecord,
objectTable.getHandles([
...node.positional,
...node.named.values,
]),
objectTable.getHandle(node.recordType)));

@override
ObjectHandle? visitMapConstant(MapConstant node) =>
objectTable.getOrAddObject(new _ConstObjectHandle(
Expand Down
8 changes: 8 additions & 0 deletions pkg/test_runner/lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@ class TestConfiguration {
}

assert(Platform.isLinux);
final nmKey = unparseKey('${CCompilerConfigImpl.configKey}.nm');
final objdumpKey = unparseKey('${CCompilerConfigImpl.configKey}.objdump');
final otoolKey = unparseKey('${CCompilerConfigImpl.configKey}.otool');
final readelfKey = unparseKey('${CCompilerConfigImpl.configKey}.readelf');
// Keep consistent with DEPS.
const clangHostFolderName = {
Abi.linuxArm64: 'linux-arm64',
Expand All @@ -350,6 +354,10 @@ class TestConfiguration {
arKey: clangBin.resolve('llvm-ar').toFilePath(),
ccKey: clangBin.resolve('clang').toFilePath(),
ldKey: clangBin.resolve('ld.lld').toFilePath(),
nmKey: clangBin.resolve('llvm-nm').toFilePath(),
otoolKey: clangBin.resolve('llvm-otool').toFilePath(),
objdumpKey: clangBin.resolve('llvm-objdump').toFilePath(),
readelfKey: clangBin.resolve('llvm-readelf').toFilePath(),
};
}();

Expand Down
5 changes: 5 additions & 0 deletions runtime/docs/contributing_to_dart_ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,8 @@ To add all the CI bots that cover running the FFI in different configurations, y
(This only works for already existing tests, so if you’re adding a new test, you can get the list of bots from a pre-existing test, for example the one above.)

Prefer using Gerrit directly for uploading a PR rather than using pull requests via GitHub. For more info see [the Contributing guide](https://github.com/dart-lang/sdk/blob/main/CONTRIBUTING.md#uploading-the-patch-for-review).

## New tests

Any new tests need to be added to the root `BUILD.gn` `test_sources`.
This adds the test sources to the `fuchsia_component` that tests FFI on Fuchsia.
3 changes: 0 additions & 3 deletions runtime/tests/concurrency/stress_test_list.json
Original file line number Diff line number Diff line change
Expand Up @@ -3461,7 +3461,6 @@
"../../../tests/lib/async/future_constructor2_test.dart",
"../../../tests/lib/async/future_constructor_test.dart",
"../../../tests/lib/async/future_delayed_error_test.dart",
"../../../tests/lib/async/future_error_test.dart",
"../../../tests/lib/async/future_extension_test.dart",
"../../../tests/lib/async/future_foreach_test.dart",
"../../../tests/lib/async/future_future_test.dart",
Expand Down Expand Up @@ -3532,7 +3531,6 @@
"../../../tests/lib/async/stack_trace23_test.dart",
"../../../tests/lib/async/stack_trace24_test.dart",
"../../../tests/lib/async/stack_trace25_test.dart",
"../../../tests/lib/async/stream_controller_add_error_test.dart",
"../../../tests/lib/async/stream_controller_async_test.dart",
"../../../tests/lib/async/stream_controller_test.dart",
"../../../tests/lib/async/stream_distinct_test.dart",
Expand Down Expand Up @@ -3576,7 +3574,6 @@
"../../../tests/lib/async/timer_repeat_test.dart",
"../../../tests/lib/async/unawaited_test.dart",
"../../../tests/lib/async/uncaught_error_handler_throws_test.dart",
"../../../tests/lib/async/zone_async_error_test.dart",
"../../../tests/lib/async/zone_error_callback_test.dart",
"../../../tests/lib/async/zone_future_schedule_microtask_test.dart",
"../../../tests/lib/collection/failing_list_test.dart",
Expand Down
54 changes: 53 additions & 1 deletion runtime/vm/bytecode_reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,7 @@ ObjectPtr BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
kString,
kMap,
kSet,
kRecord,
};

switch (tag) {
Expand Down Expand Up @@ -1221,6 +1222,20 @@ ObjectPtr BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
}
return Canonicalize(set);
}
case kRecord: {
const RecordType& record_type =
RecordType::CheckedHandle(Z, ReadObject());
const intptr_t num_fields = reader_.ReadUInt();
ASSERT(num_fields == record_type.NumFields());
const RecordShape shape = record_type.shape();
const auto& record = Record::Handle(Z, Record::New(shape));
Object& value = Object::Handle(Z);
for (intptr_t i = 0; i < num_fields; ++i) {
value = ReadObject();
record.SetFieldAt(i, value);
}
return Canonicalize(record);
}
default:
UNREACHABLE();
}
Expand Down Expand Up @@ -1337,7 +1352,44 @@ ObjectPtr BytecodeReaderHelper::ReadType(intptr_t tag,
/* has_positional_param_names = */ false,
/* has_parameter_flags */ false);
}
case kRecordType:
case kRecordType: {
const intptr_t num_positional = reader_.ReadUInt();
const intptr_t num_named = reader_.ReadUInt();

const intptr_t num_fields = num_positional + num_named;
const Array& field_types =
Array::Handle(Z, Array::New(num_fields, Heap::kOld));
const Array& field_names =
(num_named == 0)
? Object::empty_array()
: Array::Handle(Z, Array::New(num_named, Heap::kOld));
AbstractType& type = AbstractType::Handle(Z);

intptr_t pos = 0;
for (intptr_t i = 0; i < num_positional; ++i) {
type ^= ReadObject();
field_types.SetAt(pos++, type);
}

if (num_named > 0) {
String& name = String::Handle(Z);
for (intptr_t i = 0; i < num_named; ++i) {
name ^= ReadObject();
field_names.SetAt(i, name);
type ^= ReadObject();
field_types.SetAt(pos++, type);
}
field_names.MakeImmutable();
}

const RecordShape shape =
RecordShape::Register(thread_, num_fields, field_names);

type = RecordType::New(shape, field_types, nullability);
type.SetIsFinalized();
return type.Canonicalize(thread_);
}

UNIMPLEMENTED();
default:
UNREACHABLE();
Expand Down
4 changes: 4 additions & 0 deletions runtime/vm/constants_kbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,10 @@ namespace dart {
V(CompareDoubleLt, 0, ORDN, ___, ___, ___) \
V(CompareDoubleGe, 0, ORDN, ___, ___, ___) \
V(CompareDoubleLe, 0, ORDN, ___, ___, ___) \
V(AllocateRecord, D, ORDN, lit, ___, ___) \
V(AllocateRecord_Wide, D, WIDE, lit, ___, ___) \
V(LoadRecordField, D, ORDN, num, ___, ___) \
V(LoadRecordField_Wide, D, WIDE, num, ___, ___) \

// These bytecodes are only generated within the VM. Reassigning their
// opcodes is not a breaking change.
Expand Down
53 changes: 53 additions & 0 deletions runtime/vm/interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,33 @@ bool Interpreter::AllocateArray(Thread* thread,
return InvokeRuntime(thread, this, DRT_AllocateArray, args);
}

// Allocate a Record with the given shape and put it into SP[0].
// Returns false on exception.
bool Interpreter::AllocateRecord(Thread* thread,
RecordShape shape,
const KBCInstr* pc,
ObjectPtr* FP,
ObjectPtr* SP) {
const intptr_t num_fields = shape.num_fields();
RecordPtr result;
if (TryAllocate(thread, kRecordCid, Record::InstanceSize(num_fields),
reinterpret_cast<ObjectPtr*>(&result))) {
result->untag()->set_shape(shape.AsSmi());
ObjectPtr null_value = Object::null();
for (intptr_t i = 0; i < num_fields; i++) {
result->untag()->set_field(i, null_value, thread);
}
SP[0] = result;
return true;
} else {
SP[0] = 0; // Space for the result.
SP[1] = shape.AsSmi();
Exit(thread, FP, SP + 2, pc);
NativeArguments args(thread, 1, SP + 1, SP);
return InvokeRuntime(thread, this, DRT_AllocateRecord, args);
}
}

// Allocate a _Context with the given length and put it into SP[0].
// Returns false on exception.
bool Interpreter::AllocateContext(Thread* thread,
Expand Down Expand Up @@ -2293,6 +2320,14 @@ ObjectPtr Interpreter::Run(Thread* thread, ObjectPtr* sp) {
DISPATCH();
}

{
BYTECODE(LoadRecordField, D);
const intptr_t field_index = rD;
RecordPtr record = Record::RawCast(SP[0]);
SP[0] = record->untag()->field(field_index);
DISPATCH();
}

{
BYTECODE(AllocateContext, A_E);
++SP;
Expand Down Expand Up @@ -2411,6 +2446,24 @@ ObjectPtr Interpreter::Run(Thread* thread, ObjectPtr* sp) {
DISPATCH();
}

{
BYTECODE(AllocateRecord, D);
RecordTypePtr type = RecordType::RawCast(LOAD_CONSTANT(rD));
RecordShape shape(Smi::RawCast(type->untag()->shape()));
++SP;
if (!AllocateRecord(thread, shape, pc, FP, SP)) {
HANDLE_EXCEPTION;
}
RecordPtr record = Record::RawCast(SP[0]);
const intptr_t num_fields = shape.num_fields();
for (intptr_t i = 0; i < num_fields; ++i) {
record->untag()->set_field(i, SP[-num_fields + i], thread);
}
SP -= num_fields;
SP[0] = record;
DISPATCH();
}

{
BYTECODE(AssertAssignable, A_E);
// Stack: instance, type, instantiator type args, function type args, name
Expand Down
Loading

0 comments on commit 1f6c1df

Please sign in to comment.