-
-
Notifications
You must be signed in to change notification settings - Fork 687
Expand file tree
/
Copy pathrtrace.ts
More file actions
80 lines (70 loc) · 1.95 KB
/
rtrace.ts
File metadata and controls
80 lines (70 loc) · 1.95 KB
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
79
80
/**
* @fileoverview A lightweight store instrumentation pass.
*
* Can be used to find rogue stores to protected memory addresses like object
* headers or similar, without going overboard with instrumentation. Also
* passes a flag whether a store originates within the runtime or other code.
*
* @license Apache-2.0
*/
import {
Pass
} from "./pass";
import {
Compiler
} from "../compiler";
import {
createType,
ExpressionRef,
TypeRef
} from "../module";
import {
_BinaryenFunctionGetName,
_BinaryenStoreGetBytes,
_BinaryenStoreGetOffset,
_BinaryenStoreGetPtr,
_BinaryenStoreSetPtr
} from "../glue/binaryen";
/** Instruments stores to also call an import. */
export class RtraceMemory extends Pass {
/** Whether we've seen any stores. */
seenStores: bool = false;
/** Target pointer type. */
ptrType: TypeRef;
constructor(compiler: Compiler) {
super(compiler.module);
this.ptrType = compiler.options.sizeTypeRef;
}
checkRT(): bool {
let functionName = this.module.readStringCached(_BinaryenFunctionGetName(this.currentFunction))!;
return functionName.startsWith("~lib/rt/");
}
/** @override */
visitStore(store: ExpressionRef): void {
let module = this.module;
let ptr = _BinaryenStoreGetPtr(store);
let offset = _BinaryenStoreGetOffset(store);
let bytes = _BinaryenStoreGetBytes(store);
// onstore(ptr: usize, offset: i32, bytes: i32, isRT: bool) -> ptr
_BinaryenStoreSetPtr(store,
module.call("~onstore", [
ptr,
module.i32(offset),
module.i32(bytes),
module.i32(i32(this.checkRT()))
], this.ptrType)
);
this.seenStores = true;
}
// TODO: MemoryFill, Atomics
/** @override */
walkModule(): void {
super.walkModule();
if (this.seenStores) {
this.module.addFunctionImport("~onstore", "rtrace", "onstore",
createType([ this.ptrType, TypeRef.I32, TypeRef.I32, TypeRef.I32 ]),
this.ptrType
);
}
}
}