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

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

Update SBI to rev. 184.

  • Property mode set to 100644
File size: 16.5 KB
RevLine 
[09ababb7]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
[23de644]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 */
[09ababb7]47
48#include <stdlib.h>
49#include <assert.h>
[23de644]50#include "bigint.h"
[09ababb7]51#include "mytypes.h"
[94d484a]52#include "stree.h"
[074444f]53#include "symbol.h"
[09ababb7]54
55#include "rdata.h"
56
[074444f]57static void rdata_bool_copy(rdata_bool_t *src, rdata_bool_t **dest);
58static void rdata_char_copy(rdata_char_t *src, rdata_char_t **dest);
[09ababb7]59static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest);
60static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest);
61static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest);
62static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest);
[94d484a]63static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest);
[09ababb7]64static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest);
[37f527b]65static void rdata_resource_copy(rdata_resource_t *src,
66 rdata_resource_t **dest);
[09ababb7]67
[94d484a]68static int rdata_array_get_dim(rdata_array_t *array);
69
[09ababb7]70static void rdata_address_print(rdata_address_t *address);
71static void rdata_var_print(rdata_var_t *var);
72
[23de644]73/** Allocate new data item.
74 *
75 * @param ic Item class.
76 * @return New item.
77 */
[09ababb7]78rdata_item_t *rdata_item_new(item_class_t ic)
79{
80 rdata_item_t *item;
81
82 item = calloc(1, sizeof(rdata_item_t));
83 if (item == NULL) {
84 printf("Memory allocation failed.\n");
85 exit(1);
86 }
87
88 item->ic = ic;
89 return item;
90}
91
[23de644]92/** Allocate new address.
93 *
94 * @return New address.
95 */
[d0febca]96rdata_addr_var_t *rdata_addr_var_new(void)
97{
98 rdata_addr_var_t *addr_var;
99
100 addr_var = calloc(1, sizeof(rdata_addr_var_t));
101 if (addr_var == NULL) {
102 printf("Memory allocation failed.\n");
103 exit(1);
104 }
105
106 return addr_var;
107}
108
[23de644]109/** Allocate new named property address.
110 *
111 * @return New named property address.
112 */
[d0febca]113rdata_aprop_named_t *rdata_aprop_named_new(void)
114{
115 rdata_aprop_named_t *aprop_named;
116
117 aprop_named = calloc(1, sizeof(rdata_aprop_named_t));
118 if (aprop_named == NULL) {
119 printf("Memory allocation failed.\n");
120 exit(1);
121 }
122
123 return aprop_named;
124}
125
[23de644]126/** Allocate new indexed property address.
127 *
128 * @return New indexed property address.
129 */
[d0febca]130rdata_aprop_indexed_t *rdata_aprop_indexed_new(void)
131{
132 rdata_aprop_indexed_t *aprop_indexed;
133
134 aprop_indexed = calloc(1, sizeof(rdata_aprop_indexed_t));
135 if (aprop_indexed == NULL) {
136 printf("Memory allocation failed.\n");
137 exit(1);
138 }
139
140 return aprop_indexed;
141}
142
[23de644]143/** Allocate new property address.
144 *
145 * @param apc Property address class.
146 * @return New property address.
147 */
[d0febca]148rdata_addr_prop_t *rdata_addr_prop_new(aprop_class_t apc)
149{
150 rdata_addr_prop_t *addr_prop;
151
152 addr_prop = calloc(1, sizeof(rdata_addr_prop_t));
153 if (addr_prop == NULL) {
154 printf("Memory allocation failed.\n");
155 exit(1);
156 }
157
158 addr_prop->apc = apc;
159 return addr_prop;
160}
161
[23de644]162/** Allocate new address.
163 *
164 * @param ac Address class.
165 * @return New address.
166 */
[d0febca]167rdata_address_t *rdata_address_new(address_class_t ac)
[09ababb7]168{
169 rdata_address_t *address;
170
171 address = calloc(1, sizeof(rdata_address_t));
172 if (address == NULL) {
173 printf("Memory allocation failed.\n");
174 exit(1);
175 }
176
[d0febca]177 address->ac = ac;
[09ababb7]178 return address;
179}
180
[23de644]181/** Allocate new value.
182 *
183 * @return New value.
184 */
[09ababb7]185rdata_value_t *rdata_value_new(void)
186{
187 rdata_value_t *value;
188
189 value = calloc(1, sizeof(rdata_value_t));
190 if (value == NULL) {
191 printf("Memory allocation failed.\n");
192 exit(1);
193 }
194
195 return value;
196}
197
[23de644]198/** Allocate new var node.
199 *
200 * @param vc Var node class (varclass).
201 * @return New var node.
202 */
[09ababb7]203rdata_var_t *rdata_var_new(var_class_t vc)
204{
205 rdata_var_t *var;
206
207 var = calloc(1, sizeof(rdata_var_t));
208 if (var == NULL) {
209 printf("Memory allocation failed.\n");
210 exit(1);
211 }
212
213 var->vc = vc;
214 return var;
215}
216
[23de644]217/** Allocate new reference.
218 *
219 * @return New reference.
220 */
[fa36f29]221rdata_ref_t *rdata_ref_new(void)
222{
223 rdata_ref_t *ref;
224
225 ref = calloc(1, sizeof(rdata_ref_t));
226 if (ref == NULL) {
227 printf("Memory allocation failed.\n");
228 exit(1);
229 }
230
231 return ref;
232}
233
[23de644]234/** Allocate new delegate.
235 *
236 * @return New delegate.
237 */
[09ababb7]238rdata_deleg_t *rdata_deleg_new(void)
239{
240 rdata_deleg_t *deleg;
241
242 deleg = calloc(1, sizeof(rdata_deleg_t));
243 if (deleg == NULL) {
244 printf("Memory allocation failed.\n");
245 exit(1);
246 }
247
248 return deleg;
249}
250
[23de644]251/** Allocate new array.
252 *
253 * @return New array.
254 */
[94d484a]255rdata_array_t *rdata_array_new(int rank)
256{
257 rdata_array_t *array;
258
259 array = calloc(1, sizeof(rdata_array_t));
260 if (array == NULL) {
261 printf("Memory allocation failed.\n");
262 exit(1);
263 }
264
265 array->rank = rank;
266 array->extent = calloc(rank, sizeof(int));
267 if (array == NULL) {
268 printf("Memory allocation failed.\n");
269 exit(1);
270 }
271
272 return array;
273}
274
[23de644]275/** Allocate new object.
276 *
277 * @return New object.
278 */
[fa36f29]279rdata_object_t *rdata_object_new(void)
280{
281 rdata_object_t *object;
282
283 object = calloc(1, sizeof(rdata_object_t));
284 if (object == NULL) {
285 printf("Memory allocation failed.\n");
286 exit(1);
287 }
288
289 return object;
290}
291
[074444f]292/** Allocate new boolean.
293 *
294 * @return New boolean.
295 */
296rdata_bool_t *rdata_bool_new(void)
297{
298 rdata_bool_t *bool_v;
299
300 bool_v = calloc(1, sizeof(rdata_bool_t));
301 if (bool_v == NULL) {
302 printf("Memory allocation failed.\n");
303 exit(1);
304 }
305
306 return bool_v;
307}
308
309/** Allocate new character.
310 *
311 * @return New character.
312 */
313rdata_char_t *rdata_char_new(void)
314{
315 rdata_char_t *char_v;
316
317 char_v = calloc(1, sizeof(rdata_char_t));
318 if (char_v == NULL) {
319 printf("Memory allocation failed.\n");
320 exit(1);
321 }
322
323 return char_v;
324}
325
[23de644]326/** Allocate new integer.
327 *
328 * @return New integer.
329 */
[09ababb7]330rdata_int_t *rdata_int_new(void)
331{
332 rdata_int_t *int_v;
333
334 int_v = calloc(1, sizeof(rdata_int_t));
335 if (int_v == NULL) {
336 printf("Memory allocation failed.\n");
337 exit(1);
338 }
339
340 return int_v;
341}
342
[23de644]343/** Allocate new string.
344 *
345 * @return New string.
346 */
[09ababb7]347rdata_string_t *rdata_string_new(void)
348{
349 rdata_string_t *string_v;
350
351 string_v = calloc(1, sizeof(rdata_string_t));
352 if (string_v == NULL) {
353 printf("Memory allocation failed.\n");
354 exit(1);
355 }
356
357 return string_v;
358}
359
[23de644]360/** Allocate new resource.
361 *
362 * @return New resource.
363 */
[37f527b]364rdata_resource_t *rdata_resource_new(void)
365{
366 rdata_resource_t *resource_v;
367
368 resource_v = calloc(1, sizeof(rdata_resource_t));
369 if (resource_v == NULL) {
370 printf("Memory allocation failed.\n");
371 exit(1);
372 }
373
374 return resource_v;
375}
376
[23de644]377/** Allocate array elements.
378 *
379 * Allocates var nodes for elements of @a array.
380 *
381 * @param array Array.
382 */
[94d484a]383void rdata_array_alloc_element(rdata_array_t *array)
384{
385 int dim, idx;
386
387 dim = rdata_array_get_dim(array);
388
389 array->element = calloc(dim, sizeof(rdata_var_t *));
390 if (array->element == NULL) {
391 printf("Memory allocation failed.\n");
392 exit(1);
393 }
394
395 for (idx = 0; idx < dim; ++idx) {
396 array->element[idx] = calloc(1, sizeof(rdata_var_t));
397 if (array->element[idx] == NULL) {
398 printf("Memory allocation failed.\n");
399 exit(1);
400 }
401 }
402}
403
404/** Get array dimension.
405 *
406 * Dimension is the total number of elements in an array, in other words,
407 * the product of all extents.
[23de644]408 *
409 * @param array Array.
[94d484a]410 */
411static int rdata_array_get_dim(rdata_array_t *array)
412{
413 int didx, dim;
414
415 dim = 1;
416 for (didx = 0; didx < array->rank; ++didx)
417 dim = dim * array->extent[didx];
418
419 return dim;
420}
421
[23de644]422/** Make copy of a variable.
423 *
424 * Creates a new var node that is an exact copy of an existing var node.
425 * This can be thought of as a shallow copy.
426 *
427 * @param src Source var node.
428 * @param dest Place to store pointer to new var node.
429 */
[09ababb7]430void rdata_var_copy(rdata_var_t *src, rdata_var_t **dest)
431{
432 rdata_var_t *nvar;
433
434 nvar = rdata_var_new(src->vc);
435
436 switch (src->vc) {
[074444f]437 case vc_bool:
438 rdata_bool_copy(src->u.bool_v, &nvar->u.bool_v);
439 break;
440 case vc_char:
441 rdata_char_copy(src->u.char_v, &nvar->u.char_v);
442 break;
[09ababb7]443 case vc_int:
444 rdata_int_copy(src->u.int_v, &nvar->u.int_v);
445 break;
446 case vc_string:
447 rdata_string_copy(src->u.string_v, &nvar->u.string_v);
448 break;
449 case vc_ref:
450 rdata_ref_copy(src->u.ref_v, &nvar->u.ref_v);
451 break;
452 case vc_deleg:
453 rdata_deleg_copy(src->u.deleg_v, &nvar->u.deleg_v);
454 break;
[94d484a]455 case vc_array:
456 rdata_array_copy(src->u.array_v, &nvar->u.array_v);
457 break;
[09ababb7]458 case vc_object:
459 rdata_object_copy(src->u.object_v, &nvar->u.object_v);
460 break;
[37f527b]461 case vc_resource:
462 rdata_resource_copy(src->u.resource_v, &nvar->u.resource_v);
463 break;
[09ababb7]464 }
465
466 *dest = nvar;
467}
468
[074444f]469/** Copy boolean.
470 *
471 * @param src Source boolean.
472 * @param dest Place to store pointer to new boolean.
473 */
474static void rdata_bool_copy(rdata_bool_t *src, rdata_bool_t **dest)
475{
476 *dest = rdata_bool_new();
477 (*dest)->value = src->value;
478}
479
480/** Copy character.
481 *
482 * @param src Source character.
483 * @param dest Place to store pointer to new character.
484 */
485static void rdata_char_copy(rdata_char_t *src, rdata_char_t **dest)
486{
487 *dest = rdata_char_new();
488 bigint_clone(&src->value, &(*dest)->value);
489}
490
[23de644]491/** Copy integer.
492 *
493 * @param src Source integer.
494 * @param dest Place to store pointer to new integer.
495 */
[09ababb7]496static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest)
497{
498 *dest = rdata_int_new();
[23de644]499 bigint_clone(&src->value, &(*dest)->value);
[09ababb7]500}
501
[23de644]502/** Copy string.
503 *
504 * @param src Source string.
505 * @param dest Place to store pointer to new string.
506 */
[09ababb7]507static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest)
508{
509 *dest = rdata_string_new();
510 (*dest)->value = src->value;
511}
512
[23de644]513/** Copy reference.
514 *
515 * @param src Source reference.
516 * @param dest Place to store pointer to new reference.
517 */
[09ababb7]518static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest)
519{
[fa36f29]520 *dest = rdata_ref_new();
521 (*dest)->vref = src->vref;
[09ababb7]522}
523
[23de644]524/** Copy delegate.
525 *
526 * @param src Source delegate.
527 * @param dest Place to store pointer to new delegate.
528 */
[09ababb7]529static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
530{
[fa36f29]531 (void) src; (void) dest;
[09ababb7]532 printf("Unimplemented: Copy delegate.\n");
533 exit(1);
534}
535
[23de644]536/** Copy array.
537 *
538 * @param src Source array.
539 * @param dest Place to store pointer to new array.
540 */
[94d484a]541static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
542{
543 (void) src; (void) dest;
544 printf("Unimplemented: Copy array.\n");
545 exit(1);
546}
547
[23de644]548/** Copy object.
549 *
550 * @param src Source object.
551 * @param dest Place to store pointer to new object.
552 */
[09ababb7]553static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest)
554{
[fa36f29]555 (void) src; (void) dest;
[09ababb7]556 printf("Unimplemented: Copy object.\n");
557 exit(1);
558}
559
[23de644]560/** Copy resource.
561 *
562 * @param src Source resource.
563 * @param dest Place to store pointer to new resource.
564 */
[37f527b]565static void rdata_resource_copy(rdata_resource_t *src, rdata_resource_t **dest)
566{
567 *dest = rdata_resource_new();
568 (*dest)->data = src->data;
569}
570
[d0febca]571/** Read data from a variable.
[fa36f29]572 *
[23de644]573 * This copies data from the variable to a value item. Ideally any read access
574 * to a program variable should go through this function. (Keep in mind
575 * that although values are composed of var nodes internally, but are not
576 * variables per se. Therefore this function is not used to read from values)
577 *
578 * @param var Variable to read from (var node where it is stored).
579 * @param ritem Place to store pointer to new value item read from
580 * the variable.
[fa36f29]581 */
[d0febca]582void rdata_var_read(rdata_var_t *var, rdata_item_t **ritem)
[fa36f29]583{
584 rdata_value_t *value;
585 rdata_var_t *rvar;
586
[d0febca]587 /* Perform a shallow copy of @a var. */
588 rdata_var_copy(var, &rvar);
[fa36f29]589
590 value = rdata_value_new();
591 value->var = rvar;
592 *ritem = rdata_item_new(ic_value);
593 (*ritem)->u.value = value;
594}
595
[94d484a]596/** Write data to a variable.
597 *
[23de644]598 * This copies data to the variable from a value. Ideally any write access
599 * to a program variable should go through this function. (Keep in mind
600 * that even though values are composed of var nodes internally, but are not
601 * variables per se. Therefore this function is not used to write to values)
602 *
603 * @param var Variable to write to (var node where it is stored).
604 * @param value The value to write.
[94d484a]605 */
606void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
[fa36f29]607{
608 rdata_var_t *nvar;
609
610 /* Perform a shallow copy of @c value->var. */
611 rdata_var_copy(value->var, &nvar);
612
613 /* XXX do this in a prettier way. */
614
[94d484a]615 var->vc = nvar->vc;
[fa36f29]616 switch (nvar->vc) {
[074444f]617 case vc_bool: var->u.bool_v = nvar->u.bool_v; break;
618 case vc_char: var->u.char_v = nvar->u.char_v; break;
[94d484a]619 case vc_int: var->u.int_v = nvar->u.int_v; break;
620 case vc_string: var->u.string_v = nvar->u.string_v; break;
621 case vc_ref: var->u.ref_v = nvar->u.ref_v; break;
622 case vc_deleg: var->u.deleg_v = nvar->u.deleg_v; break;
623 case vc_array: var->u.array_v = nvar->u.array_v; break;
624 case vc_object: var->u.object_v = nvar->u.object_v; break;
[37f527b]625 case vc_resource: var->u.resource_v = nvar->u.resource_v; break;
[fa36f29]626 }
627
628 /* XXX We should free some stuff around here. */
629}
630
[23de644]631/** Print data item in human-readable form.
632 *
633 * @param item Item to print.
634 */
[09ababb7]635void rdata_item_print(rdata_item_t *item)
636{
637 if (item == NULL) {
638 printf("none");
639 return;
640 }
641
642 switch (item->ic) {
643 case ic_address:
644 printf("address:");
645 rdata_address_print(item->u.address);
646 break;
647 case ic_value:
648 printf("value:");
649 rdata_value_print(item->u.value);
650 break;
651 }
652}
653
[23de644]654/** Print address in human-readable form.
655 *
656 * Actually this displays contents of the var node that is being addressed.
657 *
658 * XXX Maybe we should really rather print the address and not the data
659 * it is pointing to?
660 *
661 * @param item Address to print.
662 */
[09ababb7]663static void rdata_address_print(rdata_address_t *address)
664{
[d0febca]665 switch (address->ac) {
666 case ac_var:
667 rdata_var_print(address->u.var_a->vref);
668 break;
669 case ac_prop:
670 printf("Warning: Unimplemented: Print property address.\n");
671 break;
672 }
[09ababb7]673}
674
[23de644]675/** Print value in human-readable form.
676 *
677 * @param value Value to print.
678 */
[1ebc1a62]679void rdata_value_print(rdata_value_t *value)
[09ababb7]680{
681 rdata_var_print(value->var);
682}
683
[23de644]684/** Print contents of var node in human-readable form.
685 *
686 * @param item Var node to print.
687 */
[09ababb7]688static void rdata_var_print(rdata_var_t *var)
689{
[074444f]690 int val;
691
[09ababb7]692 switch (var->vc) {
[074444f]693 case vc_bool:
694 printf("bool(%s)", var->u.bool_v->value ? "true" : "false");
695 break;
696 case vc_char:
697 printf("char(");
698 if (bigint_get_value_int(&var->u.char_v->value, &val) == EOK)
699 printf("'%c'", val);
700 else
701 printf("???:x%x\n", (unsigned) val);
702 printf(")");
703 break;
[09ababb7]704 case vc_int:
[23de644]705 printf("int(");
706 bigint_print(&var->u.int_v->value);
707 printf(")");
[09ababb7]708 break;
[fa36f29]709 case vc_string:
710 printf("string(\"%s\")", var->u.string_v->value);
711 break;
[09ababb7]712 case vc_ref:
[074444f]713 printf("ref(");
714 rdata_var_print(var->u.ref_v->vref);
715 printf(")");
[09ababb7]716 break;
717 case vc_deleg:
[074444f]718 printf("deleg(");
719 if (var->u.deleg_v->obj != NULL) {
720 rdata_var_print(var->u.deleg_v->obj);
721 printf(",");
722 }
723 symbol_print_fqn(var->u.deleg_v->sym);
724 printf(")");
725 break;
726 case vc_array:
727 printf("array");
[09ababb7]728 break;
729 case vc_object:
730 printf("object");
731 break;
[074444f]732 case vc_resource:
733 printf("resource(%p)", var->u.resource_v->data);
734 break;
[09ababb7]735 }
736}
Note: See TracBrowser for help on using the repository browser.