]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/ktap/userspace/dump.c
Merge remote-tracking branch 'staging/staging-next'
[karo-tx-linux.git] / drivers / staging / ktap / userspace / dump.c
1 /*
2  * dump.c - save precompiled ktap chunks
3  *
4  * This file is part of ktap by Jovi Zhangwei.
5  *
6  * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
7  *
8  * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
9  *  - The part of code in this file is copied from lua initially.
10  *  - lua's MIT license is compatible with GPL.
11  *
12  * ktap is free software; you can redistribute it and/or modify it
13  * under the terms and conditions of the GNU General Public License,
14  * version 2, as published by the Free Software Foundation.
15  *
16  * ktap is distributed in the hope it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19  * more details.
20  *
21  * You should have received a copy of the GNU General Public License along with
22  * this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "../include/ktap_types.h"
31 #include "../include/ktap_opcodes.h"
32 #include "ktapc.h"
33
34
35 typedef struct {
36         ktap_writer writer;
37         void *data;
38         int strip;
39         int status;
40 } DumpState;
41
42 #define DumpMem(b, n, size, D)  DumpBlock(b, (n)*(size), D)
43 #define DumpVar(x, D)           DumpMem(&x, 1, sizeof(x), D)
44
45 static void DumpBlock(const void *b, size_t size, DumpState *D)
46 {
47         if (D->status == 0)
48                 D->status = ((D->writer))(b, size, D->data);
49 }
50
51 static void DumpChar(int y, DumpState *D)
52 {
53         char x = (char)y;
54         DumpVar(x, D);
55 }
56
57 static void DumpInt(int x, DumpState *D)
58 {
59         DumpVar(x, D);
60 }
61
62 static void DumpNumber(ktap_number x, DumpState *D)
63 {
64         DumpVar(x,D);
65 }
66
67 static void DumpVector(const void *b, int n, size_t size, DumpState *D)
68 {
69         DumpInt(n, D);
70         DumpMem(b, n, size, D);
71 }
72
73 static void DumpString(const ktap_string *s, DumpState *D)
74 {
75         if (s == NULL) {
76                 int size = 0;
77                 DumpVar(size, D);
78         } else {
79                 int size = s->tsv.len + 1;              /* include trailing '\0' */
80                 DumpVar(size, D);
81                 DumpBlock(getstr(s), size * sizeof(char), D);
82         }
83 }
84
85 #define DumpCode(f, D)   DumpVector(f->code, f->sizecode, sizeof(ktap_instruction), D)
86
87 static void DumpFunction(const ktap_proto *f, DumpState *D);
88
89 static void DumpConstants(const ktap_proto *f, DumpState *D)
90 {
91         int i, n = f->sizek;
92
93         DumpInt(n, D);
94         for (i = 0; i < n; i++) {
95                 const ktap_value* o=&f->k[i];
96                 DumpChar(ttypenv(o), D);
97                 switch (ttypenv(o)) {
98                 case KTAP_TNIL:
99                         break;
100                 case KTAP_TBOOLEAN:
101                         DumpChar(bvalue(o), D);
102                         break;
103                 case KTAP_TNUMBER:
104                         DumpNumber(nvalue(o), D);
105                         break;
106                 case KTAP_TSTRING:
107                         DumpString(rawtsvalue(o), D);
108                         break;
109                 default:
110                         printf("ktap: DumpConstants with unknown vaule type %d\n", ttypenv(o));
111                         ktap_assert(0);
112                 }
113         }
114         n = f->sizep;
115         DumpInt(n, D);
116         for (i = 0; i < n; i++)
117                 DumpFunction(f->p[i], D);
118 }
119
120 static void DumpUpvalues(const ktap_proto *f, DumpState *D)
121 {
122         int i, n = f->sizeupvalues;
123
124         DumpInt(n, D);
125         for (i = 0; i < n; i++) {
126                 DumpChar(f->upvalues[i].instack, D);
127                 DumpChar(f->upvalues[i].idx, D);
128         }
129 }
130
131 static void DumpDebug(const ktap_proto *f, DumpState *D)
132 {
133         int i,n;
134
135         DumpString((D->strip) ? NULL : f->source, D);
136         n= (D->strip) ? 0 : f->sizelineinfo;
137         DumpVector(f->lineinfo, n, sizeof(int), D);
138         n = (D->strip) ? 0 : f->sizelocvars;
139         DumpInt(n, D);
140
141         for (i = 0; i < n; i++) {
142                 DumpString(f->locvars[i].varname, D);
143                 DumpInt(f->locvars[i].startpc, D);
144                 DumpInt(f->locvars[i].endpc, D);
145         }
146         n = (D->strip) ? 0 : f->sizeupvalues;
147         DumpInt(n, D);
148         for (i = 0; i < n; i++)
149                 DumpString(f->upvalues[i].name, D);
150 }
151
152 static void DumpFunction(const ktap_proto *f, DumpState *D)
153 {
154         DumpInt(f->linedefined, D);
155         DumpInt(f->lastlinedefined, D);
156         DumpChar(f->numparams, D);
157         DumpChar(f->is_vararg, D);
158         DumpChar(f->maxstacksize, D);
159         DumpCode(f, D);
160         DumpConstants(f, D);
161         DumpUpvalues(f, D);
162         DumpDebug(f, D);
163 }
164
165 static void DumpHeader(DumpState *D)
166 {
167         u8 h[KTAPC_HEADERSIZE];
168
169         kp_header(h);
170         DumpBlock(h, KTAPC_HEADERSIZE, D);
171 }
172
173 /*
174  * dump ktap function as precompiled chunk
175  */
176 int ktapc_dump(const ktap_proto *f, ktap_writer w, void *data, int strip)
177 {
178         DumpState D;
179
180         D.writer = w;
181         D.data = data;
182         D.strip = strip;
183         D.status = 0;
184         DumpHeader(&D);
185         DumpFunction(f, &D);
186         return D.status;
187 }