예제 #1
0
 public DStackContext(int module, int line, DModule f, int thisId, String functionSignature, int depth)
 {
     m_source = f;
     m_module = module;
     m_line   = line;
     // the passed-in 'thisId' seems to always be equal to one, which does more harm than good
     m_this = null;
     m_functionSignature = functionSignature;
     m_depth             = depth;
     m_args       = new LinkedHashMap(); // preserves order
     m_locals     = new LinkedHashMap(); // preserves order
     m_scopeChain = new System.Collections.ArrayList();
     m_populated  = false;
     m_location   = new DLocation(m_source, line);
 }
예제 #2
0
        public virtual void addMember(DVariable v)
        {
            if (m_members == null)
            {
                m_members = new System.Collections.Hashtable();
            }

            // if we are a proto member house away our original parent id
            String name = v.getName();
            DValue val  = (DValue)v.getValue();

            val.m_nonProtoId     = (name != null && name.Equals("__proto__"))?m_nonProtoId:val.Id;         //$NON-NLS-1$ // TODO is this right?
            v.m_nonProtoParentId = m_nonProtoId;

            m_members[name] = v;
        }
예제 #3
0
        /*
         * @see Flash.Tools.Debugger.Value#getMembers(Flash.Tools.Debugger.Session)
         */
        public override Variable[] getMembers(Session s)
        {
            obtainMembers(s);

            /* find out the size of the array */
            int count = getMemberCount(s);

            DVariable[] ar = new DVariable[count];

            if (count > 0)
            {
                m_members.Values.CopyTo(ar, 0);

                // sort the member list by name
                ArrayUtil.sort(ar);
            }

            return(ar);
        }
예제 #4
0
		public virtual void  clearLastVariable()
		{
			m_lastInGetVariable = null;
		}
예제 #5
0
		internal virtual void  setThis(DVariable v)
		{
			m_this = v;
		}
예제 #6
0
		internal virtual void  addScopeChainEntry(DVariable v)
		{
			m_scopeChain.Add(v);
		}
예제 #7
0
		/* setters */
		internal virtual void  addArgument(DVariable v)
		{
            m_args[v.getName()] = v;
		}
예제 #8
0
		/// <summary> Get the value of the variable named 'name' using varId
		/// as the context id for the Variable.
		/// 
		/// This call is used to fire getters, where the id must
		/// be that of the original object and not the object id
		/// of where the getter actually lives.  For example
		/// a getter a() may live under o.__proto__.__proto__
		/// but you must use the id of o and the name of 'a'
		/// in order for the getter to fire correctly.  [Note: This
		/// paragraph was written for AS2; __proto__ doesn't exist
		/// in AS3.  TODO: revise this paragraph]
		/// </summary>
		public virtual Value getValue(int varId, String name)
		{
			Value v = null;
			if (Suspended)
			{
				int fireGetter = getPreference(SessionManager.PREF_INVOKE_GETTERS);
				
				// disable children attaching to parent variables and clear our
				// most recently seen variable
				m_manager.clearLastVariable();
				m_manager.enableChildAttach(false);
				
				try
				{
					requestVariable(varId, name, (fireGetter != 0), false);
					v = m_manager.lastVariable().getValue();
				}
				catch (NoResponseException e)
				{
					if (fireGetter != 0)
					{
						// We fired a getter -- most likely, what happened is that that getter
						// (which is actual code in the user's movie) just took too long to
						// calculate its value.  So rather than throwing an exception, we store
						// some error text for the value of the variable itself.
						//
						// TODO [mmorearty 4/20/06] Even though I wrote the below code, I now
						// am wondering if it is incorrect that I am calling addVariableMember(),
						// because in every other case, this function does not add members to
						// existing objects.  Need to revisit this.
						v = new DValue(VariableType.STRING, "String", "String", ValueAttribute.IS_EXCEPTION, e.getLocalizedMessage());
						DVariable var = new DVariable(name, (DValue) v);
						m_manager.enableChildAttach(true);
						m_manager.addVariableMember(varId, var);
					}
					else
					{
						throw e; // re-throw
					}
				}
				finally
				{
					// reset our attach flag, so that children attach to parent variables.
					m_manager.enableChildAttach(true);
				}
			}
			else
				throw new NotSuspendedException();
			
			return v;
		}
예제 #9
0
		// TODO is this right?
		internal virtual void  addVariableMember(long parentId, DVariable child, long doubleAsId)
		{
			addVariableMember(parentId, child);
			
			// double book the child under another id
			if (m_attachChildren)
				putValue(doubleAsId, (DValue) child.getValue());
		}
예제 #10
0
        }         // triggers a reload of variables.

        /// <summary> Removes the specified variable from the list of locals, and
        /// remembers that the specified variable is the "activation object"
        /// for this frame.  See bug 155031.
        /// </summary>
        internal virtual void  convertLocalToActivationObject(DVariable v)
        {
            m_activationObject = v;
            m_locals.Remove(v.getName());
        }
예제 #11
0
 internal virtual void  setThis(DVariable v)
 {
     m_this = v;
 }
