1 /* StackFrameCommandSet.java -- class to implement the StackFrame Command Set 2 Copyright (C) 2005, 2007 Free Software Foundation 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 terms of your choice, provided that you also meet, for each linked 32 independent module, the terms and conditions of the license of that 33 module. An independent module is a module which is not derived from 34 or based on this library. If you modify this library, you may extend 35 this exception to your version of the library, but you are not 36 obligated to do so. If you do not wish to do so, delete this 37 exception statement from your version. */ 38 39 40 package gnu.classpath.jdwp.processor; 41 42 import gnu.classpath.jdwp.JdwpConstants; 43 import gnu.classpath.jdwp.VMFrame; 44 import gnu.classpath.jdwp.VMVirtualMachine; 45 import gnu.classpath.jdwp.exception.JdwpException; 46 import gnu.classpath.jdwp.exception.JdwpInternalErrorException; 47 import gnu.classpath.jdwp.exception.NotImplementedException; 48 import gnu.classpath.jdwp.id.ThreadId; 49 import gnu.classpath.jdwp.value.ObjectValue; 50 import gnu.classpath.jdwp.value.Value; 51 import gnu.classpath.jdwp.value.ValueFactory; 52 53 import java.io.DataOutputStream; 54 import java.io.IOException; 55 import java.nio.ByteBuffer; 56 57 /** 58 * A class representing the StackFrame Command Set. 59 * 60 * @author Aaron Luchko <aluchko@redhat.com> 61 */ 62 public class StackFrameCommandSet 63 extends CommandSet 64 { runCommand(ByteBuffer bb, DataOutputStream os, byte command)65 public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command) 66 throws JdwpException 67 { 68 boolean keepRunning = true; 69 try 70 { 71 switch (command) 72 { 73 case JdwpConstants.CommandSet.StackFrame.GET_VALUES: 74 executeGetValues(bb, os); 75 break; 76 case JdwpConstants.CommandSet.StackFrame.SET_VALUES: 77 executeSetValues(bb, os); 78 break; 79 case JdwpConstants.CommandSet.StackFrame.THIS_OBJECT: 80 executeThisObject(bb, os); 81 break; 82 case JdwpConstants.CommandSet.StackFrame.POP_FRAMES: 83 executePopFrames(bb, os); 84 break; 85 default: 86 throw new NotImplementedException("Command " + command + 87 " not found in Stack Frame Command Set."); 88 } 89 } 90 catch (IOException ex) 91 { 92 // The DataOutputStream we're using isn't talking to a socket at all 93 // So if we throw an IOException we're in serious trouble 94 throw new JdwpInternalErrorException(ex); 95 } 96 97 return false; 98 } 99 executeGetValues(ByteBuffer bb, DataOutputStream os)100 private void executeGetValues(ByteBuffer bb, DataOutputStream os) 101 throws JdwpException, IOException 102 { 103 ThreadId tId = (ThreadId) idMan.readObjectId(bb); 104 Thread thread = tId.getThread(); 105 106 // Although Frames look like other ids they are not. First they are not 107 // ObjectIds since they don't exist in the users code. Storing them as an 108 // ObjectId would mean they could be garbage collected since no one else 109 // has a reference to them. Furthermore they are not ReferenceTypeIds since 110 // these are held permanently and we want these to be held only as long as 111 // the Thread is suspended. 112 long frameID = bb.getLong(); 113 VMFrame frame = VMVirtualMachine.getFrame(thread, frameID); 114 int slots = bb.getInt(); 115 os.writeInt(slots); // Looks pointless but this is the protocol 116 for (int i = 0; i < slots; i++) 117 { 118 int slot = bb.getInt(); 119 byte sig = bb.get(); 120 Value val = frame.getValue(slot, sig); 121 val.writeTagged(os); 122 } 123 } 124 executeSetValues(ByteBuffer bb, DataOutputStream os)125 private void executeSetValues(ByteBuffer bb, DataOutputStream os) 126 throws JdwpException, IOException 127 { 128 ThreadId tId = (ThreadId) idMan.readObjectId(bb); 129 Thread thread = tId.getThread(); 130 131 long frameID = bb.getLong(); 132 VMFrame frame = VMVirtualMachine.getFrame(thread, frameID); 133 134 int slots = bb.getInt(); 135 for (int i = 0; i < slots; i++) 136 { 137 int slot = bb.getInt(); 138 Value value = ValueFactory.createFromTagged(bb); 139 frame.setValue(slot, value); 140 } 141 } 142 executeThisObject(ByteBuffer bb, DataOutputStream os)143 private void executeThisObject(ByteBuffer bb, DataOutputStream os) 144 throws JdwpException, IOException 145 { 146 ThreadId tId = (ThreadId) idMan.readObjectId(bb); 147 Thread thread = tId.getThread(); 148 149 long frameID = bb.getLong(); 150 VMFrame frame = VMVirtualMachine.getFrame(thread, frameID); 151 152 ObjectValue objVal = new ObjectValue(frame.getObject()); 153 objVal.writeTagged(os); 154 } 155 executePopFrames(ByteBuffer bb, DataOutputStream os)156 private void executePopFrames(ByteBuffer bb, DataOutputStream os) 157 throws JdwpException, IOException 158 { 159 if (!VMVirtualMachine.canPopFrames) 160 { 161 String msg = "popping frames is unsupported"; 162 throw new NotImplementedException(msg); 163 } 164 165 ThreadId tid = (ThreadId) idMan.readObjectId(bb); 166 Thread thread = tid.getThread(); 167 long fid = bb.getLong(); 168 VMVirtualMachine.popFrames(thread, fid); 169 } 170 } 171