source: mainline/uspace/app/sbi/src/rdata.c@ 23de644

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 23de644 was 23de644, checked in by Jiri Svoboda <jiri@…>, 16 years ago

Update SBI to rev. 174.

  • Property mode set to 100644
File size: 14.6 KB
Line 
1/*
2 * Copyright (c) 2010 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file Run-time data representation.
30 *
31 * At run time SBI represents all data as a graph of interconnected @c var
32 * nodes (variable nodes). Any piece of memory addressable by the program
33 * (i.e. all variables) are stored in var nodes. However, var nodes are also
34 * used internally to implement value items. (I.e. values in value items
35 * have exactly the same structure as program variables).
36 *
37 * Unlike byte- or word-oriented memory on a real machine, var nodes provide
38 * structured and typed storage. (This typing is dynamic, however and has
39 * nothing to do with the static type system).
40 *
41 * There are several types of var nodes, one for each primitive type,
42 * reference, delegate, array, and object. A reference var node contains
43 * a pointer to another var node. Delegate var node points to some stree
44 * declaration. Array and object var nodes refer to a collection of child
45 * nodes (fields, elements).
46 */
47
48#include <stdlib.h>
49#include <assert.h>
50#include "bigint.h"
51#include "mytypes.h"
52#include "stree.h"
53
54#include "rdata.h"
55
56static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest);
57static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest);
58static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest);
59static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest);
60static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest);
61static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest);
62static void rdata_resource_copy(rdata_resource_t *src,
63 rdata_resource_t **dest);
64
65static int rdata_array_get_dim(rdata_array_t *array);
66
67static void rdata_address_print(rdata_address_t *address);
68static void rdata_var_print(rdata_var_t *var);
69
70/** Allocate new data item.
71 *
72 * @param ic Item class.
73 * @return New item.
74 */
75rdata_item_t *rdata_item_new(item_class_t ic)
76{
77 rdata_item_t *item;
78
79 item = calloc(1, sizeof(rdata_item_t));
80 if (item == NULL) {
81 printf("Memory allocation failed.\n");
82 exit(1);
83 }
84
85 item->ic = ic;
86 return item;
87}
88
89/** Allocate new address.
90 *
91 * @return New address.
92 */
93rdata_addr_var_t *rdata_addr_var_new(void)
94{
95 rdata_addr_var_t *addr_var;
96
97 addr_var = calloc(1, sizeof(rdata_addr_var_t));
98 if (addr_var == NULL) {
99 printf("Memory allocation failed.\n");
100 exit(1);
101 }
102
103 return addr_var;
104}
105
106/** Allocate new named property address.
107 *
108 * @return New named property address.
109 */
110rdata_aprop_named_t *rdata_aprop_named_new(void)
111{
112 rdata_aprop_named_t *aprop_named;
113
114 aprop_named = calloc(1, sizeof(rdata_aprop_named_t));
115 if (aprop_named == NULL) {
116 printf("Memory allocation failed.\n");
117 exit(1);
118 }
119
120 return aprop_named;
121}
122
123/** Allocate new indexed property address.
124 *
125 * @return New indexed property address.
126 */
127rdata_aprop_indexed_t *rdata_aprop_indexed_new(void)
128{
129 rdata_aprop_indexed_t *aprop_indexed;
130
131 aprop_indexed = calloc(1, sizeof(rdata_aprop_indexed_t));
132 if (aprop_indexed == NULL) {
133 printf("Memory allocation failed.\n");
134 exit(1);
135 }
136
137 return aprop_indexed;
138}
139
140/** Allocate new property address.
141 *
142 * @param apc Property address class.
143 * @return New property address.
144 */
145rdata_addr_prop_t *rdata_addr_prop_new(aprop_class_t apc)
146{
147 rdata_addr_prop_t *addr_prop;
148
149 addr_prop = calloc(1, sizeof(rdata_addr_prop_t));
150 if (addr_prop == NULL) {
151 printf("Memory allocation failed.\n");
152 exit(1);
153 }
154
155 addr_prop->apc = apc;
156 return addr_prop;
157}
158
159/** Allocate new address.
160 *
161 * @param ac Address class.
162 * @return New address.
163 */
164rdata_address_t *rdata_address_new(address_class_t ac)
165{
166 rdata_address_t *address;
167
168 address = calloc(1, sizeof(rdata_address_t));
169 if (address == NULL) {
170 printf("Memory allocation failed.\n");
171 exit(1);
172 }
173
174 address->ac = ac;
175 return address;
176}
177
178/** Allocate new value.
179 *
180 * @return New value.
181 */
182rdata_value_t *rdata_value_new(void)
183{
184 rdata_value_t *value;
185
186 value = calloc(1, sizeof(rdata_value_t));
187 if (value == NULL) {
188 printf("Memory allocation failed.\n");
189 exit(1);
190 }
191
192 return value;
193}
194
195/** Allocate new var node.
196 *
197 * @param vc Var node class (varclass).
198 * @return New var node.
199 */
200rdata_var_t *rdata_var_new(var_class_t vc)
201{
202 rdata_var_t *var;
203
204 var = calloc(1, sizeof(rdata_var_t));
205 if (var == NULL) {
206 printf("Memory allocation failed.\n");
207 exit(1);
208 }
209
210 var->vc = vc;
211 return var;
212}
213
214/** Allocate new reference.
215 *
216 * @return New reference.
217 */
218rdata_ref_t *rdata_ref_new(void)
219{
220 rdata_ref_t *ref;
221
222 ref = calloc(1, sizeof(rdata_ref_t));
223 if (ref == NULL) {
224 printf("Memory allocation failed.\n");
225 exit(1);
226 }
227
228 return ref;
229}
230
231/** Allocate new delegate.
232 *
233 * @return New delegate.
234 */
235rdata_deleg_t *rdata_deleg_new(void)
236{
237 rdata_deleg_t *deleg;
238
239 deleg = calloc(1, sizeof(rdata_deleg_t));
240 if (deleg == NULL) {
241 printf("Memory allocation failed.\n");
242 exit(1);
243 }
244
245 return deleg;
246}
247
248/** Allocate new array.
249 *
250 * @return New array.
251 */
252rdata_array_t *rdata_array_new(int rank)
253{
254 rdata_array_t *array;
255
256 array = calloc(1, sizeof(rdata_array_t));
257 if (array == NULL) {
258 printf("Memory allocation failed.\n");
259 exit(1);
260 }
261
262 array->rank = rank;
263 array->extent = calloc(rank, sizeof(int));
264 if (array == NULL) {
265 printf("Memory allocation failed.\n");
266 exit(1);
267 }
268
269 return array;
270}
271
272/** Allocate new object.
273 *
274 * @return New object.
275 */
276rdata_object_t *rdata_object_new(void)
277{
278 rdata_object_t *object;
279
280 object = calloc(1, sizeof(rdata_object_t));
281 if (object == NULL) {
282 printf("Memory allocation failed.\n");
283 exit(1);
284 }
285
286 return object;
287}
288
289/** Allocate new integer.
290 *
291 * @return New integer.
292 */
293rdata_int_t *rdata_int_new(void)
294{
295 rdata_int_t *int_v;
296
297 int_v = calloc(1, sizeof(rdata_int_t));
298 if (int_v == NULL) {
299 printf("Memory allocation failed.\n");
300 exit(1);
301 }
302
303 return int_v;
304}
305
306/** Allocate new string.
307 *
308 * @return New string.
309 */
310rdata_string_t *rdata_string_new(void)
311{
312 rdata_string_t *string_v;
313
314 string_v = calloc(1, sizeof(rdata_string_t));
315 if (string_v == NULL) {
316 printf("Memory allocation failed.\n");
317 exit(1);
318 }
319
320 return string_v;
321}
322
323/** Allocate new resource.
324 *
325 * @return New resource.
326 */
327rdata_resource_t *rdata_resource_new(void)
328{
329 rdata_resource_t *resource_v;
330
331 resource_v = calloc(1, sizeof(rdata_resource_t));
332 if (resource_v == NULL) {
333 printf("Memory allocation failed.\n");
334 exit(1);
335 }
336
337 return resource_v;
338}
339
340/** Allocate array elements.
341 *
342 * Allocates var nodes for elements of @a array.
343 *
344 * @param array Array.
345 */
346void rdata_array_alloc_element(rdata_array_t *array)
347{
348 int dim, idx;
349
350 dim = rdata_array_get_dim(array);
351
352 array->element = calloc(dim, sizeof(rdata_var_t *));
353 if (array->element == NULL) {
354 printf("Memory allocation failed.\n");
355 exit(1);
356 }
357
358 for (idx = 0; idx < dim; ++idx) {
359 array->element[idx] = calloc(1, sizeof(rdata_var_t));
360 if (array->element[idx] == NULL) {
361 printf("Memory allocation failed.\n");
362 exit(1);
363 }
364 }
365}
366
367/** Get array dimension.
368 *
369 * Dimension is the total number of elements in an array, in other words,
370 * the product of all extents.
371 *
372 * @param array Array.
373 */
374static int rdata_array_get_dim(rdata_array_t *array)
375{
376 int didx, dim;
377
378 dim = 1;
379 for (didx = 0; didx < array->rank; ++didx)
380 dim = dim * array->extent[didx];
381
382 return dim;
383}
384
385/** Make copy of a variable.
386 *
387 * Creates a new var node that is an exact copy of an existing var node.
388 * This can be thought of as a shallow copy.
389 *
390 * @param src Source var node.
391 * @param dest Place to store pointer to new var node.
392 */
393void rdata_var_copy(rdata_var_t *src, rdata_var_t **dest)
394{
395 rdata_var_t *nvar;
396
397 nvar = rdata_var_new(src->vc);
398
399 switch (src->vc) {
400 case vc_int:
401 rdata_int_copy(src->u.int_v, &nvar->u.int_v);
402 break;
403 case vc_string:
404 rdata_string_copy(src->u.string_v, &nvar->u.string_v);
405 break;
406 case vc_ref:
407 rdata_ref_copy(src->u.ref_v, &nvar->u.ref_v);
408 break;
409 case vc_deleg:
410 rdata_deleg_copy(src->u.deleg_v, &nvar->u.deleg_v);
411 break;
412 case vc_array:
413 rdata_array_copy(src->u.array_v, &nvar->u.array_v);
414 break;
415 case vc_object:
416 rdata_object_copy(src->u.object_v, &nvar->u.object_v);
417 break;
418 case vc_resource:
419 rdata_resource_copy(src->u.resource_v, &nvar->u.resource_v);
420 break;
421 }
422
423 *dest = nvar;
424}
425
426/** Copy integer.
427 *
428 * @param src Source integer.
429 * @param dest Place to store pointer to new integer.
430 */
431static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest)
432{
433 *dest = rdata_int_new();
434 bigint_clone(&src->value, &(*dest)->value);
435}
436
437/** Copy string.
438 *
439 * @param src Source string.
440 * @param dest Place to store pointer to new string.
441 */
442static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest)
443{
444 *dest = rdata_string_new();
445 (*dest)->value = src->value;
446}
447
448/** Copy reference.
449 *
450 * @param src Source reference.
451 * @param dest Place to store pointer to new reference.
452 */
453static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest)
454{
455 *dest = rdata_ref_new();
456 (*dest)->vref = src->vref;
457}
458
459/** Copy delegate.
460 *
461 * @param src Source delegate.
462 * @param dest Place to store pointer to new delegate.
463 */
464static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
465{
466 (void) src; (void) dest;
467 printf("Unimplemented: Copy delegate.\n");
468 exit(1);
469}
470
471/** Copy array.
472 *
473 * @param src Source array.
474 * @param dest Place to store pointer to new array.
475 */
476static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
477{
478 (void) src; (void) dest;
479 printf("Unimplemented: Copy array.\n");
480 exit(1);
481}
482
483/** Copy object.
484 *
485 * @param src Source object.
486 * @param dest Place to store pointer to new object.
487 */
488static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest)
489{
490 (void) src; (void) dest;
491 printf("Unimplemented: Copy object.\n");
492 exit(1);
493}
494
495/** Copy resource.
496 *
497 * @param src Source resource.
498 * @param dest Place to store pointer to new resource.
499 */
500static void rdata_resource_copy(rdata_resource_t *src, rdata_resource_t **dest)
501{
502 *dest = rdata_resource_new();
503 (*dest)->data = src->data;
504}
505
506/** Read data from a variable.
507 *
508 * This copies data from the variable to a value item. Ideally any read access
509 * to a program variable should go through this function. (Keep in mind
510 * that although values are composed of var nodes internally, but are not
511 * variables per se. Therefore this function is not used to read from values)
512 *
513 * @param var Variable to read from (var node where it is stored).
514 * @param ritem Place to store pointer to new value item read from
515 * the variable.
516 */
517void rdata_var_read(rdata_var_t *var, rdata_item_t **ritem)
518{
519 rdata_value_t *value;
520 rdata_var_t *rvar;
521
522 /* Perform a shallow copy of @a var. */
523 rdata_var_copy(var, &rvar);
524
525 value = rdata_value_new();
526 value->var = rvar;
527 *ritem = rdata_item_new(ic_value);
528 (*ritem)->u.value = value;
529}
530
531/** Write data to a variable.
532 *
533 * This copies data to the variable from a value. Ideally any write access
534 * to a program variable should go through this function. (Keep in mind
535 * that even though values are composed of var nodes internally, but are not
536 * variables per se. Therefore this function is not used to write to values)
537 *
538 * @param var Variable to write to (var node where it is stored).
539 * @param value The value to write.
540 */
541void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
542{
543 rdata_var_t *nvar;
544
545 /* Perform a shallow copy of @c value->var. */
546 rdata_var_copy(value->var, &nvar);
547
548 /* XXX do this in a prettier way. */
549
550 var->vc = nvar->vc;
551 switch (nvar->vc) {
552 case vc_int: var->u.int_v = nvar->u.int_v; break;
553 case vc_string: var->u.string_v = nvar->u.string_v; break;
554 case vc_ref: var->u.ref_v = nvar->u.ref_v; break;
555 case vc_deleg: var->u.deleg_v = nvar->u.deleg_v; break;
556 case vc_array: var->u.array_v = nvar->u.array_v; break;
557 case vc_object: var->u.object_v = nvar->u.object_v; break;
558 case vc_resource: var->u.resource_v = nvar->u.resource_v; break;
559 }
560
561 /* XXX We should free some stuff around here. */
562}
563
564/** Print data item in human-readable form.
565 *
566 * @param item Item to print.
567 */
568void rdata_item_print(rdata_item_t *item)
569{
570 if (item == NULL) {
571 printf("none");
572 return;
573 }
574
575 switch (item->ic) {
576 case ic_address:
577 printf("address:");
578 rdata_address_print(item->u.address);
579 break;
580 case ic_value:
581 printf("value:");
582 rdata_value_print(item->u.value);
583 break;
584 }
585}
586
587/** Print address in human-readable form.
588 *
589 * Actually this displays contents of the var node that is being addressed.
590 *
591 * XXX Maybe we should really rather print the address and not the data
592 * it is pointing to?
593 *
594 * @param item Address to print.
595 */
596static void rdata_address_print(rdata_address_t *address)
597{
598 switch (address->ac) {
599 case ac_var:
600 rdata_var_print(address->u.var_a->vref);
601 break;
602 case ac_prop:
603 printf("Warning: Unimplemented: Print property address.\n");
604 break;
605 }
606}
607
608/** Print value in human-readable form.
609 *
610 * @param value Value to print.
611 */
612void rdata_value_print(rdata_value_t *value)
613{
614 rdata_var_print(value->var);
615}
616
617/** Print contents of var node in human-readable form.
618 *
619 * @param item Var node to print.
620 */
621static void rdata_var_print(rdata_var_t *var)
622{
623 switch (var->vc) {
624 case vc_int:
625 printf("int(");
626 bigint_print(&var->u.int_v->value);
627 printf(")");
628 break;
629 case vc_string:
630 printf("string(\"%s\")", var->u.string_v->value);
631 break;
632 case vc_ref:
633 printf("ref");
634 break;
635 case vc_deleg:
636 printf("deleg");
637 break;
638 case vc_object:
639 printf("object");
640 break;
641 default:
642 printf("print(%d)\n", var->vc);
643 assert(b_false);
644 }
645}
Note: See TracBrowser for help on using the repository browser.