/// <summary> This routine is called from the DSwfInfo object
		/// and is used to obtain LineRecord information 
		/// from the ActionLists
		/// 
		/// The ActionLocation record is used as a holding
		/// container for state as we traverse the lists
		/// </summary>
		internal virtual void  probeForLineRecords(ActionList list, ActionLocation where, DSwfInfo info)
		{
			int size = list.size();
			for (int i = 0; i < size; i++)
			{
				try
				{
					// set our context
					where.at = i;
					where.actions = list;
					
					// pull the action
					Action a = list.getAction(i);
					
					// then see if we need to traverse
					if ((a.code == ActionConstants.sactionDefineFunction) || (a.code == ActionConstants.sactionDefineFunction2))
					{
						where.function = (DefineFunction) a;
						probeForLineRecords(((DefineFunction) a).actionList, where, info);
						where.function = null;
					}
					else if (a.code == ActionList.sactionLineRecord)
					{
						// hit a line record, so let's do our callback
						info.processLineRecord(where, (LineRecord) a);
					}
					else if (a is DummyAction)
					{
						// our dummy container, then we drop in
						where.className = ((DummyAction) a).ClassName;
						probeForLineRecords(((DummyAction) a).ActionList, where, info);
						where.className = null;
					}
				}
				catch (Exception e)
				{
					// this is fairly bad and probably means that we have corrupt line
					// records in the swd, the exception being an ArrayIndexOutOfBoundsException. 
					// I've seen this in cases where a bad swc is built by authoring wherein a
					// script id collision occurs and thus the offset table will contain references
					// to line numbers that are non existent in one of the scripts.
					// If its another type of exception...well, hopefully the trace message will
					// help you track it down :)
					if (Trace.error)
					{
						Trace.trace("Error processing ActionList at " + where.at + " at offset " + where.actions.getOffset(where.at) + " in swf " + info.Url); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						Console.Error.Write(e.StackTrace);
                        Console.Error.Flush();
                    }
				}
			}
		}
Пример #2
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;
				}
				
			}
		}
		/// <summary> This routine is called from the DSwfInfo object
		/// and is used to obtain LineRecord information 
		/// from the ActionLists
		/// </summary>
		public virtual void  combForLineRecords(DSwfInfo info)
		{
			probeForLineRecords(MasterList, new ActionLocation(), info);
		}
Пример #4
0
		/// <summary> Walk the list of scripts and add them to our swfInfo object
		/// This method may be called when min/max are zero and the swd
		/// has not yet fully loaded in the player or it could be called
		/// before we have all the scripts.
		/// </summary>
		internal virtual void  tieScriptsToSwf(DSwfInfo info)
		{
			if (!info.hasAllSource())
			{
				int min = info.FirstSourceId;
				int max = info.LastSourceId;
				//			System.out.println("attaching scripts "+min+"-"+max+" to "+info.getUrl());
				for (int i = min; i <= max; i++)
				{
					DModule m = getSource(i);
					if (m == null)
					{
						// this is ok, it means the scripts are coming...
					}
					else
					{
						info.addSource(i, m);
					}
				}
			}
		}
Пример #5
0
		/// <summary> Obtains a SwfInfo object at the given index or if one
		/// doesn't yet exist at that location, creates a new empty
		/// one there and returns it.
		/// </summary>
		internal virtual DSwfInfo getOrCreateSwfInfo(int at)
		{
			lock (m_swfInfo.SyncRoot)
			{
				DSwfInfo i = (at > - 1 && at < SwfInfoCount)?getSwfInfo(at):null;
				if (i == null)
				{
					// are we above water
					at = (at < 0)?0:at;
					
					// fill all the gaps with null; really shouldn't be any...
					while (at > m_swfInfo.Count)
						m_swfInfo.Add(null);
					
					i = new DSwfInfo(at);
					m_swfInfo.Insert(at, i);
				}
				return i;
			}
		}
Пример #6
0
		/// <summary> Disassemble part of the swf to the output </summary>
		public static ActionLocation outputAssembly(DebugCLI cli, DSwfInfo swf, int start, int end)
		{
			// first we need to locate the action list associated with this
			// portion of the swf
			ActionLocation lStart = swf.locate(start);
			ActionLocation lEnd = (end > - 1)?swf.locate(end):swf.locateSourceLineEnd(lStart);
			
			return outputAssembly(cli, swf, lStart, lEnd);
		}
        /// <summary> This routine is called from the DSwfInfo object
        /// and is used to obtain LineRecord information
        /// from the ActionLists
        ///
        /// The ActionLocation record is used as a holding
        /// container for state as we traverse the lists
        /// </summary>
        internal virtual void  probeForLineRecords(ActionList list, ActionLocation where, DSwfInfo info)
        {
            int size = list.size();

            for (int i = 0; i < size; i++)
            {
                try
                {
                    // set our context
                    where.at      = i;
                    where.actions = list;

                    // pull the action
                    Action a = list.getAction(i);

                    // then see if we need to traverse
                    if ((a.code == ActionConstants.sactionDefineFunction) || (a.code == ActionConstants.sactionDefineFunction2))
                    {
                        where.function = (DefineFunction)a;
                        probeForLineRecords(((DefineFunction)a).actionList, where, info);
                        where.function = null;
                    }
                    else if (a.code == ActionList.sactionLineRecord)
                    {
                        // hit a line record, so let's do our callback
                        info.processLineRecord(where, (LineRecord)a);
                    }
                    else if (a is DummyAction)
                    {
                        // our dummy container, then we drop in
                        where.className = ((DummyAction)a).ClassName;
                        probeForLineRecords(((DummyAction)a).ActionList, where, info);
                        where.className = null;
                    }
                }
                catch (Exception e)
                {
                    // this is fairly bad and probably means that we have corrupt line
                    // records in the swd, the exception being an ArrayIndexOutOfBoundsException.
                    // I've seen this in cases where a bad swc is built by authoring wherein a
                    // script id collision occurs and thus the offset table will contain references
                    // to line numbers that are non existent in one of the scripts.
                    // If its another type of exception...well, hopefully the trace message will
                    // help you track it down :)
                    if (Trace.error)
                    {
                        Trace.trace("Error processing ActionList at " + where.at + " at offset " + where.actions.getOffset(where.at) + " in swf " + info.Url);                         //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        Console.Error.Write(e.StackTrace);
                        Console.Error.Flush();
                    }
                }
            }
        }
 /// <summary> This routine is called from the DSwfInfo object
 /// and is used to obtain LineRecord information
 /// from the ActionLists
 /// </summary>
 public virtual void  combForLineRecords(DSwfInfo info)
 {
     probeForLineRecords(MasterList, new ActionLocation(), info);
 }