Author: Armin Rigo <ar...@tunes.org> Branch: stm Changeset: r47637:6baab137c312 Date: 2011-09-27 21:53 +0200 http://bitbucket.org/pypy/pypy/changeset/6baab137c312/
Log: stm_setfield. diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py --- a/pypy/translator/stm/funcgen.py +++ b/pypy/translator/stm/funcgen.py @@ -34,6 +34,34 @@ cdecl(funcgen.db.gettype(STRUCT), ''), structdef.c_struct_field_name(fieldname)) +def stm_setfield(funcgen, op): + STRUCT = funcgen.lltypemap(op.args[0]).TO + structdef = funcgen.db.gettypedefnode(STRUCT) + baseexpr_is_const = isinstance(op.args[0], Constant) + basename = funcgen.expr(op.args[0]) + fieldname = op.args[1].value + T = funcgen.lltypemap(op.args[2]) + fieldtypename = funcgen.db.gettype(T) + newvalue = funcgen.expr(op.args[2], special_case_void=False) + # + assert T is not lltype.Void # XXX + fieldsize = rffi.sizeof(T) + if fieldsize >= size_of_voidp: + assert 1 # xxx assert somehow that the field is aligned + assert fieldsize == size_of_voidp # XXX + expr = structdef.ptr_access_expr(basename, + fieldname, + baseexpr_is_const) + return 'stm_write_word((long*)&%s, (long)%s);' % ( + expr, newvalue) + else: + cfieldtypename = cdecl(fieldtypename, '') + return ('stm_write_partial_word(sizeof(%s), (char*)%s, ' + 'offsetof(%s, %s), (long)%s);' % ( + cfieldtypename, basename, + cdecl(funcgen.db.gettype(STRUCT), ''), + structdef.c_struct_field_name(fieldname), newvalue)) + def op_stm(funcgen, op): func = globals()[op.opname] diff --git a/pypy/translator/stm/rstm.py b/pypy/translator/stm/rstm.py --- a/pypy/translator/stm/rstm.py +++ b/pypy/translator/stm/rstm.py @@ -12,6 +12,7 @@ def stm_getfield(structptr, fieldname): + "NOT_RPYTHON" STRUCT = lltype.typeOf(structptr).TO FIELD = getattr(STRUCT, fieldname) p = lltype.direct_fieldptr(structptr, fieldname) @@ -30,6 +31,7 @@ return rffi.cast(FIELD, res) def stm_setfield(structptr, fieldname, newvalue): + "NOT_RPYTHON" STRUCT = lltype.typeOf(structptr).TO FIELD = getattr(STRUCT, fieldname) p = lltype.direct_fieldptr(structptr, fieldname) @@ -49,7 +51,7 @@ val = rffi.cast(lltype.Signed, newvalue) val = val << (misalignment * 8) word = _rffi_stm.stm_read_word(p) - mask = (1 << (misalignment * 8)) * ((1 << (fieldsize * 8)) - 1) + mask = ((1 << (fieldsize * 8)) - 1) << (misalignment * 8) val = (val & mask) | (word & ~mask) #print 'getting %x, mask=%x, replacing with %x' % (word, mask, val) _rffi_stm.stm_write_word(p, val) diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c --- a/pypy/translator/stm/src_stm/et.c +++ b/pypy/translator/stm/src_stm/et.c @@ -750,3 +750,15 @@ { tx_abort(7); /* manual abort */ } + +// XXX little-endian only! +void stm_write_partial_word(int fieldsize, char *base, long offset, long nval) +{ + long *p = (long*)(base + (offset & ~(sizeof(void*)-1))); + int misalignment = offset & (sizeof(void*)-1); + long val = nval << (misalignment * 8); + long word = stm_read_word(p); + long mask = ((1 << (fieldsize * 8)) - 1) << (misalignment * 8); + val = (val & mask) | (word & ~mask); + stm_write_word(p, val); +} diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h --- a/pypy/translator/stm/src_stm/et.h +++ b/pypy/translator/stm/src_stm/et.h @@ -33,5 +33,7 @@ (long*)(((char*)(base)) + ((offset) & ~(sizeof(void*)-1)))) \ >> (8 * ((offset) & (sizeof(void*)-1)))) +void stm_write_partial_word(int fieldsize, char *base, long offset, long nval); + #endif /* _ET_H */ _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit