Skip to content

Commit b0585b5

Browse files
committed
Typed set/get variants for standard attribute templates -- SIMICS-17951
1 parent 513e89c commit b0585b5

File tree

5 files changed

+237
-26
lines changed

5 files changed

+237
-26
lines changed

RELEASENOTES-1.4.docu

+9
Original file line numberDiff line numberDiff line change
@@ -455,4 +455,13 @@
455455
(<tt>-g</tt>) that caused <tt>inline</tt> method calls to inline constant
456456
arguments even for parameters not declared <tt>inline</tt>
457457
<bug number="16019548195"/>.</add-note></build-id>
458+
<build-id value="next"><add-note>Two new overridable methods
459+
<tt>get_val() -> (<em>type</em>)</tt> and
460+
<tt>set_val(<em>type</em> val) throws</tt> have been introduced to the
461+
attribute templates <tt>bool_attr</tt>, <tt>uint64_attr</tt>,
462+
<tt>int64_attr</tt> and <tt>double_attr</tt>. These methods are used by
463+
the default implementations of <tt>get</tt> and <tt>set</tt>, and
464+
overriding them is an alternate way of specifying custom get/set logic for
465+
attributes making use of these templates <bug number="SIMICS-17951"/>.
466+
</add-note></build-id>
458467
</rn>

lib/1.2/dml12-compatibility.dml

+68-5
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,97 @@ template bool_attr is (attribute, _banned_init_val) {
2323
param val = this;
2424
// Since we are by definition backed by 1.2 builtins, get throws
2525
shared method get() -> (attr_value_t);
26+
method get() -> (attr_value_t) default {
27+
return SIM_make_attr_boolean(get_val());
28+
}
2629
shared method set(attr_value_t val) throws;
30+
method set(attr_value_t val) throws default {
31+
set_val(SIM_attr_boolean(val));
32+
}
33+
shared method get_val() -> (bool);
34+
method get_val() -> (bool) default {
35+
return this;
36+
}
37+
shared method set_val(bool val) throws;
38+
method set_val(bool val) throws default {
39+
this = val;
40+
}
2741
}
2842

2943
template uint64_attr is (attribute, _banned_init_val) {
3044
param allocate_type = "uint64";
3145
param val = this;
3246
shared method get() -> (attr_value_t);
47+
method get() -> (attr_value_t) default {
48+
return SIM_make_attr_uint64(get_val());
49+
}
3350
shared method set(attr_value_t val) throws;
51+
method set(attr_value_t val) throws default {
52+
if (!SIM_attr_is_uint64(val)) {
53+
SIM_c_attribute_error("negative integer value: %lld",
54+
cast(SIM_attr_integer(val), int64));
55+
throw;
56+
}
57+
set_val(SIM_attr_integer(val));
58+
}
59+
shared method set_val(uint64 val) throws;
60+
method set_val(uint64 val) throws default {
61+
this = val;
62+
}
63+
shared method get_val() -> (uint64);
64+
method get_val() -> (uint64) default {
65+
return this;
66+
}
3467
}
3568

3669
template int64_attr is (attribute, _banned_init_val) {
3770
param allocate_type = "int64";
3871
param val = this;
72+
// Note: 1.4 attribute returns signed int but 1.2 does not,
73+
// hence the override here is not only to make use of get_val(), but
74+
// also to always return signed
3975
shared method get() -> (attr_value_t);
40-
shared method set(attr_value_t val) throws;
41-
// 1.4 attribute returns signed int, but 1.2 does not,
42-
// hence we need to override get here to always return
43-
// signed
4476
method get() -> (attr_value_t) default {
45-
return SIM_make_attr_int64(val);
77+
return SIM_make_attr_int64(get_val());
78+
}
79+
shared method set(attr_value_t val) throws;
80+
method set(attr_value_t val) throws default {
81+
if (!SIM_attr_is_int64(val)) {
82+
SIM_c_attribute_error("integer value too large: %llu",
83+
cast(SIM_attr_integer(val), uint64));
84+
throw;
85+
}
86+
set_val(SIM_attr_integer(val));
87+
}
88+
shared method get_val() -> (int64);
89+
method get_val() -> (int64) default {
90+
return this;
91+
}
92+
shared method set_val(int64 val) throws;
93+
method set_val(int64 val) throws default {
94+
this = val;
4695
}
4796
}
4897

