This repository has been archived by the owner on Jan 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 32
/
allocation.dart
78 lines (69 loc) · 2.86 KB
/
allocation.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Copyright (c) 2019, 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.
import 'dart:ffi';
import 'dart:io';
// Note that kernel32.dll is the correct name in both 32-bit and 64-bit.
final DynamicLibrary stdlib = Platform.isWindows
? DynamicLibrary.open('kernel32.dll')
: DynamicLibrary.process();
typedef PosixMallocNative = Pointer Function(IntPtr);
typedef PosixMalloc = Pointer Function(int);
final PosixMalloc posixMalloc =
stdlib.lookupFunction<PosixMallocNative, PosixMalloc>('malloc');
typedef PosixFreeNative = Void Function(Pointer);
typedef PosixFree = void Function(Pointer);
final PosixFree posixFree =
stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
typedef WinGetProcessHeapFn = Pointer Function();
final WinGetProcessHeapFn winGetProcessHeap = stdlib
.lookupFunction<WinGetProcessHeapFn, WinGetProcessHeapFn>('GetProcessHeap');
final Pointer processHeap = winGetProcessHeap();
typedef WinHeapAllocNative = Pointer Function(Pointer, Uint32, IntPtr);
typedef WinHeapAlloc = Pointer Function(Pointer, int, int);
final WinHeapAlloc winHeapAlloc =
stdlib.lookupFunction<WinHeapAllocNative, WinHeapAlloc>('HeapAlloc');
typedef WinHeapFreeNative = Int32 Function(
Pointer heap, Uint32 flags, Pointer memory);
typedef WinHeapFree = int Function(Pointer heap, int flags, Pointer memory);
final WinHeapFree winHeapFree =
stdlib.lookupFunction<WinHeapFreeNative, WinHeapFree>('HeapFree');
/// Allocates memory on the native heap.
///
/// For POSIX-based systems, this uses malloc. On Windows, it uses HeapAlloc
/// against the default public heap. Allocation of either element size or count
/// of 0 is undefined.
///
/// Throws an ArgumentError on failure to allocate.
Pointer<T> allocate<T extends NativeType>({int count = 1}) {
final int totalSize = count * sizeOf<T>();
Pointer<T> result;
if (Platform.isWindows) {
result = winHeapAlloc(processHeap, /*flags=*/ 0, totalSize).cast();
} else {
result = posixMalloc(totalSize).cast();
}
if (result.address == 0) {
throw ArgumentError('Could not allocate $totalSize bytes.');
}
return result;
}
/// Releases memory on the native heap.
///
/// For POSIX-based systems, this uses free. On Windows, it uses HeapFree
/// against the default public heap. It may only be used against pointers
/// allocated in a manner equivalent to [allocate].
///
/// Throws an ArgumentError on failure to free.
///
// TODO(dartbug.com/36855): Once we have a ffi.Bool type we can use it instead
// of testing the return integer to be non-zero.
void free(Pointer pointer) {
if (Platform.isWindows) {
if (winHeapFree(processHeap, /*flags=*/ 0, pointer) == 0) {
throw ArgumentError('Could not free $pointer.');
}
} else {
posixFree(pointer);
}
}