예제 #12
0
 internal virtual void  removeAllLocals()
 {
     m_locals.Clear(); m_activationObject = null;
 }
예제 #13
0
 internal virtual void  addScopeChainEntry(DVariable v)
 {
     m_scopeChain.Add(v);
 }
예제 #14
0
 internal virtual void  addLocal(DVariable v)
 {
     m_locals[v.getName()] = v;
 }
예제 #15
0
 /* setters */
 internal virtual void  addArgument(DVariable v)
 {
     m_args[v.getName()] = v;
 }
예제 #16
0
		internal virtual void  addVariableMember(long parentId, DVariable child)
		{
			DValue parent = getValue(parentId);
			addVariableMember(parent, child);
		}
예제 #17
0
		internal virtual void  addVariableMember(DValue parent, DVariable child)
		{
			if (m_attachChildren)
			{
				// There are certain situations when the Flash player will send us more
				// than one variable or getter with the same name.  Basically, when a
				// subclass implements (or overrides) something that was also declared in a
				// superclass, then we'll see that variable or getter in both the
				// superclass and the subclass.
				//
				// Here are a few situations where that affects the debugger in different
				// ways:
				//
				// 1. When a class implements an interface, the class instance actually has
				//    *two* members for each implemented function: One which is public and
				//    represents the implementation function, and another which is internal
				//    to the interface, and represents the declaration of the function.
				//    Both of these come in to us.  In the UI, the one we want to show is
				//    the public one.  They come in in random order (they are stored in a
				//    hash table in the VM), so we don't know which one will come first.
				//
				// 2. When a superclass has a private member "m", and a subclass has its own
				//    private member with the same name "m", we will receive both of them.
				//    (They are scoped by different packages.)  In this case, the first one
				//    the player sent us is the one from the subclass, and that is the one
				//    we want to display in the debugger.
				//
				// The following logic correctly deals with all variations of those cases.
				DVariable existingChildWithSameName = parent.findMember(child.getName());
				if (existingChildWithSameName != null)
				{
					int existingScope = existingChildWithSameName.Scope;
					int newScope = child.Scope;
					
					if (existingScope == VariableAttribute.NAMESPACE_SCOPE && newScope == VariableAttribute.PUBLIC_SCOPE)
					{
						// This is the case described above where a class implements an interface,
						// so that class's definition includes both a namespace-scoped declaration
						// and a public declaration, in random order; in this case, the
						// namespace-scoped declaration came first.  We want to use the public
						// declaration.
						parent.addMember(child);
					}
					else if (existingScope == VariableAttribute.PUBLIC_SCOPE && newScope == VariableAttribute.NAMESPACE_SCOPE)
					{
						// One of two things happened here:
						//
						// 1. This is the case described above where a class implements an interface,
						//    so that class's definition includes both a namespace-scoped declaration
						//    and a public declaration, in random order; in this case, the
						//    public declaration came first.  It is tempting to use the public
						//    member in this case, but there is a catch...
						// 2. It might be more complicated than that: Perhaps there is interface I,
						//    and class C1 implements I, but class C2 extends C1, and overrides
						//    one of the members of I that was already implemented by C1.  In this
						//    case, the public declaration from C2 came first, but now we are seeing
						//    a namespace-scoped declaration in C1.  We need to record that the
						//    member is public, but we also need to record that it is a member
						//    of the base class, not just a member of the superclass.
						//
						// The easiest way to deal with both cases is to use the child that came from
						// the superclass, but to change its scope to public.
						child.makePublic();
						parent.addMember(child);
					}
					else if (existingScope != VariableAttribute.PRIVATE_SCOPE && existingScope == newScope)
					{
						// This is a public, protected, internal, or namespace-scoped member which
						// was defined in a base class and overridden in a subclass.  We want to
						// use the member from the base class, to that the debugger knows where the
						// variable was actually defined.
						parent.addMember(child);
					}
				}
				else
				{
					parent.addMember(child);
				}
				
				// put child in the registry if it has an id and not already there
				DValue childValue = (DValue) child.getValue();
				int childId = childValue.Id;
				if (childId != Value.UNKNOWN_ID)
				{
					DValue existingValue = getValue(childId);
					if (existingValue != null)
					{
						Debug.Assert(existingValue == childValue); // TODO is this right? what about getters?
					}
					else
					{
						putValue(childId, childValue);
					}
				}
			}
		}
예제 #18
0
		/*
		* @see Flash.Tools.Debugger.Value#getMembers(Flash.Tools.Debugger.Session)
		*/
		public override Variable[] getMembers(Session s)
		{
			obtainMembers(s);
			
			/* find out the size of the array */
			int count = getMemberCount(s);
			DVariable[] ar = new DVariable[count];
			
			if (count > 0)
			{
                m_members.Values.CopyTo(ar, 0);
				
				// sort the member list by name
				ArrayUtil.sort(ar);
			}
			
			return ar;
		}
