Skip to content

Commit 41261b9

Browse files
committed
Bugfixes, incompatibility fixes, touch-ups
1 parent 3bfb6f9 commit 41261b9

File tree

8 files changed

+136
-66
lines changed

8 files changed

+136
-66
lines changed

include/simics/dmllib.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,12 +3210,6 @@ UNUSED static void _dml_vect_set_compound_init_raii(
32103210
memcpy(tgt->elements, src, no_elements*elem_size);
32113211
}
32123212

3213-
// TODO(RAII): Just replace usages with _dml_vect_append_array?
3214-
UNUSED static inline void _dml_vect_append_compound_init_raii(
3215-
size_t elem_size, _dml_vect_t *tgt, const void *src, uint32 no_elements) {
3216-
_dml_vect_append_array(elem_size, tgt, src, no_elements);
3217-
}
3218-
32193213
// TODO(RAII): Not currently used.
32203214
#define _DML_RAII_MOVED(x) (({ \
32213215
typeof(x) *__val = &(x); \

lib/1.2/simics-api.dml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ extern uint16 CONVERT_BE16(uint16 val);
4848
extern uint32 CONVERT_BE32(uint32 val);
4949
extern uint64 CONVERT_BE64(uint64 val);
5050

51-
extern uint8 LOAD_LE8 (void *src);
52-
extern uint16 LOAD_LE16(void *src);
53-
extern uint32 LOAD_LE32(void *src);
54-
extern uint64 LOAD_LE64(void *src);
51+
extern uint8 LOAD_LE8 (const void *src);
52+
extern uint16 LOAD_LE16(const void *src);
53+
extern uint32 LOAD_LE32(const void *src);
54+
extern uint64 LOAD_LE64(const void *src);
5555

56-
extern uint8 LOAD_BE8 (void *src);
57-
extern uint16 LOAD_BE16(void *src);
58-
extern uint32 LOAD_BE32(void *src);
59-
extern uint64 LOAD_BE64(void *src);
56+
extern uint8 LOAD_BE8 (const void *src);
57+
extern uint16 LOAD_BE16(const void *src);
58+
extern uint32 LOAD_BE32(const void *src);
59+
extern uint64 LOAD_BE64(const void *src);
6060

6161
extern void STORE_LE8 (void *dst, uint8 val);
6262
extern void STORE_LE16(void *dst, uint16 val);
@@ -68,15 +68,15 @@ extern void STORE_BE16(void *dst, uint16 val);
6868
extern void STORE_BE32(void *dst, uint32 val);
6969
extern void STORE_BE64(void *dst, uint64 val);
7070

71-
extern uint8 UNALIGNED_LOAD_LE8 (void *src);
72-
extern uint16 UNALIGNED_LOAD_LE16(void *src);
73-
extern uint32 UNALIGNED_LOAD_LE32(void *src);
74-
extern uint64 UNALIGNED_LOAD_LE64(void *src);
71+
extern uint8 UNALIGNED_LOAD_LE8 (const void *src);
72+
extern uint16 UNALIGNED_LOAD_LE16(const void *src);
73+
extern uint32 UNALIGNED_LOAD_LE32(const void *src);
74+
extern uint64 UNALIGNED_LOAD_LE64(const void *src);
7575

76-
extern uint8 UNALIGNED_LOAD_BE8 (void *src);
77-
extern uint16 UNALIGNED_LOAD_BE16(void *src);
78-
extern uint32 UNALIGNED_LOAD_BE32(void *src);
79-
extern uint64 UNALIGNED_LOAD_BE64(void *src);
76+
extern uint8 UNALIGNED_LOAD_BE8 (const void *src);
77+
extern uint16 UNALIGNED_LOAD_BE16(const void *src);
78+
extern uint32 UNALIGNED_LOAD_BE32(const void *src);
79+
extern uint64 UNALIGNED_LOAD_BE64(const void *src);
8080

