Check-in [1429835cc3]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add side by side debug to compare byte code and native instructions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:1429835cc369d1cf063a1a937faaecf216763610
User & Date: stephanie.gawroriski 2019-06-12 18:54:28
Context
2019-06-12
19:00
Add line population change count to show when a line has gone back (such as for loops). check-in: 37e31228d6 user: stephanie.gawroriski tags: trunk
18:54
Add side by side debug to compare byte code and native instructions. check-in: 1429835cc3 user: stephanie.gawroriski tags: trunk
17:13
Do not translate value for LOAD_POOL in debug print. check-in: b02eedf11f user: stephanie.gawroriski tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to bldt/libs/builder-support/cc/squirreljme/builder/support/Binary.java.

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
...
214
215
216
217
218
219
220























221
222
223
224
225
226
227
import cc.squirreljme.runtime.swm.DependencyInfo;
import cc.squirreljme.runtime.swm.MatchResult;
import cc.squirreljme.runtime.swm.ProvidedInfo;
import cc.squirreljme.runtime.swm.SuiteInfo;
import cc.squirreljme.runtime.swm.SuiteName;
import cc.squirreljme.runtime.swm.SuiteVendor;
import cc.squirreljme.runtime.swm.SuiteVersion;
import java.io.InputStream;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.nio.file.attribute.FileTime;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.multiphasicapps.collections.SortedTreeSet;



import net.multiphasicapps.tool.manifest.JavaManifest;
import net.multiphasicapps.tool.manifest.JavaManifestAttributes;
import net.multiphasicapps.tool.manifest.JavaManifestKey;
import net.multiphasicapps.zip.blockreader.FileChannelBlockAccessor;
import net.multiphasicapps.zip.blockreader.ZipBlockReader;
import net.multiphasicapps.zip.streamreader.ZipStreamReader;

................................................................................
	 * @return The binary path.
	 * @since 2017/11/28
	 */
	public final Path path()
	{
		return this.path;
	}























	
	/**
	 * Returns the source project that this binary is built from.
	 *
	 * @return The source project or {@code null} if there is no source.
	 * @since 2017/11/06
	 */







|
|


<




>










>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
import cc.squirreljme.runtime.swm.DependencyInfo;
import cc.squirreljme.runtime.swm.MatchResult;
import cc.squirreljme.runtime.swm.ProvidedInfo;
import cc.squirreljme.runtime.swm.SuiteInfo;
import cc.squirreljme.runtime.swm.SuiteName;
import cc.squirreljme.runtime.swm.SuiteVendor;
import cc.squirreljme.runtime.swm.SuiteVersion;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.FileTime;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.multiphasicapps.collections.SortedTreeSet;
import net.multiphasicapps.javac.CompilerException;
import net.multiphasicapps.javac.CompilerPathSet;
import net.multiphasicapps.javac.ZipPathSet;
import net.multiphasicapps.tool.manifest.JavaManifest;
import net.multiphasicapps.tool.manifest.JavaManifestAttributes;
import net.multiphasicapps.tool.manifest.JavaManifestKey;
import net.multiphasicapps.zip.blockreader.FileChannelBlockAccessor;
import net.multiphasicapps.zip.blockreader.ZipBlockReader;
import net.multiphasicapps.zip.streamreader.ZipStreamReader;

................................................................................
	 * @return The binary path.
	 * @since 2017/11/28
	 */
	public final Path path()
	{
		return this.path;
	}
	
	/**
	 * Returns the path set which represents the binary.
	 *
	 * @return The path set for this binary
	 * @since 2019/06/12
	 */
	public final CompilerPathSet pathSet()
		throws IOException, NullPointerException
	{
		// Just wrap the ZIP
		try
		{
			return new ZipPathSet(this.zipBlock());
		}
		
		// {@squirreljme.error AU2f Could not get the path set for this
		// binary.}
		catch (IOException e)
		{
			throw new CompilerException("AU2f", e);
		}
	}
	
	/**
	 * Returns the source project that this binary is built from.
	 *
	 * @return The source project or {@code null} if there is no source.
	 * @since 2017/11/06
	 */

Added bldt/mids/sxs/META-INF/MANIFEST.MF.



























>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
Manifest-Version: 1.0
X-SquirrelJME-UUID: 62285c91-c4f4-4f61-83fe-ddc2c97e849c
X-SquirrelJME-Error: BL
X-SquirrelJME-Name: Side By Side Code Debug
X-SquirrelJME-Vendor: Stephanie Gawroriski
X-SquirrelJME-Version: 0.3.0
X-SquirrelJME-Description: This utility is used to provide a view into 
 the native code translation by showing a side by side representation 
 of the input source code, the original byte code, and then the 
 generated native code.
Microedition-Configuration: CLDC-1.8-Compact
Main-Class: dev.shadowtail.sxs.Main
X-SquirrelJME-Depends: builder-support

Added bldt/mids/sxs/dev/shadowtail/sxs/Main.java.























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package dev.shadowtail.sxs;

import cc.squirreljme.builder.support.Binary;
import cc.squirreljme.builder.support.BinaryManager;
import cc.squirreljme.builder.support.ProjectManager;
import cc.squirreljme.builder.support.Source;
import cc.squirreljme.builder.support.SourceManager;
import cc.squirreljme.builder.support.SourceName;
import cc.squirreljme.builder.support.SourcePathSetType;
import cc.squirreljme.builder.support.TimeSpaceType;
import dev.shadowtail.classfile.nncc.NativeInstruction;
import dev.shadowtail.classfile.nncc.NativeInstructionType;
import dev.shadowtail.classfile.nncc.NativeCode;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import net.multiphasicapps.classfile.ByteCode;
import net.multiphasicapps.classfile.ClassFile;
import net.multiphasicapps.classfile.Method;
import net.multiphasicapps.javac.CompilerPathSet;
import net.multiphasicapps.javac.NoSuchInputException;