예제 #19
0
		/// <summary> This is the core routine for decoding incoming messages and deciding what should be
		/// done with them.  We have registered ourself with DProtocol to be notified when any
		/// incoming messages have been received.
		/// 
		/// It is important to note that we should not rely on the contents of the message
		/// since it may be reused after we exit this method.
		/// </summary>
		public virtual void  messageArrived(DMessage msg, DProtocol which)
		{
			/* at this point we just open up a big switch statement and walk through all possible cases */
			int type = msg.Type;
			//		System.out.println("manager msg = "+DMessage.inTypeName(type));
			
			switch (type)
			{
				
				case DMessage.InVersion: 
				{
                    long ver = msg.getDWord();
					m_playerVersion = (int) ver;
					break;
				}
				
				
				case DMessage.InErrorExecLimit: 
				{
					handleFaultEvent(new RecursionLimitFault());
					break;
				}
				
				
				case DMessage.InErrorWith: 
				{
					handleFaultEvent(new InvalidWithFault());
					break;
				}
				
				
				case DMessage.InErrorProtoLimit: 
				{
					handleFaultEvent(new ProtoLimitFault());
					break;
				}
				
				
				case DMessage.InErrorURLOpen: 
				{
                    String url = msg.getString();
					handleFaultEvent(new InvalidURLFault(url));
					break;
				}
				
				
				case DMessage.InErrorTarget: 
				{
                    String name = msg.getString();
					handleFaultEvent(new InvalidTargetFault(name));
					break;
				}
				
				
				case DMessage.InErrorException: 
				{
                    long offset = msg.getDWord();
					// As of FP9, the player will also send the "toString()" message
					// of the exception.  But for backward compatibility with older
					// players, we won't assume that that is there.
					String exceptionMessage;
					if (msg.Remaining > 0)
                        exceptionMessage = msg.getString();
					else
						exceptionMessage = ""; //$NON-NLS-1$
					handleFaultEvent(new ExceptionFault(exceptionMessage));
					break;
				}
				
				
				case DMessage.InErrorStackUnderflow: 
				{
                    long offset = msg.getDWord();
					handleFaultEvent(new StackUnderFlowFault());
					break;
				}
				
				
				case DMessage.InErrorZeroDivide: 
				{
                    long offset = msg.getDWord();
					handleFaultEvent(new DivideByZeroFault());
					break;
				}
				
				
				case DMessage.InErrorScriptStuck: 
				{
					handleFaultEvent(new ScriptTimeoutFault());
					break;
				}
				
				
				case DMessage.InErrorConsole: 
				{
                    String s = msg.getString();
					handleFaultEvent(new ConsoleErrorFault(s));
					break;
				}
				
				
				case DMessage.InTrace: 
				{
                    String text = msg.getString();
					addEvent(new TraceEvent(text));
					break;
				}
				
				
				case DMessage.InSquelch: 
				{
                    long state = msg.getDWord();
					m_squelchEnabled = (state != 0)?true:false;
					break;
				}
				
				
				case DMessage.InParam: 
				{
                    String name = msg.getString();
                    String value = msg.getString();
					
					// here's where we get movie = URL and password which I'm not sure what to do with?
					//				System.out.println(name+"="+value);
					m_parms[name] = value;
					
					// if string is a "movie", then this is a URL
					if (name.StartsWith("movie"))
					//$NON-NLS-1$
						m_uri = convertToURI(value);
					break;
				}
				
				
				case DMessage.InPlaceObject: 
				{
                    long objId = msg.getDWord();
					String path = msg.getString();
					//				m_bag.placeObject((int)objId, path);
					break;
				}
				
				
				case DMessage.InSetProperty: 
				{
                    long objId = msg.getDWord();
					int item = msg.getWord();
                    String value = msg.getString();
					break;
				}
				
				
				case DMessage.InNewObject: 
				{
                    long objId = msg.getDWord();
					break;
				}
				
				
				case DMessage.InRemoveObject: 
				{
                    long objId = msg.getDWord();
					//				m_bag.removeObject((int)objId);
					break;
				}
				
				
				case DMessage.InSetVariable: 
				{
                    long objId = msg.getDWord();
                    String name = msg.getString();
					int dType = msg.getWord();
                    int flags = (int)msg.getDWord();
                    String value = msg.getString();
					
					//				m_bag.createVariable((int)objId, name, dType, flags, value);
					break;
				}
				
				
				case DMessage.InDeleteVariable: 
				{
                    long objId = msg.getDWord();
                    String name = msg.getString();
					//				m_bag.deleteVariable((int)objId, name);
					break;
				}
				
				
				case DMessage.InScript: 
				{
                    int module = (int)msg.getDWord();
                    int bitmap = (int)msg.getDWord();
                    String name = msg.getString(); // in "basepath;package;filename" format
                    String text = msg.getString();
					int swfIndex = - 1;
					
					/* new in flash player 9: player tells us what swf this is for */
					if (msg.Remaining >= 4)
                        swfIndex = (int)msg.getDWord();
					
					lock (m_source)
					{
						// create new source file
						if (putSource(swfIndex, module, bitmap, name, text))
						{
							// have we changed the list since last query
							if (!m_sourceListModified)
								addEvent(new FileListModifiedEvent());
							
							m_sourceListModified = true; /* current source list is stale */
						}
					}
					break;
				}
				
				
				case DMessage.InRemoveScript: 
				{
                    long module = msg.getDWord();
					lock (m_source)
					{
						if (removeSource((int) module))
						{
							// have we changed the list since last query
							if (!m_sourceListModified)
								addEvent(new FileListModifiedEvent());
							
							m_sourceListModified = true; /* current source list is stale */
						}
					}
					break;
				}
				
				
				case DMessage.InAskBreakpoints: 
				{
					// the player has just loaded a swf and we know the player
					// has halted, waiting for us to continue.  The only caveat
					// is that it looks like it still does a number of things in
					// the background which take a few seconds to complete.
					if (m_suspendInfo == null)
						m_suspendInfo = new DSuspendInfo(SuspendReason.ScriptLoaded, 0, 0, 0, 0);
					break;
				}
				
				
				case DMessage.InBreakAt: 
				{
                    long bp = msg.getDWord();
                    long id = msg.getDWord();
                    String stack = msg.getString();
					//				System.out.println(msg.getInTypeName()+",bp="+(bp&0xffff)+":"+(bp>>16)+",id="+id+",stack=\n"+stack);
					
					//System.out.println("InBreakAt");
					
					int module = DLocation.decodeFile(bp);
					int line = DLocation.decodeLine(bp);
					addEvent(new BreakEvent(module, line));
					break;
				}
				
				
				case DMessage.InContinue: 
				{
					/* we are running again so trash all our variable contents */
					continuing();
					break;
				}
				
				
				case DMessage.InSetLocalVariables: 
				{
                    long objId = msg.getDWord();
					//				m_bag.markObjectLocal((int)objId, true);
					break;
				}
				
				
				case DMessage.InSetBreakpoint: 
				{
                    long count = msg.getDWord();
					while (count-- > 0)
					{
                        long bp = msg.getDWord();
						
						int fileId = DLocation.decodeFile(bp);
						int line = DLocation.decodeLine(bp);
						
						DModule file = getSource(fileId);
						DLocation l = new DLocation(file, line);
						
						if (file != null)
							addBreakpoint((int) bp, l);
					}
					break;
				}
				
				
				case DMessage.InNumScript: 
				{
					/* lets us know how many scripts there are */
                    int num = (int)msg.getDWord();
					DSwfInfo swf;
					
					/*
					* New as of flash player 9: another dword indicating which swf this is for.
					* That means we don't have to guess whether this is for an old SWF
					* which has just had some more modules loaded, or for a new SWF!
					*/
					if (msg.Remaining >= 4)
					{
                        int swfIndex = (int)msg.getDWord();
						swf = getOrCreateSwfInfo(swfIndex);
						m_lastSwfInfo = swf;
					}
					else
					{
						/* This is not flash player 9 (or it is an early build of fp9).
						*
						* We use this message as a trigger that a new swf has been loaded, so make sure
						* we are ready to accept the scripts.
						*/
						swf = ActiveSwfInfo;
					}
					
					// It is NOT an error for the player to have sent us a new,
					// different sourceExpectedCount from whatever we had before!
					// In fact, this happens all the time, whenever a SWF has more
					// than one ABC.
					swf.SourceExpectedCount = num;
					break;
				}
				
				
				case DMessage.InRemoveBreakpoint: 
				{
                    long count = msg.getDWord();
					while (count-- > 0)
					{
                        long bp = msg.getDWord();
						removeBreakpoint((int) bp);
					}
					break;
				}
				
				
				case DMessage.InBreakAtExt: 
				{
                    long bp = msg.getDWord();
                    long num = msg.getDWord();
					
					//				System.out.println(msg.getInTypeName()+",bp="+(bp&0xffff)+":"+(bp>>16));
					/* we have stack info to store away */
					clearFrames(); // just in case
					int depth = 0;
					while (num-- > 0)
					{
                        long bpi = msg.getDWord();
                        long id = msg.getDWord();
                        String stack = msg.getString();
						int module = DLocation.decodeFile(bpi);
						int line = DLocation.decodeLine(bpi);
						DModule m = getSource(module);
						DStackContext c = new DStackContext(module, line, m, (int) id, stack, depth);
						// If addFrame() returns false, that means it chose to ignore this
						// frame, so we do NOT want to increment our depth for the next
						// time through the loop.  If it returns true, then we do want to.
						if (addFrame(c))
							++depth;
						//					System.out.println("   this="+id+",@"+(bpi&0xffff)+":"+(bpi>>16)+",stack="+stack);
					}
					mapOldFramesToNew();
					break;
				}
				
				
				case DMessage.InFrame: 
				{
					// For InFrame the first element is really our frame id
					DValue frame = null;
					DVariable child = null;
					System.Collections.ArrayList v = new System.Collections.ArrayList();
					System.Collections.ArrayList registers = new System.Collections.ArrayList();

                    int depth = (int)msg.getDWord(); // depth of frame
					
					// make sure we have a valid depth
					if (depth > - 1)
					{
						// first thing is number of registers
                        int num = (int)msg.getDWord();
						for (int i = 0; i < num; i++)
							registers.Add(extractRegister(msg, i + 1));
					}
					
					int currentArg = - 1;
					bool gettingScopeChain = false;
					
					// then our frame itself
					while (msg.Remaining > 0)
					{
                        long frameId = msg.getDWord();
						
						if (frame == null)
						{
							frame = getOrCreateValue(frameId);
							extractVariable(msg); // put the rest of the info in the trash
						}
						else
						{
							child = extractVariable(msg);
							if (currentArg == - 1 && child.getName().Equals(ARGUMENTS_MARKER))
							{
								currentArg = 0;
								gettingScopeChain = false;
							}
							else if (child.getName().Equals(SCOPE_CHAIN_MARKER))
							{
								currentArg = - 1;
								gettingScopeChain = true;
							}
							else if (currentArg >= 0)
							{
								// work around a compiler bug: If the variable's name is "undefined",
								// then change its name to "_argN", where "N" is the argument index,
								// e.g. _arg1, _arg2, etc.
								++currentArg;
								if (child.getName().Equals("undefined"))
								//$NON-NLS-1$
									child.setName("_arg" + currentArg); //$NON-NLS-1$
							}
							
							// All args and locals get added as "children" of
							// the frame; but scope chain entries do not.
							if (!gettingScopeChain)
								addVariableMember(frameId, child);
							
							// Everything gets added to the ordered list of
							// variables that came in.
							v.Add(child);
						}
					}
					
					// let's transfer our newly gained knowledge into the stack context
					if (depth == 0)
						populateRootNode(frame, v);
					else
						populateFrame(depth, v);
					
					break;
				}
				
				
				case DMessage.InOption: 
				{
                    String s = msg.getString();
                    String v = msg.getString();
					m_options[s] = v;
					break;
				}
				
				
				case DMessage.InGetVariable: 
				{
					// For InGetVariable the first element is the original entity we requested
					DValue parent = null;
					DVariable child = null;
					String definingClass = null;
					int level = 0;
					int highestLevelWithMembers = - 1;
					System.Collections.IList classes = new System.Collections.ArrayList();
					
					while (msg.Remaining > 0)
					{
                        long parentId = msg.getDWord();
						
						// build or get parent node
						if (parent == null)
						{
                            String name = msg.getString();
							
							// pull the contents of the node which normally are disposed of except if we did a 0,name call
							m_lastInGetVariable = extractVariable(msg, name);
							
							parent = getOrCreateValue(parentId);
						}
						else
						{
							// extract the child and add it to the parent.
							child = extractVariable(msg);
							if (showMember(child))
							{
								if (child.isAttributeSet(VariableAttribute.IS_DYNAMIC))
								{
									// Dynamic attributes always come in marked as a member of
									// class "Object"; but to the user, it makes more sense to
									// consider them as members of the topmost class.
									if (classes.Count > 0)
									{
										child.setDefiningClass(0, (String) classes[0]);
										highestLevelWithMembers = Math.Max(highestLevelWithMembers, 0);
									}
								}
								else
								{
									child.setDefiningClass(level, definingClass);
									if (definingClass != null)
									{
										highestLevelWithMembers = Math.Max(highestLevelWithMembers, level);
									}
								}
								addVariableMember(parent.Id, child);
							}
							else
							{
								if (isTraits(child))
								{
									definingClass = child.QualifiedName;
									level = classes.Count;
									
									// If the traits name end with "$", then it represents a class object --
									// in other words, the variables inside it are static variables of that
									// class.  In that case, we need to juggle the information.  For example,
									// if we are told that a variable is a member of "MyClass$", we actually
									// store it into the information for "MyClass".
									if (definingClass.EndsWith("$"))
									{
										//$NON-NLS-1$
										String classWithoutDollar = definingClass.Substring(0, (definingClass.Length - 1) - (0));
										int indexOfClass = classes.IndexOf(classWithoutDollar);
										if (indexOfClass != - 1)
										{
											level = indexOfClass;
											definingClass = classWithoutDollar;
										}
									}
									
									// It wasn't static -- so, add this class to the end of the list of classes
									if (level == classes.Count)
									{
										classes.Add(definingClass);
									}
								}
							}
						}
					}
					
					if (parent != null && parent.getClassHierarchy(true) == null)
					{
                        String[] classesArray = new String[classes.Count];
                        int index = 0;

                        foreach (String className in classes)
                        {
                            classesArray[index++] = className;
                        }

						parent.setClassHierarchy(classesArray, highestLevelWithMembers + 1);
					}
					
					break;
				}
				
				
				case DMessage.InWatch: 
				// for AS2; sends 16-bit ID field
				case DMessage.InWatch2:  // for AS3; sends 32-bit ID field
					{
						// This message is sent whenever a watchpoint is added
						// modified or removed.
						//
						// For an addition, flags will be non-zero and
						// success will be true.
						//
						// For a modification flags  will be non-zero.
						// and oldFlags will be non-zero and success
						// will be true.  Additionally oldFlags will not
						// be equal to flags.
						//
						// For a removal flags will be zero.  oldFlags
						// will be non-zero.
						//
						// flags identifies the type of watchpoint added,
						// see WatchKind.
						//
						// success indicates whether the operation was successful
						//
						// request.   It will be associated with the watchpoint.
                        int success = msg.getWord();
                        int oldFlags = msg.getWord();
                        int oldTag = msg.getWord();
                        int flags = msg.getWord();
                        int tag = msg.getWord();
						// for AS2, the ID came in above as a Word.  For AS3, the above value is
						// bogus, and it has been sent again as a DWord.
                        int id = (int)((type == DMessage.InWatch2) ? msg.getDWord() : msg.getWord());
                        String name = msg.getString();
						
						if (success != 0)
						{
							if (flags == 0)
							{
								removeWatchpoint(oldTag);
							}
							else
							{
								// modification or addition is the same to us
								// a new watch is created and added into the table
								// while any old entry if it exists is removed.
								removeWatchpoint(oldTag);
								DWatch w = new DWatch(id, name, flags, tag);
								addWatchpoint(w);
							}
						}
						break;
					}
				
				
				case DMessage.InGetSwf: 
				{
					// we only house the swf temporarily, PlayerSession then
					// pieces it back into swfinfo record.  Also, we don't
					// send any extra data in the message so that we need not
					// copy the bytes.
					m_swf = msg.Data;
					break;
				}
				
				
				case DMessage.InGetSwd: 
				{
					// we only house the swd temporarily, PlayerSession then
					// pieces it back into swfinfo record.
					m_swd = msg.Data;
					break;
				}
				
				
				case DMessage.InBreakReason: 
					{
						// the id map 1-1 with out SuspendReason interface constants
                        int suspendReason = msg.getWord();
                        int suspendPlayer = msg.getWord(); // item index of player
                        int breakOffset = (int)msg.getDWord(); // current script offset
                        int prevBreakOffset = (int)msg.getDWord(); // prev script offset
                        int nextBreakOffset = (int)msg.getDWord(); // next script offset
						m_suspendInfo = new DSuspendInfo(suspendReason, suspendPlayer, breakOffset, prevBreakOffset, nextBreakOffset);
						
						// augment the current frame with this information.  It
						// should work ok since we only get this message after a
						// InBreakAtExt message
						try
						{
							DStackContext c = getFrame(0);
							c.Offset = breakOffset;
							c.SwfIndex = suspendPlayer;
						}
						catch (Exception e)
						{
							if (Trace.error)
							{
								Trace.trace("Oh my god, gag me with a spoon...getFrame(0) call failed"); //$NON-NLS-1$
                                Console.Error.Write(e.StackTrace);
                                Console.Error.Flush();
                            }
						}
						break;
					}
					
					// obtain raw action script byte codes
				
				case DMessage.InGetActions: 
					{
                        int item = msg.getWord();
                        int rsvd = msg.getWord();
                        int at = (int)msg.getDWord();
                        int len = (int)msg.getDWord();
						int i = 0;
						
						m_actions = (len <= 0)?null:new byte[len];
						while (len-- > 0)
                            m_actions[i++] = (byte)msg.getByte();
						
						break;
					}
					
					// obtain data about a SWF
				
				case DMessage.InSwfInfo: 
					{
                        int count = msg.getWord();
						for (int i = 0; i < count; i++)
						{
                            long index = msg.getDWord();
                            long id = msg.getDWord();
							
							// get it
							DSwfInfo info = getOrCreateSwfInfo((int) index);
							
							// remember which was last seen
							m_lastSwfInfo = info;
							
							if (id != 0)
							{
                                bool debugComing = (msg.getByte() == 0) ? false : true;
                                byte vmVersion = (byte)msg.getByte(); // AS vm version number (1 = avm+, 0 == avm-)
                                int rsvd1 = msg.getWord();

                                long swfSize = msg.getDWord();
                                long swdSize = msg.getDWord();
                                long scriptCount = msg.getDWord();
                                long offsetCount = msg.getDWord();
                                long breakpointCount = msg.getDWord();

                                long port = msg.getDWord();
                                String path = msg.getString();
                                String url = msg.getString();
                                String host = msg.getString();
								
								// now we read in the swd debugging map (which provides
								// local to global mappings of the script ids
                                long num = msg.getDWord();
								IntMap local2global = new IntMap();
								int minId = Int32.MaxValue;
								int maxId = Int32.MinValue;
								for (int j = 0; j < num; j++)
								{
                                    long local = msg.getDWord();
                                    long global = msg.getDWord();
									local2global.put((int) local, (Int32) global);
									minId = ((int) global < minId)?(int) global:minId;
									maxId = ((int) global > maxId)?(int) global:maxId;
								}
								
								// If its a new record then the swf size would have been unknown at creation time
								bool justCreated = (info.SwfSize == 0);
								
								// if we are a avm+ engine then we don't wait for the swd to load
								if (vmVersion > 0)
								{
									debugComing = false;
									info.VmVersion = vmVersion;
									info.setPopulated(); // added by mmorearty on 9/5/05 for RSL debugging
								}
								
								// update this swfinfo with the lastest data
								info.freshen(id, path, url, host, port, debugComing, swfSize, swdSize, breakpointCount, offsetCount, scriptCount, local2global, minId, maxId);
								// now tie any scripts that have been loaded into this swfinfo object
								tieScriptsToSwf(info);
								
								// notify if its newly created
								if (justCreated)
									addEvent(new SwfLoadedEvent(id, (int) index, path, url, host, port, swfSize));
							}
							else
							{
								// note our state before marking it
								bool alreadyUnloaded = info.isUnloaded();
								
								// clear it out
								info.setUnloaded();
								
								// notify if this information is new.
								if (!alreadyUnloaded)
									addEvent(new SwfUnloadedEvent(info.Id, info.Path, (int) index));
							}
							//					System.out.println("[SWFLOAD] Loaded "+path+", size="+swfSize+", scripts="+scriptCount);
						}
						break;
					}
					
					// obtain the constant pool of some player
				
				case DMessage.InConstantPool: 
					{
                        int item = msg.getWord();
                        int count = (int)msg.getDWord();
						
						String[] pool = new String[count];
						for (int i = 0; i < count; i++)
						{
                            long id = msg.getDWord();
							DVariable var = extractVariable(msg);
							
							// we only need the contents of the variable
							pool[i] = var.getValue().ValueAsString;
						}
						m_lastConstantPool = pool;
						break;
					}
					
					// obtain one or more function name line number mappings.
				
				case DMessage.InGetFncNames: 
				{
                    long id = msg.getDWord(); // module id
                    long count = msg.getDWord(); // number of entries
					
					// get the DModule
					DModule m = getSource((int) id);
					if (m != null)
					{
						for (int i = 0; i < count; i++)
						{
                            int offset = (int)msg.getDWord();
                            int firstLine = (int)msg.getDWord();
                            int lastLine = (int)msg.getDWord();
                            String name = msg.getString();
							
							// now add the entries
							m.addLineFunctionInfo(offset, firstLine, lastLine, name);
						}
					}
					break;
				}
				
				
				default: 
				{
					break;
				}
				
			}
		}