8181
extern void UNALIGNED_STORE_LE8 (void *dst, uint8 val);
8282
extern void UNALIGNED_STORE_LE16(void *dst, uint16 val);

lib/1.4/internal.dml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ extern uint16 CONVERT_BE16(uint16 val);
3939
extern uint32 CONVERT_BE32(uint32 val);
4040
extern uint64 CONVERT_BE64(uint64 val);
4141

42-
extern uint8 LOAD_LE8 (void *src);
43-
extern uint16 LOAD_LE16(void *src);
44-
extern uint32 LOAD_LE32(void *src);
45-
extern uint64 LOAD_LE64(void *src);
42+
extern uint8 LOAD_LE8 (const void *src);
43+
extern uint16 LOAD_LE16(const void *src);
44+
extern uint32 LOAD_LE32(const void *src);
45+
extern uint64 LOAD_LE64(const void *src);
4646

47-
extern uint8 LOAD_BE8 (void *src);
48-
extern uint16 LOAD_BE16(void *src);
49-
extern uint32 LOAD_BE32(void *src);
50-
extern uint64 LOAD_BE64(void *src);
47+
extern uint8 LOAD_BE8 (const void *src);
48+
extern uint16 LOAD_BE16(const void *src);
49+
extern uint32 LOAD_BE32(const void *src);
50+
extern uint64 LOAD_BE64(const void *src);
5151

5252
extern void STORE_LE8 (void *dst, uint8 val);
5353
extern void STORE_LE16(void *dst, uint16 val);
@@ -59,15 +59,15 @@ extern void STORE_BE16(void *dst, uint16 val);
5959
extern void STORE_BE32(void *dst, uint32 val);
6060
extern void STORE_BE64(void *dst, uint64 val);
6161

62-
extern uint8 UNALIGNED_LOAD_LE8 (void *src);
63-
extern uint16 UNALIGNED_LOAD_LE16(void *src);
64-
extern uint32 UNALIGNED_LOAD_LE32(void *src);
65-
extern uint64 UNALIGNED_LOAD_LE64(void *src);
62+
extern uint8 UNALIGNED_LOAD_LE8 (const void *src);
63+
extern uint16 UNALIGNED_LOAD_LE16(const void *src);
64+
extern uint32 UNALIGNED_LOAD_LE32(const void *src);
65+
extern uint64 UNALIGNED_LOAD_LE64(const void *src);
6666

67-
extern uint8 UNALIGNED_LOAD_BE8 (void *src);
68-
extern uint16 UNALIGNED_LOAD_BE16(void *src);
69-
extern uint32 UNALIGNED_LOAD_BE32(void *src);
70-
extern uint64 UNALIGNED_LOAD_BE64(void *src);
67+
extern uint8 UNALIGNED_LOAD_BE8 (const void *src);
68+
extern uint16 UNALIGNED_LOAD_BE16(const void *src);
69+
extern uint32 UNALIGNED_LOAD_BE32(const void *src);
70+
extern uint64 UNALIGNED_LOAD_BE64(const void *src);
7171

7272
extern void UNALIGNED_STORE_LE8 (void *dst, uint8 val);
7373
extern void UNALIGNED_STORE_LE16(void *dst, uint16 val);

py/dml/codegen.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,14 +2895,28 @@ def stmt_assignop(stmt, location, scope):
28952895
if ttype.is_raii:
28962896
tmp_ret_sym.init = get_initializer(site, ttype, None, location, scope)
28972897

