Skip to content

Commit 2c5c83e

Browse files
committed
Merge pull request #252 from pixie-lang/specialize-deftype-fields
Specialize deftype fields
2 parents d00f1c4 + 0f2f45d commit 2c5c83e

File tree

1 file changed

+66
-5
lines changed

1 file changed

+66
-5
lines changed

pixie/vm/custom_types.py

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import rpython.rlib.jit as jit
33
from rpython.rlib.rarithmetic import r_uint
44
from pixie.vm.code import as_var
5+
from pixie.vm.numbers import Integer, Float
56
from pixie.vm.keyword import Keyword
67
import pixie.vm.rt as rt
78

@@ -46,12 +47,15 @@ def type(self):
4647
return self._custom_type
4748

4849
def set_field(self, name, val):
49-
self._custom_type.set_mutable(name)
5050
idx = self._custom_type.get_slot_idx(name)
5151
if idx == -1:
5252
runtime_error(u"Invalid field named " + rt.name(rt.str(name)) + u" on type " + rt.name(rt.str(self.type())))
5353

54-
self._fields[idx] = val
54+
old_val = self._fields[idx]
55+
if isinstance(old_val, AbstractMutableCell):
56+
old_val.set_mutable_cell_value(self._custom_type, self._fields, name, idx, val)
57+
else:
58+
self._fields[idx] = val
5559
return self
5660

5761
@jit.elidable_promote()
@@ -65,9 +69,14 @@ def get_field(self, name):
6569
runtime_error(u"Invalid field named " + rt.name(rt.str(name)) + u" on type " + rt.name(rt.str(self.type())))
6670

6771
if self._custom_type.is_mutable(name):
68-
return self._fields[idx]
72+
value = self._fields[idx]
73+
else:
74+
value = self.get_field_immutable(idx)
75+
76+
if isinstance(value, AbstractMutableCell):
77+
return value.get_mutable_cell_value()
6978
else:
70-
return self.get_field_immutable(idx)
79+
return value
7180

7281
def set_field_by_idx(self, idx, val):
7382
affirm(isinstance(idx, r_uint), u"idx must be a r_uint")
@@ -98,7 +107,13 @@ def _new__args(args):
98107
affirm(cnt - 1 != tp.get_num_slots(), u"Wrong number of initializer fields to custom type")
99108
arr = [None] * cnt
100109
for x in range(cnt):
101-
arr[x] = args[x + 1]
110+
val = args[x + 1]
111+
if isinstance(val, Integer):
112+
val = IntegerMutableCell(val.int_val())
113+
elif isinstance(val, Float):
114+
val = FloatMutableCell(val.float_val())
115+
116+
arr[x] = val
102117
return CustomTypeInstance(tp, arr)
103118

104119
@as_var("set-field!")
@@ -114,3 +129,49 @@ def get_field(inst, field):
114129
affirm(isinstance(field, Keyword), u"Field must be a keyword")
115130
return inst.get_field(field)
116131

132+
133+
134+
class AbstractMutableCell(Object):
135+
_type = Type(u"pixie.stdlib.AbstractMutableCell")
136+
def type(self):
137+
return self._type
138+
139+
def set_mutable_cell_value(self, ct, fields, nm, idx, value):
140+
pass
141+
142+
def get_mutable_cell_value(self):
143+
pass
144+
145+
class IntegerMutableCell(AbstractMutableCell):
146+
def __init__(self, int_val):
147+
self._mutable_integer_val = int_val
148+
149+
def set_mutable_cell_value(self, ct, fields, nm, idx, value):
150+
if not isinstance(value, Integer):
151+
ct.set_mutable(nm)
152+
if isinstance(value, Float):
153+
fields[idx] = FloatMutableCell(value.float_val())
154+
else:
155+
fields[idx] = value
156+
else:
157+
self._mutable_integer_val = value.int_val()
158+
159+
def get_mutable_cell_value(self):
160+
return rt.wrap(self._mutable_integer_val)
161+
162+
class FloatMutableCell(AbstractMutableCell):
163+
def __init__(self, float_val):
164+
self._mutable_float_val = float_val
165+
166+
def set_mutable_cell_value(self, ct, fields, nm, idx, value):
167+
if not isinstance(value, Float):
168+
ct.set_mutable(nm)
169+
if isinstance(value, Integer):
170+
fields[idx] = IntegerMutableCell(value.int_val())
171+
else:
172+
fields[idx] = value
173+
else:
174+
self._mutable_float_val = value.float_val()
175+
176+
def get_mutable_cell_value(self):
177+
return rt.wrap(self._mutable_float_val)

0 commit comments

Comments
 (0)