예제 #20
0
        public virtual void addMember(DVariable v)
		{
			if (m_members == null)
			{
				m_members = new System.Collections.Hashtable();
			}
			
			// if we are a proto member house away our original parent id
			String name = v.getName();
			DValue val = (DValue) v.getValue();
			val.m_nonProtoId = (name != null && name.Equals("__proto__"))?m_nonProtoId:val.Id; //$NON-NLS-1$ // TODO is this right?
			v.m_nonProtoParentId = m_nonProtoId;
			
			m_members[name] = v;
		}
예제 #21
0
		public DStackContext(int module, int line, DModule f, int thisId, String functionSignature, int depth)
		{
			m_source = f;
			m_module = module;
			m_line = line;
			// the passed-in 'thisId' seems to always be equal to one, which does more harm than good
			m_this = null;
			m_functionSignature = functionSignature;
			m_depth = depth;
            m_args = new LinkedHashMap(); // preserves order
            m_locals = new LinkedHashMap(); // preserves order
			m_scopeChain = new System.Collections.ArrayList();
			m_populated = false;
			m_location = new DLocation(m_source, line);
		}
예제 #22
0
		/// <summary> Returns whether a given child member should be shown, or should be filtered out.</summary>
		private bool showMember(DVariable child)
		{
			if (isTraits(child))
				return false;
			return true;
		}