2898+
# TODO(RAII): Not ideal... 'p += m();' where m is a throwing method
2899+
# returning an integer and p is a pointer will fail.
28982900
method_invocation = try_codegen_invocation(
28992901
site, [src_ast], [mkLocalVariable(tgt.site, tmp_ret_sym)], location,
29002902
scope)
29012903
if method_invocation:
29022904
src = OrphanWrap(site, mkLocalVariable(tmp_ret_sym.site, tmp_ret_sym))
29032905
else:
2904-
src = (eval_initializer(site, ttype, src_ast, location, scope, False)
2905-
.as_expr(ttype))
2906+
# Only use eval_initializer if we have to. This is because the RHS
2907+
# of a binary operator need not be compatible with the LHS, such as
2908+
# 'p += 4', where 'p' is a pointer.
2909+
# HACK/TODO(RAII): scalar initializers may receive special treatment
2910+
# by eval_initializer. Currently, that only applies to string literals,
2911+
# which are valid initializers for TString. This one case gets handled
2912+
# by mkStringAppend. However, one could imagine additional cases, with
2913+
# which one may use a binary operator with, could be added in the
2914+
# future.
2915+
if src_ast.kind != 'initializer_scalar':
2916+
src = (eval_initializer(site, ttype, src_ast, location, scope,
2917+
False).as_expr(ttype))
2918+
else:
2919+
src = codegen_expression(src_ast.args[0], location, scope)
29062920

29072921
operation = None
29082922
# TODO(RAII) this is somewhat hacky.

py/dml/ctree.py

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,7 +2484,7 @@ def apply(self, inits, location, scope):
24842484
class StringCStrApply(Expression):
24852485
priority = dml.expr.Apply.priority
24862486

2487-
slots = ('type', 'constant', 'value')
2487+
slots = ('type',)
24882488

24892489
@auto_init
24902490
def __init__(self, site, expr):
@@ -2493,16 +2493,21 @@ def __init__(self, site, expr):
24932493
TNamed('char',
24942494
const=(not expr.writable
24952495
or safe_realtype_shallow(expr.ctype()).const)))
2496-
self.constant = expr.constant
2497-
self.value = expr.value if expr.constant else None
24982496

24992497
def __str__(self):
25002498
return str_expr_pseudomethod(self.expr, 'c_str()')
25012499

25022500
def read(self):
25032501
return f'_dml_string_str({self.expr.read()})'
25042502

2503+
@property
2504+
def is_pointer_to_stack_allocation(self):
2505+
return self.expr.is_stack_allocated
2506+
25052507
def mkStringCStrApply(site, expr):
2508+
if expr.constant and isinstance(expr, FromCString):
2509+
return mkStringConstant(site, expr.value)
2510+
25062511
if expr.orphan:
25072512
expr = mkAdoptedOrphan(expr.site, expr)
25082513
return StringCStrApply(site, expr)
@@ -2807,7 +2812,7 @@ def make_simple(cls, site, rh):
28072812

28082813
@property
28092814
def is_pointer_to_stack_allocation(self):
2810-
return self.rh.writable and self.rh.is_stack_allocated
2815+
return self.rh.is_stack_allocated
28112816

28122817
def mkAddressOf(site, rh):
28132818
if dml.globals.compat_dml12_int(site):
@@ -4612,11 +4617,14 @@ class StructMember(Expression):
46124617
priority = 160
46134618
explicit_type = True
46144619

4620+
slots = ('orphan',)
4621+
46154622
@auto_init
46164623
def __init__(self, site, expr, sub, type, op):
46174624
assert not expr.writable or expr.c_lval
46184625
assert_type(site, expr, Expression)
46194626
assert_type(site, sub, str)
4627+
self.orphan = expr.orphan and op == '.'
46204628

46214629
@property
46224630
def writable(self):
@@ -4643,7 +4651,9 @@ def read(self):
46434651

46444652
@property
46454653
def is_stack_allocated(self):
4646-
return self.expr.writable and self.expr.is_stack_allocated
4654+
return (self.expr.is_stack_allocated
4655+
if self.op == '.' else
4656+
self.expr.is_pointer_to_stack_allocation)
46474657

