| // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // Regression test for b/306327173. |
| |
| import 'dart:ffi'; |
| |
| import 'package:expect/expect.dart'; |
| import 'package:ffi/ffi.dart'; |
| import 'package:vm/testing/il_matchers.dart'; |
| |
| @pragma('vm:never-inline') |
| @pragma('vm:testing:print-flow-graph') |
| int deref(Pointer<Pointer<Void>> a) { |
| return a.value.address; |
| } |
| |
| void matchIL$deref(FlowGraph graph) { |
| final retvalName = is32BitConfiguration ? 'address' : 'unboxed'; |
| graph.match([ |
| match.block('Graph', ['c0' << match.UnboxedConstant(value: 0)]), |
| match.block('Function', [ |
| 'ptr' << match.Parameter(index: 0), |
| 'array' << match.LoadField('ptr', slot: 'PointerBase.data'), |
| 'unboxed' << match.LoadIndexed('array', 'c0'), |
| // 'unboxed' is uint32 on 32-bit archs and int64 on 64-bit archs, so |
| // that 32-bit addresses are zero-extended to a 64-bit Dart integer. |
| if (is32BitConfiguration) ...[ |
| // 'unboxed' needs to be converted to int64 before returning. |
| 'address' << match.IntConverter('unboxed', from: 'uint32', to: 'int64'), |
| ], |
| match.DartReturn(retvalName), |
| ]), |
| ]); |
| } |
| |
| void main() { |
| const ptrValue = 0x80000000; |
| if (!isSimulator) { |
| using((arena) { |
| final p = arena.allocate<Pointer<Void>>(sizeOf<Pointer<Void>>()); |
| p.value = Pointer.fromAddress(ptrValue); |
| Expect.equals(ptrValue, deref(p)); |
| }); |
| } |
| } |