예제 #23
0
		internal virtual void  addLocal(DVariable v)
		{
			m_locals[v.getName()] = v;
		}
예제 #24
0
		/// <summary> Returns whether this is not a variable at all, but is instead a representation
		/// of a "traits" object.  A "traits" object is the Flash player's way of describing
		/// one class.
		/// </summary>
		private bool isTraits(DVariable variable)
		{
			Value value = variable.getValue();
			if (value.getType() == VariableType.UNKNOWN && Value.TRAITS_TYPE_NAME.Equals(value.getTypeName()))
			{
				return true;
			}
			return false;
		}
예제 #25
0
		internal virtual void  removeAllLocals()
		{
			m_locals.Clear(); m_activationObject = null;
		}
예제 #26
0
		/// <summary> Does the job of pulling together a variable based on
		/// the type of object encountered.
		/// </summary>
		internal virtual DVariable extractAtom(DMessage msg, String name, int oType, int flags)
		{
			int vType = VariableType.UNKNOWN;
			Object value = null;
			String typeName = ""; //$NON-NLS-1$
			String className = ""; //$NON-NLS-1$
			
			/* now we vary depending upon type */
			switch (oType)
			{
				
				case DMessage.kNumberType: 
				{
                    String s = msg.getString();
					double dval = 0;
					try
					{
                        System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
                        dval = Double.Parse(s, nfi);
                    }
					catch (FormatException)
					{
					}
					
					value = (double) dval;
					vType = VariableType.NUMBER;
					typeName = "Number"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kBooleanType: 
				{
                    int bval = msg.getByte();
					value = (bval == 0)?false:true;
					vType = VariableType.BOOLEAN;
					typeName = "Boolean"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kStringType: 
				{
                    String s = msg.getString();
					
					value = s;
					vType = VariableType.STRING;
					typeName = "String"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kObjectType: 
				case DMessage.kNamespaceType: 
				{
                    long oid = msg.getDWord();
                    long cType = (oid == -1) ? 0 : msg.getDWord();
                    int isFnc = (oid == -1) ? 0 : msg.getWord();
                    int rsvd = (oid == -1) ? 0 : msg.getWord();
                    typeName = (oid == -1) ? "" : msg.getString(); //$NON-NLS-1$
					className = DVariable.classNameFor(cType, false);
					
					value = (long) oid;
					vType = (isFnc == 0)?VariableType.OBJECT:VariableType.FUNCTION;
					break;
				}
				
				
				case DMessage.kMovieClipType: 
				{
                    long oid = msg.getDWord();
                    long cType = (oid == -1) ? 0 : msg.getDWord();
                    long rsvd = (oid == -1) ? 0 : msg.getDWord();
                    typeName = (oid == -1) ? "" : msg.getString(); //$NON-NLS-1$
					className = DVariable.classNameFor(cType, true);
					
					value = (long) oid;
					vType = VariableType.MOVIECLIP;
					break;
				}
				
				
				case DMessage.kNullType: 
				{
					vType = VariableType.NULL;
					typeName = "null"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kUndefinedType: 
				{
					vType = VariableType.UNDEFINED;
					typeName = "undefined"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kTraitsType: 
				{
					// This one is special: When passed to the debugger, it indicates
					// that the "variable" is not a variable at all, but rather is a
					// class name.  For example, if class Y extends class X, then
					// we will send a kDTypeTraits for class Y; then we'll send all the
					// members of class Y; then we'll send a kDTypeTraits for class X;
					// and then we'll send all the members of class X.  This is only
					// used by the AVM+ debugger.
					vType = VariableType.UNKNOWN;
					typeName = Value.TRAITS_TYPE_NAME;
					break;
				}
				
				
				case DMessage.kReferenceType: 
				case DMessage.kArrayType: 
				case DMessage.kObjectEndType: 
				case DMessage.kStrictArrayType: 
				case DMessage.kDateType: 
				case DMessage.kLongStringType: 
				case DMessage.kUnsupportedType: 
				case DMessage.kRecordSetType: 
				case DMessage.kXMLType: 
				case DMessage.kTypedObjectType: 
				case DMessage.kAvmPlusObjectType: 
				default: 
				{
					//				System.out.println("<unknown>");
					break;
				}
				}
			
			// create the variable based on the content we received.
			DValue valueObject = null;
			if (value is Int64)
			{
				valueObject = getValue((long) ((Int64) value));
			}
			
			if (valueObject == null)
			{
				valueObject = new DValue(vType, typeName, className, toAttributes(flags), value);
				
				if (value is Int64 && (toAttributes(flags) & VariableAttribute.HAS_GETTER) == 0)
					putValue((long) ((Int64) value), valueObject);
			}
			else
			{
				valueObject.setType(vType);
				valueObject.setTypeName(typeName);
				valueObject.setClassName(className);
				valueObject.setAttributes(toAttributes(flags));
				valueObject.Value = value;
			}
			
			DVariable var = new DVariable(name, valueObject);
			return var;
		}
예제 #27
0
		} // triggers a reload of variables.
		
		/// <summary> Removes the specified variable from the list of locals, and
		/// remembers that the specified variable is the "activation object"
		/// for this frame.  See bug 155031.
		/// </summary>
		internal virtual void  convertLocalToActivationObject(DVariable v)
		{
			m_activationObject = v;
			m_locals.Remove(v.getName());
		}
예제 #28
0
		public const String SCOPE_CHAIN_MARKER = "$scopechain"; //$NON-NLS-1$
		
		public DManager()
		{
			m_parms = new System.Collections.Hashtable();
			m_source = new IntMap();
			m_breakpoints = new System.Collections.ArrayList();
			m_values = new IntMap();
			m_previousValues = new IntMap();
			m_frames = new System.Collections.ArrayList();
			m_previousFrames = new System.Collections.ArrayList();
			m_swfInfo = new System.Collections.ArrayList();
			m_watchpoints = new System.Collections.ArrayList();
			m_event = new System.Collections.ArrayList();
			m_suspendInfo = null;
			m_sourceLocator = null;
			
			m_lastInGetVariable = null;
			m_attachChildren = true;
			m_squelchEnabled = false;
			m_lastConstantPool = null;
			m_playerVersion = - 1; // -1 => unknown
		}