46484658
@property
46494659
def is_pointer_to_stack_allocation(self):
@@ -4697,7 +4707,12 @@ def structmember_expr(): return mkAdoptedOrphan(expr.site, expr)
46974707
typ = real_basetype.get_member_qualified(sub)
46984708
if not typ:
46994709
raise EMEMBER(site, baseexpr, sub)
4700-
return StructMember(site, structmember_expr(), sub, typ, op)
4710+
subref = StructMember(site, structmember_expr(), sub, typ, op)
4711+
return (AdoptedOrphan(site, subref)
4712+
if (subref.orphan
4713+
and isinstance(safe_realtype_shallow(typ), TArray))
4714+
else subref)
4715+
47014716
elif real_basetype.is_int and real_basetype.is_bitfields:
47024717
member = real_basetype.members.get(sub)
47034718
if member is None:
@@ -4844,7 +4859,9 @@ class ArrayRef(LValue):
48444859
@auto_init
48454860
def __init__(self, site, expr, idx):
48464861
expr_type = realtype_shallow(expr.ctype())
4847-
self.type = conv_const(expr_type.const, expr_type.base)
4862+
self.type = conv_const(expr_type.const
4863+
and isinstance(expr_type, TArray),
4864+
expr_type.base)
48484865
def __str__(self):
48494866
return '%s[%s]' % (self.expr, self.idx)
48504867
def read(self):
@@ -4893,6 +4910,8 @@ def mkStringCharRef(site, expr, idx):
48934910
# Not considered addressable, as the address of an elem is very easily
48944911
# invalidated.
48954912
# Users have to use .c_buf() instead to acknowledge that possibility.
4913+
# TODO(RAII): users may shoot themselves in the foot anyway, if the basetype
4914+
# is an array or a struct with array member. What do we do about that?
48964915
class VectorRef(Expression):
48974916
slots = ('type',)
48984917
priority = dml.expr.Apply.priority
@@ -4901,6 +4920,7 @@ class VectorRef(Expression):
49014920

49024921
@auto_init
49034922
def __init__(self, site, expr, idx):
4923+
assert not expr.orphan
49044924
typ = safe_realtype_shallow(self.expr.ctype())
49054925
self.type = conv_const(typ.const, typ.base)
49064926

@@ -4914,6 +4934,15 @@ def read(self):
49144934
% (base_typ.declaration(''), self.expr.read(),
49154935
self.idx.read()))
49164936

