Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / validator / x86 / decoder / generator / ncdecode_st.c
1 /*
2  * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 /*
8  * ncdecode_st.c - Implements nested symbol tables.
9  *
10  * Note: We use linear lists
11  */
12
13 #ifndef NACL_TRUSTED_BUT_NOT_TCB
14 #error("This file is not meant for use in the TCB")
15 #endif
16
17 #include <assert.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_st.h"
22
23 #include "native_client/src/include/nacl_macros.h"
24 #include "native_client/src/include/portability.h"
25 #include "native_client/src/shared/platform/nacl_log.h"
26 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tablegen.h"
27
28 /* To turn on debugging of instruction decoding, change value of
29  * DEBUGGING to 1.
30  */
31 #define DEBUGGING 0
32
33 #include "native_client/src/shared/utils/debugging.h"
34
35 const char* NaClStValueKindName(NaClStValueKind kind) {
36   /*
37    * See https://code.google.com/p/nativeclient/issues/detail?id=3750
38    */
39   switch (kind) {
40     case nacl_byte:
41       return "nacl_byte";
42     case nacl_text:
43       return "nacl_text";
44     case nacl_int:
45       return "nacl_int";
46     case nacl_defop:
47       return "nacl_defop";
48   }
49   return "???";  /* better not be DCE'd */
50 }
51
52 void NaClStValueAssign(
53     NaClStValue* lhs,
54     NaClStValue* rhs) {
55   memcpy(lhs, rhs, sizeof(NaClStValue));
56 }
57
58 void NaClStValuePrint(struct Gio* g, NaClStValue* value) {
59   gprintf(g, "<%s : ", NaClStValueKindName(value->kind));
60   switch (value->kind) {
61     case nacl_byte:
62       gprintf(g, "0x%02"NACL_PRIx8, value->value.byte_value);
63       break;
64     case nacl_int:
65       gprintf(g, "%d", value->value.int_value);
66       break;
67     case nacl_text:
68       gprintf(g, "'%s'", value->value.text_value);
69       break;
70     case nacl_defop:
71       gprintf(g, "<defop>");
72       break;
73     default:
74       gprintf(g, "???");
75       break;
76   }
77   gprintf(g, ">");
78 }
79
80 /* Element in the symbol table. */
81 typedef struct NaClSymbolTablePair {
82   const char* name;          /* The name of the symbol. */
83   NaClStValue value;   /* The value associated with the symbol. */
84 } NaClSymbolTablePair;
85
86 /* Simple implementation of a symbol table using an array of size capacity. */
87 typedef struct NaClSymbolTable {
88   /* The calling context defines the outer scope for processing
89    * nested scopes.
90    */
91   struct NaClSymbolTable* calling_context;
92   /* The current size of the symbol table. */
93   size_t size;
94   /* The maximum size of the symbol table. */
95   size_t capacity;
96   /* The array holding the contents of the symbol table. */
97   NaClSymbolTablePair* values;
98 } NaClSymbolTable;
99
100 NaClSymbolTable* NaClSymbolTableCreate(
101     size_t capacity,
102     NaClSymbolTable* calling_context) {
103   NaClSymbolTable* st = (NaClSymbolTable*) malloc(sizeof(NaClSymbolTable));
104   assert(NULL != st);
105   st->calling_context = calling_context;
106   st->size = 0;
107   st->capacity = capacity;
108   st->values = (NaClSymbolTablePair*)
109       calloc(capacity, sizeof(NaClSymbolTablePair));
110   assert(NULL != st->values);
111   DEBUG(NaClLog(LOG_INFO,
112                 "NaClSymbolTableCreate(%"NACL_PRIdS") = %p\n",
113                 capacity, (void*) st));
114   return st;
115 }
116
117 void NaClSymbolTableDestroy(NaClSymbolTable* st) {
118   DEBUG(NaClLog(LOG_INFO, "NaClSymbolTableDestroy(%p)\n", (void*) st));
119   free(st);
120 }
121
122 void NaClSymbolTablePut(
123     const char* name,
124     struct NaClStValue* value,
125     NaClSymbolTable* st) {
126   size_t i;
127   DEBUG(NaClLog(LOG_INFO,
128                 "NaClSymbolTablePut('%s', ", name);
129         NaClStValuePrint(NaClLogGetGio(), value);
130         gprintf(NaClLogGetGio(), ", %p)\n", (void*) st));
131   /* First see if already in the symbol table. */
132   for (i = 0; i < st->size; ++i) {
133     if (0 == strcmp(name, st->values[i].name)) {
134       NaClStValueAssign(&(st->values[i].value), value);
135       return;
136     }
137   }
138   /* If reached, not in symbol table, add. */
139   assert(st->size < st->capacity);
140   st->values[st->size].name = strdup(name);
141   assert(NULL != st->values[st->size].name);
142   NaClStValueAssign(&(st->values[st->size++].value), value);
143 }
144
145 void NaClSymbolTablePutByte(const char* name,
146                             uint8_t byte,
147                             struct NaClSymbolTable* st) {
148   NaClStValue value;
149   value.kind = nacl_byte;
150   value.value.byte_value = byte;
151   NaClSymbolTablePut(name, &value, st);
152 }
153
154 void NaClSymbolTablePutText(const char* name,
155                             const char* text,
156                             struct NaClSymbolTable* st) {
157   NaClStValue value;
158   value.kind = nacl_text;
159   value.value.text_value = text;
160   NaClSymbolTablePut(name, &value, st);
161 }
162
163 void NaClSymbolTablePutInt(const char* name,
164                            int ival,
165                            struct NaClSymbolTable* st) {
166   NaClStValue value;
167   value.kind = nacl_int;
168   value.value.int_value = ival;
169   NaClSymbolTablePut(name, &value, st);
170 }
171
172 struct NaClStValue* NaClSymbolTableGet(
173     const char* name,
174     struct NaClSymbolTable* st) {
175   size_t i;
176   NaClStValue* result;
177   DEBUG(NaClLog(LOG_INFO,
178                 "-> NaClSymbolTableGet('%s', %p):\n", name, (void*) st));
179   while (NULL != st) {
180     /* First see if already in the symbol table. */
181     for (i = 0; i < st->size; ++i) {
182       if (0 == strcmp(name, st->values[i].name)) {
183         result = &(st->values[i].value);
184         DEBUG(NaClLog(LOG_INFO, "<- NaClSymbolTableGet = ");
185               NaClStValuePrint(NaClLogGetGio(), result);
186               gprintf(NaClLogGetGio(), ")\n"));
187         return result;
188       }
189     }
190     /* If reached, not in this symbol table. Try calling context. */
191     st = st->calling_context;
192   }
193   /* If reached, not defined in any calling context. */
194   DEBUG(NaClLog(LOG_INFO, "<- NaClSymbolTableGet = NULL\n"));
195   return NULL;
196 }