Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.debug.examples.core/.classpath1
-rw-r--r--org.eclipse.debug.examples.core/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.debug.examples.core/pdavm/docs/protocol.html198
-rw-r--r--org.eclipse.debug.examples.core/pdavm/pda.pl678
-rw-r--r--org.eclipse.debug.examples.core/pdavm/src/org/eclipse/debug/examples/pdavm/PDAVirtualMachine.java1408
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest10.pda38
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda2
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest9.pda23
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest_children.pda8
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl448
-rw-r--r--org.eclipse.debug.examples.core/samples/registers.pda72
-rw-r--r--org.eclipse.debug.examples.core/samples/stack.pda21
-rw-r--r--org.eclipse.debug.examples.core/samples/structures.pda21
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java46
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java29
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java44
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java54
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java7
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java104
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java253
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java34
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java59
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java325
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java40
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java14
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDABitFieldData.java41
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAChildrenCommand.java34
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAClearBreakpointCommand.java31
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommand.java40
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommandResult.java27
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADataCommand.java35
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADropFrameCommand.java44
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalCommand.java43
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalResultEvent.java32
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvent.java75
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEventStopCommand.java48
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAExitedEvent.java29
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommand.java36
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommandResult.java30
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameData.java46
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAGroupsCommand.java33
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAListResult.java43
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDANoSuchLabelEvent.java40
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPopDataCommand.java34
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPushDataCommand.java36
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegisterData.java43
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommand.java33
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommandResult.java39
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersEvent.java30
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumeCommand.java40
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumedEvent.java29
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARunControlEvent.java69
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetBreakpointCommand.java46
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetDataCommand.java36
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetVarCommand.java38
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommand.java39
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommandResult.java40
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommand.java36
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommandResult.java31
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStartedEvent.java30
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepCommand.java45
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepReturnCommand.java46
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendCommand.java40
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendedEvent.java43
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminateCommand.java34
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminatedEvent.java29
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAUnimplementedInstructionEvent.java41
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumeCommand.java37
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumedEvent.java36
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMStartedEvent.java30
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendCommand.java37
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendedEvent.java44
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMTerminatedEvent.java29
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVarCommand.java39
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAWatchCommand.java43
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/package.html99
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java9
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java7
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/AbstractDataStackViewHandler.java33
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/CanPushTester.java17
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java86
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopHandler.java14
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushHandler.java8
83 files changed, 4351 insertions, 1781 deletions
diff --git a/org.eclipse.debug.examples.core/.classpath b/org.eclipse.debug.examples.core/.classpath
index 3e3e97273..9f8cf0e63 100644
--- a/org.eclipse.debug.examples.core/.classpath
+++ b/org.eclipse.debug.examples.core/.classpath
@@ -2,6 +2,7 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src_ant"/>
+ <classpathentry kind="src" path="pdavm/src"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
<classpathentry kind="output" path="bin"/>
diff --git a/org.eclipse.debug.examples.core/META-INF/MANIFEST.MF b/org.eclipse.debug.examples.core/META-INF/MANIFEST.MF
index 03f4944c1..c0a830633 100644
--- a/org.eclipse.debug.examples.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.debug.examples.core/META-INF/MANIFEST.MF
@@ -15,6 +15,7 @@ Export-Package: org.eclipse.debug.examples.core.midi.launcher,
org.eclipse.debug.examples.core.pda.breakpoints,
org.eclipse.debug.examples.core.pda.launcher,
org.eclipse.debug.examples.core.pda.model,
- org.eclipse.debug.examples.core.pda.sourcelookup
+ org.eclipse.debug.examples.core.pda.sourcelookup,
+ org.eclipse.debug.examples.core.protocol
Bundle-RequiredExecutionEnvironment: J2SE-1.4
Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.debug.examples.core/pdavm/docs/protocol.html b/org.eclipse.debug.examples.core/pdavm/docs/protocol.html
deleted file mode 100644
index 9e2b92749..000000000
--- a/org.eclipse.debug.examples.core/pdavm/docs/protocol.html
+++ /dev/null
@@ -1,198 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
- <meta content="text/html; charset=ISO-8859-1"
- http-equiv="content-type">
- <title>PDA Debugger Protocol Reference</title>
-</head>
-<body>
-
-<h2>PDA Debugger Protocol Reference</h2>
-
-<h3>clear</h3>
-Clears any breakpoint set on given line
-<pre>
- C: clear {line}
- R: ok
-</pre>
-
-
-<h3>data</h3>
-Retrieves data stack information
-<pre>
- C: data
- R: {value 1}|{value 2}|{value 3}|...|
-</pre>
-
-
-<h3>drop</h3>
-Returns from the current frame without executing the rest of instructions.
-
-<pre>
- C: drop
- R: ok
- E: resumed drop
- E: suspended drop
-</pre>
-
-
-<h3>eval</h3>
-Sets what events cause the execution to stop.
-
-<pre>
- C: eval {instruction}%20{parameter}|{instruction}%20{parameter}|...
- R: ok
- E: resume client
- E: evalresult result
- E: suspended eval
-</pre>
-
-
-<h3>eventstop</h3>
-Sets what events cause the execution to stop.
-
-<pre>
- C: eventstop {event_name} {0|1}
- R: ok
- ...
- E: suspended event {event_name}
-</pre>
-
-
-<h3>exit</h3>
-Instructs the debugger to exit.
-
-<pre>
- C: exit
- R: ok
-</pre>
-
-
-<h3>popdata</h3>
-Pops the top value from the data stack
-
-<pre>
- C: popdata
- R: ok
-</pre>
-
-
-<h3>pushdata</h3>
-Pushes the given value on top of the data stack.
-
-<pre>
- C: pushdata {value}
- R: ok
-</pre>
-
-
-<h3>resume</h3>
-Resumes the execution
-
-<pre>
- C: resume
- R: ok
- E: resumed client
-</pre>
-
-
-<h3>set</h3>
-Sets a breakpoint at given line
-
-<pre>
- C: set {line_number}
- R: ok
- C: resume
- E: resumed client
- E: suspended breakpoint line_number
-</pre>
-
-
-<h3>setdata</h3>
-Sets a data value in the data stack at the given location
-
-<pre>
- C: setdata {index} {value}
- R: ok
-</pre>
-
-
-<h3>setvar</h3>
-Sets a variable value
-
-<pre>
- C: setvar {frame_number} {variable} {value}
- R: ok
-</pre>
-
-
-<h3>stack</h3>
-Retrieves command stack information
-
-<pre>
- C: stack
- R: {file}|{line}|{function}|{var_1}|{var_2}|...{file}|{line}|{function}|{var_1}|{var_2}|......
-</pre>
-
-
-<h3>step</h3>
-Executes next instruction
-
-<pre>
- C: step
- R: ok
- E: resumed step
- E: suspended step
-</pre>
-
-
-<h3>stepreturn</h3>
-Executes instructions until the current subroutine is finished
-
-<pre>
- C: stepreturn
- R: ok
- E: resumed step
- E: suspended step
-</pre>
-
-
-<h3>suspend</h3>
-Suspends execution
-
-<pre>
- C: suspend
- R: ok
- E: suspended client
-</pre>
-
-
-<h3>var</h3>
-Retrieves variable value
-
-<pre>
- C: var {frame_number} {variable_name}
- R: {variable_value}
-</pre>
-
-
-<h3>watch</h3>
-Sets a watchpoint on a given variable
-
-<pre>
- C: watch {function}::{variable_name} {watch_operation}
- R: ok
- C: resume
- R: resumed client
- E: suspended watch {watch_operation} {function}::{variable_name}
-</pre>
-
-The <code>watch_operation<code> value can be:
-<ul>
- <li>0 - no watch</li>
- <li>1 - read watch</li>
- <li>2 - write watch</li>
- <li>3 - both, etc.</li>
-</ul>
-</body>
-</html>
diff --git a/org.eclipse.debug.examples.core/pdavm/pda.pl b/org.eclipse.debug.examples.core/pdavm/pda.pl
deleted file mode 100644
index de0866eba..000000000
--- a/org.eclipse.debug.examples.core/pdavm/pda.pl
+++ /dev/null
@@ -1,678 +0,0 @@
-#!perl.exe
-
-use strict;
-use warnings;
-use IO::Socket;
-
-#####################################################################
-# Copyright (c) 2005, 2008 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# Bjorn Freeman-Benson - initial API and implementation
-# Pawel Piech - WindRiver Systems - Bug 217211: PDA example debugger does not run on linux
-#####################################################################
-
-#####################################################################
-# #
-# I N I T I A L I Z A T I O N A N D V A R I A B L E S #
-# #
-#####################################################################
-#
-# The push down automata stack (the data stack)
-#
-my @stack;
-#
-# Load all the code into memory
-# The code is stored as an array of strings, each line of
-# the source file being one entry in the array.
-#
-my $filename = shift;
-open INFILE, $filename or die $!;
-my @code = <INFILE>;
-close INFILE;
-
-my %labels;
-sub map_labels {
- #
- # A mapping of labels to indicies in the code array
- #
- %labels = ( );
- my $idx = 0;
- while( $idx <= $#code ) {
- if( length $code[$idx] > 0 ) {
- $code[$idx] =~ /^\s*(.+?)\s*$/;
- $code[$idx] = $1;
- $labels{$1} = $idx if( $code[$idx] =~ /^:(\S+)/ );
- } else {
- $code[$idx] = "\n";
- }
- $idx ++;
- }
-}
-map_labels();
-#
-# The stack of stack frames (the control stack)
-# Each stack frame is a mapping of variable names to values.
-# There are a number of special variable names:
-# _pc_ is the current program counter in the frame
-# the pc points to the next instruction to be executed
-# _func_ is the name of the function in this frame
-#
-my @frames;
-my $currentframe;
-$currentframe = {
- _pc_ => 0,
- _func_ => 'main'
- };
-
-#
-# The command line argument to start a debug session.
-#
-my $debugflag = shift;
-#
-# The port to listen for debug commands on
-# and the port to send debug events to
-#
-my $debugport;
-my $debugport2;
-#
-# The socket to listen for debug commands on
-# and the socket to send debug events on
-#
-my $debugsock;
-my $debugsock2;
-#
-# An input buffer
-#
-my $debugbuf;
-#
-# Breakpoint array
-# breakpoints are stored as a boolean for each line of code
-# if the boolean is true, there is a breakpoint on that line
-#
-my @breakpoints;
-#
-# Mapping of debugger commands to functions that evaluate them
-#
-my %debug_commands = (
- clear => \&debug_clear_breakpoint,
- data => \&debug_data,
- drop => \&debug_drop_frame,
- eval => \&debug_eval,
- eventstop => \&debug_event_stop,
- exit => \&debug_exit,
- popdata => \&debug_pop,
- pushdata => \&debug_push,
- resume => \&debug_resume,
- set => \&debug_set_breakpoint,
- setdata => \&debug_set_data,
- setvar => \&debug_set_variable,
- stack => \&debug_stack,
- step => \&debug_step,
- stepreturn => \&debug_step_return,
- suspend => \&debug_suspend,
- var => \&debug_var,
- watch => \&debug_watch
-);
-
-#
-# The run flag is true if the VM is running.
-# If the run flag is false, the VM exits the
-# next time the main instruction loop runs.
-#
-my $run = 1;
-#
-# The suspend flag is true if the VM should suspend
-# running the program and just listen for debug commands.
-#
-my $suspend = 0;
-my $started = 1;
-$suspend = "client" if( $debugflag );
-#
-# The step flag is used to control single-stepping.
-# See the implementation of the "step" debug command.
-# The stepreturn flag is used to control step-return.
-# The eventstops table holds which events cause suspends and which do not.
-# The watchpoints table holds watchpoint information.
-# variablename_stackframedepth => N
-# N = 0 is no watch
-# N = 1 is read watch
-# N = 2 is write watch
-# N = 3 is both, etc.
-#
-my $step = 0;
-my $stepreturn = 0;
-my %eventstops = ( "unimpinstr" => 0,
- "nosuchlabel" => 0,
- );
-my %watchpoints = ( );
-
-#
-# Mapping of the names of the instructions to the functions that evaluate them
-#
-my %instructions = (
- add => \&add,
- branch_not_zero => \&branch_not_zero,
- call => \&call,
- dec => \&dec,
- dup => \&dup,
- halt => \&halt,
- output => \&output,
- pop => \&ipop,
- push => \&ipush,
- return => \&ireturn,
- var => \&var,
- xyzzy => \&internal_end_eval,
-);
-
-#####################################################################
-# #
-# M A I N I N T E R P R E T E R #
-# #
-#####################################################################
-#
-# Open a debug session if the command line argument is given.
-#
-start_debugger();
-send_debug_event( "started", 0 );
-debug_ui() if( $suspend );
-#
-# The main run loop
-#
-while( $run ) {
- check_for_breakpoint();
- debug_ui() if( $suspend );
- yield_to_debug();
- my $instruction = fetch_instruction();
- increment_pc();
- do_one_instruction($instruction);
- if( $$currentframe{_pc_} > $#code ) {
- $run = 0;
- } elsif( $stepreturn ) {
- $instruction = fetch_instruction();
- $suspend = "step" if( is_return_instruction($instruction) );
- }
-}
-send_debug_event( "terminated", 0 );
-
-sub fetch_instruction {
- my $pc = $$currentframe{_pc_};
- my $theinstruction = $code[$pc];
- return $theinstruction;
-}
-sub is_return_instruction {
- my $theinstruction = shift;
- if( $theinstruction =~ /^:/ ) {
- return 0;
- } elsif( $theinstruction =~ /^#/ ) {
- return 0;
- } else {
- $theinstruction =~ /^(\S+)\s*(.*)/;
- return $1 eq "return";
- }
-}
-sub increment_pc {
- my $pc = $$currentframe{_pc_};
- $pc++;
- $$currentframe{_pc_} = $pc;
-}
-sub decrement_pc {
- my $pc = $$currentframe{_pc_};
- $pc--;
- $$currentframe{_pc_} = $pc;
-}
-sub do_one_instruction {
- my $theinstruction = shift;
- if( $theinstruction =~ /^:/ ) {
- # label
- $suspend = "step" if( $step );
- } elsif( $theinstruction =~ /^#/ ) {
- # comment
- } else {
- $theinstruction =~ /^(\S+)\s*(.*)/;
- my $op = $1;
- my $instr = $instructions{$op};
- if( $instr ) {
- &$instr( $theinstruction, $2 );
- $suspend = "step" if( $step );
- } else {
- send_debug_event( "unimplemented instruction $op", 1 );
- if( $eventstops{"unimpinstr"} ) {
- $suspend = "event unimpinstr";
- decrement_pc();
- }
- }
- }
-}
-
-#####################################################################
-# #
-# I N S T R U C T I O N S #
-# #
-#####################################################################
-sub add {
- my $val1 = pop @stack;
- my $val2 = pop @stack;
- my $val = $val1 + $val2;
- push @stack, $val;
-}
-
-sub branch_not_zero {
- my $val = pop @stack;
- if( $val ) {
- shift;
- my $label = shift;
- my $dest = $labels{$label};
- if( !defined $dest ) {
- send_debug_event( "no such label $label", 1 );
- if( $eventstops{"nosuchlabel"} ) {
- $suspend = "event nosuchlabel";
- push @stack, $val;
- decrement_pc();
- }
- } else {
- $$currentframe{_pc_} = $dest;
- }
- }
-}
-
-sub call {
- shift;
- my $label = shift;
- my $dest = $labels{$label};
- if( !defined $dest ) {
- send_debug_event( "no such label $label", 1 );
- if( $eventstops{"nosuchlabel"} ) {
- $suspend = "event nosuchlabel";
- decrement_pc();
- }
- } else {
- push @frames, $currentframe;
- $currentframe = {
- _pc_ => $dest,
- _func_ => $label
- };
- }
-}
-
-sub dec {
- my $val = pop @stack;
- $val--;
- push @stack, $val;
-}
-
-sub dup {
- my $val = pop @stack;
- push @stack, $val;
- push @stack, $val;
-}
-
-sub halt {
- $run = 0;
-}
-
-sub output {
- my $val = pop @stack;
- print "$val\n";
-}
-
-sub ipop {
- shift;
- my $arg = shift;
- if( $arg =~ /^\$(.*)/ ) {
- $$currentframe{$1} = pop @stack;
- my $key = "$$currentframe{_func_}\:\:$1";
- if( defined $watchpoints{$key} ) {
- if( $watchpoints{$key} & 2 ) {
- $suspend = "watch write $key";
- }
- }
- } else {
- pop @stack;
- }
-}
-
-sub ipush {
- shift;
- my $arg = shift;
- if( $arg =~ /^\$(.*)/ ) {
- my $val = $$currentframe{$1};
- push @stack, $val;
- my $key = "$$currentframe{_func_}\:\:$1";
- if( defined $watchpoints{$key} ) {
- if( $watchpoints{$key} & 1 ) {
- $suspend = "watch read $key";
- }
- }
- } else {
- push @stack, $arg;
- }
-}
-
-sub ireturn {
- $currentframe = pop @frames;
-}
-
-sub var {
- shift;
- my $name = shift;
- $$currentframe{$name} = 0;
-}
-
-#####################################################################
-# #
-# D E B U G G E R I N T E R F A C E #
-# #
-#####################################################################
-
-sub check_for_breakpoint {
- if( $debugflag ) {
- my $pc = $$currentframe{_pc_};
- if( $breakpoints[$pc] ) {
- $suspend = "breakpoint $pc" unless $suspend eq "eval";
- }
- }
-}
-#
-# For each instruction, we check the debug co-routine for
-# control input. If there is input, we process it.
-#
-sub yield_to_debug {
- if( $debugflag ) {
- my $bytes_to_read = 1024;
- my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read);
- if( defined($bytes_read) ) {
- #print "read $bytes_to_read\n";
- my $rin = '';
- my $win = '';
- my $ein = '';
- vec($rin,fileno($debugsock),1) = 1;
- $ein = $rin | $win;
- my $debugline = $debugbuf;
- while( !($debugline =~ /\n/) ) {
- select($rin, undef, undef, undef);
- my $bytes_to_read = 1024;
- my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read);
- $debugline .= $debugbuf;
- }
- #print "read: $debugline";
- process_debug_command($debugline);
- $debugline = '';
- } else {
- # no bytes read
- }
- }
-}
-
-#
-# If the execution is suspended, then we go into the debug
-# ui loop, reading and processing instructions.
-#
-sub debug_ui {
- return unless( $suspend );
- my $pc = $$currentframe{_pc_};
- if (!$started) {
- send_debug_event( "suspended $suspend", 0 );
- } else {
- $started = 0;
- }
- $step = 0;
- $stepreturn = 0;
- my $rin = '';
- my $win = '';
- my $ein = '';
- vec($rin,fileno($debugsock),1) = 1;
- $ein = $rin | $win;
- my $debugline = '';
- while( $suspend ) {
- select($rin, undef, undef, undef);
- my $bytes_to_read = 1024;
- my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read);
- $debugline .= $debugbuf;
- if( $debugline =~ /\n/ ) {
- #print "read: $debugline";
- process_debug_command($debugline);
- $debugline = '';
- }
- }
- send_debug_event( "resumed step", 0 ) if( $step );
- send_debug_event( "resumed client", 0 ) unless( $step );
-}
-
-sub process_debug_command {
- my $line = shift;
- return if( length $line < 2 );
- my @words = split /\s/, $line;
- my $command = lc($words[0]);
- my $dfunc = $debug_commands{$words[0]};
- if( $dfunc ) {
- &$dfunc( @words );
- }
-}
-
-sub debug_clear_breakpoint {
- shift;
- my $line = shift;
- $breakpoints[$line] = 0;
- print $debugsock "ok\n";
-}
-my @saved_code;
-my %saved_labels;
-my $saved_pc;
-sub debug_eval {
- shift;
- my $code = shift;
- my @lines = split /\|/, $code;
- my $newpc = scalar @code;
- @saved_code = @code;
- %saved_labels = %labels;
- foreach my $line ( @lines ) {
- $line =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
- push @code, $line;
- }
- push @code, "xyzzy";
- map_labels();
- $saved_pc = $$currentframe{_pc_};
- $$currentframe{_pc_} = $newpc;
- print $debugsock "ok\n";
- $suspend = 0;
-}
-sub internal_end_eval {
- my $result = pop @stack;
- @code = @saved_code;
- %labels = %saved_labels;
- $$currentframe{_pc_} = $saved_pc;
- send_debug_event( "evalresult $result", 0 );
- $suspend = "eval";
-}
-
-sub debug_data {
- my $result = '';
- foreach my $d ( @stack ) {
- $result .= $d . '|';
- }
- print $debugsock "$result\n";
-}
-sub debug_drop_frame {
- ireturn();
- decrement_pc();
- print $debugsock "ok\n";
- send_debug_event( "resumed drop", 0 );
- send_debug_event( "suspended drop", 0 );
-}
-sub debug_event_stop {
- shift;
- my $event = shift;
- my $bool = shift;
- $eventstops{$event} = $bool;
- print $debugsock "ok\n";
-}
-sub debug_exit {
- print $debugsock "ok\n";
- send_debug_event( "terminated", 0 );
- exit 0;
-}
-sub debug_pop {
- pop @stack;
- print $debugsock "ok\n";
-}
-sub debug_push {
- shift;
- my $value = shift;
- push @stack, $value;
- print $debugsock "ok\n";
-}
-sub debug_resume {
- $suspend = 0;
- print $debugsock "ok\n";
-}
-sub debug_set_breakpoint {
- shift;
- my $line = shift;
- $breakpoints[$line] = 1;
- print $debugsock "ok\n";
-}
-sub debug_set_data {
- shift;
- my $offset = shift;
- my $value = shift;
- $stack[$offset] = $value;
- print $debugsock "ok\n";
-}
-sub debug_set_variable {
- shift;
- my $sfnumber = shift;
- my $var = shift;
- my $value = shift;
- if( $sfnumber > $#frames ) {
- $$currentframe{$var} = $value;
- } else {
- my $theframe = $frames[$sfnumber];
- $$theframe{$var} = $value;
- }
- print $debugsock "ok\n";
-}
-sub debug_stack {
- my $result = '';
- foreach my $frame ( @frames ) {
- $result .= print_frame($frame);
- $result .= '#';
- }
- $result .= print_frame($currentframe);
- print $debugsock "$result\n";
-}
-sub debug_step {
- # set suspend to 0 to allow the debug loop to exit back to
- # the instruction loop and thus run an instruction. However,
- # we want to come back to the debug loop right away, so the
- # step flag is set to true which will cause the suspend flag
- # to get set to true when we get to the next instruction.
- $step = 1;
- $suspend = 0;
- print $debugsock "ok\n";
-}
-sub debug_step_return {
- $stepreturn = 1;
- $suspend = 0;
- print $debugsock "ok\n";
-}
-sub debug_suspend {
- $suspend = "client";
- print $debugsock "ok\n";
-}
-sub debug_var {
- shift;
- my $sfnumber = shift;
- my $var = shift;
- if( $sfnumber > $#frames ) {
- print $debugsock "$$currentframe{$var}\n";
- } else {
- my $theframe = $frames[$sfnumber];
- print $debugsock "$$theframe{$var}\n";
- }
-}
-sub debug_watch {
- shift;
- my $key = shift;
- my $value = shift;
- $watchpoints{$key} = $value;
- print $debugsock "ok\n";
-}
-#
-# Some event has happened so notify the debugger.
-# If there is no debugger, we may still want to report the
-# event (such as if it is an error).
-#
-sub send_debug_event {
- my $event = shift;
- if( $debugflag ) {
- print $debugsock2 "$event\n";
- } else {
- my $use_stderr = shift;
- print "Error: $event\n" if $use_stderr;
- }
-}
-#
-# The stack frame output is:
-# frame # frame # frame ...
-# where each frame is:
-# filename | line number | function name | var | var | var | var ...
-#
-sub print_frame {
- my $frame = shift;
- my $result = $filename;
- $result .= '|' . $$frame{_pc_};
- $result .= '|' . $$frame{_func_};
- for my $var ( keys %$frame ) {
- $result .= '|' . $var unless( substr($var,0,1) eq '_');
- }
- return $result;
-}
-
-sub start_debugger {
- if( defined($debugflag) ) {
- if( $debugflag eq "-debug" ) {
- { # make STDOUT unbuffered
- my $ofh = select STDOUT;
- $| = 1;
- select $ofh;
- }
- $debugflag = 1;
- $debugport = shift @ARGV;
- $debugport2 = shift @ARGV;
- print "-debug $debugport $debugport2\n";
-
- my $mainsock = new IO::Socket::INET (LocalHost => '127.0.0.1',
- LocalPort => $debugport,
- Listen => 1,
- Proto => 'tcp',
- Reuse => 1,
- );
- $debugsock = $mainsock->accept();
-
- # make the socket non-blocking on windows
- my $set_it = "1";
- my $ioctl_val = 0x80000000 | (4 << 16) | (ord('f') << 8) | 126;
- ioctl($debugsock, $ioctl_val, $set_it);
-
- # make the socket non-blocking on linux
- $debugsock->blocking(0);
-
- my $mainsock2 = new IO::Socket::INET (LocalHost => '127.0.0.1',
- LocalPort => $debugport2,
- Listen => 1,
- Proto => 'tcp',
- Reuse => 1,
- );
- $debugsock2 = $mainsock2->accept();
-
- print "debug connection accepted\n";
- } else {
- $debugflag = 0;
- }
- }
-}
diff --git a/org.eclipse.debug.examples.core/pdavm/src/org/eclipse/debug/examples/pdavm/PDAVirtualMachine.java b/org.eclipse.debug.examples.core/pdavm/src/org/eclipse/debug/examples/pdavm/PDAVirtualMachine.java
new file mode 100644
index 000000000..98a56ddc3
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/src/org/eclipse/debug/examples/pdavm/PDAVirtualMachine.java
@@ -0,0 +1,1408 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
+ *******************************************************************************/
+package org.eclipse.debug.examples.pdavm;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StringWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Push Down Automata interpreter.
+ *
+ * @since 3.5
+ */
+public class PDAVirtualMachine {
+
+ static class Stack extends LinkedList {
+ private static final long serialVersionUID = 1L;
+
+ public Object pop() {
+ return isEmpty() ? new Integer(0) : remove(size() - 1);
+ }
+
+ public void push(Object value) {
+ add(value);
+ }
+ }
+
+ static class Register {
+ Register(String name) {
+ fName = name;
+ }
+ String fName;
+ String fGroup = "<no_group>";
+ boolean fIsWriteable = true;
+ Map fBitFields = new LinkedHashMap(0);
+ int fValue;
+ }
+
+ static class BitField {
+ BitField(String name) {
+ fName = name;
+ }
+ String fName;
+ int fBitOffset;
+ int fBitCount;
+ Map fMnemonics = new LinkedHashMap(0);
+ }
+
+ Map fRegisters = new LinkedHashMap(0);
+
+ class Args {
+ final String[] fArgs;
+
+ int next = 0;
+
+ Args(String[] args) {
+ fArgs = args;
+ }
+
+ boolean hasNextArg() {
+ return fArgs.length > next;
+ }
+
+ String getNextStringArg() {
+ if (fArgs.length > next) {
+ return fArgs[next++];
+ }
+ return "";
+ }
+
+ int getNextIntArg() {
+ String arg = getNextStringArg();
+ try {
+ return Integer.parseInt(arg);
+ } catch (NumberFormatException e) {
+ }
+ return 0;
+ }
+
+ boolean getNextBooleanArg() {
+ String arg = getNextStringArg();
+ try {
+ return Boolean.getBoolean(arg);
+ } catch (NumberFormatException e) {
+ }
+ return false;
+ }
+
+ Object getNextIntOrStringArg() {
+ String arg = getNextStringArg();
+ try {
+ return new Integer(arg);
+ } catch (NumberFormatException e) {
+ }
+ return arg;
+ }
+
+ PDAThread getThreadArg() {
+ int id = getNextIntArg();
+ return (PDAThread)fThreads.get( new Integer(id) );
+ }
+ }
+
+ class PDAThread {
+ final int fID;
+
+ /** The push down automata data stack (the data stack). */
+ final Stack fStack = new Stack();
+
+ /**
+ * PDAThread copy of the code. It can differ from the program if
+ * performing an evaluation.
+ */
+ String[] fThreadCode;
+
+ /** PDAThread copy of the labels. */
+ Map fThreadLabels;
+
+ /** The stack of stack frames (the control stack) */
+ final List fFrames = new LinkedList();
+
+ /** Current stack frame (not includced in fFrames) */
+ Frame fCurrentFrame;
+
+ /**
+ * The run flag is true if the thread is running. If the run flag is
+ * false, the thread exits the next time the main instruction loop runs.
+ */
+ boolean fRun = true;
+
+ String fSuspend = null;
+
+ boolean fStep = false;
+
+ boolean fStepReturn = false;
+
+ int fSavedPC;
+
+ boolean fPerformingEval = false;
+
+ PDAThread(int id, String function, int pc) {
+ fID = id;
+ fCurrentFrame = new Frame(function, pc);
+ fThreadCode = fCode;
+ fThreadLabels = fLabels;
+ }
+ }
+
+ final Map fThreads = new LinkedHashMap();
+
+ int fNextThreadId = 1;
+
+ boolean fStarted = true;
+ /**
+ * The code is stored as an array of strings, each line of the source file
+ * being one entry in the array.
+ */
+ final String[] fCode;
+
+ /** A mapping of labels to indicies in the code array */
+ final Map fLabels;
+
+ /** Each stack frame is a mapping of variable names to values. */
+ class Frame {
+ final Map fLocalVariables = new LinkedHashMap();
+
+ /**
+ * The name of the function in this frame
+ */
+ final String fFunction;
+
+ /**
+ * The current program counter in the frame the pc points to the next
+ * instruction to be executed
+ */
+ int fPC;
+
+ Frame(String function, int pc) {
+ fFunction = function;
+ fPC = pc;
+ }
+
+ void set(String name, Object value) {
+ if (name.startsWith("$")) {
+ setRegisterValue(name, value);
+ } else {
+ fLocalVariables.put(name, value);
+ }
+ }
+
+ Object get(String name) {
+ if (name.startsWith("$")) {
+ return getRegisterValue(name);
+ } else {
+ return fLocalVariables.get(name);
+ }
+ }
+ }
+
+ void setRegisterValue(String name, Object value) {
+ Register reg = (Register)fRegisters.get(getRegisterPartOfName(name));
+ if (reg == null) return;
+ String bitFieldName = getBitFieldPartOfName(name);
+ if (bitFieldName != null) {
+ BitField bitField = (BitField)reg.fBitFields.get(bitFieldName);
+ if (bitField == null) return;
+ Integer intValue = null;
+ if (value instanceof Integer) {
+ intValue = (Integer)value;
+ } else if (value instanceof String) {
+ intValue = (Integer)bitField.fMnemonics.get(value);
+ }
+ if (intValue != null) {
+ int bitFieldMask = 2^(bitField.fBitCount - 1);
+ int registerMask = ~(bitFieldMask << bitField.fBitOffset);
+ int bitFieldValue = intValue.intValue() & bitFieldMask;
+ reg.fValue = (reg.fValue & registerMask) | (bitFieldValue << bitField.fBitOffset);
+ }
+ } else if (value instanceof Integer) {
+ reg.fValue = ((Integer)value).intValue();
+ }
+ }
+
+ Object getRegisterValue(String name) {
+ Register reg = (Register)fRegisters.get(getRegisterPartOfName(name));
+ if (reg == null) return null;
+ String bitFieldName = getBitFieldPartOfName(name);
+ if (bitFieldName != null) {
+ BitField bitField = (BitField)reg.fBitFields.get(bitFieldName);
+ if (bitField == null) return null;
+ int bitFieldMask = 2^(bitField.fBitCount - 1);
+ int registerMask = bitFieldMask << bitField.fBitOffset;
+ return new Integer( (reg.fValue & registerMask) >> bitField.fBitOffset );
+ } else {
+ return new Integer(reg.fValue);
+ }
+ }
+
+ /**
+ * Breakpoints are stored per each each line of code. The boolean indicates
+ * whether the whole VM should suspend or just the triggering thread.
+ */
+ final Map fBreakpoints = new HashMap();
+
+ /**
+ * The suspend flag is true if the VM should suspend running the program and
+ * just listen for debug commands.
+ */
+ String fSuspendVM;
+
+ /** Flag indicating whether the debugger is performing a step. */
+ boolean fStepVM = false;
+
+ /** Flag indicating whether the debugger is performing a step return */
+ boolean fStepReturnVM = false;
+
+ int fSteppingThread = 0;
+
+ /** Name of the pda program being debugged */
+ final String fFilename;
+
+ /** The command line argument to start a debug session. */
+ final boolean fDebug;
+
+ /** The port to listen for debug commands on */
+ final int fCommandPort;
+
+ /**
+ * Command socket for receiving debug commands and sending command responses
+ */
+ Socket fCommandSocket;
+
+ /** Command socket reader */
+ BufferedReader fCommandReceiveStream;
+
+ /** Command socket write stream. */
+ OutputStream fCommandResponseStream;
+
+ /** The port to send debug events to */
+ final int fEventPort;
+
+ /** Event socket */
+ Socket fEventSocket;
+
+ /** Event socket and write stream. */
+ OutputStream fEventStream;
+
+ /** The eventstops table holds which events cause suspends and which do not. */
+ final Map fEventStops = new HashMap();
+ {
+ fEventStops.put("unimpinstr", Boolean.FALSE);
+ fEventStops.put("nosuchlabel", Boolean.FALSE);
+ }
+
+ /**
+ * The watchpoints table holds watchpoint information.
+ * <p/>
+ * variablename_stackframedepth => N
+ * <ul>
+ * <li>N = 0 is no watch</li>
+ * <li>N = 1 is read watch</li>
+ * <li>N = 2 is write watch</li>
+ * <li>N = 3 is both, etc.</li>
+ */
+ final Map fWatchpoints = new HashMap();
+
+ public static void main(String[] args) {
+ String programFile = args.length >= 1 ? args[0] : null;
+ if (programFile == null) {
+ System.err.println("Error: No program specified");
+ return;
+ }
+
+ String debugFlag = args.length >= 2 ? args[1] : "";
+ boolean debug = "-debug".equals(debugFlag);
+ int commandPort = 0;
+ int eventPort = 0;
+
+ if (debug) {
+ String commandPortStr = args.length >= 3 ? args[2] : "";
+ try {
+ commandPort = Integer.parseInt(commandPortStr);
+ } catch (NumberFormatException e) {
+ System.err.println("Error: Invalid command port");
+ return;
+ }
+
+ String eventPortStr = args.length >= 4 ? args[3] : "";
+ try {
+ eventPort = Integer.parseInt(eventPortStr);
+ } catch (NumberFormatException e) {
+ System.err.println("Error: Invalid event port");
+ return;
+ }
+ }
+
+ PDAVirtualMachine pdaVM = null;
+ try {
+ pdaVM = new PDAVirtualMachine(programFile, debug, commandPort, eventPort);
+ pdaVM.startDebugger();
+ } catch (IOException e) {
+ System.err.println("Error: " + e.toString());
+ return;
+ }
+ pdaVM.run();
+ }
+
+ PDAVirtualMachine(String inputFile, boolean debug, int commandPort, int eventPort) throws IOException {
+ fFilename = inputFile;
+
+ // Load all the code into memory
+ FileReader fileReader = new FileReader(inputFile);
+ StringWriter stringWriter = new StringWriter();
+ List code = new LinkedList();
+ int c = fileReader.read();
+ while (c != -1) {
+ if (c == '\n') {
+ code.add(stringWriter.toString().trim());
+ stringWriter = new StringWriter();
+ } else {
+ stringWriter.write(c);
+ }
+ c = fileReader.read();
+ }
+ code.add(stringWriter.toString().trim());
+ fCode = (String[])code.toArray(new String[code.size()]);
+
+ fLabels = mapLabels(fCode);
+
+ fDebug = debug;
+ fCommandPort = commandPort;
+ fEventPort = eventPort;
+ }
+
+ /**
+ * Initializes the labels map
+ */
+ Map mapLabels(String[] code) {
+ Map labels = new HashMap();
+ for (int i = 0; i < code.length; i++) {
+ if (code[i].length() != 0 && code[i].charAt(0) == ':') {
+ labels.put(code[i].substring(1), new Integer(i));
+ }
+ }
+ return labels;
+ }
+
+ void sendCommandResponse(String response) {
+ try {
+ fCommandResponseStream.write(response.getBytes());
+ fCommandResponseStream.flush();
+ } catch (IOException e) {
+ }
+ }
+
+ void sendDebugEvent(String event, boolean error) {
+ if (fDebug) {
+ try {
+ fEventStream.write(event.getBytes());
+ fEventStream.write('\n');
+ fEventStream.flush();
+ } catch (IOException e) {
+ System.err.println("Error: " + e);
+ System.exit(1);
+ }
+ } else if (error) {
+ System.err.println("Error: " + event);
+ }
+ }
+
+ void startDebugger() throws IOException {
+ if (fDebug) {
+ System.out.println("-debug " + fCommandPort + " " + fEventPort);
+ }
+
+ ServerSocket commandServerSocket = new ServerSocket(fCommandPort);
+ fCommandSocket = commandServerSocket.accept();
+ fCommandReceiveStream = new BufferedReader(new InputStreamReader(fCommandSocket.getInputStream()));
+ fCommandResponseStream = new PrintStream(fCommandSocket.getOutputStream());
+ commandServerSocket.close();
+
+ ServerSocket eventServerSocket = new ServerSocket(fEventPort);
+ fEventSocket = eventServerSocket.accept();
+ fEventStream = new PrintStream(fEventSocket.getOutputStream());
+ eventServerSocket.close();
+
+ System.out.println("debug connection accepted");
+
+ fSuspendVM = "client";
+ }
+
+ void run() {
+ int id = fNextThreadId++;
+ sendDebugEvent("vmstarted", false);
+ fThreads.put(new Integer(id), new PDAThread(id, "main", 0));
+ if (fDebug) {
+ sendDebugEvent("started " + id, false);
+ }
+
+ boolean allThreadsSuspended = false;
+ while (!fThreads.isEmpty()) {
+ checkForBreakpoint();
+
+ if (fSuspendVM != null) {
+ debugUI();
+ } else {
+ yieldToDebug(allThreadsSuspended);
+ if (fSuspendVM != null) {
+ // Received a command to suspend VM, skip executing threads.
+ continue;
+ }
+ }
+
+ PDAThread[] threadsCopy = (PDAThread[])fThreads.values().toArray(new PDAThread[fThreads.size()]);
+ allThreadsSuspended = true;
+ for (int i = 0; i < threadsCopy.length; i++) {
+ PDAThread thread = threadsCopy[i];
+ if (thread.fSuspend == null) {
+ allThreadsSuspended = false;
+
+ String instruction = thread.fThreadCode[thread.fCurrentFrame.fPC];
+ thread.fCurrentFrame.fPC++;
+ doOneInstruction(thread, instruction);
+ if (thread.fCurrentFrame.fPC >= thread.fThreadCode.length) {
+ // Thread reached end of code, exit from the thread.
+ thread.fRun = false;
+ } else if (thread.fStepReturn) {
+ // If this thread is in a step-return operation, check
+ // if we've returned from a call.
+ instruction = thread.fThreadCode[thread.fCurrentFrame.fPC];
+ if ("return".equals(instruction)) {
+ // Note: this will only be triggered if the current
+ // thread also has the fStepReturn flag set.
+ if (fStepReturnVM) {
+ fSuspendVM = thread.fID + " step";
+ } else {
+ thread.fSuspend = "step";
+ }
+ }
+ }
+ if (!thread.fRun) {
+ sendDebugEvent("exited " + thread.fID, false);
+ fThreads.remove(new Integer(thread.fID));
+ } else if (thread.fSuspend != null) {
+ sendDebugEvent("suspended " + thread.fID + " " + thread.fSuspend, false);
+ thread.fStep = thread.fStepReturn = thread.fPerformingEval = false;
+ }
+ }
+ }
+
+ // Force thread context switch to avoid starving out other
+ // processes in the system.
+ Thread.yield();
+ }
+
+ sendDebugEvent("vmterminated", false);
+ if (fDebug) {
+ try {
+ fCommandReceiveStream.close();
+ fCommandResponseStream.close();
+ fCommandSocket.close();
+ fEventStream.close();
+ fEventSocket.close();
+ } catch (IOException e) {
+ System.out.println("Error: " + e);
+ }
+ }
+
+ }
+
+ void doOneInstruction(PDAThread thread, String instr) {
+ StringTokenizer tokenizer = new StringTokenizer(instr);
+ String op = tokenizer.nextToken();
+ List tokens = new LinkedList();
+ while (tokenizer.hasMoreTokens()) {
+ tokens.add(tokenizer.nextToken());
+ }
+ Args args = new Args( (String[])tokens.toArray(new String[tokens.size()]) );
+
+ boolean opValid = true;
+ if (op.equals("add")) iAdd(thread, args);
+ else if (op.equals("branch_not_zero")) iBranchNotZero(thread, args);
+ else if (op.equals("call")) iCall(thread, args);
+ else if (op.equals("dec")) iDec(thread, args);
+ else if (op.equals("def")) iDef(thread, args);
+ else if (op.equals("dup")) iDup(thread, args);
+ else if (op.equals("exec")) iExec(thread, args);
+ else if (op.equals("halt")) iHalt(thread, args);
+ else if (op.equals("output")) iOutput(thread, args);
+ else if (op.equals("pop")) iPop(thread, args);
+ else if (op.equals("push")) iPush(thread, args);
+ else if (op.equals("return")) iReturn(thread, args);
+ else if (op.equals("var")) iVar(thread, args);
+ else if (op.equals("xyzzy")) iInternalEndEval(thread, args);
+ else if (op.startsWith(":")) {} // label
+ else if (op.startsWith("#")) {} // comment
+ else {
+ opValid = false;
+ }
+
+ if (!opValid) {
+ sendDebugEvent("unimplemented instruction " + op, true);
+ if ( ((Boolean)fEventStops.get("unimpinstr")).booleanValue() ) {
+ fSuspendVM = thread.fID + " event unimpinstr";
+ thread.fCurrentFrame.fPC--;
+ }
+ } else if (thread.fStep) {
+ if (fStepVM) {
+ fSuspendVM = thread.fID + " step";
+ fStepVM = false;
+ } else {
+ thread.fSuspend = "step";
+ }
+ thread.fStep = false;
+ }
+ }
+
+ void checkForBreakpoint() {
+ if (fDebug) {
+ for (Iterator itr = fThreads.values().iterator(); itr.hasNext();) {
+ PDAThread thread = (PDAThread)itr.next();
+ Integer pc = new Integer(thread.fCurrentFrame.fPC);
+ // Suspend for breakpoint if:
+ // - the VM is not yet set to suspend, for e.g. as a result of step end,
+ // - the thread is not yet suspended and is not performing an evaluation
+ // - the breakpoints table contains a breakpoint for the given line.
+ if (fSuspendVM == null &&
+ thread.fSuspend == null && !thread.fPerformingEval &&
+ fBreakpoints.containsKey(pc))
+ {
+ if ( ((Boolean)fBreakpoints.get(pc)).booleanValue() ) {
+ fSuspendVM = thread.fID + " breakpoint " + pc;
+ } else {
+ thread.fSuspend = "breakpoint " + pc;
+ thread.fStep = thread.fStepReturn = false;
+ sendDebugEvent("suspended " + thread.fID + " " + thread.fSuspend, false);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * After each instruction, we check the debug command channel for control input. If
+ * there are commands, process them.
+ */
+ void yieldToDebug(boolean allThreadsSuspended) {
+ if (fDebug) {
+ String line = "";
+ try {
+ if (allThreadsSuspended || fCommandReceiveStream.ready()) {
+ line = fCommandReceiveStream.readLine();
+ processDebugCommand(line);
+ }
+ } catch (IOException e) {
+ System.err.println("Error: " + e);
+ System.exit(1);
+ }
+ }
+ }
+
+ /**
+ * Service the debugger commands while the VM is suspended
+ */
+ void debugUI() {
+ if (!fStarted) {
+ sendDebugEvent("vmsuspended " + fSuspendVM, false);
+ } else {
+ fStarted = false;
+ }
+
+ // Clear all stepping flags. In case the VM suspended while
+ // a step operation was being performed for the VM or some thread.
+ fStepVM = fStepReturnVM = false;
+ for (Iterator itr = fThreads.values().iterator(); itr.hasNext();) {
+ PDAThread thread = (PDAThread)itr.next();
+ thread.fSuspend = null;
+ thread.fStep = thread.fStepReturn = thread.fPerformingEval = false;
+ }
+
+ while (fSuspendVM != null) {
+ String line = "";
+ try {
+ line = fCommandReceiveStream.readLine();
+ } catch (IOException e) {
+ System.err.println("Error: " + e);
+ System.exit(1);
+ return;
+ }
+ processDebugCommand(line);
+ }
+
+ if (fStepVM || fStepReturnVM) {
+ sendDebugEvent("vmresumed step", false);
+ } else {
+ sendDebugEvent("vmresumed client", false);
+ }
+ }
+
+ void processDebugCommand(String line) {
+ StringTokenizer tokenizer = new StringTokenizer(line.trim());
+ if (line.length() == 0) {
+ return;
+ }
+
+ String command = tokenizer.nextToken();
+ List tokens = new LinkedList();
+ while (tokenizer.hasMoreTokens()) {
+ tokens.add(tokenizer.nextToken());
+ }
+ Args args = new Args( (String[])tokens.toArray(new String[tokens.size()]));
+
+ if ("children".equals(command)) debugChildren(args);
+ else if ("clear".equals(command)) debugClearBreakpoint(args);
+ else if ("data".equals(command)) debugData(args);
+ else if ("drop".equals(command)) debugDropFrame(args);
+ else if ("eval".equals(command)) debugEval(args);
+ else if ("eventstop".equals(command)) debugEventStop(args);
+ else if ("frame".equals(command)) debugFrame(args);
+ else if ("groups".equals(command)) debugGroups(args);
+ else if ("popdata".equals(command)) debugPopData(args);
+ else if ("pushdata".equals(command)) debugPushData(args);
+ else if ("registers".equals(command)) debugRegisters(args);
+ else if ("resume".equals(command)) debugResume(args);
+ else if ("set".equals(command)) debugSetBreakpoint(args);
+ else if ("setdata".equals(command)) debugSetData(args);
+ else if ("setvar".equals(command)) debugSetVariable(args);
+ else if ("stack".equals(command)) debugStack(args);
+ else if ("stackdepth".equals(command)) debugStackDepth(args);
+ else if ("state".equals(command)) debugState(args);
+ else if ("step".equals(command)) debugStep(args);
+ else if ("stepreturn".equals(command)) debugStepReturn(args);
+ else if ("suspend".equals(command)) debugSuspend(args);
+ else if ("terminate".equals(command)) debugTerminate();
+ else if ("threads".equals(command)) debugThreads();
+ else if ("var".equals(command)) debugVar(args);
+ else if ("vmresume".equals(command)) debugVMResume();
+ else if ("vmsuspend".equals(command)) debugVMSuspend();
+ else if ("watch".equals(command)) debugWatch(args);
+ else {
+ sendCommandResponse("error: invalid command\n");
+ }
+ }
+
+ void debugChildren(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ int sfnumber = args.getNextIntArg();
+ String var = args.getNextStringArg();
+
+ Frame frame = sfnumber >= thread.fFrames.size()
+ ? thread.fCurrentFrame : (Frame)thread.fFrames.get(sfnumber);
+
+ String varDot = var + ".";
+ List children = new ArrayList();
+ for (Iterator itr = frame.fLocalVariables.keySet().iterator(); itr.hasNext();) {
+ String localVar = (String)itr.next();
+ if (localVar.startsWith(varDot) && localVar.indexOf('.', varDot.length() + 1) == -1) {
+ children.add(localVar);
+ }
+ }
+
+ StringBuffer result = new StringBuffer();
+ for (Iterator itr = children.iterator(); itr.hasNext();) {
+ result.append(itr.next());
+ result.append('|');
+ }
+ result.append('\n');
+
+ sendCommandResponse(result.toString());
+ }
+
+ void debugClearBreakpoint(Args args) {
+ int line = args.getNextIntArg();
+
+ fBreakpoints.remove( new Integer(line) );
+ sendCommandResponse("ok\n");
+ }
+
+ private static Pattern fPackPattern = Pattern.compile("%([a-fA-F0-9][a-fA-F0-9])");
+
+ void debugData(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ StringBuffer result = new StringBuffer();
+ for (Iterator itr = thread.fStack.iterator(); itr.hasNext();) {
+ result.append(itr.next());
+ result.append('|');
+ }
+ result.append('\n');
+ sendCommandResponse(result.toString());
+ }
+
+ void debugDropFrame(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ if (!thread.fFrames.isEmpty()) {
+ thread.fCurrentFrame = (Frame)thread.fFrames.remove(thread.fFrames.size() - 1);
+ }
+ thread.fCurrentFrame.fPC--;
+ sendCommandResponse("ok\n");
+ if (fSuspendVM != null) {
+ sendDebugEvent("vmresumed drop", false);
+ sendDebugEvent("vmsuspended " + thread.fID + " drop", false);
+ } else {
+ sendDebugEvent("resumed " + thread.fID + " drop", false);
+ sendDebugEvent("suspended " + thread.fID + " drop", false);
+ }
+ }
+
+ void debugEval(Args args) {
+ if (fSuspendVM != null) {
+ sendCommandResponse("error: cannot evaluate while vm is suspended\n");
+ return;
+ }
+
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ if (thread.fSuspend == null) {
+ sendCommandResponse("error: thread running\n");
+ return;
+ }
+
+ StringTokenizer tokenizer = new StringTokenizer(args.getNextStringArg(), "|");
+ tokenizer.countTokens();
+
+ int numEvalLines = tokenizer.countTokens();
+ thread.fThreadCode = new String[fCode.length + numEvalLines + 1];
+ System.arraycopy(fCode, 0, thread.fThreadCode, 0, fCode.length);
+ for (int i = 0; i < numEvalLines; i++) {
+ String line = tokenizer.nextToken();
+ StringBuffer lineBuf = new StringBuffer(line.length());
+ Matcher matcher = fPackPattern.matcher(line);
+ int lastMatchEnd = 0;
+ while (matcher.find()) {
+ lineBuf.append(line.substring(lastMatchEnd, matcher.start()));
+ String charCode = line.substring(matcher.start() + 1, matcher.start() + 3);
+ try {
+ lineBuf.append((char) Integer.parseInt(charCode, 16));
+ } catch (NumberFormatException e) {
+ }
+ lastMatchEnd = matcher.end();
+ }
+ if (lastMatchEnd < line.length()) {
+ lineBuf.append(line.substring(lastMatchEnd));
+ }
+ thread.fThreadCode[fCode.length + i] = lineBuf.toString();
+ }
+ thread.fThreadCode[fCode.length + numEvalLines] = "xyzzy";
+ thread.fThreadLabels = mapLabels(fCode);
+
+ thread.fSavedPC = thread.fCurrentFrame.fPC;
+ thread.fCurrentFrame.fPC = fCode.length;
+ thread.fPerformingEval = true;
+
+ thread.fSuspend = null;
+
+ sendCommandResponse("ok\n");
+
+ sendDebugEvent("resumed " + thread.fID + " eval", false);
+ }
+
+ void debugEventStop(Args args) {
+ String event = args.getNextStringArg();
+ int stop = args.getNextIntArg();
+ fEventStops.put(event, new Boolean(stop > 0));
+ sendCommandResponse("ok\n");
+ }
+
+ void debugTerminate() {
+ sendCommandResponse("ok\n");
+ sendDebugEvent("vmterminated", false);
+ System.exit(0);
+ }
+
+ void debugFrame(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ int sfnumber = args.getNextIntArg();
+ Frame frame = null;
+ if (sfnumber >= thread.fFrames.size()) {
+ frame = thread.fCurrentFrame;
+ } else {
+ frame = (Frame)thread.fFrames.get(sfnumber);
+ }
+ sendCommandResponse(printFrame(frame) + "\n");
+ }
+
+ void debugGroups(Args args) {
+ TreeSet groups = new TreeSet();
+ for (Iterator itr = fRegisters.values().iterator(); itr.hasNext();) {
+ Register reg = (Register)itr.next();
+ groups.add(reg.fGroup);
+ }
+ StringBuffer response = new StringBuffer();
+ for (Iterator itr = groups.iterator(); itr.hasNext();) {
+ response.append(itr.next());
+ response.append('|');
+ }
+ response.append('\n');
+ sendCommandResponse(response.toString());
+ }
+
+ void debugPopData(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ thread.fStack.pop();
+ sendCommandResponse("ok\n");
+ }
+
+ void debugPushData(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ Object val = args.getNextIntOrStringArg();
+ thread.fStack.push(val);
+ sendCommandResponse("ok\n");
+ }
+
+ void debugRegisters(Args args) {
+ String group = args.getNextStringArg();
+
+ StringBuffer response = new StringBuffer();
+ for (Iterator itr = fRegisters.values().iterator(); itr.hasNext();) {
+ Register reg = (Register)itr.next();
+ if (group.equals(reg.fGroup)) {
+ response.append(reg.fName);
+ response.append(' ');
+ response.append(reg.fIsWriteable);
+ for (Iterator itr2 = reg.fBitFields.values().iterator(); itr2.hasNext();) {
+ BitField bitField = (BitField)itr2.next();
+ response.append('|');
+ response.append(bitField.fName);
+ response.append(' ');
+ response.append(bitField.fBitOffset);
+ response.append(' ');
+ response.append(bitField.fBitCount);
+ response.append(' ');
+ for (Iterator itr3 = bitField.fMnemonics.entrySet().iterator(); itr3.hasNext();) {
+ Map.Entry mnemonicEntry = (Map.Entry)itr3.next();
+ response.append(mnemonicEntry.getKey());
+ response.append(' ');
+ response.append(mnemonicEntry.getValue());
+ response.append(' ');
+ }
+ }
+
+ response.append('#');
+ }
+ }
+ response.append('\n');
+ sendCommandResponse(response.toString());
+ }
+
+ void debugResume(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+ if (fSuspendVM != null) {
+ sendCommandResponse("error: cannot resume thread when vm is suspended\n");
+ return;
+ }
+ if (thread.fSuspend == null) {
+ sendCommandResponse("error: thread already running\n");
+ return;
+ }
+
+ thread.fSuspend = null;
+ sendDebugEvent("resumed " + thread.fID + " client", false);
+
+ sendCommandResponse("ok\n");
+ }
+
+ void debugSetBreakpoint(Args args) {
+ int line = args.getNextIntArg();
+ int stopVM = args.getNextIntArg();
+
+ fBreakpoints.put(new Integer(line), new Boolean(stopVM != 0));
+ sendCommandResponse("ok\n");
+ }
+
+ void debugSetData(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ int offset = args.getNextIntArg();
+ Object val = args.getNextIntOrStringArg();
+
+ if (offset < thread.fStack.size()) {
+ thread.fStack.set(offset, val);
+ } else {
+ thread.fStack.add(0, val);
+ }
+ sendCommandResponse("ok\n");
+ }
+
+ void debugSetVariable(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ int sfnumber = args.getNextIntArg();
+ String var = args.getNextStringArg();
+ Object val = args.getNextIntOrStringArg();
+ while (args.hasNextArg()) {
+ val = val.toString() + " " + args.getNextStringArg();
+ }
+
+ if (sfnumber >= thread.fFrames.size()) {
+ thread.fCurrentFrame.set(var, val);
+ } else {
+ ((Frame)thread.fFrames.get(sfnumber)).set(var, val);
+ }
+ sendCommandResponse("ok\n");
+ }
+
+ void debugStack(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ StringBuffer result = new StringBuffer();
+
+ for (Iterator itr = thread.fFrames.iterator(); itr.hasNext();) {
+ Frame frame = (Frame)itr.next();
+ result.append(printFrame(frame));
+ result.append('#');
+ }
+ result.append(printFrame(thread.fCurrentFrame));
+ result.append('\n');
+ sendCommandResponse(result.toString());
+ }
+
+ void debugStackDepth(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+ sendCommandResponse( Integer.toString(thread.fFrames.size() + 1) + "\n" );
+ }
+
+
+ /**
+ * The stack frame output is: frame # frame # frame ... where each frame is:
+ * filename | line number | function name | var | var | var | var ...
+ */
+ private String printFrame(Frame frame) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(fFilename);
+ buf.append('|');
+ buf.append(frame.fPC);
+ buf.append('|');
+ buf.append(frame.fFunction);
+ for (Iterator itr = frame.fLocalVariables.keySet().iterator(); itr.hasNext();) {
+ String var = (String)itr.next();
+ if (var.indexOf('.') == -1) {
+ buf.append('|');
+ buf.append(var);
+ }
+ }
+ return buf.toString();
+ }
+
+ void debugState(Args args) {
+ PDAThread thread = args.getThreadArg();
+ String response = null;
+ if (thread == null) {
+ response = fSuspendVM == null ? "running" : fSuspendVM;
+ } else if (fSuspendVM != null) {
+ response = "vm";
+ } else {
+ response = thread.fSuspend == null ? "running" : thread.fSuspend;
+ }
+ sendCommandResponse(response + "\n");
+ }
+
+ void debugStep(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ // Set suspend to null to allow the debug loop to exit back to the
+ // instruction loop and thus run an instruction. However, we want to
+ // come back to the debug loop right away, so the step flag is set to
+ // true which will cause the suspend flag to get set to true when we
+ // get to the next instruction.
+ if (fSuspendVM != null) {
+ // All threads are suspended, so suspend all threads again when
+ // step completes.
+ fSuspendVM = null;
+ fStepVM = true;
+ // Also mark the thread that initiated the step to mark it as
+ // the triggering thread when suspending.
+ thread.fStep = true;
+ } else {
+ if (thread.fSuspend == null) {
+ sendCommandResponse("error: thread already running\n");
+ return;
+ }
+ thread.fSuspend = null;
+ thread.fStep = true;
+ sendDebugEvent("resumed " + thread.fID + " step", false);
+ }
+ sendCommandResponse("ok\n");
+ }
+
+ void debugStepReturn(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ if (fSuspendVM != null) {
+ fSuspendVM = null;
+ fStepReturnVM = true;
+ thread.fStepReturn = true;
+ } else {
+ if (thread.fSuspend == null) {
+ sendCommandResponse("error: thread running\n");
+ return;
+ }
+ thread.fSuspend = null;
+ thread.fStepReturn = true;
+ sendDebugEvent("resumed " + thread.fID + " step", false);
+ }
+ sendCommandResponse("ok\n");
+ }
+
+ void debugSuspend(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+ if (fSuspendVM != null) {
+ sendCommandResponse("error: vm already suspended\n");
+ return;
+ }
+ if (thread.fSuspend != null) {
+ sendCommandResponse("error: thread already suspended\n");
+ return;
+ }
+
+ thread.fSuspend = "client";
+ sendDebugEvent("suspended " + thread.fID + " client", false);
+ sendCommandResponse("ok\n");
+ }
+
+ void debugThreads() {
+ StringBuffer response = new StringBuffer();
+ for (Iterator itr = fThreads.keySet().iterator(); itr.hasNext();) {
+ response.append(itr.next());
+ response.append(' ');
+ }
+ sendCommandResponse(response.toString().trim() + "\n");
+ }
+
+ void debugVar(Args args) {
+ PDAThread thread = args.getThreadArg();
+ if (thread == null) {
+ sendCommandResponse("error: invalid thread\n");
+ return;
+ }
+
+ int sfnumber = args.getNextIntArg();
+ String var = args.getNextStringArg();
+
+ Frame frame = sfnumber >= thread.fFrames.size()
+ ? thread.fCurrentFrame : (Frame)thread.fFrames.get(sfnumber);
+
+ Object val = frame.get(var);
+ if (val == null) {
+ sendCommandResponse("error: variable undefined\n");
+ } else {
+ sendCommandResponse(val.toString() + "\n");
+ }
+ }
+
+ void debugVMResume() {
+ if (fSuspendVM == null) {
+ sendCommandResponse("error: vm already running\n");
+ return;
+ }
+
+ fSuspendVM = null;
+ sendCommandResponse("ok\n");
+ }
+
+ void debugVMSuspend() {
+ if (fSuspendVM != null) {
+ sendCommandResponse("error: vm already suspended\n");
+ return;
+ }
+
+ fSuspendVM = "client";
+ sendCommandResponse("ok\n");
+ }
+
+ void debugWatch(Args args) {
+ String funcAndVar = args.getNextStringArg();
+ int flags = args.getNextIntArg();
+ fWatchpoints.put(funcAndVar, new Integer(flags));
+ sendCommandResponse("ok\n");
+ }
+
+ void iAdd(PDAThread thread, Args args) {
+ Object val1 = thread.fStack.pop();
+ Object val2 = thread.fStack.pop();
+ if (val1 instanceof Integer && val2 instanceof Integer) {
+ int intVal1 = ((Integer) val1).intValue();
+ int intVal2 = ((Integer) val2).intValue();
+ thread.fStack.push( new Integer(intVal1 + intVal2) );
+ } else {
+ thread.fStack.push( new Integer(-1) );
+ }
+ }
+
+ void iBranchNotZero(PDAThread thread, Args args) {
+ Object val = thread.fStack.pop();
+ if (val instanceof Integer && ((Integer) val).intValue() != 0) {
+ String label = args.getNextStringArg();
+ if (thread.fThreadLabels.containsKey(label)) {
+ thread.fCurrentFrame.fPC = ((Integer)thread.fThreadLabels.get(label)).intValue();
+ } else {
+ sendDebugEvent("no such label " + label, true);
+ if ( ((Boolean)fEventStops.get("nosuchlabel")).booleanValue() ) {
+ fSuspendVM = thread.fID + " event nosuchlabel";
+ thread.fStack.push(val);
+ thread.fCurrentFrame.fPC--;
+ }
+ }
+ }
+ }
+
+ void iCall(PDAThread thread, Args args) {
+ String label = args.getNextStringArg();
+ if (thread.fThreadLabels.containsKey(label)) {
+ thread.fFrames.add(thread.fCurrentFrame);
+ thread.fCurrentFrame = new Frame(label, ((Integer)thread.fThreadLabels.get(label)).intValue());
+ } else {
+ sendDebugEvent("no such label " + label, true);
+ if ( ((Boolean)fEventStops.get("nosuchlabel")).booleanValue() ) {
+ fSuspendVM = thread.fID + " event nosuchlabel";
+ thread.fCurrentFrame.fPC--;
+ }
+ }
+ }
+
+ void iDec(PDAThread thread, Args args) {
+ Object val = thread.fStack.pop();
+ if (val instanceof Integer) {
+ val = new Integer(((Integer) val).intValue() - 1);
+ }
+ thread.fStack.push(val);
+ }
+
+ void iDef(PDAThread thread, Args args) {
+ String type = args.getNextStringArg();
+
+ String name = args.getNextStringArg();
+ String regName = getRegisterPartOfName(name);
+ String bitFieldName = getBitFieldPartOfName(name);
+
+ if ("register".equals(type)) {
+ Register reg = new Register(regName);
+ reg.fGroup = args.getNextStringArg();
+ fRegisters.put(regName, reg);
+ reg.fIsWriteable = args.getNextBooleanArg();
+ } else if ("bitfield".equals(type)) {
+ Register reg = (Register)fRegisters.get(regName);
+ if (reg == null) return;
+ BitField bitField = new BitField(bitFieldName);
+ bitField.fBitOffset = args.getNextIntArg();
+ bitField.fBitCount = args.getNextIntArg();
+ reg.fBitFields.put(bitFieldName, bitField);
+ } else if ("mnemonic".equals(type)) {
+ Register reg = (Register)fRegisters.get(regName);
+ if (reg == null) return;
+ BitField bitField = (BitField)reg.fBitFields.get(bitFieldName);
+ if (bitField == null) return;
+ bitField.fMnemonics.put(args.getNextStringArg(), new Integer(args.getNextIntArg()));
+ }
+ sendDebugEvent("registers", false);
+ }
+
+ private String getRegisterPartOfName(String name) {
+ if (name.startsWith("$")) {
+ int end = name.indexOf('.');
+ end = end != -1 ? end : name.length();
+ return name.substring(1, end);
+ }
+ return null;
+ }
+
+ private String getBitFieldPartOfName(String name) {
+ int start = name.indexOf('.');
+ if (name.startsWith("$") && start != -1) {
+ return name.substring(start + 1, name.length());
+ }
+ return null;
+ }
+
+ void iDup(PDAThread thread, Args args) {
+ Object val = thread.fStack.pop();
+ thread.fStack.push(val);
+ thread.fStack.push(val);
+ }
+
+ void iExec(PDAThread thread, Args args) {
+ String label = args.getNextStringArg();
+ if (fLabels.containsKey(label)) {
+ int id = fNextThreadId++;
+ fThreads.put( new Integer(id), new PDAThread(id, label, ((Integer)fLabels.get(label)).intValue()) );
+ sendDebugEvent("started " + id, false);
+ } else {
+ sendDebugEvent("no such label " + label, true);
+ if ( ((Boolean)fEventStops.get("nosuchlabel")).booleanValue() ) {
+ thread.fSuspend = "event nosuchlabel";
+ thread.fCurrentFrame.fPC--;
+ }
+ }
+ }
+
+ void iHalt(PDAThread thread, Args args) {
+ thread.fRun = false;
+ }
+
+ void iOutput(PDAThread thread, Args args) {
+ System.out.println(thread.fStack.pop());
+ }
+
+ void iPop(PDAThread thread, Args args) {
+ String arg = args.getNextStringArg();
+ if (arg.startsWith("$")) {
+ String var = arg.substring(1);
+ thread.fCurrentFrame.set(var, thread.fStack.pop());
+ String key = thread.fCurrentFrame.fFunction + "::" + var;
+ if ( fWatchpoints.containsKey(key) && (((Integer)fWatchpoints.get(key)).intValue() & 2) != 0 ) {
+ fSuspendVM = thread.fID + " watch write " + key;
+ }
+ } else {
+ thread.fStack.pop();
+ }
+ }
+
+ void iPush(PDAThread thread, Args args) {
+ String arg = args.getNextStringArg();
+ while (arg.length() != 0) {
+ if (arg.startsWith("$")) {
+ String var = arg.substring(1);
+ Object val = thread.fCurrentFrame.get(var);
+ if (val == null) val = "<undefined>";
+ thread.fStack.push(val);
+ String key = thread.fCurrentFrame.fFunction + "::" + var;
+ if (fWatchpoints.containsKey(key) && (((Integer)fWatchpoints.get(key)).intValue() & 1) != 0) {
+ fSuspendVM = thread.fID + " watch read " + key;
+ }
+ } else {
+ Object val = arg;
+ if (args.hasNextArg()) {
+ while (args.hasNextArg()) {
+ val = val.toString() + " " + args.getNextStringArg();
+ }
+ } else {
+ try {
+ val = new Integer(arg);
+ } catch (NumberFormatException e) {
+ }
+ }
+ thread.fStack.push(val);
+ }
+
+ arg = args.getNextStringArg();
+ }
+ }
+
+ void iReturn(PDAThread thread, Args args) {
+ if (!thread.fFrames.isEmpty()) {
+ thread.fCurrentFrame = (Frame)thread.fFrames.remove(thread.fFrames.size() - 1);
+ } else {
+ // Execution returned from the top frame, which means this thread
+ // should exit.
+ thread.fRun = false;
+ }
+ }
+
+ void iVar(PDAThread thread, Args args) {
+ String var = args.getNextStringArg();
+ thread.fCurrentFrame.set(var, new Integer(0));
+ }
+
+ void iInternalEndEval(PDAThread thread, Args args) {
+ Object result = thread.fStack.pop();
+ thread.fThreadCode = fCode;
+ thread.fThreadLabels = fLabels;
+ thread.fCurrentFrame.fPC = thread.fSavedPC;
+ sendDebugEvent("evalresult " + result, false);
+ thread.fSuspend = "eval";
+ thread.fPerformingEval = false;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest10.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest10.pda
new file mode 100644
index 000000000..837277f5f
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest10.pda
@@ -0,0 +1,38 @@
+def register $reg1 group1 true
+def register $reg2 group1 false
+def register $reg3 group2 true
+def bitfield $reg1.field1 0 2
+def bitfield $reg1.field2 2 2
+def mnemonic $reg1.field2 zero 0
+def mnemonic $reg1.field2 one 1
+def mnemonic $reg1.field2 two 2
+def mnemonic $reg1.field2 three 3
+push 1
+pop $$reg1
+push $$reg1
+output
+push 2
+pop $$reg1.field1
+push $$reg1.field1
+output
+push 4
+pop $$reg1.field1
+push $$reg1.field1
+output
+push 1
+pop $$reg1.field2
+push $$reg1
+output
+push zero
+pop $$reg1.field2
+push $$reg1.field2
+output
+push $$reg1
+output
+push 2
+pop $$reg1.field2
+push $$reg1.field2
+output
+push $$reg1
+output
+halt \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda
index a9fcfc2a8..5aecdc5e6 100644
--- a/org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda
@@ -8,4 +8,6 @@ add
call zippy
add
output
+push 1
+branch_not_zero swishy
halt
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest9.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest9.pda
new file mode 100644
index 000000000..336a251d9
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest9.pda
@@ -0,0 +1,23 @@
+push 5
+:thread_create
+exec foo
+dec
+dup
+branch_not_zero thread_create
+push finished
+output
+halt
+:foo
+push thread_created
+output
+call inner
+halt
+:inner
+var b
+call inner2
+push 2
+return
+:inner2
+var c
+push 3
+return
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest_children.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest_children.pda
new file mode 100644
index 000000000..b0bbd163d
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest_children.pda
@@ -0,0 +1,8 @@
+var a
+var a.b
+var a.c
+push 1
+pop $a.b
+push $a.b
+output
+halt
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl b/org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl
deleted file mode 100644
index 0e2f8a358..000000000
--- a/org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl
+++ /dev/null
@@ -1,448 +0,0 @@
-#!perl.exe
-
-use strict;
-use warnings;
-use IO::Socket;
-
-#####################################################################
-# Copyright (c) 2004-2005 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# Bjorn Freeman-Benson - initial API and implementation
-#####################################################################
-#
-# This test is designed to run on Windows:
-#
-# cd c:\eclipse\workspace\org.eclipse.debug.examples.core
-# perl pdavm\tests\vmtests.pl
-#
-# If the tests fail, they often indicate that by hanging in an
-# infinite loop. Additionally, the vm under test often becomes
-# a 100% CPU usage zombie. Use the task manager to kill them.
-#
-my $socket1;
-my $socket2;
-
-sub expect_output {
- my $expect = shift;
- my $line = <PROGRAM_OUTPUT>;
- chomp($line);
- return if( $line eq $expect );
- die "expected output: $expect\nSaw output: $line";
-}
-sub expect_output_eof {
- my $line = <PROGRAM_OUTPUT>;
- return if( !defined $line );
- die "expected: EOF on output";
-}
-sub send_command {
- my $string = shift;
- my $expect = shift;
- $expect = "ok" if( !defined $expect );
- #print STDERR "SEND: $string\n";
- print $socket1 "$string\n";
- my $result = <$socket1>;
- chomp($result);
- #print STDERR "RESULT: $result\n";
- die "sent: $string\nexpected: $expect\nsaw: $result" if( !($result eq $expect) );
-}
-sub expect_event {
- my $string = shift;
- my $event = <$socket2>;
- chomp($event);
- #print STDERR "EVENT: $event\n";
- die "expected event: $string\nsaw event: $event" if( !($string eq $event) );
-}
-sub setup_sockets {
- #print STDERR "calling socket 12345\n";
- $socket1 = IO::Socket::INET->new(
- Proto => "tcp",
- PeerAddr => "localhost",
- PeerPort => "12345",
- Timeout => 10,
- )
- or die "cannot connect to debug socket 12345";
- #print STDERR "calling socket 12346\n";
- $socket2 = IO::Socket::INET->new(
- Proto => "tcp",
- PeerAddr => "localhost",
- PeerPort => "12346",
- Timeout => 10,
- )
- or die "cannot connect to debug socket 12346";
- #print STDERR "done calling sockets\n";
-}
-
-sub test2 {
- print "test2 (common debug commands)..\n";
-
- my $kidpid;
- die "can't fork: $!" unless defined($kidpid = fork());
- if( $kidpid ) {
- #print STDERR "starting program\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest2.pda -debug 12345 12346 |";
- #print STDERR "done starting program\n";
- expect_output("-debug 12345 12346");
- expect_output("debug connection accepted");
- expect_output("10");
- expect_output_eof();
- exit 0;
- } else {
- setup_sockets();
- expect_event("started");
- # test step
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- # test breakpoint
- send_command("set 4");
- send_command("data", "6|");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended breakpoint 4");
- # test data stack
- send_command("data", "6|7|8|9|");
- send_command("popdata");
- send_command("data", "6|7|8|");
- send_command("pushdata 11");
- send_command("data", "6|7|8|11|");
- send_command("setdata 1 2");
- send_command("data", "6|2|8|11|");
- # test call stack
- send_command("set 12");
- send_command("set 19");
- send_command("stepreturn");
- expect_event("resumed client");
- expect_event("suspended breakpoint 12");
- send_command("clear 19");
- send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|12|sub2" );
- send_command("stepreturn");
- expect_event("resumed client");
- expect_event("suspended step");
- send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|13|sub2" );
- send_command("stepreturn");
- expect_event("resumed client");
- expect_event("suspended step");
- send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|22|sub1|m|n" );
- send_command("set 6");
- send_command("stepreturn");
- expect_event("resumed client");
- expect_event("suspended breakpoint 6");
- # test set and clear
- send_command("set 27");
- send_command("set 29");
- send_command("set 33");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended breakpoint 33");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended breakpoint 27");
- send_command("clear 33");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended breakpoint 29");
- # test var and setvar
- send_command("set 47");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended breakpoint 47");
- send_command("var 1 b", "4");
- send_command("var 2 b", "2");
- send_command("var 1 a", "0");
- send_command("setvar 1 a 99");
- send_command("data", "6|2|8|11|27|1|4|");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("var 1 a", "99");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("data", "6|2|8|11|27|1|4|99|");
- # test exit
- send_command("exit");
- expect_event("terminated");
- }
- #print STDERR "waiting for child\n";
- wait();
- #print STDERR "child joined\n";
- close PROGRAM_OUTPUT;
- print "test2..SUCCESS\n";
-}
-
-sub test3 {
- print "test3 (uncaught events)..\n";
-
- my $kidpid;
- die "can't fork: $!" unless defined($kidpid = fork());
- if( $kidpid ) {
- #print STDERR "starting program\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |";
- #print STDERR "done starting program\n";
- expect_output("-debug 12345 12346");
- expect_output("debug connection accepted");
- expect_output("10");
- expect_output_eof();
- exit 0;
- } else {
- setup_sockets();
- expect_event("started");
- send_command("resume");
- expect_event("resumed client");
- expect_event("unimplemented instruction foobar");
- expect_event("no such label zippy");
- expect_event("terminated");
- }
- #print STDERR "waiting for child\n";
- wait();
- #print STDERR "child joined\n";
- close PROGRAM_OUTPUT;
- print "test3..SUCCESS\n";
-}
-sub test4 {
- print "test4 (caught events)..\n";
-
- my $kidpid;
- die "can't fork: $!" unless defined($kidpid = fork());
- if( $kidpid ) {
- #print STDERR "starting program\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |";
- #print STDERR "done starting program\n";
- expect_output("-debug 12345 12346");
- expect_output("debug connection accepted");
- expect_output("10");
- expect_output_eof();
- exit 0;
- } else {
- setup_sockets();
- expect_event("started");
- send_command("eventstop unimpinstr 1");
- send_command("resume");
- expect_event("resumed client");
- expect_event("unimplemented instruction foobar");
- expect_event("suspended event unimpinstr");
- send_command("eventstop unimpinstr 0");
- send_command("resume");
- expect_event("resumed client");
- expect_event("unimplemented instruction foobar");
- expect_event("no such label zippy");
- expect_event("terminated");
- }
- #print STDERR "waiting for child\n";
- wait();
- #print STDERR "child joined\n";
- close PROGRAM_OUTPUT;
- print "test4..SUCCESS\n";
-}
-sub test5 {
- print "test5 (caught events)..\n";
-
- my $kidpid;
- die "can't fork: $!" unless defined($kidpid = fork());
- if( $kidpid ) {
- #print STDERR "starting program\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |";
- #print STDERR "done starting program\n";
- expect_output("-debug 12345 12346");
- expect_output("debug connection accepted");
- expect_output("10");
- expect_output_eof();
- exit 0;
- } else {
- setup_sockets();
- expect_event("started");
- send_command("eventstop nosuchlabel 1");
- send_command("resume");
- expect_event("resumed client");
- expect_event("unimplemented instruction foobar");
- expect_event("no such label zippy");
- expect_event("suspended event nosuchlabel");
- send_command("eventstop nosuchlabel 0");
- send_command("resume");
- expect_event("resumed client");
- expect_event("no such label zippy");
- expect_event("terminated");
- }
- #print STDERR "waiting for child\n";
- wait();
- #print STDERR "child joined\n";
- close PROGRAM_OUTPUT;
- print "test5..SUCCESS\n";
-}
-sub test6 {
- print "test6 (watch points)..\n";
-
- my $kidpid;
- die "can't fork: $!" unless defined($kidpid = fork());
- if( $kidpid ) {
- #print STDERR "starting program\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |";
- #print STDERR "done starting program\n";
- expect_output("-debug 12345 12346");
- expect_output("debug connection accepted");
- expect_output("8");
- expect_output_eof();
- exit 0;
- } else {
- setup_sockets();
- expect_event("started");
- send_command("watch inner::a 1");
- send_command("watch main::a 2");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended watch write main::a");
- send_command("stack", "pdavm\\tests\\vmtest6.pda|4|main|a|b");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended watch read inner::a");
- send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|25|inner|a|c");
- send_command("watch inner::a 0");
- send_command("resume");
- expect_event("resumed client");
- expect_event("terminated");
- }
- #print STDERR "waiting for child\n";
- wait();
- #print STDERR "child joined\n";
- close PROGRAM_OUTPUT;
- print "test6..SUCCESS\n";
-}
-sub test7 {
- print "test7 (eval)..\n";
-
- my $kidpid;
- die "can't fork: $!" unless defined($kidpid = fork());
- if( $kidpid ) {
- #print STDERR "starting program\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |";
- #print STDERR "done starting program\n";
- expect_output("-debug 12345 12346");
- expect_output("debug connection accepted");
- expect_output("8");
- expect_output_eof();
- exit 0;
- } else {
- setup_sockets();
- expect_event("started");
- send_command("set 25");
- send_command("resume");
- expect_event("resumed client");
- expect_event("suspended breakpoint 25");
- #
- send_command("eval push%204|push%205|add");
- expect_event("resumed client");
- expect_event("evalresult 9");
- expect_event("suspended eval");
- #
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c");
- send_command("data", "4|4|");
- send_command("eval call%20other");
- expect_event("resumed client");
- expect_event("evalresult 15");
- expect_event("suspended eval");
- send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c");
- send_command("data", "4|4|");
- send_command("resume");
- expect_event("resumed client");
- expect_event("terminated");
- }
- #print STDERR "waiting for child\n";
- wait();
- #print STDERR "child joined\n";
- close PROGRAM_OUTPUT;
- print "test7..SUCCESS\n";
-}
-sub test1 {
- print "test1 (normal run mode)..\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl examples\\example.pda |" or die $!;
- expect_output("\"hello\"");
- expect_output("\"barfoo\"");
- expect_output("\"first\"");
- expect_output("\"second\"");
- expect_output("12");
- expect_output("11");
- expect_output("10");
- expect_output("\"barfoo\"");
- expect_output("\"first\"");
- expect_output("\"second\"");
- expect_output("\"end\"");
- expect_output_eof();
- print "test1..SUCCESS\n";
-}
-sub test8 {
- print "test8 (drop to frame)..\n";
-
- my $kidpid;
- die "can't fork: $!" unless defined($kidpid = fork());
- if( $kidpid ) {
- #print STDERR "starting program\n";
- open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest8.pda -debug 12345 12346 |";
- #print STDERR "done starting program\n";
- expect_output("-debug 12345 12346");
- expect_output("debug connection accepted");
- expect_output("1");
- expect_output_eof();
- exit 0;
- } else {
- setup_sockets();
- expect_event("started");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|12|inner2|c");
- send_command("drop");
- expect_event("suspended drop");
- send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|7|inner|b");
- send_command("step");
- expect_event("resumed step");
- expect_event("suspended step");
- send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|10|inner2");
- send_command("resume");
- expect_event("resumed client");
- expect_event("terminated");
- }
- #print STDERR "waiting for child\n";
- wait();
- #print STDERR "child joined\n";
- close PROGRAM_OUTPUT;
- print "test8..SUCCESS\n";
-}
-
-#
-# Run the tests
-#
-test1();
-test2();
-test3();
-test4();
-test5();
-test6();
-test7();
-test8();
-print "All tests complete\n"; \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/samples/registers.pda b/org.eclipse.debug.examples.core/samples/registers.pda
new file mode 100644
index 000000000..97fd8d409
--- /dev/null
+++ b/org.eclipse.debug.examples.core/samples/registers.pda
@@ -0,0 +1,72 @@
+def register $pc General true
+def register $sp General true
+def register $status General true
+def bitfield $status.BITS_00_07 0 8
+def bitfield $status.BITS_08_15 8 8
+def bitfield $status.BITS_16_23 16 8
+def bitfield $status.BITS_24_31 24 8
+def mnemonic $status.BITS_24_31 three 3
+def mnemonic $status.BITS_24_31 twelve 12
+def mnemonic $status.BITS_24_31 fourty_eight 48
+def mnemonic $status.BITS_24_31 one_nighty_two 192
+def register $stackdepth General true
+def register $stack[0] General true
+def register $stack[1] General true
+def register $stack[2] General true
+def register $stack[3] General true
+def register $stack[4] General true
+push 103
+pop $$pc
+push 306
+push 2
+pop $$sp
+push 400
+pop $$status
+push 5
+pop $$stackdepth
+push 12
+pop $$stack[0]
+push 45
+pop $$stack[1]
+push 146
+pop $$stack[2]
+push 215
+pop $$stack[3]
+push 251
+pop $$stack[4]
+push 306
+pop $$stack[5]
+def register $total-instructions Analysis false
+def register $add-instructions Analysis false
+def register $call-instructions Analysis false
+def register $dec-instructions Analysis false
+def register $dup-instructions Analysis false
+def register $halt-instructions Analysis false
+def register $output-instructions Analysis false
+def register $pop-instructions Analysis false
+def register $push-instructions Analysis false
+def register $return-instructions Analysis false
+def register $var-instructions Analysis false
+push 1046
+pop $$total-instructions
+push 12
+pop $$add-instructions
+push 24
+pop $$call-instructions
+push 36
+pop $$dec-instructions
+push 50
+pop $$dup-instructions
+push 62
+pop $$halt-instructions
+push 74
+pop $$output-instructions
+push 106
+pop $$pop-instructions
+push 120
+pop $$push-instructions
+push 132
+pop $$return-instructions
+push 144
+pop $$var-instructions
+halt \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/samples/stack.pda b/org.eclipse.debug.examples.core/samples/stack.pda
new file mode 100644
index 000000000..c7fa1628b
--- /dev/null
+++ b/org.eclipse.debug.examples.core/samples/stack.pda
@@ -0,0 +1,21 @@
+push 5
+:thread_create
+exec stack
+dec
+dup
+branch_not_zero thread_create
+push finished
+output
+halt
+:stack
+push 100
+:inner
+dup
+output
+dup
+branch_not_zero descend
+return
+:descend
+dec
+call inner
+return \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/samples/structures.pda b/org.eclipse.debug.examples.core/samples/structures.pda
index 97858b079..4cc881728 100644
--- a/org.eclipse.debug.examples.core/samples/structures.pda
+++ b/org.eclipse.debug.examples.core/samples/structures.pda
@@ -1,8 +1,29 @@
+push a
+push b
+push c
+push x
+push y
+push z
push one two three
push 1 2 3
+push I II III
var x
+var x.a
+var x.b
var y
+var y.c
+var y.d
+var y.d.1
+var y.d.2
+var y.d.3
pop $x
+pop $x.a
+pop $x.b
pop $y
+pop $y.c
+pop $y.d
+pop $y.d.1
+pop $y.d.2
+pop $y.d.3
push Done
output \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java
index 24062b0b5..894d7432c 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.breakpoints;
@@ -16,14 +17,18 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
-import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.LineBreakpoint;
import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
import org.eclipse.debug.examples.core.pda.model.IPDAEventListener;
import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
import org.eclipse.debug.examples.core.pda.model.PDAThread;
+import org.eclipse.debug.examples.core.protocol.PDAClearBreakpointCommand;
+import org.eclipse.debug.examples.core.protocol.PDAEvent;
+import org.eclipse.debug.examples.core.protocol.PDARunControlEvent;
+import org.eclipse.debug.examples.core.protocol.PDASetBreakpointCommand;
+import org.eclipse.debug.examples.core.protocol.PDASuspendedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAVMSuspendedEvent;
/**
@@ -108,7 +113,7 @@ public class PDALineBreakpoint extends LineBreakpoint implements IPDAEventListen
//#ifdef ex3
//# // TODO: Exercise 3 - create breakpoint request in interpreter
//#else
- target.sendRequest("set " + (getLineNumber() - 1));
+ target.sendCommand(new PDASetBreakpointCommand((getLineNumber() - 1), false));
//#endif
}
@@ -123,7 +128,7 @@ public class PDALineBreakpoint extends LineBreakpoint implements IPDAEventListen
//#ifdef ex3
//# // TODO: Exercise 3 - clear breakpoint request in interpreter
//#else
- target.sendRequest("clear " + (getLineNumber() - 1));
+ target.sendCommand(new PDAClearBreakpointCommand((getLineNumber() - 1)));
//#endif
}
@@ -154,16 +159,12 @@ public class PDALineBreakpoint extends LineBreakpoint implements IPDAEventListen
/**
* Notify's the PDA interprettor that this breakpoint has been hit.
*/
- protected void notifyThread() {
+ protected void notifyThread(int threadId) {
if (fTarget != null) {
- try {
- IThread[] threads = fTarget.getThreads();
- if (threads.length == 1) {
- PDAThread thread = (PDAThread)threads[0];
- thread.suspendedBy(this);
- }
- } catch (DebugException e) {
- }
+ PDAThread thread = fTarget.getThread(threadId);
+ if (thread != null) {
+ thread.suspendedBy(this);
+ }
}
}
@@ -173,9 +174,12 @@ public class PDALineBreakpoint extends LineBreakpoint implements IPDAEventListen
*
* @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
*/
- public void handleEvent(String event) {
- if (event.startsWith("suspended breakpoint")) {
- handleHit(event);
+ public void handleEvent(PDAEvent event) {
+ if (event instanceof PDASuspendedEvent || event instanceof PDAVMSuspendedEvent) {
+ PDARunControlEvent rcEvent = (PDARunControlEvent)event;
+ if (rcEvent.fReason.equals("breakpoint")) {
+ handleHit(rcEvent);
+ }
}
}
@@ -184,16 +188,16 @@ public class PDALineBreakpoint extends LineBreakpoint implements IPDAEventListen
*
* @param event breakpoint event
*/
- private void handleHit(String event) {
- int lastSpace = event.lastIndexOf(' ');
+ private void handleHit(PDARunControlEvent event) {
+ int lastSpace = event.fMessage.lastIndexOf(' ');
if (lastSpace > 0) {
- String line = event.substring(lastSpace + 1);
+ String line = event.fMessage.substring(lastSpace + 1);
int lineNumber = Integer.parseInt(line);
// breakpoints event line numbers are 0 based, model objects are 1 based
lineNumber++;
try {
if (getLineNumber() == lineNumber) {
- notifyThread();
+ notifyThread(event.fThreadId);
}
} catch (CoreException e) {
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java
index ab819d0b5..651532909 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.breakpoints;
@@ -19,6 +20,11 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IWatchpoint;
import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.protocol.PDAEvent;
+import org.eclipse.debug.examples.core.protocol.PDARunControlEvent;
+import org.eclipse.debug.examples.core.protocol.PDASuspendedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAVMSuspendedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAWatchCommand;
/**
@@ -177,23 +183,26 @@ public class PDAWatchpoint extends PDALineBreakpoint implements IWatchpoint {
if (isModification()) {
flag = flag | 2;
}
- target.sendRequest("watch " + getFunctionName() + "::" + getVariableName() + " " + flag);
+ target.sendCommand(new PDAWatchCommand(getFunctionName(), getVariableName(), flag));
}
/* (non-Javadoc)
* @see org.eclipse.debug.examples.core.pda.breakpoints.PDALineBreakpoint#clearRequest(org.eclipse.debug.examples.core.pda.model.PDADebugTarget)
*/
protected void clearRequest(PDADebugTarget target) throws CoreException {
- target.sendRequest("watch " + getFunctionName() + "::" + getVariableName() + " " + 0);
+ target.sendCommand(new PDAWatchCommand(getFunctionName(), getVariableName(), 0));
}
/* (non-Javadoc)
* @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
*/
- public void handleEvent(String event) {
- if (event.startsWith("suspended watch")) {
- handleHit(event);
- }
+ public void handleEvent(PDAEvent event) {
+ if (event instanceof PDASuspendedEvent || event instanceof PDAVMSuspendedEvent) {
+ PDARunControlEvent rcEvent = (PDARunControlEvent)event;
+ if (rcEvent.fReason.equals("watch")) {
+ handleHit(rcEvent);
+ }
+ }
}
/**
@@ -201,8 +210,8 @@ public class PDAWatchpoint extends PDALineBreakpoint implements IWatchpoint {
*
* @param event breakpoint event
*/
- private void handleHit(String event) {
- String[] strings = event.split(" ");
+ private void handleHit(PDARunControlEvent event) {
+ String[] strings = event.fMessage.split(" ");
if (strings.length == 4) {
String fv = strings[3];
int j = fv.indexOf("::");
@@ -212,7 +221,7 @@ public class PDAWatchpoint extends PDALineBreakpoint implements IWatchpoint {
try {
if (getVariableName().equals(var) && getFunctionName().equals(fcn)) {
setSuspendType(strings[2]);
- notifyThread();
+ notifyThread(event.fThreadId);
}
} catch (CoreException e) {
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java
index b5fd026dd..be7db91dd 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.launcher;
@@ -55,28 +56,23 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate {
List commandList = new ArrayList();
- // Perl executable
- IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(DebugCorePlugin.VARIALBE_PERL_EXECUTABLE);
- if (perl == null) {
- abort("Perl executable location undefined. Check value of ${perlExecutable}.", null);
- }
- String path = perl.getValue();
- if (path == null) {
- abort("Perl executable location unspecified. Check value of ${perlExecutable}.", null);
- }
- File exe = new File(path);
- if (!exe.exists()) {
- abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $perlExecutable.", new String[]{path}), null);
- }
- commandList.add(path);
-
- // Add PDA VM
- File vm = DebugCorePlugin.getFileInPlugin(new Path("pdavm/pda.pl"));
- if (vm == null) {
- abort("Missing PDA VM", null);
- }
- commandList.add(vm.getAbsolutePath());
-
+ // Get Java VM path
+ String javaVMHome = System.getProperty("java.home");
+ String javaVMExec = javaVMHome + File.separatorChar + "bin" + File.separatorChar + "java";
+ if (File.separatorChar == '\\') {
+ javaVMExec += ".exe";
+ }
+ File exe = new File(javaVMExec);
+ if (!exe.exists()) {
+ abort(MessageFormat.format("Specified java VM executable {0} does not exist.", new Object[]{javaVMExec}), null);
+ }
+ commandList.add(javaVMExec);
+
+ commandList.add("-cp");
+ commandList.add(File.pathSeparator + DebugCorePlugin.getFileInPlugin(new Path("bin")));
+
+ commandList.add("org.eclipse.debug.examples.pdavm.PDAVirtualMachine");
+
// program name
String program = configuration.getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
if (program == null) {
@@ -106,7 +102,7 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate {
String[] commandLine = (String[]) commandList.toArray(new String[commandList.size()]);
Process process = DebugPlugin.exec(commandLine, null);
- IProcess p = DebugPlugin.newProcess(launch, process, path);
+ IProcess p = DebugPlugin.newProcess(launch, process, javaVMExec);
// if in debug mode, create a debug target
if (mode.equals(ILaunchManager.DEBUG_MODE)) {
IDebugTarget target = new PDADebugTarget(launch, p, requestPort, eventPort);
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java
index 6935ad32b..b681dc880 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,46 +8,28 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
+import org.eclipse.debug.examples.core.protocol.PDAEvent;
+
/**
* Listeners are notified of events occurring in a PDA program
* being interpreted.
- * <p>
- * The events generated by the interpreter are:
- * <ul>
- * <li><code>started</code> - the interpreter has started (guaranteed to be the
- * first event sent)</li>
- * <li><code>terminated</code> - the interpreter has terminated (guaranteed to be
- * the last event sent)</li>
- * <li><code>suspended X</code> - the interpreter has suspended and entered debug mode;
- * <code>X</code> is the cause of the suspension:
- * <ul>
- * <li><code>breakpoint N</code> - a breakpoint at line <code>N</code> was hit</li>
- * <li><code>client</code> - a client request to suspend has completed</li>
- * <li><code>drop</code> - a client request to drop a frame has completed</li>
- * <li><code>event E</code> - an error was encountered, where <code>E</code> is one
- * of <code>unimpinstr</code> or <code>nosuchlabel</code></li>
- * <li><code>step</code> - a step request has completed</li>
- * <li><code>watch A F::V</code> - a watchpoint was hit for reason <code>A</code>
- * (<code>read</code> or <code>write</code>), on variable <code>V</code> in
- * function <code>F</code></li>
- * </ul>
- * </li>
- * <li><code>resumed X</code> - the interpreter has resumed execution in run mode;
- * <code>X</code> is the cause of the resume:
- * <ul>
- * <li><code>step</code> - a step request has been initiated</li>
- * <li><code>client</code> - a client request to resume has been initiated</li>
- * </ul>
- * </li>
- * <li><code>unimplemented instruction X</code> - an unimplemented instruction <code>X</code>
- * was encountered</li>
- * <li><code>no such label X</code> - a branch or call to an unknown label <code>X</code>
- * was encountered</li>
- * </ul>
- * </p>
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDAVMStarted
+ * @see org.eclipse.debug.examples.core.protocol.PDAVMTerminated
+ * @see org.eclipse.debug.examples.core.protocol.PDAVMSuspneded
+ * @see org.eclipse.debug.examples.core.protocol.PDAVMResumed
+ * @see org.eclipse.debug.examples.core.protocol.PDAStarted
+ * @see org.eclipse.debug.examples.core.protocol.PDAExited
+ * @see org.eclipse.debug.examples.core.protocol.PDASuspended
+ * @see org.eclipse.debug.examples.core.protocol.PDAResumed
+ * @see org.eclipse.debug.examples.core.protocol.PDAUnimplementedInstructionEvent
+ * @see org.eclipse.debug.examples.core.protocol.PDARegisterData
+ * @see org.eclipse.debug.examples.core.protocol.PDANoSuchLabelEvent
+ * @see org.eclipse.debug.examples.core.protocol.PDAEvalResultEvent
*/
public interface IPDAEventListener {
@@ -57,6 +39,6 @@ public interface IPDAEventListener {
*
* @param event the event
*/
- public void handleEvent(String event);
+ public void handleEvent(PDAEvent event);
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java
index e27e1bad1..bcc07ba35 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
@@ -23,7 +24,7 @@ public class PDAArray extends PDAValue {
* @throws DebugException
*/
public PDAArray(PDAValue value) throws DebugException {
- super(value.getPDADebugTarget(), value.getValueString());
+ super(value.getVariable(), value.getValueString());
}
/* (non-Javadoc)
@@ -42,7 +43,7 @@ public class PDAArray extends PDAValue {
IVariable[] variables = new IVariable[words.length];
for (int i = 0; i < words.length; i++) {
String word = words[i];
- variables[i] = new PDAArrayEntry(getPDADebugTarget(), i, new PDAValue(getPDADebugTarget(), word));
+ variables[i] = new PDAArrayEntry(getPDADebugTarget(), i, new PDAValue(getVariable(), word));
}
return variables;
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java
index e64f22050..6bf39f31d 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
@@ -17,6 +18,8 @@ import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.DebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.core.protocol.PDACommand;
+import org.eclipse.debug.examples.core.protocol.PDACommandResult;
/**
@@ -41,61 +44,50 @@ public class PDADebugElement extends DebugElement {
}
/**
- * Sends a request to the PDA interpreter, waits for and returns the reply.
- * <p>
- * Interpreter commands and replies are as follows:
- * <ul>
- * <li><code>clear N</code> - clear the breakpoint on line <code>N</code>;
- * reply is <code>ok</code></li>
- * <li><code>data</code> - return the contents of the data stack; reply is the data
- * from oldest to newest as a single string <code>"value|value|value|...|value|"</code></li>
- * <li><code>drop</code> - pops the top stack frame off the call stack setting the
- * instruction pointer to the calling statement in the calling frame</li>
- * <li><code>eventstop E B</code> - optionally stop the interpreter when an error event
- * <code>E</code> is encountered; <code>B</code> specifies stop (<code>1</code>) or
- * continue (<code>0</code>). The possible events are <code>unimpinstr</code> and
- * <code>nosuchlabel</code>. Reply is <code>ok</code>. When an event is encountered,
- * the interpreter sends the error event (for example <code>unimlpemented instruction foo</code>)
- * and corresponding suspend event (for example <code>suspended event unimpinstr</code>).</li>
- * <li><code>exit</code> - end the interpreter; reply is <code>ok</code></li>
- * <li><code>popdata</code> - pop the top value off the data stack; reply is the value</li>
- * <li><code>pushdata V</code> - push the value <code>V</code> onto the data stack; reply is
- * <code>ok</code></li>
- * <li><code>resume</code> - resume execution of the program; reply is <code>ok</code></li>
- * <li><code>set N</code> - set a line breakpoint on line <code>N</code> (lines are indexed
- * from 0); reply is <code>ok</code></li>
- * <li><code>setdata N V</code> - set the contents of data stack element <code>N</code> to
- * value <code>V</code> (the data stack is indexed from 0, 0 being the oldest); reply
- * is <code>ok</code></li>
- * <li><code>setvar N M V</code> - set the contents of variable <code>M</code> from the control
- * stack <code>N</code> to value <code>V</code> (the control stack is indexed from 0,
- * 0 being the oldest); reply is <code>ok</code></li>
- * <li><code>stack</code> - return the contents of the control stack (program counters, function and
- * variable names); reply is control stack from oldest to newest as a single string
- * <code>frame#frame#frame...#frame</code> where each frame is a string
- * <code>"filename|pc|function name|variable name|variable name|...|variable name"</code></li>
- * <li><code>step</code> - single step forward; reply is <code>ok</code></li>
- * <li><code>stepreturn</code> - single step forward until the next <code>return</code> op code;
- * stop before executing the <code>return</code> ; reply is <code>ok</code></li>
- * <li><code>suspend</code> - suspend execution of the program and listen for debug commands;
- * reply is <code>ok</code></li>
- * <li><code>watch F::V M</code> - set a watchpoint on variable <code>V</code> in function
- * <code>F</code> to magic value <code>M</code>; the magic value is a bit flag corresponding
- * to read access (1), write access (2), or both (3); the magic value 0 clears the watchpoint;
- * reply is <code>ok</code></li>
- * <li><code>var N M</code> - return the contents of variable <code>M</code> in the control
- * stack frame <code>N</code> (stack frames are indexed from 0, 0 being the oldest);
- * reply is variable value</li>
- * </ul>
- * </p>
- *
- * @param request command
- * @return reply
- * @throws DebugException if the request fails
- */
- public String sendRequest(String request) throws DebugException {
- return getPDADebugTarget().sendRequest(request);
- }
+ * Sends a request to the PDA interpreter, waits for and returns the reply.
+ *
+ * @param request command
+ * @return reply
+ * @throws DebugException if the request fails
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDATerminateCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAVMSuspendCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAVMResumeCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDASuspendCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAResumeCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAStepCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDADropFrameCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDASetBreakpointCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAClearBreakpointCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAWatchCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDADataCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDASetDataCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAPopDataCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAPushDataCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDAEvalCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDAEventStopCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDAStackCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAStackDepthCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAFrameCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDASetVarCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAVarCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDAChildrenCommand
+ *
+ * @see org.eclipse.debug.examples.core.protocol.PDAGroupsCommand
+ * @see org.eclipse.debug.examples.core.protocol.PDARegistersCommand
+ *
+ * @since 3.5
+ */
+ public PDACommandResult sendCommand(PDACommand command) throws DebugException {
+ return getPDADebugTarget().sendCommand(command);
+ }
/**
* Returns the debug target as a PDA target.
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java
index 6df9fad76..44437af5d 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
@@ -17,7 +18,11 @@ import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
@@ -29,6 +34,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.IBreakpointManagerListener;
@@ -38,10 +44,22 @@ import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IThread;
-import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
import org.eclipse.debug.examples.core.pda.breakpoints.PDALineBreakpoint;
import org.eclipse.debug.examples.core.pda.breakpoints.PDARunToLineBreakpoint;
+import org.eclipse.debug.examples.core.protocol.PDACommand;
+import org.eclipse.debug.examples.core.protocol.PDACommandResult;
+import org.eclipse.debug.examples.core.protocol.PDAEvent;
+import org.eclipse.debug.examples.core.protocol.PDAEventStopCommand;
+import org.eclipse.debug.examples.core.protocol.PDAExitedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAStartedEvent;
+import org.eclipse.debug.examples.core.protocol.PDATerminateCommand;
+import org.eclipse.debug.examples.core.protocol.PDAVMResumeCommand;
+import org.eclipse.debug.examples.core.protocol.PDAVMResumedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAVMStartedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAVMSuspendCommand;
+import org.eclipse.debug.examples.core.protocol.PDAVMSuspendedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAVMTerminatedEvent;
/**
@@ -62,17 +80,20 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
private Socket fEventSocket;
private BufferedReader fEventReader;
+ // suspended state
+ private boolean fVMSuspended = false;
+
// terminated state
private boolean fTerminated = false;
// threads
- private IThread[] fThreads;
- private PDAThread fThread;
+ private Map fThreads = Collections.synchronizedMap(new LinkedHashMap());
// event dispatch job
private EventDispatchJob fEventDispatch;
+
// event listeners
- private Vector fEventListeners = new Vector();
+ private List fEventListeners = Collections.synchronizedList(new ArrayList());
/**
* Listens to events from the PDA VM and fires corresponding
@@ -89,18 +110,28 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
protected IStatus run(IProgressMonitor monitor) {
- String event = "";
- while (!isTerminated() && event != null) {
+ String message = "";
+ while (!isTerminated() && message != null) {
try {
- event = fEventReader.readLine();
- if (event != null) {
+ message = fEventReader.readLine();
+ System.out.println(message);
+ if (message != null) {
+ PDAEvent event = null;
+ try {
+ event = PDAEvent.parseEvent(message);
+ }
+ catch (IllegalArgumentException e) {
+ DebugCorePlugin.getDefault().getLog().log(
+ new Status (IStatus.ERROR, "org.eclipse.debug.examples.core", "Error parsing PDA event", e));
+ continue;
+ }
Object[] listeners = fEventListeners.toArray();
for (int i = 0; i < listeners.length; i++) {
((IPDAEventListener)listeners[i]).handleEvent(event);
}
}
} catch (IOException e) {
- terminated();
+ vmTerminated();
}
}
return Status.OK_STATUS;
@@ -116,9 +147,11 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
* @param listener event listener
*/
public void addEventListener(IPDAEventListener listener) {
- if (!fEventListeners.contains(listener)) {
- fEventListeners.add(listener);
- }
+ synchronized(fEventListeners) {
+ if (!fEventListeners.contains(listener)) {
+ fEventListeners.add(listener);
+ }
+ }
}
/**
@@ -167,8 +200,6 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
} catch (IOException e) {
requestFailed("Unable to connect to PDA VM", e);
}
- fThread = new PDAThread(this);
- fThreads = new IThread[] {fThread};
fEventDispatch = new EventDispatchJob();
fEventDispatch.schedule();
IBreakpointManager breakpointManager = getBreakpointManager();
@@ -176,8 +207,8 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
breakpointManager.addBreakpointManagerListener(this);
// initialize error hanlding to suspend on 'unimplemented instructions'
// and 'no such label' errors
- sendRequest("eventstop unimpinstr 1");
- sendRequest("eventstop nosuchlabel 1");
+ sendCommand(new PDAEventStopCommand(PDAEventStopCommand.UNIMPINSTR, true));
+ sendCommand(new PDAEventStopCommand(PDAEventStopCommand.NOSUCHLABEL, true));
}
/* (non-Javadoc)
@@ -190,13 +221,15 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
* @see org.eclipse.debug.core.model.IDebugTarget#getThreads()
*/
public IThread[] getThreads() throws DebugException {
- return fThreads;
+ synchronized (fThreads) {
+ return (IThread[])fThreads.values().toArray(new IThread[fThreads.size()]);
+ }
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IDebugTarget#hasThreads()
*/
public boolean hasThreads() throws DebugException {
- return true;
+ return fThreads.size() > 0;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IDebugTarget#getName()
@@ -253,14 +286,18 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ITerminate#isTerminated()
*/
- public boolean isTerminated() {
+ public synchronized boolean isTerminated() {
return fTerminated || getProcess().isTerminated();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ITerminate#terminate()
*/
public void terminate() throws DebugException {
- getThread().terminate();
+//#ifdef ex2
+//# // TODO: Exercise 2 - send termination request to interpreter
+//#else
+ sendCommand(new PDATerminateCommand());
+//#endif
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#canResume()
@@ -277,22 +314,24 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
*/
- public boolean isSuspended() {
- return !isTerminated() && getThread().isSuspended();
+ public synchronized boolean isSuspended() {
+ return !isTerminated() && fVMSuspended;
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#resume()
*/
public void resume() throws DebugException {
- getThread().resume();
+ sendCommand(new PDAVMResumeCommand());
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#suspend()
*/
public void suspend() throws DebugException {
- getThread().suspend();
+ sendCommand(new PDAVMSuspendCommand());
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
*/
@@ -368,7 +407,7 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
* Notification we have connected to the VM and it has started.
* Resume the VM.
*/
- private void started() {
+ private void vmStarted(PDAVMStartedEvent event) {
fireCreationEvent();
installDeferredBreakpoints();
try {
@@ -391,10 +430,9 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
/**
* Called when this debug target terminates.
*/
- private synchronized void terminated() {
- fTerminated = true;
- fThread = null;
- fThreads = new IThread[0];
+ private void vmTerminated() {
+ setTerminated(true);
+ fThreads.clear();
IBreakpointManager breakpointManager = getBreakpointManager();
breakpointManager.removeBreakpointListener(this);
breakpointManager.removeBreakpointManagerListener(this);
@@ -402,29 +440,58 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
removeEventListener(this);
}
- /**
- * Returns the values on the data stack (top down)
- *
- * @return the values on the data stack (top down)
- */
- public IValue[] getDataStack() throws DebugException {
- String dataStack = sendRequest("data");
- if (dataStack != null && dataStack.length() > 0) {
- String[] values = dataStack.split("\\|");
- IValue[] theValues = new IValue[values.length];
- for (int i = 0; i < values.length; i++) {
- String value = values[values.length - i - 1];
- theValues[i] = new PDAStackValue(this, value, i);
- }
- return theValues;
- }
- return new IValue[0];
+ private void vmResumed(PDAVMResumedEvent event) {
+ setVMSuspended(false);
+ fireResumeEvent(calcDetail(event.fReason));
+ }
+
+ private void vmSuspended(PDAVMSuspendedEvent event) {
+ setVMSuspended(true);
+ int detail = DebugEvent.UNSPECIFIED;
+ fireSuspendEvent(calcDetail(event.fReason));
+ }
+
+ private int calcDetail(String reason) {
+ if (reason.equals("breakpoint") || reason.equals("watch")) {
+ return DebugEvent.BREAKPOINT;
+ } else if (reason.equals("step")) {
+ return DebugEvent.STEP_OVER;
+ } else if (reason.equals("drop")) {
+ return DebugEvent.STEP_RETURN;
+ } else if (reason.equals("client")) {
+ return DebugEvent.CLIENT_REQUEST;
+ } else if (reason.equals("event")) {
+ return DebugEvent.BREAKPOINT;
+ } else {
+ return DebugEvent.UNSPECIFIED;
+ }
+ }
+
+ private void started(PDAStartedEvent event) {
+ PDAThread newThread = new PDAThread(this, event.fThreadId);
+ fThreads.put(new Integer(event.fThreadId), newThread);
+ newThread.start();
+ }
+
+ private void exited(PDAExitedEvent event) {
+ PDAThread thread = (PDAThread)fThreads.remove(new Integer(event.fThreadId));
+ if (thread != null) {
+ thread.exit();
+ }
+ }
+
+ private synchronized void setVMSuspended(boolean suspended) {
+ fVMSuspended = suspended;
}
+ private synchronized void setTerminated(boolean terminated) {
+ fTerminated = terminated;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.debug.examples.core.pda.model.PDADebugElement#sendRequest(java.lang.String)
*/
- public String sendRequest(String request) throws DebugException {
+ private String sendRequest(String request) throws DebugException {
synchronized (fRequestSocket) {
fRequestWriter.println(request);
fRequestWriter.flush();
@@ -438,6 +505,11 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
return null;
}
+ public PDACommandResult sendCommand(PDACommand command) throws DebugException {
+ String response = sendRequest(command.getRequest());
+ return command.createResult(response);
+ }
+
/**
* When the breakpoint manager disables, remove all registered breakpoints
* requests from the VM. When it enables, reinstall them.
@@ -452,74 +524,45 @@ public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBr
}
}
}
-
- /**
- * Returns whether popping the data stack is currently permitted
- *
- * @return whether popping the data stack is currently permitted
- */
- public boolean canPop() {
- try {
- return !isTerminated() && isSuspended() && getDataStack().length > 0;
- } catch (DebugException e) {
- }
- return false;
- }
-
- /**
- * Pops and returns the top of the data stack
- *
- * @return the top value on the stack
- * @throws DebugException if the stack is empty or the request fails
- */
- public IValue pop() throws DebugException {
- IValue[] dataStack = getDataStack();
- if (dataStack.length > 0) {
- sendRequest("popdata");
- return dataStack[0];
- }
- requestFailed("Empty stack", null);
- return null;
- }
-
- /**
- * Returns whether pushing a value is currently supported.
- *
- * @return whether pushing a value is currently supported
- */
- public boolean canPush() {
- return !isTerminated() && isSuspended();
- }
-
- /**
- * Pushes a value onto the stack.
- *
- * @param value value to push
- * @throws DebugException on failure
- */
- public void push(String value) throws DebugException {
- sendRequest("pushdata " + value);
- }
/* (non-Javadoc)
* @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
*/
- public void handleEvent(String event) {
- if (event.equals("started")) {
- started();
- } else if (event.equals("terminated")) {
- terminated();
- }
+ public void handleEvent(PDAEvent event) {
+ if (event instanceof PDAStartedEvent) {
+ started((PDAStartedEvent)event);
+ } else if (event instanceof PDAExitedEvent) {
+ exited((PDAExitedEvent)event);
+ } else if (event instanceof PDAVMStartedEvent) {
+ vmStarted((PDAVMStartedEvent)event);
+ } else if (event instanceof PDAVMTerminatedEvent) {
+ vmTerminated();
+ } else if (event instanceof PDAVMSuspendedEvent) {
+ vmSuspended((PDAVMSuspendedEvent)event);
+ } else if (event instanceof PDAVMResumedEvent) {
+ vmResumed((PDAVMResumedEvent)event);
+ }
}
/**
* Returns this debug target's single thread, or <code>null</code>
* if terminated.
*
+ * @param threadId ID of the thread to return, or <code>0</code>
+ * to return the first available thread
* @return this debug target's single thread, or <code>null</code>
* if terminated
*/
- public synchronized PDAThread getThread() {
- return fThread;
+ public PDAThread getThread(int threadId) {
+ if (threadId > 0) {
+ return (PDAThread)fThreads.get(new Integer(threadId));
+ } else {
+ synchronized(fThreads) {
+ if (fThreads.size() > 0) {
+ return (PDAThread)fThreads.values().iterator().next();
+ }
+ }
+ }
+ return null;
}
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java
index a3cbe43c8..fbd1c7bb8 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
@@ -17,6 +18,7 @@ import org.eclipse.debug.core.model.IRegisterGroup;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.debug.examples.core.protocol.PDAFrameData;
/**
* PDA stack frame.
@@ -37,7 +39,7 @@ public class PDAStackFrame extends PDADebugElement implements IStackFrame {
* @param data frame data
* @param id stack frame id (0 is the bottom of the stack)
*/
- public PDAStackFrame(PDAThread thread, String data, int id) {
+ public PDAStackFrame(PDAThread thread, PDAFrameData data, int id) {
super(thread.getPDADebugTarget());
fId = id;
fThread = thread;
@@ -49,17 +51,13 @@ public class PDAStackFrame extends PDADebugElement implements IStackFrame {
*
* @param data
*/
- private void init(String data) {
- String[] strings = data.split("\\|");
- String fileName = strings[0];
- fFileName = (new Path(fileName)).lastSegment();
- String pc = strings[1];
- fPC = Integer.parseInt(pc) + 1;
- fName = strings[2];
- int numVars = strings.length - 3;
- IVariable[] vars = new IVariable[numVars];
- for (int i = 0; i < numVars; i++) {
- vars[i] = new PDAVariable(this, strings[i + 3]);
+ private void init(PDAFrameData data) {
+ fFileName = data.fFilePath.lastSegment();
+ fPC = data.fPC + 1;
+ fName = data.fFunction;
+ IVariable[] vars = new IVariable[data.fVariables.length];
+ for (int i = 0; i < data.fVariables.length; i++) {
+ vars[i] = new PDAVariable(this, data.fVariables[i]);
}
fThread.setVariables(this, vars);
}
@@ -247,5 +245,15 @@ public class PDAStackFrame extends PDADebugElement implements IStackFrame {
return fId;
}
+ /**
+ * Returns the stack frame's thread's unique identifier
+ *
+ * @return this stack frame's thread's unique identifier
+ *
+ * @since 3.5
+ */
+ protected int getThreadIdentifier() {
+ return fThread.getIdentifier();
+ }
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java
index 2f13211f4..a7909d485 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,15 +8,22 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+
/**
* A value on the data stack
*/
-public class PDAStackValue extends PDAValue {
-
- private int fIndex;
+public class PDAStackValue extends PDADebugElement implements IValue {
+
+ final private PDAThread fThread;
+ final private String fValue;
+ final private int fIndex;
/**
* Constructs a value that appears on the data stack
@@ -25,17 +32,55 @@ public class PDAStackValue extends PDAValue {
* @param value value on the stack
* @param index index on the stack
*/
- public PDAStackValue(PDADebugTarget target, String value, int index) {
- super(target, value);
+ public PDAStackValue(PDAThread thread, String value, int index) {
+ super(thread.getDebugTarget());
+ fThread = thread;
+ fValue = value;
fIndex = index;
}
+ public PDAThread getThread() {
+ return fThread;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#getValueString()
+ */
+ public String getValueString() throws DebugException {
+ return fValue;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#isAllocated()
+ */
+ public boolean isAllocated() throws DebugException {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#getVariables()
+ */
+ public IVariable[] getVariables() throws DebugException {
+ return new IVariable[0];
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#hasVariables()
+ */
+ public boolean hasVariables() throws DebugException {
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#getReferenceTypeName()
+ */
+ public String getReferenceTypeName() throws DebugException {
+ return null;
+ }
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
- return super.equals(obj) && ((PDAStackValue)obj).fIndex == fIndex;
+ return obj instanceof PDAStackValue &&
+ ((PDAStackValue)obj).fValue.equals(fValue) &&
+ ((PDAStackValue)obj).fIndex == fIndex;
}
/*
* (non-Javadoc)
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java
index 6a4102ac3..e9dfd9bea 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,9 +8,11 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -19,13 +21,37 @@ import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.debug.examples.core.protocol.PDADataCommand;
+import org.eclipse.debug.examples.core.protocol.PDADropFrameCommand;
+import org.eclipse.debug.examples.core.protocol.PDAEvent;
+import org.eclipse.debug.examples.core.protocol.PDAListResult;
+import org.eclipse.debug.examples.core.protocol.PDANoSuchLabelEvent;
+import org.eclipse.debug.examples.core.protocol.PDAPopDataCommand;
+import org.eclipse.debug.examples.core.protocol.PDAPushDataCommand;
+import org.eclipse.debug.examples.core.protocol.PDAResumeCommand;
+import org.eclipse.debug.examples.core.protocol.PDAResumedEvent;
+import org.eclipse.debug.examples.core.protocol.PDARunControlEvent;
+import org.eclipse.debug.examples.core.protocol.PDAStackCommand;
+import org.eclipse.debug.examples.core.protocol.PDAStackCommandResult;
+import org.eclipse.debug.examples.core.protocol.PDAStepCommand;
+import org.eclipse.debug.examples.core.protocol.PDASuspendCommand;
+import org.eclipse.debug.examples.core.protocol.PDASuspendedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAUnimplementedInstructionEvent;
+import org.eclipse.debug.examples.core.protocol.PDAVMResumedEvent;
+import org.eclipse.debug.examples.core.protocol.PDAVMSuspendedEvent;
/**
* A PDA thread. A PDA VM is single threaded.
*/
public class PDAThread extends PDADebugElement implements IThread, IPDAEventListener {
+ /**
+ * ID of this thread as reported by PDA.
+ */
+ private final int fThreadId;
+
/**
* Breakpoint this thread is suspended at or <code>null</code>
* if none.
@@ -38,7 +64,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
private boolean fStepping = false;
/**
- * Wether this thread is suspended
+ * Whether this thread is suspended
*/
private boolean fSuspended = false;
@@ -50,16 +76,36 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
/**
* Table mapping stack frames to current variables
*/
- private Map fVariables = new HashMap();
+ private Map fVariables = Collections.synchronizedMap(new HashMap());
/**
* Constructs a new thread for the given target
*
* @param target VM
*/
- public PDAThread(PDADebugTarget target) {
+ public PDAThread(PDADebugTarget target, int threadId) {
super(target);
- getPDADebugTarget().addEventListener(this);
+ fThreadId = threadId;
+ }
+
+ /**
+ * Called by the debug target after the thread is created.
+ *
+ * @since 3.5
+ */
+ void start() {
+ fireCreationEvent();
+ getPDADebugTarget().addEventListener(this);
+ }
+
+ /**
+ * Called by the debug target before the thread is removed.
+ *
+ * @since 3.5
+ */
+ void exit() {
+ getPDADebugTarget().removeEventListener(this);
+ fireTerminateEvent();
}
/* (non-Javadoc)
@@ -67,16 +113,12 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
*/
public IStackFrame[] getStackFrames() throws DebugException {
if (isSuspended()) {
- String framesData = sendRequest("stack");
- if (framesData != null) {
- String[] frames = framesData.split("#");
- IStackFrame[] theFrames = new IStackFrame[frames.length];
- for (int i = 0; i < frames.length; i++) {
- String data = frames[i];
- theFrames[frames.length - i - 1] = new PDAStackFrame(this, data, i);
- }
- return theFrames;
+ PDAStackCommandResult result = (PDAStackCommandResult)sendCommand(new PDAStackCommand(fThreadId));
+ IStackFrame[] frames = new IStackFrame[result.fFrames.length];
+ for (int i = 0; i < result.fFrames.length; i++) {
+ frames[frames.length - i - 1] = new PDAStackFrame(this, result.fFrames[i], i);
}
+ return frames;
}
return new IStackFrame[0];
}
@@ -109,10 +151,11 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
public String getName() {
return "Main thread";
}
+
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IThread#getBreakpoints()
*/
- public IBreakpoint[] getBreakpoints() {
+ public synchronized IBreakpoint[] getBreakpoints() {
if (fBreakpoint == null) {
return new IBreakpoint[0];
}
@@ -124,7 +167,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
*
* @param breakpoint breakpoint
*/
- public void suspendedBy(IBreakpoint breakpoint) {
+ public synchronized void suspendedBy(IBreakpoint breakpoint) {
fBreakpoint = breakpoint;
suspended(DebugEvent.BREAKPOINT);
}
@@ -133,7 +176,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
* @see org.eclipse.debug.core.model.ISuspendResume#canResume()
*/
public boolean canResume() {
- return isSuspended();
+ return isSuspended() && !getDebugTarget().isSuspended();
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
@@ -145,7 +188,15 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
* @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
*/
public boolean isSuspended() {
- return fSuspended && !isTerminated();
+ if (getDebugTarget().isTerminated()) {
+ return false;
+ }
+ if (getDebugTarget().isSuspended()) {
+ return true;
+ }
+ synchronized (this) {
+ return fSuspended;
+ }
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.ISuspendResume#resume()
@@ -154,7 +205,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
//#ifdef ex2
//# // TODO: Exercise 2 - send resume request to interpreter
//#else
- sendRequest("resume");
+ sendCommand(new PDAResumeCommand(fThreadId));
//#endif
}
/* (non-Javadoc)
@@ -164,7 +215,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
//#ifdef ex2
//# // TODO: Exercise 2 - send suspend request to interpreter
//#else
- sendRequest("suspend");
+ sendCommand(new PDASuspendCommand(fThreadId));
//#endif
}
/* (non-Javadoc)
@@ -200,7 +251,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
* @see org.eclipse.debug.core.model.IStep#stepOver()
*/
public void stepOver() throws DebugException {
- sendRequest("step");
+ sendCommand(new PDAStepCommand(fThreadId));
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IStep#stepReturn()
@@ -223,11 +274,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
* @see org.eclipse.debug.core.model.ITerminate#terminate()
*/
public void terminate() throws DebugException {
- //#ifdef ex2
-//# // TODO: Exercise 2 - send termination request to interpreter
- //#else
- sendRequest("exit");
- //#endif
+ getDebugTarget().terminate();
}
/**
@@ -235,7 +282,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
*
* @param stepping whether stepping
*/
- private void setStepping(boolean stepping) {
+ private synchronized void setStepping(boolean stepping) {
fStepping = stepping;
}
@@ -244,7 +291,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
*
* @param suspended whether suspended
*/
- private void setSuspended(boolean suspended) {
+ private synchronized void setSuspended(boolean suspended) {
fSuspended = suspended;
}
@@ -254,15 +301,15 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
*
* @param event one of 'unimpinstr' or 'nosuchlabel' or <code>null</code>
*/
- private void setError(String event) {
+ private synchronized void setError(String event) {
fErrorEvent = event;
}
/**
- * Returns the most revent error event encountered since the last
+ * Returns the most recent error event encountered since the last
* suspend, or <code>null</code> if none.
*
- * @return the most revent error event encountered since the last
+ * @return the most recent error event encountered since the last
* suspend, or <code>null</code> if none
*/
public Object getError() {
@@ -272,63 +319,65 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
/* (non-Javadoc)
* @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
*/
- public void handleEvent(String event) {
- // clear previous state
- fBreakpoint = null;
- setStepping(false);
-
- // handle events
- if (event.startsWith("resumed")) {
- setSuspended(false);
- if (event.endsWith("step")) {
- setStepping(true);
- resumed(DebugEvent.STEP_OVER);
- //#ifdef ex2
-//# }
-//# // TODO: Exercise 2 - handle/fire "client" resume event
- //#else
- } else if (event.endsWith("client")) {
- resumed(DebugEvent.CLIENT_REQUEST);
- }
- //#endif
- //#ifdef ex5
-//# // TODO: Exercise 5 - handle start of drop event
- //#else
- else if (event.endsWith("drop")) {
- resumed(DebugEvent.STEP_RETURN);
- }
- //#endif
- } else if (event.startsWith("suspended")) {
- setSuspended(true);
- //#ifdef ex2
-//# // TODO: Exercise 2 - handle/fire "client" suspend event
-//# if (event.endsWith("step")) {
-//# suspended(DebugEvent.STEP_END);
-//# } else if (event.startsWith("suspended event") && getError() != null) {
-//# exceptionHit();
-//# }
- //#else
- if (event.endsWith("client")) {
- suspended(DebugEvent.CLIENT_REQUEST);
- } else if (event.endsWith("step")) {
- suspended(DebugEvent.STEP_END);
- } else if (event.startsWith("suspended event") && getError() != null) {
- exceptionHit();
- }
- //#endif
- //#ifdef ex5
-//# // TODO: Exercise 5 - handle end of drop event
- //#else
- else if (event.endsWith("drop")) {
- suspended(DebugEvent.STEP_END);
- }
- //#endif
- } else if (event.equals("started")) {
- fireCreationEvent();
- } else {
- setError(event);
- }
-
+ public void handleEvent(PDAEvent _event) {
+ if (_event instanceof PDARunControlEvent && fThreadId == ((PDARunControlEvent)_event).fThreadId) {
+ PDARunControlEvent event = (PDARunControlEvent)_event;
+ // clear previous state
+ fBreakpoint = null;
+ setStepping(false);
+
+ // handle events
+ if (event instanceof PDAResumedEvent || event instanceof PDAVMResumedEvent) {
+ setSuspended(false);
+ if ("step".equals(event.fReason)) {
+ setStepping(true);
+ resumed(DebugEvent.STEP_OVER);
+ //#ifdef ex2
+ //# }
+ //# // TODO: Exercise 2 - handle/fire "client" resume event
+ //#else
+ } else if ("client".equals(event.fReason)) {
+ resumed(DebugEvent.CLIENT_REQUEST);
+ }
+ //#endif
+ //#ifdef ex5
+ //# // TODO: Exercise 5 - handle start of drop event
+ //#else
+ else if ("drop".equals(event.fReason)) {
+ resumed(DebugEvent.STEP_RETURN);
+ }
+ //#endif
+ } else if (event instanceof PDASuspendedEvent || event instanceof PDAVMSuspendedEvent) {
+ setSuspended(true);
+ //#ifdef ex2
+ //# // TODO: Exercise 2 - handle/fire "client" suspend event
+ //# if (event.endsWith("step")) {
+ //# suspended(DebugEvent.STEP_END);
+ //# } else if (event.startsWith("suspended event") && getError() != null) {
+ //# exceptionHit();
+ //# }
+ //#else
+ if ("client".equals(event.fReason)) {
+ suspended(DebugEvent.CLIENT_REQUEST);
+ } else if ("step".equals(event.fReason)) {
+ suspended(DebugEvent.STEP_END);
+ } else if ("event".equals(event.fReason) && getError() != null) {
+ exceptionHit();
+ }
+ //#endif
+ //#ifdef ex5
+ //# // TODO: Exercise 5 - handle end of drop event
+ //#else
+ else if ("drop".equals(event.fReason)) {
+ suspended(DebugEvent.STEP_END);
+ }
+ //#endif
+ } else if (_event instanceof PDANoSuchLabelEvent ||
+ _event instanceof PDAUnimplementedInstructionEvent)
+ {
+ setError(event.fMessage);
+ }
+ }
}
/**
@@ -341,9 +390,7 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
*/
private void resumed(int detail) {
setError(null);
- synchronized (fVariables) {
- fVariables.clear();
- }
+ fVariables.clear();
fireResumeEvent(detail);
}
@@ -398,12 +445,14 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
* Pops the top frame off the callstack.
*
* @throws DebugException
+ *
+ * @since 3.5
*/
- public void pop() throws DebugException {
+ public void popFrame() throws DebugException {
//#ifdef ex5
//# // TODO: Exercise 5 - send drop request
//#else
- sendRequest("drop");
+ sendCommand(new PDADropFrameCommand(fThreadId));
//#endif
}
@@ -411,8 +460,10 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
* Returns whether this thread can pop the top stack frame.
*
* @return whether this thread can pop the top stack frame
+ *
+ * @since 3.5
*/
- public boolean canPop() {
+ public boolean canPopFrame() {
//#ifdef ex5
//# // TODO: Exercise 5 - allow pop if there is more than 1 frame on the stack
//#else
@@ -423,4 +474,90 @@ public class PDAThread extends PDADebugElement implements IThread, IPDAEventList
//#endif
return false;
}
+
+ /**
+ * Returns the values on the data stack (top down)
+ *
+ * @return the values on the data stack (top down)
+ *
+ * @since 3.5
+ */
+ public IValue[] getDataStack() throws DebugException {
+ PDAListResult result = (PDAListResult)sendCommand(new PDADataCommand(fThreadId));
+ if (result.fValues.length > 0) {
+ IValue[] values = new IValue[result.fValues.length];
+ for (int i = 0; i < result.fValues.length; i++) {
+ values[values.length - i - 1] = new PDAStackValue(this, result.fValues[i], i);
+ }
+ return values;
+ }
+ return new IValue[0];
+ }
+
+ /**
+ * Returns whether popping the data stack is currently permitted
+ *
+ * @return whether popping the data stack is currently permitted
+ *
+ * @since 3.5
+ */
+ public boolean canPopData() {
+ try {
+ return !isTerminated() && isSuspended() && getDataStack().length > 0;
+ } catch (DebugException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Pops and returns the top of the data stack
+ *
+ * @return the top value on the stack
+ * @throws DebugException if the stack is empty or the request fails
+ *
+ * @since 3.5
+ */
+ public IValue popData() throws DebugException {
+ IValue[] dataStack = getDataStack();
+ if (dataStack.length > 0) {
+ sendCommand(new PDAPopDataCommand(fThreadId));
+ return dataStack[0];
+ }
+ requestFailed("Empty stack", null);
+ return null;
+ }
+
+ /**
+ * Returns whether pushing a value is currently supported.
+ *
+ * @return whether pushing a value is currently supported
+ *
+ * @since 3.5
+ */
+ public boolean canPushData() {
+ return !isTerminated() && isSuspended();
+ }
+
+ /**
+ * Pushes a value onto the stack.
+ *
+ * @param value value to push
+ * @throws DebugException on failure
+ *
+ * @since 3.5
+ */
+ public void pushData(String value) throws DebugException {
+ sendCommand(new PDAPushDataCommand(fThreadId, value));
+ }
+
+ /**
+ * Returns this thread's unique identifier
+ *
+ * @return this thread's unique identifier
+ *
+ * @since 3.5
+ */
+ public int getIdentifier() {
+ return fThreadId;
+ }
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java
index e871004af..e3f371588 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,22 +8,27 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.debug.examples.core.protocol.PDAChildrenCommand;
+import org.eclipse.debug.examples.core.protocol.PDAListResult;
/**
* Value of a PDA variable.
*/
public class PDAValue extends PDADebugElement implements IValue {
- private String fValue;
+ final private PDAVariable fVariable;
+ final private String fValue;
- public PDAValue(PDADebugTarget target, String value) {
- super(target);
+ public PDAValue(PDAVariable variable, String value) {
+ super(variable.getStackFrame().getPDADebugTarget());
+ fVariable = variable;
fValue = value;
}
@@ -54,12 +59,26 @@ public class PDAValue extends PDADebugElement implements IValue {
* @see org.eclipse.debug.core.model.IValue#getVariables()
*/
public IVariable[] getVariables() throws DebugException {
- return new IVariable[0];
+ PDAStackFrame frame = fVariable.getStackFrame();
+ PDAListResult result = (PDAListResult) sendCommand(
+ new PDAChildrenCommand(frame.getThreadIdentifier(), frame.getIdentifier(), fVariable.getName()) );
+
+ IVariable[] children = new IVariable[result.fValues.length];
+ for(int i = 0; i < result.fValues.length; i++) {
+ children[i] = new PDAVariable(frame, result.fValues[i]);
+ }
+ return children;
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.model.IValue#hasVariables()
*/
public boolean hasVariables() throws DebugException {
+ if (getVariables().length != 0) {
+ return true;
+ }
+ // Value with multiple words can be show as an array using logical
+ // structures. If the value has multiple words, it needs to indicate
+ // that it has children even if logical structures are not turned on.
return fValue.split("\\W+").length > 1;
}
/*
@@ -76,4 +95,15 @@ public class PDAValue extends PDADebugElement implements IValue {
public int hashCode() {
return fValue.hashCode();
}
+
+ /**
+ * Returns the variable that this value was created for.
+ *
+ * @return The variable that this value was created for.
+ *
+ * @since 3.5
+ */
+ public PDAVariable getVariable() {
+ return fVariable;
+ }
}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java
index b0ddd6433..135a173c7 100644
--- a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
* Wind River Systems - added support for IToggleBreakpointsTargetFactory
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;
@@ -16,6 +17,9 @@ import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.debug.examples.core.protocol.PDACommandResult;
+import org.eclipse.debug.examples.core.protocol.PDASetVarCommand;
+import org.eclipse.debug.examples.core.protocol.PDAVarCommand;
/**
* A variable in a PDA stack frame
@@ -43,8 +47,9 @@ public class PDAVariable extends PDADebugElement implements IVariable {
* @see org.eclipse.debug.core.model.IVariable#getValue()
*/
public IValue getValue() throws DebugException {
- String value = sendRequest("var " + getStackFrame().getIdentifier() + " " + getName());
- return new PDAValue(this.getPDADebugTarget(), value);
+ PDACommandResult result = sendCommand(new PDAVarCommand(
+ fFrame.getThreadIdentifier(), getStackFrame().getIdentifier(), getName()));
+ return new PDAValue(this, result.fResponseText);
}
/* (non-Javadoc)
@@ -69,7 +74,8 @@ public class PDAVariable extends PDADebugElement implements IVariable {
* @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String)
*/
public void setValue(String expression) throws DebugException {
- sendRequest("setvar " + getStackFrame().getIdentifier() + " " + getName() + " " + expression);
+ sendCommand(new PDASetVarCommand(
+ fFrame.getThreadIdentifier(), getStackFrame().getIdentifier(), getName(), expression));
fireChangeEvent(DebugEvent.CONTENT);
}
/* (non-Javadoc)
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDABitFieldData.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDABitFieldData.java
new file mode 100644
index 000000000..116b3db72
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDABitFieldData.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * Object representing a bit field in the stack command results.
+ *
+ * @see PDARegistersCommand
+ */
+public class PDABitFieldData {
+
+ final public String fName;
+ final public int fOffset;
+ final public int fCount;
+ final public Map fMnemonics;
+
+ PDABitFieldData(String bitFieldString) {
+ StringTokenizer st = new StringTokenizer(bitFieldString, " ");
+
+ fName = st.nextToken();
+ fOffset = Integer.parseInt(st.nextToken());
+ fCount = Integer.parseInt(st.nextToken());
+
+ fMnemonics = new LinkedHashMap(0);
+ while (st.hasMoreTokens()) {
+ fMnemonics.put(st.nextToken(), st.nextToken());
+ }
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAChildrenCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAChildrenCommand.java
new file mode 100644
index 000000000..e9392fafb
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAChildrenCommand.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Retrieves data stack information
+ *
+ * <pre>
+ * C: children {thread_id} {frame_id} {variable_name}
+ * R: {child variable 1}|{child variable 2}|{child variable 3}|...|
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+public class PDAChildrenCommand extends PDACommand {
+
+ public PDAChildrenCommand(int threadId, int frameId, String name ) {
+ super("children " + threadId + " " + frameId + " " + name);
+ }
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDAListResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAClearBreakpointCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAClearBreakpointCommand.java
new file mode 100644
index 000000000..9522b007d
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAClearBreakpointCommand.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Clears any breakpoint set on given line
+ *
+ * <pre>
+ * C: clear {line}
+ * R: ok
+ * </pre>
+ */
+public class PDAClearBreakpointCommand extends PDACommand {
+
+ public PDAClearBreakpointCommand(int line) {
+ super("clear " + (line - 1));
+ }
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommand.java
new file mode 100644
index 000000000..f3ab89d7a
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommand.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Base class for PDA commands. Sub-classes should format the request string
+ * and implement the method to create the proper result object.
+ */
+abstract public class PDACommand {
+
+ final private String fRequest;
+
+ public PDACommand(String request) {
+ fRequest = request;
+ }
+
+ /**
+ * Returns the request to be sent to PDA.
+ */
+ public String getRequest() {
+ return fRequest;
+ }
+
+ /**
+ * Returns the command result based on the given PDA response. This command
+ * uses the class type parameter as the return type to allow the compiler to
+ * enforce the correct command result. This class must be implemented by
+ * each command to create the concrete result type.
+ */
+ abstract public PDACommandResult createResult(String resultText);
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommandResult.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommandResult.java
new file mode 100644
index 000000000..737678c44
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDACommandResult.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+
+/**
+ * Basic command result object. This command result simply allows access to the
+ * PDA response. Sub-classes may override to optionally parse the response text
+ * and return higher-level objects.
+ */
+public class PDACommandResult {
+
+ final public String fResponseText;
+
+ public PDACommandResult(String response) {
+ fResponseText = response;
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADataCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADataCommand.java
new file mode 100644
index 000000000..f3bddaad2
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADataCommand.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Return the contents of the data stack; reply is the data from oldest to newest
+ * as a single string
+ *
+ * <pre>
+ * C: data {thread_id}
+ * R: {value 1}|{value 2}|{value 3}|...|
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+public class PDADataCommand extends PDACommand {
+
+ public PDADataCommand(int threadId) {
+ super("data " + threadId);
+ }
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDAListResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADropFrameCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADropFrameCommand.java
new file mode 100644
index 000000000..3955afcd0
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDADropFrameCommand.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Pops the top stack frame off the call stack setting the instruction pointer to
+ * the calling statement in the calling frame
+ *
+ * <pre>
+ * If VM running:
+ * C: drop {thread_id}
+ * R: ok
+ * E: resumed {thread_id} drop
+ * E: suspended {thread_id} drop
+ *
+ * If VM suspended:
+ * C: drop {thread_id}
+ * R: ok
+ * E: vmresumed drop
+ * E: vmsuspended {thread_id} drop
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+public class PDADropFrameCommand extends PDACommand {
+
+ public PDADropFrameCommand(int threadId) {
+ super("drop " + threadId);
+ }
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalCommand.java
new file mode 100644
index 000000000..3a8aa7cbf
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalCommand.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Causes the interperter to execute the given set of instructions. At the end
+ * of the evaluation the top value is poped off the stack and returned in the
+ * evaluation result.
+ *
+ * <pre>
+ * C: eval {thread_id} {instruction}%20{parameter}|{instruction}%20{parameter}|...
+ * R: ok
+ * E: resumed {thread_id} client
+ * E: evalresult result
+ * E: suspended {thread_id} eval
+ *
+ * Errors:
+ * error: invalid thread
+ * error: cannot evaluate while vm is suspended
+ * error: thread running
+ * </pre>
+ *
+ * Where event_name could be <code>unimpinstr</code> or <code>nosuchlabel</code>.
+ */
+public class PDAEvalCommand extends PDACommand {
+
+ public PDAEvalCommand(int threadId, String operation) {
+ super("eval " + threadId + " " + operation);
+ }
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalResultEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalResultEvent.java
new file mode 100644
index 000000000..397eeca7b
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvalResultEvent.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Eval result event generated when an evaluation has completed.
+ *
+ * <pre>
+ * E: evalresult {result}
+ * </pre>
+ */
+public class PDAEvalResultEvent extends PDAEvent {
+
+ public final String fResult;
+
+ public PDAEvalResultEvent(String message) {
+ super(message);
+ fResult = message.substring(getName(message).length() + 1);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("evalresult");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvent.java
new file mode 100644
index 000000000..fdc217844
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEvent.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Base class for PDA events.
+ */
+public class PDAEvent {
+ public final String fMessage;
+ public final String fName;
+
+ public PDAEvent(String message) {
+ fMessage = message;
+ fName = getName(message);
+ }
+
+ protected String getName(String message) {
+ int nameEnd = message.indexOf(' ');
+ nameEnd = nameEnd == -1 ? message.length() : nameEnd;
+ return message.substring(0, nameEnd);
+ }
+
+ public static PDAEvent parseEvent(String message) {
+ if (PDAEvalResultEvent.isEventMessage(message)) {
+ return new PDAEvalResultEvent(message);
+ }
+ else if (PDAExitedEvent.isEventMessage(message)) {
+ return new PDAExitedEvent(message);
+ }
+ else if (PDANoSuchLabelEvent.isEventMessage(message)) {
+ return new PDANoSuchLabelEvent(message);
+ }
+ else if (PDARegistersEvent.isEventMessage(message)) {
+ return new PDARegistersEvent(message);
+ }
+ else if (PDAResumedEvent.isEventMessage(message)) {
+ return new PDAResumedEvent(message);
+ }
+ else if (PDAStartedEvent.isEventMessage(message)) {
+ return new PDAStartedEvent(message);
+ }
+ else if (PDASuspendedEvent.isEventMessage(message)) {
+ return new PDASuspendedEvent(message);
+ }
+ else if (PDATerminatedEvent.isEventMessage(message)) {
+ return new PDATerminatedEvent(message);
+ }
+ else if (PDAUnimplementedInstructionEvent.isEventMessage(message)) {
+ return new PDAUnimplementedInstructionEvent(message);
+ }
+ else if (PDAVMResumedEvent.isEventMessage(message)) {
+ return new PDAVMResumedEvent(message);
+ }
+ else if (PDAVMStartedEvent.isEventMessage(message)) {
+ return new PDAVMStartedEvent(message);
+ }
+ else if (PDAVMSuspendedEvent.isEventMessage(message)) {
+ return new PDAVMSuspendedEvent(message);
+ }
+ else if (PDAExitedEvent.isEventMessage(message)) {
+ return new PDAExitedEvent(message);
+ }
+ else {
+ return new PDAEvent(message);
+ }
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEventStopCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEventStopCommand.java
new file mode 100644
index 000000000..f02519cf9
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAEventStopCommand.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Optionally stop the interpreter when an error event <code>event_name</code>
+ * is encountered; <code>{0|1}</code> specifies stop (<code>1</code>) or
+ * continue (<code>0</code>). The possible events are <code>unimpinstr</code> and
+ * <code>nosuchlabel</code>. Reply is <code>ok</code>. When an event is encountered,
+ * the interpreter sends the error event (for example <code>unimlpemented instruction
+ * foo</code>) and corresponding suspend event (for example <code>suspended event
+ * unimpinstr</code>).
+ *
+ * <pre>
+ * C: eventstop {event_name} {0|1}
+ * R: ok
+ * ...
+ * E: suspended event {event_name}
+ * </pre>
+ *
+ * Where event_name could be <code>unimpinstr</code> or <code>nosuchlabel</code>.
+ */
+
+public class PDAEventStopCommand extends PDACommand {
+
+ public static final int UNIMPINSTR = 0;
+ public static final int NOSUCHLABEL = 1;
+
+ public PDAEventStopCommand(int event, boolean enable) {
+ super("eventstop " +
+ (event == UNIMPINSTR ? "unimpinstr " : "nosuchlabel ") +
+ (enable ? "1" : "0"));
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAExitedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAExitedEvent.java
new file mode 100644
index 000000000..98ccaa331
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAExitedEvent.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Exited event generated when a thread has exited.
+ *
+ * <pre>
+ * E: started {thread_id}
+ * </pre>
+ */
+public class PDAExitedEvent extends PDARunControlEvent {
+
+ public PDAExitedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("exited");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommand.java
new file mode 100644
index 000000000..81b0463ee
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommand.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Retrieves command stack frame information for frame <code>frame_number</code>
+ * (stack frames are indexed from 0, 0 being the oldest).
+ *
+ * <pre>
+ * C: stack {thread_id} {frame_number}
+ * R: {file}|{line}|{function}|{var_1}|{var_2}|...
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+public class PDAFrameCommand extends PDACommand {
+
+ public PDAFrameCommand(int threadId, int frameNum) {
+ super("frame " + threadId + " " + frameNum);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDAFrameCommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommandResult.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommandResult.java
new file mode 100644
index 000000000..953acf704
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameCommandResult.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+
+/**
+ * @see PDAFrameCommand
+ */
+
+public class PDAFrameCommandResult extends PDACommandResult {
+
+ /**
+ * Frame data return by the frame command.
+ */
+ final public PDAFrameData fFrame;
+
+ PDAFrameCommandResult(String response) {
+ super(response);
+ fFrame = new PDAFrameData(response);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameData.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameData.java
new file mode 100644
index 000000000..45de9ad46
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAFrameData.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Object representing a frame in the stack command results.
+ *
+ * @see PDAStackCommand
+ */
+
+public class PDAFrameData {
+
+ final public IPath fFilePath;
+ final public int fPC;
+ final public String fFunction;
+ final public String[] fVariables;
+
+ PDAFrameData(String frameString) {
+ StringTokenizer st = new StringTokenizer(frameString, "|");
+
+ fFilePath = new Path(st.nextToken());
+ fPC = Integer.parseInt(st.nextToken());
+ fFunction = st.nextToken();
+
+ List variablesList = new ArrayList();
+ while (st.hasMoreTokens()) {
+ variablesList.add(st.nextToken());
+ }
+ fVariables = (String[])variablesList.toArray(new String[variablesList.size()]);
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAGroupsCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAGroupsCommand.java
new file mode 100644
index 000000000..9dcffbdc8
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAGroupsCommand.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Retrieves register groups information
+ *
+ * <pre>
+ * C: groups
+ * R: {group 1}|{group 2}|{group 3}|...|
+ * </pre>
+ */
+
+public class PDAGroupsCommand extends PDACommand {
+
+ public PDAGroupsCommand() {
+ super("groups");
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDAListResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAListResult.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAListResult.java
new file mode 100644
index 000000000..3ba409dd6
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAListResult.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+
+/**
+ * @see PDADataCommand
+ */
+
+public class PDAListResult extends PDACommandResult {
+
+ final public String[] fValues;
+
+ PDAListResult(String response) {
+ super(response);
+ StringTokenizer st = new StringTokenizer(response, "|");
+ List valuesList = new ArrayList();
+
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if (token.length() != 0) {
+ valuesList.add(token);
+ }
+ }
+
+ fValues = new String[valuesList.size()];
+ for (int i = 0; i < valuesList.size(); i++) {
+ fValues[i] = (String)valuesList.get(i);
+ }
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDANoSuchLabelEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDANoSuchLabelEvent.java
new file mode 100644
index 000000000..11d6a1b05
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDANoSuchLabelEvent.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * No Such Label event generated when the PDA program encounters an call to a
+ * non-existant label in a PDA program.
+ *
+ * <pre>
+ * E: no such label {label}
+ * </pre>
+ */
+public class PDANoSuchLabelEvent extends PDAEvent {
+
+ public final String fLabel;
+
+ public PDANoSuchLabelEvent(String message) {
+ super(message);
+ fLabel = message.substring(getName(message).length() + 1);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("no such label");
+ }
+
+ protected String getName(String message) {
+ if (isEventMessage(message)) {
+ return "no such label";
+ }
+ throw new IllegalArgumentException("Invalid event: " + message);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPopDataCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPopDataCommand.java
new file mode 100644
index 000000000..bfc7cfe9e
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPopDataCommand.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Pops the top value from the data stack
+ *
+ * <pre>
+ * C: popdata {thread_id}
+ * R: ok
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+public class PDAPopDataCommand extends PDACommand {
+
+ public PDAPopDataCommand(int threadId) {
+ super("popdata " + threadId);
+ }
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPushDataCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPushDataCommand.java
new file mode 100644
index 000000000..6969d3e02
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAPushDataCommand.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Pushes the given value on top of the data stack.
+ *
+ * <pre>
+ * C: pushdata {thread_id} {value}
+ * R: ok
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+
+public class PDAPushDataCommand extends PDACommand {
+
+ public PDAPushDataCommand(int threadId, String value) {
+ super("pushdata " + threadId + " " + value);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegisterData.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegisterData.java
new file mode 100644
index 000000000..5adfadd3f
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegisterData.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Object representing a register in the registers command results.
+ *
+ * @see PDARCommand
+ */
+
+public class PDARegisterData {
+
+ final public String fName;
+ final public boolean fWritable;
+ final public PDABitFieldData[] fBitFields;
+
+ PDARegisterData(String regString) {
+ StringTokenizer st = new StringTokenizer(regString, "|");
+
+ String regInfo = st.nextToken();
+ StringTokenizer regSt = new StringTokenizer(regInfo, " ");
+ fName = regSt.nextToken();
+ fWritable = Boolean.getBoolean(regSt.nextToken());
+
+ List bitFieldsList = new ArrayList();
+ while (st.hasMoreTokens()) {
+ bitFieldsList.add(new PDABitFieldData(st.nextToken()));
+ }
+ fBitFields = (PDABitFieldData[])bitFieldsList.toArray(new PDABitFieldData[bitFieldsList.size()]);
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommand.java
new file mode 100644
index 000000000..4bdfcaa5f
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommand.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Retrieves registers definition information
+ *
+ * <pre>
+ * C: registers {group name}
+ * R: {register name} {true|false}|{bit field name} {start bit} {bit count} {mnemonic 1} {mnemonic 2} ...#{register name} ...
+ * </pre>
+ */
+
+public class PDARegistersCommand extends PDACommand {
+
+ public PDARegistersCommand(String group) {
+ super("registers " + group);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDARegistersCommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommandResult.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommandResult.java
new file mode 100644
index 000000000..76c935341
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersCommandResult.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+
+/**
+ * @see PDARegistersCommand
+ */
+
+public class PDARegistersCommandResult extends PDACommandResult {
+
+ /**
+ * Array of registers returned by the registers commands.
+ */
+ final public PDARegisterData[] fRegisters;
+
+ PDARegistersCommandResult(String response) {
+ super(response);
+ StringTokenizer st = new StringTokenizer(response, "#");
+ List regList = new ArrayList();
+
+ while (st.hasMoreTokens()) {
+ regList.add(new PDARegisterData(st.nextToken()));
+ }
+ fRegisters = (PDARegisterData[])regList.toArray(new PDARegisterData[regList.size()]);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersEvent.java
new file mode 100644
index 000000000..8a79ade44
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARegistersEvent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Registers event generated when the registers' definitions are changed in a
+ * program.
+ *
+ * <pre>
+ * E: registers
+ * </pre>
+ */
+public class PDARegistersEvent extends PDAEvent {
+
+ public PDARegistersEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("registers");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumeCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumeCommand.java
new file mode 100644
index 000000000..a7b084159
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumeCommand.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Resumes the execution of a single thread. Can be issued only if the virtual
+ * machine is running.
+ *
+ * <pre>
+ * C: resume {thread_id}
+ * R: ok
+ * E: resumed {thread_id} client
+ *
+ * Errors:
+ * error: invalid thread
+ * error: cannot resume thread when vm is suspended
+ * error: thread already running
+ * </pre>
+ */
+
+public class PDAResumeCommand extends PDACommand {
+
+ public PDAResumeCommand(int threadId) {
+ super("resume " + threadId);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumedEvent.java
new file mode 100644
index 000000000..81bd4f9d7
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAResumedEvent.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Resumed event generated when a thread is resumed.
+ *
+ * <pre>
+ * E: resumed {thread_id} [reason]
+ * </pre>
+ */
+public class PDAResumedEvent extends PDARunControlEvent {
+
+ public PDAResumedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("resumed");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARunControlEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARunControlEvent.java
new file mode 100644
index 000000000..3590f04e5
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDARunControlEvent.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Base class for run-control events.
+ */
+public class PDARunControlEvent extends PDAEvent {
+
+ public final int fThreadId;
+ public final String fReason;
+
+ public PDARunControlEvent(String message) {
+ super(message);
+ fThreadId = getThreadId(message);
+ fReason = getStateChangeReason(message);
+ }
+
+ protected int getThreadId(String message) {
+ int nameEnd = getName(message).length();
+ if ( Character.isDigit(message.charAt(nameEnd + 1)) ) {
+ int threadIdEnd = message.indexOf(' ', nameEnd + 1);
+ threadIdEnd = threadIdEnd == -1 ? message.length() : threadIdEnd;
+ try {
+ return Integer.parseInt(message.substring(nameEnd + 1, threadIdEnd));
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid event: " + message);
+ }
+ } else {
+ return -1;
+ }
+ }
+
+ protected String getStateChangeReason(String message) {
+ int idx = getName(message).length();
+ if ( Character.isDigit(message.charAt(idx + 1)) ) {
+ idx = message.indexOf(' ', idx + 1);
+ idx = idx == -1 ? message.length() : idx + 1;
+ } else {
+ idx++;
+ }
+ if (idx >= message.length()) {
+ return "";
+ }
+
+ int endIdx = message.indexOf(' ', idx);
+ endIdx = endIdx == -1 ? message.length() : endIdx;
+ return message.substring(idx, endIdx);
+ }
+
+ protected String getName(String message) {
+ int nameEnd = message.indexOf(' ');
+ nameEnd = nameEnd == -1 ? message.length() : nameEnd;
+ return message.substring(0, nameEnd);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("started");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetBreakpointCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetBreakpointCommand.java
new file mode 100644
index 000000000..098507fc0
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetBreakpointCommand.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Sets a breakpoint at given line
+ *
+ * <pre>
+ * Suspend a single thread:
+ * C: set {line_number} 0
+ * R: ok
+ * C: resume {thread_id}
+ * E: resumed {thread_id} client
+ * E: suspended {thread_id} breakpoint line_number
+ *
+ * Suspend the VM:
+ * C: set {line_number} 1
+ * R: ok
+ * C: vmresume
+ * E: vmresumed client
+ * E: vmsuspended {thread_id} breakpoint line_number
+ * </pre>
+ */
+
+public class PDASetBreakpointCommand extends PDACommand {
+
+ public PDASetBreakpointCommand(int line, boolean stopVM) {
+ super("set " +
+ line + " " +
+ (stopVM ? "1" : "0"));
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetDataCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetDataCommand.java
new file mode 100644
index 000000000..12d8d177e
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetDataCommand.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Sets a data value in the data stack at the given location (the data stack is
+ * indexed from 0, 0 being the oldest).
+ *
+ * <pre>
+ * C: setdata {thread_id} {index} {value}
+ * R: ok
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+public class PDASetDataCommand extends PDACommand {
+
+ public PDASetDataCommand(int threadId, int index, String value) {
+ super("setdata " + threadId + " " + index + " " + value);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetVarCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetVarCommand.java
new file mode 100644
index 000000000..4cde68f2c
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASetVarCommand.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Set the contents of variable <code>variable</code> from the control stack
+ * <code>frame_number</code> to value <code>value</code> (the control stack is
+ * indexed from 0, 0 being the oldest).
+ *
+ * <pre>
+ * C: setvar {thread_id} {frame_number} {variable} {value}
+ * R: ok
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+
+public class PDASetVarCommand extends PDACommand {
+
+ public PDASetVarCommand(int threadId, int frame, String variable, String value) {
+ super("setvar " + threadId + " " + frame + " " + variable + " " + value);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommand.java
new file mode 100644
index 000000000..08f6dd673
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommand.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Return the contents of the control stack (program counters, function and
+ * variable names). The reply is control stack from oldest to newest as a single string
+ * <code>frame#frame#frame...#frame</code>, where each frame is a string
+ * <code>"filename|pc|function name|variable name|variable name|...|variable name"</code></li>.
+ *
+ * <pre>
+ * C: stack {thread_id}
+ * R: {file}|{line}|{function}|{var_1}|{var_2}|...#{file}|{line}|{function}|{var_1}|{var_2}|...#...
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+
+public class PDAStackCommand extends PDACommand {
+
+ public PDAStackCommand(int threadId) {
+ super("stack " + threadId);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDAStackCommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommandResult.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommandResult.java
new file mode 100644
index 000000000..6562dd279
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackCommandResult.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+
+/**
+ * @see PDAStackCommand
+ */
+
+public class PDAStackCommandResult extends PDACommandResult {
+
+ /**
+ * Array of frames return by the stack commands. The frames are ordered
+ * with the highest-level frame first.
+ */
+ final public PDAFrameData[] fFrames;
+
+ PDAStackCommandResult(String response) {
+ super(response);
+ StringTokenizer st = new StringTokenizer(response, "#");
+ List framesList = new ArrayList();
+
+ while (st.hasMoreTokens()) {
+ framesList.add(new PDAFrameData(st.nextToken()));
+ }
+ fFrames = (PDAFrameData[])framesList.toArray(new PDAFrameData[framesList.size()]);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommand.java
new file mode 100644
index 000000000..34e40d648
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommand.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Retrieves command stack depth
+ *
+ * <pre>
+ * C: stackdepth {thread_id}
+ * R: {depth}
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+
+public class PDAStackDepthCommand extends PDACommand {
+
+ public PDAStackDepthCommand(int threadId) {
+ super("stackdepth " + threadId);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDAStackDepthCommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommandResult.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommandResult.java
new file mode 100644
index 000000000..81bb90680
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStackDepthCommandResult.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+
+/**
+ * @see PDADataCommand
+ */
+
+public class PDAStackDepthCommandResult extends PDACommandResult {
+
+ final public int fDepth;
+
+ PDAStackDepthCommandResult(String response) {
+ super(response);
+ int depth = 1; // default to something that won't cause NPEs
+ try {
+ depth = Integer.parseInt(response);
+ } catch (NumberFormatException e) {}
+ fDepth = depth;
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStartedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStartedEvent.java
new file mode 100644
index 000000000..1a1b5cdec
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStartedEvent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Started event generated when a new thread is started. A started event
+ * is always sent for the first thread when a PDA program is started.
+ *
+ * <pre>
+ * E: started {thread_id}
+ * </pre>
+ */
+public class PDAStartedEvent extends PDARunControlEvent {
+
+ public PDAStartedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("started");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepCommand.java
new file mode 100644
index 000000000..e948cfb74
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepCommand.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Executes next instruction
+ *
+ * <pre>
+ * If VM running:
+ * C: step {thread_id}
+ * R: ok
+ * E: resumed {thread_id} step
+ * E: suspended {thread_id} step
+ *
+ * If VM suspended:
+ * C: step {thread_id}
+ * R: ok
+ * E: vmresumed step
+ * E: vmsuspended {thread_id} step
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+
+public class PDAStepCommand extends PDACommand {
+
+ public PDAStepCommand(int threadId) {
+ super("step " + threadId);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepReturnCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepReturnCommand.java
new file mode 100644
index 000000000..5211c90a9
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAStepReturnCommand.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Single step forward until the next <code>return</code> op code. Stop before
+ * executing the <code>return</code> .
+ *
+ * <pre>
+ * If VM running:
+ * C: stepreturn {thread_id}
+ * R: ok
+ * E: resumed {thread_id} client
+ * E: suspended {thread_id} step
+ *
+ * If VM suspended:
+ * C: stepreturn {thread_id}
+ * R: ok
+ * E: vmresumed client
+ * E: vmsuspended {thread_id} step
+ *
+ * Errors:
+ * error: invalid thread
+ * </pre>
+ */
+
+public class PDAStepReturnCommand extends PDACommand {
+
+ public PDAStepReturnCommand(int threadId) {
+ super("stepreturn " + threadId);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendCommand.java
new file mode 100644
index 000000000..3da5f2f53
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendCommand.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Suspends execution of a single thread. Can be issued only if the virtual
+ * machine is running.
+ *
+ * <pre>
+ * C: suspend {thread_id}
+ * R: ok
+ * E: suspended {thread_id} client
+ *
+ * Errors:
+ * error: invalid thread
+ error: vm already suspended
+ * error: thread already suspended
+ * </pre>
+ */
+
+public class PDASuspendCommand extends PDACommand {
+
+ public PDASuspendCommand(int threadId) {
+ super("suspend " + threadId);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendedEvent.java
new file mode 100644
index 000000000..7ed4eb330
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDASuspendedEvent.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Suspended event generated when a thread is suspended.
+ *
+ * <pre>
+ * E: suspended {thread_id} [reason]
+ * </pre>
+ *
+ * <code>[reason]</code> is the cause of the suspension and it's optional:
+ * <ul>
+ * <li><code>breakpoint N</code> - a breakpoint at line <code>N</code> was hit</li>
+ * <li><code>client</code> - a client request to suspend has completed</li>
+ * <li><code>drop</code> - a client request to drop a frame has completed</li>
+ * <li><code>event E</code> - an error was encountered, where <code>E</code> is one
+ * of <code>unimpinstr</code> or <code>nosuchlabel</code></li>
+ * <li><code>step</code> - a step request has completed</li>
+ * <li><code>watch A F::V</code> - a watchpoint was hit for reason <code>A</code>
+ * (<code>read</code> or <code>write</code>), on variable <code>V</code> in
+ * function <code>F</code></li>
+ * </ul>
+
+ */
+public class PDASuspendedEvent extends PDARunControlEvent {
+
+ public PDASuspendedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("suspended");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminateCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminateCommand.java
new file mode 100644
index 000000000..1b3eabb1d
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminateCommand.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Instructs the debugger to terminate.
+ *
+ * <pre>
+ * C: terminate
+ * R: ok
+ * E: vmterminated
+ * </pre>
+ */
+
+public class PDATerminateCommand extends PDACommand {
+
+ public PDATerminateCommand() {
+ super("terminate");
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminatedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminatedEvent.java
new file mode 100644
index 000000000..7a3a55fdd
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDATerminatedEvent.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Terminated event generated when the PDA program has ended execution.
+ *
+ * <pre>
+ * E: termianted
+ * </pre>
+ */
+public class PDATerminatedEvent extends PDAEvent {
+
+ public PDATerminatedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("terminated");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAUnimplementedInstructionEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAUnimplementedInstructionEvent.java
new file mode 100644
index 000000000..8c51c1ef8
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAUnimplementedInstructionEvent.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Unimplemented Instruction event generated when the PDA program encounters
+ * an instruction that it does not recognize. This event is usually followed
+ * by a VM Suspended event.
+ *
+ * <pre>
+ * E: unimplemented instruction {label}
+ * </pre>
+ */
+public class PDAUnimplementedInstructionEvent extends PDAEvent {
+
+ public final String fOperation;
+
+ public PDAUnimplementedInstructionEvent(String message) {
+ super(message);
+ fOperation = message.substring(getName(message).length() + 1);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("unimplemented instruction");
+ }
+
+ protected String getName(String message) {
+ if (isEventMessage(message)) {
+ return "unimplemented instruction";
+ }
+ throw new IllegalArgumentException("Invalid event: " + message);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumeCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumeCommand.java
new file mode 100644
index 000000000..2c2a03d3e
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumeCommand.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Resumes the execution of the whole virtual machine
+ *
+ * <pre>
+ * C: vmresume
+ * R: ok
+ * E: vmresumed client
+ *
+ * Errors:
+ * error: vm already running
+ * </pre>
+ */
+
+public class PDAVMResumeCommand extends PDACommand {
+
+ public PDAVMResumeCommand() {
+ super("vmresume");
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumedEvent.java
new file mode 100644
index 000000000..56fbace71
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMResumedEvent.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * VM Resumed event generated when the whole virtual machine is resumed. When
+ * the VM is resumed all previously suspended threads are resumed as well.
+ *
+ * <pre>
+ * E: vmresumed [reason]
+ * </pre>
+ *
+ * <code>[reason]</code> is the cause of the resume: and it's optional:
+ * <ul>
+ * <li><code>step</code> - a step request has been initiated</li>
+ * <li><code>client</code> - a client request to resume has been initiated</li>
+ * </ul>
+ */
+public class PDAVMResumedEvent extends PDARunControlEvent {
+
+ public PDAVMResumedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("vmresumed");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMStartedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMStartedEvent.java
new file mode 100644
index 000000000..a98a10c55
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMStartedEvent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * VM started event generated when the the interpreter has started (guaranteed
+ * to be the first event sent)
+ *
+ * <pre>
+ * E: vmstarted
+ * </pre>
+ */
+public class PDAVMStartedEvent extends PDAEvent {
+
+ public PDAVMStartedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("vmstarted");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendCommand.java
new file mode 100644
index 000000000..693d59a7f
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendCommand.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Suspends the execution of the whole virtual machine
+ *
+ * <pre>
+ * C: vmsuspend
+ * R: ok
+ * E: vmsuspended client
+ *
+ * Errors:
+ * error: thread already suspended
+ * </pre>
+ */
+
+public class PDAVMSuspendCommand extends PDACommand {
+
+ public PDAVMSuspendCommand() {
+ super("vmsuspend");
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendedEvent.java
new file mode 100644
index 000000000..9385fae59
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMSuspendedEvent.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * VM Suspended event generated when the virtual machine is suspended. If the VM
+ * is suspended as a result of a thread event (e.g. thread hitting a breakpoint),
+ * then the thread_id is included in the event.
+ *
+ * <pre>
+ * E: vmsuspended [thread_id] {reason}
+ * </pre>
+ *
+ * <code>{reason}</code> is the cause of the suspension:
+ * <ul>
+ * <li><code>breakpoint N</code> - a breakpoint at line <code>N</code> was hit</li>
+ * <li><code>client</code> - a client request to suspend has completed</li>
+ * <li><code>drop</code> - a client request to drop a frame has completed</li>
+ * <li><code>event E</code> - an error was encountered, where <code>E</code> is one
+ * of <code>unimpinstr</code> or <code>nosuchlabel</code></li>
+ * <li><code>step</code> - a step request has completed</li>
+ * <li><code>watch A F::V</code> - a watchpoint was hit for reason <code>A</code>
+ * (<code>read</code> or <code>write</code>), on variable <code>V</code> in
+ * function <code>F</code></li>
+ * </ul>
+ */
+public class PDAVMSuspendedEvent extends PDARunControlEvent {
+
+ public PDAVMSuspendedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("vmsuspended");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMTerminatedEvent.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMTerminatedEvent.java
new file mode 100644
index 000000000..624afc9f5
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVMTerminatedEvent.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+/**
+ * Terminated event generated when the PDA program has ended execution.
+ *
+ * <pre>
+ * E: termianted
+ * </pre>
+ */
+public class PDAVMTerminatedEvent extends PDAEvent {
+
+ public PDAVMTerminatedEvent(String message) {
+ super(message);
+ }
+
+ public static boolean isEventMessage(String message) {
+ return message.startsWith("vmterminated");
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVarCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVarCommand.java
new file mode 100644
index 000000000..c9c0497fa
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAVarCommand.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Return the contents of variable <code>variable_name</code> in the control
+ * stack frame <code>frame_number</code> (stack frames are indexed from 0, 0
+ * being the oldest).
+ *
+ * <pre>
+ * C: var {thread_id} {frame_number} {variable_name}
+ * R: {variable_value}
+ *
+ * Errors:
+ * error: invalid thread
+ * error: variable undefined
+ * </pre>
+ */
+
+public class PDAVarCommand extends PDACommand {
+
+ public PDAVarCommand(int threadId, int frameId, String name) {
+ super("var " + threadId + " " + frameId + " " + name);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAWatchCommand.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAWatchCommand.java
new file mode 100644
index 000000000..f45ad0208
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/PDAWatchCommand.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.protocol;
+
+
+/**
+ * Set a watchpoint on variable <code>variable_name</code> in function
+ * <code>function</code> to magic value <code>watch_operation</code>. The magic
+ * value is a bit flag corresponding to read access (1), write access (2), or
+ * both (3); the magic value 0 clears the watchpoint.
+ *
+ * <pre>
+ * C: watch {function}::{variable_name} {watch_operation}
+ * R: ok
+ * C: vmresume
+ * R: vmresumed client
+ * E: vmsuspended {thread_id} watch {watch_operation} {function}::{variable_name}
+ * </pre>
+ */
+public class PDAWatchCommand extends PDACommand {
+
+ public static final int READ = 1;
+ public static final int WRITE = 2;
+ public static final int BOTH = READ | WRITE;
+ public static final int NONE = 0;
+
+ public PDAWatchCommand(String function, String variable, int operation) {
+ super("watch " + function+ "::" + variable + " " + operation);
+ }
+
+
+ public PDACommandResult createResult(String resultText) {
+ return new PDACommandResult(resultText);
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/package.html b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/package.html
new file mode 100644
index 000000000..90bdaae51
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/protocol/package.html
@@ -0,0 +1,99 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>PDA Interpreter Debug Protocol</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<p>Provides classes representing PDA protocol commands, command results and events</p>
+
+<h2>Package Specification</h2>
+
+<h3>Virtual Machine execution control</h3>
+<h4>Commands</h4>
+<ul>
+<li>{@link PDATerminateCommand}</li>
+<li>{@link PDAVMSuspendCommand}</li>
+<li>{@link PDAVMResumeCommand}</li>
+<li>{@link PDAEventStopCommand}</li>
+</ul>
+<h4>Events</h4>
+<ul>
+<li>{@link PDAVMStarted}</li>
+<li>{@link PDAVMTerminated}</li>
+<li>{@link PDAVMSuspneded}</li>
+<li>{@link PDAVMResumed}</li>
+<li>{@link PDAUnimplementedInstructionEvent}</li>
+<li>{@link PDANoSuchLabelEvent}</li>
+</ul>
+
+<h3>Thread execution control</h3>
+<h4>Commands</h4>
+<ul>
+<li>{@link PDASuspendCommand}</li>
+<li>{@link PDAResumeCommand}</li>
+<li>{@link PDAStepCommand}</li>
+<li>{@link PDADropFrameCommand}</li>
+</ul>
+<h4>Events</h4>
+<ul>
+<li>{@link PDAStarted}</li>
+<li>{@link PDAExited}</li>
+<li>{@link PDASuspended}</li>
+<li>{@link PDAResumed}</li>
+</ul>
+
+<h3>Breakpoints</h3>
+<h4>Commands</h4>
+<ul>
+<li>{@link PDASetBreakpointCommand}</li>
+<li>{@link PDAClearBreakpointCommand}</li>
+<li>{@link PDAWatchCommand}</li>
+</ul>
+
+<h3>Data stack</h3>
+<h4>Commands</h4>
+<ul>
+<li>{@link PDADataCommand}</li>
+<li>{@link PDASetDataCommand}</li>
+<li>{@link PDAPopDataCommand}</li>
+<li>{@link PDAPushDataCommand}</li>
+</ul>
+
+<h3>Expression evaluation</h3>
+<h4>Commands</h4>
+<ul>
+<li>{@link PDAEvalCommand}</li>
+</ul>
+<h4>Events</h4>
+<ul>
+<li>{@link PDAEvalResultEvent}</li>
+</ul>
+
+<h3>Execution control stack</h3>
+<h4>Commands</h4>
+<ul>
+<li>{@link PDAStackCommand}</li>
+<li>{@link PDAStackDepthCommand}</li>
+<li>{@link PDAFrameCommand}</li>
+<li>{@link PDAVarCommand}</li>
+<li>{@link PDASetVarCommand}</li>
+<li>{@link PDAChildrenCommand}</li>
+</ul>
+
+<h3>Registers</h3>
+<h4>Commands</h4>
+<ul>
+<li>{@link PDAGroupsCommand}</li>
+<li>{@link PDARegistersCommand}</li>
+</ul>
+<h4>Events</h4>
+<ul>
+<li>{@link PDARegistersEvent}</li>
+</ul>
+
+</body>
+</html>
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java
index ab33ae4f2..ed0c069ee 100644
--- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.ui.pda.adapters;
@@ -27,7 +28,7 @@ public class PDADebugTargetContentProvider extends ElementContentProvider {
* @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
*/
protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
- PDAThread thread = ((PDADebugTarget) element).getThread();
+ PDAThread thread = ((PDADebugTarget) element).getThread(0);
if (thread != null) {
if (thread.hasStackFrames()) {
return thread.getStackFrames().length;
@@ -40,7 +41,7 @@ public class PDADebugTargetContentProvider extends ElementContentProvider {
* @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#hasChildren(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
*/
protected boolean hasChildren(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
- PDAThread thread = ((PDADebugTarget) element).getThread();
+ PDAThread thread = ((PDADebugTarget) element).getThread(0);
if (thread != null) {
return thread.hasStackFrames();
}
@@ -52,7 +53,7 @@ public class PDADebugTargetContentProvider extends ElementContentProvider {
*/
protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
if (context.getId().equals(IDebugUIConstants.ID_DEBUG_VIEW)) {
- PDAThread thread = ((PDADebugTarget) parent).getThread();
+ PDAThread thread = ((PDADebugTarget) parent).getThread(0);
if (thread != null) {
return getElements(thread.getStackFrames(), index, length);
}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java
index 1c13bac19..43e35dc26 100644
--- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
*******************************************************************************/
package org.eclipse.debug.examples.ui.pda.editor;
@@ -41,7 +42,7 @@ public class PopFrameActionDelegate implements IObjectActionDelegate, IActionDel
//# // TODO: Exercise 5 - pop the top frame
//#else
try {
- fThread.pop();
+ fThread.popFrame();
} catch (DebugException e) {
}
//#endif
@@ -61,7 +62,7 @@ public class PopFrameActionDelegate implements IObjectActionDelegate, IActionDel
//#else
fThread = (PDAThread) frame.getThread();
try {
- action.setEnabled(fThread.canPop() && fThread.getTopStackFrame().equals(frame));
+ action.setEnabled(fThread.canPopFrame() && fThread.getTopStackFrame().equals(frame));
} catch (DebugException e) {
}
return;
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/AbstractDataStackViewHandler.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/AbstractDataStackViewHandler.java
index 2fd5ec826..d9a279f4b 100644
--- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/AbstractDataStackViewHandler.java
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/AbstractDataStackViewHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Wind River Systems and others.
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13,9 +13,8 @@ package org.eclipse.debug.examples.ui.pda.views;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.debug.examples.core.pda.model.PDADebugElement;
-import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAStackFrame;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
@@ -34,16 +33,20 @@ abstract public class AbstractDataStackViewHandler extends AbstractHandler {
ISelection selection = DebugUITools.getDebugContextForEventChecked(event);
if (selection instanceof IStructuredSelection) {
- IStructuredSelection ss = (IStructuredSelection)selection;
- if (ss.getFirstElement() instanceof IAdaptable) {
- PDADebugElement element = (PDADebugElement)
- ((IAdaptable)ss.getFirstElement()).getAdapter(PDADebugElement.class);
- if (element != null) {
- doExecute(
- view,
- (PDADebugTarget)element.getDebugTarget(),
- HandlerUtil.getCurrentSelectionChecked(event));
- }
+ Object element = ((IStructuredSelection)selection).getFirstElement();
+
+ PDAThread thread = null;
+ if (element instanceof PDAThread) {
+ thread = (PDAThread)element;
+ } else if (element instanceof PDAStackFrame) {
+ thread = (PDAThread)((PDAStackFrame)element).getThread();
+ }
+
+ if (element != null) {
+ doExecute(
+ view,
+ thread,
+ HandlerUtil.getCurrentSelectionChecked(event));
}
}
} else {
@@ -59,5 +62,5 @@ abstract public class AbstractDataStackViewHandler extends AbstractHandler {
* @param target The current active debug target.
* @param selection The current selection in view.
*/
- abstract protected void doExecute(DataStackView view, PDADebugTarget target, ISelection selection) throws ExecutionException;
+ abstract protected void doExecute(DataStackView view, PDAThread target, ISelection selection) throws ExecutionException;
}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/CanPushTester.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/CanPushTester.java
index 9be29dceb..10b5acd31 100644
--- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/CanPushTester.java
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/CanPushTester.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Wind River Systems and others.
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13,7 +13,8 @@ package org.eclipse.debug.examples.ui.pda.views;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.examples.core.pda.model.PDADebugElement;
-import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAStackFrame;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
/**
* Property tester for use with standard expressions to determine whether
@@ -28,9 +29,15 @@ public class CanPushTester extends PropertyTester {
if (receiver instanceof IAdaptable) {
PDADebugElement element = (PDADebugElement)
((IAdaptable)receiver).getAdapter(PDADebugElement.class);
- if (element != null) {
- PDADebugTarget target = (PDADebugTarget)element.getDebugTarget();
- return target.canPush();
+ PDAThread thread = null;
+ if (element instanceof PDAThread) {
+ thread = (PDAThread)element;
+ } else if (element instanceof PDAStackFrame) {
+ thread = (PDAThread)((PDAStackFrame)element).getThread();
+ }
+
+ if (thread != null) {
+ return thread.canPushData();
}
}
}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java
index 5eeaa37a6..5e204755b 100644
--- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -9,37 +9,39 @@
* IBM Corporation - initial API and implementation
* Bjorn Freeman-Benson - initial API and implementation
* Wind River - Pawel Piech - replaced actions with handlers (bug 229219)
+ * Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
******************************************************************************/
package org.eclipse.debug.examples.ui.pda.views;
-import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.model.IDebugElement;
-import org.eclipse.debug.core.model.IDebugTarget;
-import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
-import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAStackFrame;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.debug.ui.DebugUITools;
-import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.contexts.DebugContextEvent;
+import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.progress.UIJob;
/**
* View of the PDA VM data stack
*/
-public class DataStackView extends AbstractDebugView implements ISelectionListener {
+public class DataStackView extends AbstractDebugView implements IDebugContextListener {
- private PDADebugTarget fTarget;
+ private PDAThread fThread;
class StackViewContentProvider implements ITreeContentProvider {
@@ -47,9 +49,9 @@ public class DataStackView extends AbstractDebugView implements ISelectionListen
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof PDADebugTarget) {
+ if (parentElement instanceof PDAThread) {
try {
- return ((PDADebugTarget)parentElement).getDataStack();
+ return ((PDAThread)parentElement).getDataStack();
} catch (DebugException e) {
}
}
@@ -60,10 +62,10 @@ public class DataStackView extends AbstractDebugView implements ISelectionListen
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
*/
public Object getParent(Object element) {
- if (element instanceof IDebugTarget) {
+ if (element instanceof PDAThread) {
return null;
} else {
- return ((IDebugElement)element).getDebugTarget();
+ return fThread;
}
}
@@ -71,10 +73,7 @@ public class DataStackView extends AbstractDebugView implements ISelectionListen
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
*/
public boolean hasChildren(Object element) {
- if (element instanceof IDebugElement) {
- return getChildren(element).length > 0;
- }
- return false;
+ return element instanceof PDAThread;
}
/* (non-Javadoc)
@@ -105,7 +104,7 @@ public class DataStackView extends AbstractDebugView implements ISelectionListen
TreeViewer viewer = new TreeViewer(parent);
viewer.setLabelProvider(DebugUITools.newDebugModelPresentation());
viewer.setContentProvider(new StackViewContentProvider());
- getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
+ DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).addDebugContextListener(this);
getSite().setSelectionProvider(viewer);
return viewer;
}
@@ -135,33 +134,40 @@ public class DataStackView extends AbstractDebugView implements ISelectionListen
* @see org.eclipse.ui.IWorkbenchPart#dispose()
*/
public void dispose() {
- getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
+ DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).removeDebugContextListener(this);
super.dispose();
}
- /* (non-Javadoc)
- * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
- */
- public void selectionChanged(IWorkbenchPart part, ISelection selection) {
- update();
+
+ public void debugContextChanged(final DebugContextEvent event) {
+ new UIJob(getSite().getShell().getDisplay(), "DataStackView update") {
+ {
+ setSystem(true);
+ }
+
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ update(event.getContext());
+ return Status.OK_STATUS;
+ }
+ }.schedule();
}
/**
- * Updates the view for the selected target (if suspended)
+ * Updates the view for the selected thread (if suspended)
*/
- private synchronized void update() {
- IAdaptable adaptable = DebugUITools.getDebugContext();
- fTarget = null;
- if (adaptable != null) {
- IDebugElement element = (IDebugElement) adaptable.getAdapter(IDebugElement.class);
- if (element != null) {
- if (element.getModelIdentifier().equals(DebugCorePlugin.ID_PDA_DEBUG_MODEL)) {
- fTarget = (PDADebugTarget) element.getDebugTarget();
- }
- }
- }
+ private void update(ISelection context) {
+ fThread = null;
+
+ if (context instanceof IStructuredSelection) {
+ Object element = ((IStructuredSelection)context).getFirstElement();
+ if (element instanceof PDAThread) {
+ fThread = (PDAThread)element;
+ } else if (element instanceof PDAStackFrame) {
+ fThread = (PDAThread)((PDAStackFrame)element).getThread();
+ }
+ }
Object input = null;
- if (fTarget != null && fTarget.isSuspended()) {
- input = fTarget;
+ if (fThread != null && fThread.isSuspended()) {
+ input = fThread;
}
getViewer().setInput(input);
getViewer().refresh();
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopHandler.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopHandler.java
index 59f00c857..1c0c5bc72 100644
--- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopHandler.java
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Wind River Systems and others.
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -16,7 +16,7 @@ import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValue;
-import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
@@ -27,28 +27,28 @@ import org.eclipse.jface.viewers.TreeViewer;
*/
public class PopHandler extends AbstractDataStackViewHandler {
- protected void doExecute(DataStackView view, PDADebugTarget target, ISelection selection) throws ExecutionException {
+ protected void doExecute(DataStackView view, PDAThread thread, ISelection selection) throws ExecutionException {
TreeViewer viewer = (TreeViewer)view.getViewer();
Object popee = selection instanceof IStructuredSelection
? ((IStructuredSelection)selection).getFirstElement() : null;
if (popee != null) {
try {
- IValue[] stack = target.getDataStack();
+ IValue[] stack = thread.getDataStack();
List restore = new ArrayList();
for (int i = 0; i < stack.length; i++) {
Object value = stack[i];
if (popee.equals(value)) {
// pop & stop
- target.pop();
+ thread.popData();
break;
} else {
// remember value to push back on
- restore.add(target.pop());
+ restore.add(thread.popData());
}
}
while (!restore.isEmpty()) {
IValue value = (IValue) restore.remove(restore.size() - 1);
- target.push(value.getValueString());
+ thread.pushData(value.getValueString());
}
} catch (DebugException e) {
throw new ExecutionException("Failed to execute push command", e);
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushHandler.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushHandler.java
index 306508f5a..58fbc7c0e 100644
--- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushHandler.java
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Wind River Systems and others.
+ * Copyright (c) 2008, 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,7 +12,7 @@ package org.eclipse.debug.examples.ui.pda.views;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
@@ -22,11 +22,11 @@ import org.eclipse.jface.window.Window;
*/
public class PushHandler extends AbstractDataStackViewHandler {
- protected void doExecute(DataStackView view, PDADebugTarget target, ISelection selection) throws ExecutionException {
+ protected void doExecute(DataStackView view, PDAThread thread, ISelection selection) throws ExecutionException {
InputDialog dialog = new InputDialog(view.getSite().getShell(), "Specify Value", "Enter value to push", null, null);
if (dialog.open() == Window.OK) {
try {
- target.push(dialog.getValue());
+ thread.pushData(dialog.getValue());
} catch (DebugException e) {
throw new ExecutionException("Failed to execute push command", e);
}

Back to the top