4998
template double_attr is (attribute, _banned_init_val) {
5099
param allocate_type = "double";
51100
param val = this;
52101
shared method get() -> (attr_value_t);
102+
method get() -> (attr_value_t) default {
103+
return SIM_make_attr_floating(get_val());
104+
}
53105
shared method set(attr_value_t val) throws;
106+
method set(attr_value_t val) throws default {
107+
set_val(SIM_attr_floating(val));
108+
}
109+
shared method get_val() -> (double);
110+
method get_val() -> (double) default {
111+
return this;
112+
}
113+
shared method set_val(double val) throws;
114+
method set_val(double val) throws default {
115+
this = val;
116+
}
54117
}
55118

56119
template pseudo_attr is attribute {

lib/1.4/dml-builtins.dml

+40-9
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,14 @@ standard types. Each store the attribute value in a member `val`,
10401040
provide default implementations of methods `get` and `set` according to the
10411041
type, and provide a default implementation of `init` that initializes
10421042
`val` using the `init_val` parameter also provided by the template (whose
1043-
default definition simply zero-initializes `val`.) These four templates are:
1043+
default definition simply zero-initializes `val`.)
1044+
The default implementations of `get` and `set` make use of corresponding
1045+
methods <tt>get_val() -> (<em>type</em>)</tt> and
1046+
<tt>set_val(<em>type</em> val) throws</tt>, which can be overridden in order to
1047+
provide custom get/set logic in a more ergonomic way compared to overriding
1048+
`get`/`set` directly.
1049+
1050+
The four templates are:
10441051

10451052
<dl><dt>
10461053

@@ -1110,10 +1117,16 @@ template bool_attr is (attribute, init) {
11101117
val = init_val;
11111118
}
11121119
shared method get() -> (attr_value_t) default {
1113-
return SIM_make_attr_boolean(val);
1120+
return SIM_make_attr_boolean(get_val());
11141121
}
11151122
shared method set(attr_value_t val) throws default {
1116-
this.val = SIM_attr_boolean(val);
1123+
set_val(SIM_attr_boolean(val));
1124+
}
1125+
shared method set_val(bool val) throws default {
1126+
this.val = val;
1127+
}
1128+
shared method get_val() -> (bool) default {
1129+
return this.val;
11171130
}
11181131
}
11191132

@@ -1126,15 +1139,21 @@ template uint64_attr is (attribute, init) {
11261139
val = init_val;
11271140
}
11281141
shared method get() -> (attr_value_t) default {
1129-
return SIM_make_attr_uint64(val);
1142+
return SIM_make_attr_uint64(get_val());
11301143
}
11311144
shared method set(attr_value_t val) throws default {
11321145
if (!SIM_attr_is_uint64(val)) {
11331146
SIM_c_attribute_error("negative integer value: %lld",
11341147
cast(SIM_attr_integer(val), int64));
11351148
throw;
11361149
}
1137-
this.val = SIM_attr_integer(val);
1150+
set_val(SIM_attr_integer(val));
1151+
}
1152+
shared method set_val(uint64 val) throws default {
1153+
this.val = val;
1154+
}
1155+
shared method get_val() -> (uint64) default {
1156+
return this.val;
11381157
}
11391158
}
11401159

