| 1 |
|
|---|
| 2 | For implementing malloc:
|
|---|
| 3 |
|
|---|
| 4 | Add sizeof expression in model.
|
|---|
| 5 | Semantics: get the dynamic type and evaluate the sizeof that
|
|---|
| 6 | using some well-known formulas. Introduce a symbolic function
|
|---|
| 7 | SIZEOF that takes a dynamic type and returns an int.
|
|---|
| 8 | Add things to the path condition
|
|---|
| 9 | as a side effect, like sizes are greater than 0, or 1, or
|
|---|
| 10 | whatever.
|
|---|
| 11 |
|
|---|
| 12 | Add a MallocStatement to the model. Example
|
|---|
| 13 | (double*)malloc(&h, sizeof(double)*10).
|
|---|
| 14 | - int getMallocId();
|
|---|
| 15 | - Expression getHeapPointerExpression(); // &h
|
|---|
| 16 | - Type getStaticElementType(); // double
|
|---|
| 17 | - SymbolicType getDynamicElementType() // symbolic real
|
|---|
| 18 | - SymbolicType getDynamicObjectType(); // symbolic array of real
|
|---|
| 19 | - Expression getSizeExpression(); // sizeof(double)*10
|
|---|
| 20 | - SymbolicExpression getUndefinedObject(); // symbolic constant UNDEFINED
|
|---|
| 21 | // of type array of real
|
|---|
| 22 |
|
|---|
| 23 | During model building, count the malloc statements as they are
|
|---|
| 24 | encountered and assign each a unique ID.
|
|---|
| 25 |
|
|---|
| 26 | Complete the $heap type:
|
|---|
| 27 | For each i, you have the static CIVL type T_i and the
|
|---|
| 28 | __malloc__ function. Compute the most general symbolic
|
|---|
| 29 | type t_i by translating t_i and using incomplete types
|
|---|
| 30 | for arrays. Store t_i in the malloc call object.
|
|---|
| 31 | let $heap be the symbolic type which is the tuple type
|
|---|
| 32 |
|
|---|
| 33 | [array of array of t1,
|
|---|
| 34 | array of array of t2,
|
|---|
| 35 | array of array of t3, ...]
|
|---|
| 36 |
|
|---|
| 37 | Initial value:
|
|---|
| 38 |
|
|---|
| 39 | [array of length 0, array of length 0, ...]
|
|---|
| 40 |
|
|---|
| 41 | Semantics:
|
|---|
| 42 | to execute a malloc statement with malloc index i:
|
|---|
| 43 | let h be the result of evaluating the heap argument. *h is a tuple.
|
|---|
| 44 | (*h).i is a concrete array. Let l be its concrete length.
|
|---|
| 45 | create a new symbolic constant whose name is a function of
|
|---|
| 46 | the pid, dynamic scope id, heap variable ID, index i, and
|
|---|
| 47 | l. The type of this new symbolic constant is array of t_i
|
|---|
| 48 | of length arg/sizeof(t+i), where arg is the result of evaluating
|
|---|
| 49 | the size argument. Check that it evenly divides, and log
|
|---|
| 50 | an error if it might not. Now append this symbolic constant
|
|---|
| 51 | to the concrete array. [Really need a method in SARL to do this.]
|
|---|
| 52 | Anyway, since it is concrete, get its sequence and append on to that.
|
|---|
| 53 | Return the reference with tree:
|
|---|
| 54 | - ref to heap (h)
|
|---|
| 55 | - tuple component ref (i)
|
|---|
| 56 | - array element reference (l)
|
|---|
| 57 | - array element reference (0)
|
|---|
| 58 | which is a reference to the first element of the newly allocated
|
|---|
| 59 | array.
|
|---|
| 60 |
|
|---|
| 61 | free: sets the value in the heap array to some symbolic constant
|
|---|
| 62 | UNDEFINED of type array of t_i.
|
|---|
| 63 |
|
|---|
| 64 | Canonicalization: map
|
|---|
| 65 | Ref[h,i,l,0] -> Ref[h,i,l',0]
|
|---|
| 66 | H_p_s_v_i_l -> H_p_s_v_i_l' (symbolic constants)
|
|---|
| 67 | Perform substitution on the state
|
|---|
| 68 |
|
|---|
| 69 |
|
|---|
| 70 | ---
|
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 | Think about moving more stuff into model factory, like pointer value
|
|---|
| 74 | manipulation
|
|---|
| 75 |
|
|---|
| 76 | better printing of model
|
|---|
| 77 |
|
|---|
| 78 | better printing of states during execution
|
|---|