/**
 * Main entry point and dumber for the class code side by side
 *
 * @since 2019/06/12
 */
public class Main
{
	/**
	 * Dumps the given method.
	 *
	 * @param __ps The stream to write to.
	 * @param __srclines The source lines.
	 * @param __m The method to dump.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/12
	 */
	public static final void dump(PrintStream __ps,
		List<String> __srclines, Method __m)
		throws NullPointerException
	{
		if (__ps == null || __srclines == null || __m == null)
			throw new NullPointerException("NARG");
		
		// Note what is being dumped
		__ps.printf("****** %s ******%n", __m.nameAndType());
		
		// Get byte code and native code
		ByteCode bc = __m.byteCode();
		NativeCode nc = __m.nativeCode();
		
		// Native debug information
		int nijln = -1,
			nijop = -1,
			nijpc = -1;
		
		// Last position information, to detect changes
		int lljln = nijln,
			lljop = nijop,
			lljpc = nijpc;
		
		// Major order is the native code
		for (int nidx = 0, numni = nc.length(); nidx < numni; nidx++)
		{
			// Get native instruction details
			NativeInstruction ni = nc.get(nidx);
			int niop = ni.operation();
			
			// Update location information?
			if (niop == NativeInstructionType.DEBUG_POINT)
			{
				nijln = ni.intArgument(0);
				nijop = (ni.intArgument(1) & 0xFF);
				nijpc = ni.intArgument(2);
			}
			
			// Change of source line?
			if (nijln != lljln)
			{
				// Get the line, turn tabs to spaces to save room
				String ln = (nijln > 0 && nijln <= __srclines.size() ?
					__srclines.get(nijln - 1) : "<INVALID LINE?>").
					replace('\t', ' ');
				
				// Print the line text
				__ps.printf("    L%03d: %s%n", nijln, ln);
				
				// Set new last line
				lljln = nijln;
			}
			
			//__ps.println(ni);
		}
		
		// Spacing
		__ps.println();
	}
	
	/**
	 * Main entry points.
	 *
	 * @param __args Arguments.
	 * @throws Throwable On any exception.
	 * @since 2019/06/12
	 */
	public static void main(String... __args)
		throws Throwable
	{
		// Must exist
		if (__args == null)
			__args = new String[0];
		
		// Load project manager
		ProjectManager pm = ProjectManager.fromArguments(__args);
		
		// Get source and binary manager
		SourceManager sm = pm.sourceManager(TimeSpaceType.BUILD);
		BinaryManager bm = pm.binaryManager(TimeSpaceType.BUILD);
		
		// Get project to look in
		SourceName projectname = new SourceName(__args[0]);
		
		// Get both the source and the binary for this project
		Source psrc = sm.get(projectname);
		Binary pbin = bm.get(projectname);
		
		// Get the class we want to look at, make sure dots are slashes!
		String wantclass = __args[1].replace('.', '/');
		
		// Load the class file itself
		ClassFile classfile;
		try (CompilerPathSet cps = pbin.pathSet())
		{
			// Open source for parsing
			try (InputStream in = cps.input(wantclass + ".class").open())
			{
				classfile = ClassFile.decode(in);
			}
		}
		
		// Source file line information
		List<String> lines = new ArrayList<>();
		
		// If a source file is set, read all of it!
		String sfn = classfile.sourceFile();
		if (sfn != null)
			try (CompilerPathSet cps = psrc.pathSet(SourcePathSetType.SOURCE))
			{
				// Read
				try (BufferedReader br =
					new BufferedReader(new InputStreamReader(
						cps.input(wantclass + ".java").open())))
				{
					// Debug
					todo.DEBUG.note("Reading lines...");
					
					// Note
					for (;;)
					{
						String ln = br.readLine();
						
						if (ln == null)
							break;
						
						// Add line
						lines.add(ln);
					}
					
					// Debug
					todo.DEBUG.note("Read %d lines!", lines.size());
				}
			}
			catch (NoSuchInputException e)
			{
				// Ignore
			}
		
		// Process each method
		for (Method m : classfile.methods())
		{
			// Ignore abstracts/native
			if (m.flags().isAbstract() || m.flags().isNative())
				continue;
			
			// Dump it
			Main.dump(System.out, lines, m);
		}
	}
}

Added bldt/mids/sxs/dev/shadowtail/sxs/package-info.java.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

/**
 * This package contains the side by side debug stuff.
 *
 * @since 2019/06/12
 */

package dev.shadowtail.sxs;

Added utils-dev/sxs.sh.





















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/bin/sh
# ---------------------------------------------------------------------------
# Multi-Phasic Applications: SquirrelJME
#     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
# ---------------------------------------------------------------------------
# SquirrelJME is under the GNU General Public License v3+, or later.
# See license.mkd for licensing and copyright information.
# ---------------------------------------------------------------------------
# DESCRIPTION: This quickly and easily launches the side by side debug.

# Force C locale
export LC_ALL=C

# Directory of this script
__exedir="$(dirname -- "$0")"

# Go to temp dir
__tempdir="/tmp/sx"
if [ ! -d "$__tempdir" ]
then
	mkdir -p "$__tempdir"
fi
cd "$__tempdir"

# Execute handler
"$__exedir/hostedlaunch.sh" sxs "$@"