15ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver/*
25ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * Copyright 2013, Google Inc.
35ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * All rights reserved.
45ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver *
55ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * Redistribution and use in source and binary forms, with or without
65ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * modification, are permitted provided that the following conditions are
75ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * met:
85ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver *
95ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver *     * Redistributions of source code must retain the above copyright
105ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * notice, this list of conditions and the following disclaimer.
115ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver *     * Redistributions in binary form must reproduce the above
125ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * copyright notice, this list of conditions and the following disclaimer
135ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * in the documentation and/or other materials provided with the
145ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * distribution.
155ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver *     * Neither the name of Google Inc. nor the names of its
165ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * contributors may be used to endorse or promote products derived from
175ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * this software without specific prior written permission.
185ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver *
195ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver */
315ff4ee9a3fc898dbe9a67386e984f14c21338391Ben Gruver
32160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruverpackage org.jf.dexlib2.builder;
33160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
3490db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruverimport com.google.common.collect.ImmutableList;
35688611814ddff6babff935e81dcf51aff903563aBen Gruverimport org.jf.dexlib2.builder.debug.*;
36160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruverimport org.jf.dexlib2.iface.instruction.Instruction;
37688611814ddff6babff935e81dcf51aff903563aBen Gruverimport org.jf.dexlib2.iface.reference.StringReference;
38688611814ddff6babff935e81dcf51aff903563aBen Gruverimport org.jf.dexlib2.iface.reference.TypeReference;
39160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
40160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruverimport javax.annotation.Nonnull;
41160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruverimport javax.annotation.Nullable;
4290db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruverimport java.util.*;
43160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
44160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruverpublic class MethodLocation {
45e80efa670f1027fdf3882a298216a460199e38d0Ben Gruver    @Nullable BuilderInstruction instruction;
46160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    int codeAddress;
47160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    int index;
48160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
4990db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    // We end up creating and keeping around a *lot* of MethodLocation objects
5090db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    // when building a new dex file, so it's worth the trouble of lazily creating
5190db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    // the labels and debugItems lists only when they are needed
5290db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver
5390db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    @Nullable
5490db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    private List<Label> labels = null;
5590db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    @Nullable
5690db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    private List<BuilderDebugItem> debugItems = null;
57160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
58160449b83a0a19244ae27d0c9acf539c0c730be5Ben Gruver    MethodLocation(@Nullable BuilderInstruction instruction, int codeAddress, int index) {
59160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver        this.instruction = instruction;
60160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver        this.codeAddress = codeAddress;
61160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver        this.index = index;
62160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    }
63160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
64160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    @Nullable
65160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    public Instruction getInstruction() {
66160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver        return instruction;
67160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    }
68160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
69160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    public int getCodeAddress() {
70160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver        return codeAddress;
71160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    }
72160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
73160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    public int getIndex() {
74160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver        return index;
75160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    }
76160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
7790db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    @Nonnull
7890db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    private List<Label> getLabels(boolean mutable) {
7990db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        if (labels == null) {
8090db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            if (mutable) {
8190db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                labels = new ArrayList<Label>(1);
8290db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                return labels;
8390db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            }
8490db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            return ImmutableList.of();
8590db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        }
8690db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        return labels;
8790db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    }
8890db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver
8990db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    @Nonnull
9090db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    private List<BuilderDebugItem> getDebugItems(boolean mutable) {
9190db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        if (debugItems == null) {
9290db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            if (mutable) {
9390db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                debugItems = new ArrayList<BuilderDebugItem>(1);
9490db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                return debugItems;
9590db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            }
9690db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            return ImmutableList.of();
9790db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        }
9890db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        return debugItems;
9990db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver    }
10090db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver
101e80efa670f1027fdf3882a298216a460199e38d0Ben Gruver    void mergeInto(@Nonnull MethodLocation other) {
10290db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        if (this.labels != null || other.labels != null) {
10390db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            List<Label> otherLabels = other.getLabels(true);
10490db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            for (Label label: this.getLabels(false)) {
10590db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                label.location = other;
10690db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                otherLabels.add(label);
10790db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            }
10890db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            this.labels = null;
109e80efa670f1027fdf3882a298216a460199e38d0Ben Gruver        }
110e80efa670f1027fdf3882a298216a460199e38d0Ben Gruver
11190db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        if (this.debugItems != null || other.labels != null) {
11290db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            // We need to keep the debug items in the same order. We add the other debug items to this list, then reassign
11390db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            // the list.
11490db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            List<BuilderDebugItem> debugItems = getDebugItems(true);
11590db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            for (BuilderDebugItem debugItem: debugItems) {
11690db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                debugItem.location = other;
11790db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            }
11890db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            debugItems.addAll(other.getDebugItems(false));
11990db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            other.debugItems = debugItems;
12090db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver            this.debugItems = null;
121e80efa670f1027fdf3882a298216a460199e38d0Ben Gruver        }
122e80efa670f1027fdf3882a298216a460199e38d0Ben Gruver    }
123e80efa670f1027fdf3882a298216a460199e38d0Ben Gruver
124160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    @Nonnull
125688611814ddff6babff935e81dcf51aff903563aBen Gruver    public Set<Label> getLabels() {
126688611814ddff6babff935e81dcf51aff903563aBen Gruver        return new AbstractSet<Label>() {
127688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Nonnull
128688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Override public Iterator<Label> iterator() {
12990db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                final Iterator<Label> it = getLabels(false).iterator();
130160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
131688611814ddff6babff935e81dcf51aff903563aBen Gruver                return new Iterator<Label>() {
132688611814ddff6babff935e81dcf51aff903563aBen Gruver                    private @Nullable Label currentLabel = null;
133688611814ddff6babff935e81dcf51aff903563aBen Gruver
134688611814ddff6babff935e81dcf51aff903563aBen Gruver                    @Override public boolean hasNext() {
135688611814ddff6babff935e81dcf51aff903563aBen Gruver                        return it.hasNext();
136688611814ddff6babff935e81dcf51aff903563aBen Gruver                    }
137688611814ddff6babff935e81dcf51aff903563aBen Gruver
138688611814ddff6babff935e81dcf51aff903563aBen Gruver                    @Override public Label next() {
139688611814ddff6babff935e81dcf51aff903563aBen Gruver                        currentLabel = it.next();
140688611814ddff6babff935e81dcf51aff903563aBen Gruver                        return currentLabel;
141688611814ddff6babff935e81dcf51aff903563aBen Gruver                    }
142688611814ddff6babff935e81dcf51aff903563aBen Gruver
143688611814ddff6babff935e81dcf51aff903563aBen Gruver                    @Override public void remove() {
144688611814ddff6babff935e81dcf51aff903563aBen Gruver                        if (currentLabel != null) {
145688611814ddff6babff935e81dcf51aff903563aBen Gruver                            currentLabel.location = null;
146688611814ddff6babff935e81dcf51aff903563aBen Gruver                        }
147688611814ddff6babff935e81dcf51aff903563aBen Gruver                        it.remove();
148688611814ddff6babff935e81dcf51aff903563aBen Gruver                    }
149688611814ddff6babff935e81dcf51aff903563aBen Gruver                };
150688611814ddff6babff935e81dcf51aff903563aBen Gruver            }
151688611814ddff6babff935e81dcf51aff903563aBen Gruver
152688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Override public int size() {
15390db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                return getLabels(false).size();
154688611814ddff6babff935e81dcf51aff903563aBen Gruver            }
155688611814ddff6babff935e81dcf51aff903563aBen Gruver
156688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Override public boolean add(@Nonnull Label label) {
157688611814ddff6babff935e81dcf51aff903563aBen Gruver                if (label.isPlaced()) {
158688611814ddff6babff935e81dcf51aff903563aBen Gruver                    throw new IllegalArgumentException("Cannot add a label that is already placed. You must remove " +
159688611814ddff6babff935e81dcf51aff903563aBen Gruver                            "it from its current location first.");
160688611814ddff6babff935e81dcf51aff903563aBen Gruver                }
161688611814ddff6babff935e81dcf51aff903563aBen Gruver                label.location = MethodLocation.this;
16290db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                getLabels(true).add(label);
163688611814ddff6babff935e81dcf51aff903563aBen Gruver                return true;
164688611814ddff6babff935e81dcf51aff903563aBen Gruver            }
165688611814ddff6babff935e81dcf51aff903563aBen Gruver        };
166160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    }
167160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
168160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    @Nonnull
169bb7937fd308738b46db61e5e6181dff3c8e6e19eBen Gruver    public Label addNewLabel() {
170bb7937fd308738b46db61e5e6181dff3c8e6e19eBen Gruver        Label label = new Label(this);
17190db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver        getLabels(true).add(label);
172160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver        return label;
173160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    }
174160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver
175688611814ddff6babff935e81dcf51aff903563aBen Gruver    @Nonnull
176688611814ddff6babff935e81dcf51aff903563aBen Gruver    public Set<BuilderDebugItem> getDebugItems() {
177688611814ddff6babff935e81dcf51aff903563aBen Gruver        return new AbstractSet<BuilderDebugItem>() {
178688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Nonnull
179688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Override public Iterator<BuilderDebugItem> iterator() {
18090db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                final Iterator<BuilderDebugItem> it = getDebugItems(false).iterator();
181688611814ddff6babff935e81dcf51aff903563aBen Gruver
182688611814ddff6babff935e81dcf51aff903563aBen Gruver                return new Iterator<BuilderDebugItem>() {
183688611814ddff6babff935e81dcf51aff903563aBen Gruver                    private @Nullable BuilderDebugItem currentDebugItem = null;
184688611814ddff6babff935e81dcf51aff903563aBen Gruver
185688611814ddff6babff935e81dcf51aff903563aBen Gruver                    @Override public boolean hasNext() {
186688611814ddff6babff935e81dcf51aff903563aBen Gruver                        return it.hasNext();
187688611814ddff6babff935e81dcf51aff903563aBen Gruver                    }
188688611814ddff6babff935e81dcf51aff903563aBen Gruver
189688611814ddff6babff935e81dcf51aff903563aBen Gruver                    @Override public BuilderDebugItem next() {
190688611814ddff6babff935e81dcf51aff903563aBen Gruver                        currentDebugItem = it.next();
191688611814ddff6babff935e81dcf51aff903563aBen Gruver                        return currentDebugItem;
192688611814ddff6babff935e81dcf51aff903563aBen Gruver                    }
193688611814ddff6babff935e81dcf51aff903563aBen Gruver
194688611814ddff6babff935e81dcf51aff903563aBen Gruver                    @Override public void remove() {
195688611814ddff6babff935e81dcf51aff903563aBen Gruver                        if (currentDebugItem != null) {
196688611814ddff6babff935e81dcf51aff903563aBen Gruver                            currentDebugItem.location = null;
197688611814ddff6babff935e81dcf51aff903563aBen Gruver                        }
198688611814ddff6babff935e81dcf51aff903563aBen Gruver                        it.remove();
199688611814ddff6babff935e81dcf51aff903563aBen Gruver                    }
200688611814ddff6babff935e81dcf51aff903563aBen Gruver                };
201688611814ddff6babff935e81dcf51aff903563aBen Gruver            }
202688611814ddff6babff935e81dcf51aff903563aBen Gruver
203688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Override public int size() {
20490db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                return getDebugItems(false).size();
205688611814ddff6babff935e81dcf51aff903563aBen Gruver            }
206688611814ddff6babff935e81dcf51aff903563aBen Gruver
207688611814ddff6babff935e81dcf51aff903563aBen Gruver            @Override public boolean add(@Nonnull BuilderDebugItem debugItem) {
208688611814ddff6babff935e81dcf51aff903563aBen Gruver                if (debugItem.location != null) {
209688611814ddff6babff935e81dcf51aff903563aBen Gruver                    throw new IllegalArgumentException("Cannot add a debug item that has already been added to a " +
210688611814ddff6babff935e81dcf51aff903563aBen Gruver                            "method. You must remove it from its current location first.");
211688611814ddff6babff935e81dcf51aff903563aBen Gruver                }
212688611814ddff6babff935e81dcf51aff903563aBen Gruver                debugItem.location = MethodLocation.this;
21390db3a16b79470f4b67a4e3c008f98f9c90e0326Ben Gruver                getDebugItems(true).add(debugItem);
214688611814ddff6babff935e81dcf51aff903563aBen Gruver                return true;
215688611814ddff6babff935e81dcf51aff903563aBen Gruver            }
216688611814ddff6babff935e81dcf51aff903563aBen Gruver        };
217688611814ddff6babff935e81dcf51aff903563aBen Gruver    }
218688611814ddff6babff935e81dcf51aff903563aBen Gruver
219688611814ddff6babff935e81dcf51aff903563aBen Gruver    public void addLineNumber(int lineNumber) {
22084be16bf51399a2198fb48d614050d72f6b042d0Ben Gruver        getDebugItems().add(new BuilderLineNumber(lineNumber));
221688611814ddff6babff935e81dcf51aff903563aBen Gruver    }
222688611814ddff6babff935e81dcf51aff903563aBen Gruver
223688611814ddff6babff935e81dcf51aff903563aBen Gruver    public void addStartLocal(int registerNumber, @Nullable StringReference name, @Nullable TypeReference type,
224688611814ddff6babff935e81dcf51aff903563aBen Gruver                              @Nullable StringReference signature) {
22584be16bf51399a2198fb48d614050d72f6b042d0Ben Gruver        getDebugItems().add(new BuilderStartLocal(registerNumber, name, type, signature));
226688611814ddff6babff935e81dcf51aff903563aBen Gruver    }
227688611814ddff6babff935e81dcf51aff903563aBen Gruver
228688611814ddff6babff935e81dcf51aff903563aBen Gruver    public void addEndLocal(int registerNumber) {
22984be16bf51399a2198fb48d614050d72f6b042d0Ben Gruver        getDebugItems().add(new BuilderEndLocal(registerNumber));
230688611814ddff6babff935e81dcf51aff903563aBen Gruver    }
231688611814ddff6babff935e81dcf51aff903563aBen Gruver
232688611814ddff6babff935e81dcf51aff903563aBen Gruver    public void addRestartLocal(int registerNumber) {
23384be16bf51399a2198fb48d614050d72f6b042d0Ben Gruver        getDebugItems().add(new BuilderRestartLocal(registerNumber));
234688611814ddff6babff935e81dcf51aff903563aBen Gruver    }
235688611814ddff6babff935e81dcf51aff903563aBen Gruver
236688611814ddff6babff935e81dcf51aff903563aBen Gruver    public void addPrologue() {
23784be16bf51399a2198fb48d614050d72f6b042d0Ben Gruver        getDebugItems().add(new BuilderPrologueEnd());
238688611814ddff6babff935e81dcf51aff903563aBen Gruver    }
239688611814ddff6babff935e81dcf51aff903563aBen Gruver
240688611814ddff6babff935e81dcf51aff903563aBen Gruver    public void addEpilogue() {
24184be16bf51399a2198fb48d614050d72f6b042d0Ben Gruver        getDebugItems().add(new BuilderEpilogueBegin());
242688611814ddff6babff935e81dcf51aff903563aBen Gruver    }
243688611814ddff6babff935e81dcf51aff903563aBen Gruver
244263083faede803c028b2807b4abe761391bc3a98Ben Gruver    public void addSetSourceFile(@Nullable StringReference sourceFile) {
24584be16bf51399a2198fb48d614050d72f6b042d0Ben Gruver        getDebugItems().add(new BuilderSetSourceFile(sourceFile));
246160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver    }
247160fc1cdbabb1aafaadde1f8d872574b0666f1dcBen Gruver}
248