@@ -1147,15 +1166,21 @@ template int64_attr is (attribute, init) {
11471166
val = init_val;
11481167
}
11491168
shared method get() -> (attr_value_t) default {
1150-
return SIM_make_attr_int64(val);
1169+
return SIM_make_attr_int64(get_val());
11511170
}
11521171
shared method set(attr_value_t val) throws default {
11531172
if (!SIM_attr_is_int64(val)) {
11541173
SIM_c_attribute_error("integer value too large: %llu",
11551174
cast(SIM_attr_integer(val), uint64));
11561175
throw;
11571176
}
1158-
this.val = SIM_attr_integer(val);
1177+
set_val(SIM_attr_integer(val));
1178+
}
1179+
shared method set_val(int64 val) throws default {
1180+
this.val = val;
1181+
}
1182+
shared method get_val() -> (int64) default {
1183+
return this.val;
11591184
}
11601185
}
11611186

@@ -1168,10 +1193,16 @@ template double_attr is (attribute, init) {
11681193
val = init_val;
11691194
}
11701195
shared method get() -> (attr_value_t) default {
1171-
return SIM_make_attr_floating(val);
1196+
return SIM_make_attr_floating(get_val());
11721197
}
11731198
shared method set(attr_value_t val) throws default {
1174-
this.val = SIM_attr_floating(val);
1199+
set_val(SIM_attr_floating(val));
1200+
}
1201+
shared method set_val(double val) throws default {
1202+
this.val = val;
1203+
}
1204+
shared method get_val() -> (double) default {
1205+
return this.val;
11751206
}
11761207
}
11771208

test/1.2/misc/dml14.dml

+63-12
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,44 @@ attribute woa is (write_only_attr) {
358358
method set(attr_value_t val) throws {}
359359
}
360360

361+
attribute ia2 is (int64_attr) {
362+
method get_val() -> (int64) {
363+
return this.val + 1;
364+
}
365+
366+
method set_val(int64 val) throws {
367+
this.val = val - 1;
368+
}
369+
}
370+
371+
attribute ua2 is (uint64_attr) {
372+
method get_val() -> (uint64) {
373+
return this.val + 1;
374+
}
375+
376+
method set_val(uint64 val) throws {
377+
this.val = val - 1;
378+
}
379+
}
380+
attribute ba2 is (bool_attr) {
381+
method get_val() -> (bool) {
382+
return !this.val;
383+
}
384+
385+
method set_val(bool val) throws {
386+
this.val = !val;
387+
}
388+
}
389+
attribute fa2 is (double_attr) {
390+
method get_val() -> (double) {
391+
return -this.val;
392+
}
393+
394+
method set_val(double val) throws {
395+
this.val = -val;
396+
}
397+
}
398+
361399
param global_sym = 14;
362400