4937+
@property
4938+
def is_stack_allocated(self):
4939+
return self.expr.is_stack_allocated
4940+
4941+
@property
4942+
def is_pointer_to_stack_allocation(self):
4943+
return (isinstance(safe_realtype_shallow(self.type), TArray)
4944+
and self.is_stack_allocated)
4945+
49174946
def mkVectorRef(site, expr, idx):
49184947
if idx.constant and idx.value < 0:
49194948
raise EOOB(expr)
@@ -5029,6 +5058,8 @@ def mkCast(site, expr, new_type):
50295058
# these casts are permitted by C only if old and new are
50305059
# the same type, which is useless
50315060
return Cast(site, expr, new_type)
5061+
if isinstance(real, (TVoid, TArray, TFunction)):
5062+
raise ECAST(site, expr, new_type)
50325063
if old_type.cmp(real) == 0:
50335064
if (old_type.is_int
50345065
and not old_type.is_endian
@@ -5041,7 +5072,7 @@ def mkCast(site, expr, new_type):
50415072
raise ECAST(site, expr, new_type)
50425073
if isinstance(real, TExternStruct):
50435074
raise ECAST(site, expr, new_type)
5044-
if isinstance(real, (TVoid, TArray, TVector, TTraitList, TFunction)):
5075+
if isinstance(real, (TVector, TTraitList)):
50455076
raise ECAST(site, expr, new_type)
50465077
if isinstance(old_type, (TVoid, TStruct, TVector, TTraitList, TTrait)):
50475078
raise ECAST(site, expr, new_type)
@@ -5599,20 +5630,27 @@ def read(self):
55995630
return f'(({self.type.declaration("")}){self.init.read()})'
56005631

56015632
class ArrayCompoundLiteral(Expression):
5602-
slots = ('read_adopted',)
5633+
slots = ('read_adopted', 'is_stack_allocated')
56035634
# TODO(RAII) writable?
56045635
addressable = True
56055636
c_lval = True
56065637
@auto_init
56075638
def __init__(self, site, init, type):
56085639
assert isinstance(init, (CompoundInitializer, MemsetInitializer))
5640+
self.is_stack_allocated = isinstance(TopRAIIScope.active,
5641+
MethodRAIIScope)
56095642
self.read_adopted = RAIIScope.reserve_orphan_adoption(
56105643
site, CompoundLiteral(site, init, type))
5644+
56115645
def __str__(self):
56125646
return 'cast(%s, %s)' % (self.init, self.type)
56135647
def read(self):
56145648
return self.read_adopted()
56155649

5650+
@property
5651+
def is_pointer_to_stack_allocation(self):
5652+
return self.is_stack_allocated
5653+
56165654
class VectorCompoundLiteral(Orphan):
56175655
'''Initializer for a variable of vector type, using the
56185656
{value1, value2, ...} syntax as in C'''
@@ -5670,14 +5708,14 @@ def discard(self):
56705708

56715709
class AdoptedOrphan(Expression):
56725710
priority = dml.expr.Apply.priority
5673-
slots = ('read_adopted', 'constant', 'value')
5711+
slots = ('read_adopted', 'is_stack_allocated')
56745712
c_lval = True
56755713
@auto_init
56765714
def __init__(self, site, expr):
56775715
assert expr.orphan
5716+
self.is_stack_allocated = isinstance(TopRAIIScope.active,
5717+
MethodRAIIScope)
56785718
self.read_adopted = RAIIScope.reserve_orphan_adoption(site, expr)
5679-
self.constant = expr.constant
5680-
self.value = expr.value if expr.constant else None
56815719

56825720
def __str__(self):
56835721
return str(self.expr)
@@ -5947,6 +5985,13 @@ def read():
59475985
def scope_stack(self):
59485986
return [self]
59495987

5988+
# TODO(RAII): Very niche, and currently unleveraged! This is for orphans
5989+
# adopted in the constant initializers of sessions/saveds. For example...
5990+
#
5991+
# session int *p = cast({0, 1, 2, 3}, int[4]);
5992+
#
5993+
# But no expression using RAIIScope.reserve_orphan_adoption is currently
5994+
# considered constant.
59505995
class SessionRAIIScope(TopRAIIScope):
59515996
def reserve_orphan_adoption(self, site, expr, subscope):
59525997
assert subscope is self
@@ -6058,7 +6103,6 @@ def toc_stmt(self):
60586103
class StringCAppend(Statement):
60596104
@auto_init
60606105
def __init__(self, site, tgt, src):
6061-
assert not src.orphan
60626106
assert tgt.c_lval
60636107

60646108
def toc_stmt(self):
@@ -6070,8 +6114,8 @@ def mkStringAppend(site, tgt, src):
60706114
raise ERVAL(tgt, '+=')
60716115
elif deep_const(tgt.ctype()):
60726116
raise ENCONST(site)
6073-
if isinstance(src, FromCString):
6074-
return StringCAppend(site, tgt, src.expr)
6117+
if isinstance(src, StringConstant):
6118+
return StringCAppend(site, tgt, src)
60756119
return StringAppend(site, tgt, mkAdoptedOrphan(site, src))
60766120

60776121
class VectorAppend(Statement):
@@ -6177,6 +6221,11 @@ def read(self):
61776221
def ctype(self):
61786222
return TPtr(self.basetype)
61796223

6224+
@property
6225+
def is_pointer_to_stack_allocation(self):
6226+
return self.expr.is_stack_allocated
6227+
6228+
61806229
mkVectorCBuf = VectorCBufRef
61816230

61826231
class VectorPopRef(PseudoMethodRef):

0 commit comments

Comments
 (0)