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