363401
/// WARNING WEXPERIMENTAL
@@ -432,21 +470,34 @@ method len_test() {
432470
// checks that typed attribute access works
433471
method attribute_test() throws {
434472
cast(ia, int64_attr).set(SIM_make_attr_int64(-16));
435-
local attr_value_t ia_get;
436-
(ia_get) = cast(ia, int64_attr).get();
437-
assert(SIM_attr_integer(ia_get) == -16);
473+
local attr_value_t ia_get = cast(ia, int64_attr).get();
474+
assert SIM_attr_integer(ia_get) == -16;
438475
cast(ua, uint64_attr).set(SIM_make_attr_uint64(32));
439-
local attr_value_t ua_get;
440-
(ua_get) = cast(ua, uint64_attr).get();
441-
assert(SIM_attr_integer(ua_get) == 32);
476+
local attr_value_t ua_get = cast(ua, uint64_attr).get();
477+
assert SIM_attr_integer(ua_get) == 32;
442478
cast(ba, bool_attr).set(SIM_make_attr_boolean(true));
443-
local attr_value_t ba_get;
444-
(ba_get) = cast(ba, bool_attr).get();
445-
assert(SIM_attr_boolean(ba_get));
479+
local attr_value_t ba_get = cast(ba, bool_attr).get();
480+
assert SIM_attr_boolean(ba_get);
446481
cast(fa, double_attr).set(SIM_make_attr_floating(4.13));
447-
local attr_value_t fa_get;
448-
(fa_get) = cast(fa, double_attr).get();
449-
assert(SIM_attr_floating(fa_get) == 4.13);
482+
local attr_value_t fa_get = cast(fa, double_attr).get();
483+
assert SIM_attr_floating(fa_get) == 4.13;
484+
485+
cast(ia2, int64_attr).set(SIM_make_attr_int64(-16));
486+
local attr_value_t ia2_get = cast(ia2, int64_attr).get();
487+
assert SIM_attr_integer(ia2_get) == -16;
488+
assert ia2.val == -17;
489+
cast(ua2, uint64_attr).set(SIM_make_attr_uint64(32));
490+
local attr_value_t ua2_get = cast(ua2, uint64_attr).get();
491+
assert SIM_attr_integer(ua2_get) == 32;
492+
assert ua2.val == 31;
493+
cast(ba2, bool_attr).set(SIM_make_attr_boolean(true));
494+
local attr_value_t ba2_get = cast(ba2, bool_attr).get();
495+
assert SIM_attr_boolean(ba2_get);
496+
assert !ba2.val;
497+
cast(fa2, double_attr).set(SIM_make_attr_floating(4.13));
498+
local attr_value_t fa2_get = cast(fa2, double_attr).get();
499+
assert SIM_attr_floating(fa2_get) == 4.13;
500+
assert fa2.val == -4.13;
450501
}
451502

452503
method pseudo_attr_test() throws {

test/1.4/lib/T_attributes.dml

+57
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,41 @@ attribute overridden_init is (bool_attr) {
5151
method init() { }
5252
}
5353

54+
attribute b3 is (bool_attr) {
55+
method get_val() -> (bool) {
56+
return !this.val;
57+
}
58+
method set_val(bool val) throws {
59+
this.val = !val;
60+
}
61+
}
62+
63+
attribute u3 is (uint64_attr) {
64+
method get_val() -> (uint64) {
65+
return this.val + 1;
66+
}
67+
method set_val(uint64 val) throws {
68+
this.val = val - 1;
69+
}
70+
}
71+
72+
attribute i3 is (int64_attr) {
73+
method get_val() -> (int64) {
74+
return this.val + 1;
75+
}
76+
method set_val(int64 val) throws {
77+
this.val = val - 1;
78+
}
79+
}
80+
81+
attribute f3 is (double_attr) {
82+
method get_val() -> (double) {
83+
return -this.val;
84+
}
85+
method set_val(double val) throws {
86+
this.val = -val;
87+
}
88+
}
5489

5590
method test() throws {
5691
b.val = true;
@@ -94,4 +129,26 @@ method test() throws {
94129
assert i2.val == -33;
95130
assert f2.val == 3.3;
96131
assert !overridden_init.val;
132+
133+
// local attr_value_t bool_attr = SIM_make_attr_boolean(false);
134+
SIM_set_attribute(dev.obj, "b3", &bool_attr);
135+
assert b3.val;
136+
assert !SIM_attr_boolean(SIM_get_attribute(dev.obj, "b3"));
137+
138+
local attr_value_t uint_attr = SIM_make_attr_uint64(134);
139+
SIM_set_attribute(dev.obj, "u3", &uint_attr);
140+
assert u3.val == 133;
141+
assert cast(SIM_attr_integer(SIM_get_attribute(dev.obj, "u3")), uint64)
142+
== 134;
143+
144+
local attr_value_t int_attr = SIM_make_attr_int64(-134);
145+
SIM_set_attribute(dev.obj, "i3", &int_attr);
146+
assert i3.val == -135;
147+
assert SIM_attr_integer(SIM_get_attribute(dev.obj, "i3")) == -134;
148+
149+
// local attr_value_t float_attr = SIM_make_attr_floating(1.414);
150+
SIM_set_attribute(dev.obj, "f3", &float_attr);
151+
assert f3.val == -1.414;
152+
assert SIM_attr_floating(SIM_get_attribute(dev.obj, "f3"))
153+
== 1.414;
97154
}

0 commit comments

Comments
 (0)