1 /*
2     Ming, an SWF output library
3     Copyright (C) 2002  Opaque Industries - http://www.opaque.net/
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "assembler.h"
24 #include "compile.h"
25 #include "actiontypes.h"
26 #include "libming.h"
27 
28 
29 int len;
30 Buffer asmBuffer;
31 int nLabels;
32 
33 struct label
34 {
35 	char *name;
36 	int offset;
37 };
38 
39 struct label labels[256];
40 
41 
42 static int
findLabel(char * l)43 findLabel(char *l)
44 {
45 	int i;
46 
47 	for ( i=0; i<nLabels; ++i )
48 	{
49 		if ( strcmp(l, labels[i].name) == 0 )
50 			return i;
51 	}
52 
53 	return -1;
54 }
55 
56 
57 static void
addLabel(char * l)58 addLabel(char *l)
59 {
60 	int i = findLabel(l);
61 
62 	if ( i == -1 )
63 	{
64 		labels[nLabels].name = strdup(l);
65 		labels[nLabels].offset = len;
66 		++nLabels;
67 	}
68 	else
69 		labels[i].offset = len;
70 }
71 
72 
73 int
bufferBranchTarget(Buffer output,char * l)74 bufferBranchTarget(Buffer output, char *l)
75 {
76 	int i = findLabel(l);
77 
78 	if ( i == -1 )
79 	{
80 		i = nLabels;
81 		addLabel(l);
82 	}
83 
84 	return bufferWriteS16(output, i);
85 }
86 
87 
88 void
bufferPatchTargets(Buffer buffer)89 bufferPatchTargets(Buffer buffer)
90 {
91 	int l, i = 0;
92 	unsigned char *output = buffer->buffer;
93 
94 	while ( i < len )
95 	{
96 		if ( output[i] & 0x80 ) /* then it's a multibyte instruction */
97 		{
98 			if ( output[i] == SWFACTION_JUMP ||
99 					 output[i] == SWFACTION_IF )
100 			{
101 				int target, offset;
102 
103 				i += 3; /* plus instruction plus two-byte length */
104 
105 				target = output[i];
106 				offset = labels[target].offset - (i+2);
107 				output[i] = offset & 0xff;
108 				output[++i] = (offset>>8) & 0xff;
109 				++i;
110 			}
111 			else
112 			{
113 				++i;
114 				l = output[i];
115 				++i;
116 				l += output[i]<<8;
117 
118 				i += l+1;
119 			}
120 		}
121 		else
122 			++i;
123 	}
124 }
125 
126 
127 /*
128  * Local variables:
129  * tab-width: 2
130  * c-basic-offset: 2
131  * End:
132  */
133