You can look at the source code for the objects (all located in pypy/objspace/std) and find the method implementations there.
Here's append's (form pypy/objspace/std/listobject.py): def append(self, w_item): """L.append(object) -- append object to end""" self.strategy.append(self, w_item) So it's just appending to an RPython list. If you want to see the source for that, look in rpython/rtyper. append's is in rpython/rtyper/rlist.py: def rtype_method_append(self, hop): v_lst, v_value = hop.inputargs(self, self.item_repr) hop.exception_cannot_occur() hop.gendirectcall(ll_append, v_lst, v_value) This ends up calling ll_append in the end (I think the other stuff is for the JIT?), which is defined in the same file: def ll_append(l, newitem): length = l.ll_length() l._ll_resize_ge(length+1) # see "a note about overflows" above l.ll_setitem_fast(length, newitem) Now, these ll_* functions are defined in the corresponding file inside rpython/rtyper/lltypesystem; in this case, it's rpython/rtyper/lltypesystem/rlist.py: self.LIST.become(GcStruct("list", ("length", Signed), ("items", Ptr(ITEMARRAY)), adtmeths = ADTIList({ "ll_newlist": ll_newlist, "ll_newlist_hint": ll_newlist_hint, "ll_newemptylist": ll_newemptylist, "ll_length": ll_length, "ll_items": ll_items, "ITEM": ITEM, "ll_getitem_fast": ll_getitem_fast, "ll_setitem_fast": ll_setitem_fast, "_ll_resize_ge": _ll_list_resize_ge, "_ll_resize_le": _ll_list_resize_le, "_ll_resize": _ll_list_resize, "_ll_resize_hint": _ll_list_resize_hint, }), hints = {'list': True}) ) It's signaling to RPython all the different methods on the low-level list representation. Here, you want ll_setitem_fast and _ll_list_resize_ge (I also copy-pasted the functions they call): @jit.look_inside_iff(lambda l, newsize, overallocate: jit.isconstant(len(l.items)) and jit.isconstant(newsize)) @signature(types.any(), types.int(), types.bool(), returns=types.none()) def _ll_list_resize_hint_really(l, newsize, overallocate): """ Ensure l.items has room for at least newsize elements. Note that l.items may change, and even if newsize is less than l.length on entry. """ # This over-allocates proportional to the list size, making room # for additional growth. The over-allocation is mild, but is # enough to give linear-time amortized behavior over a long # sequence of appends() in the presence of a poorly-performing # system malloc(). # The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... if newsize <= 0: ll_assert(newsize == 0, "negative list length") l.length = 0 l.items = _ll_new_empty_item_array(typeOf(l).TO) return elif overallocate: if newsize < 9: some = 3 else: some = 6 some += newsize >> 3 new_allocated = newsize + some else: new_allocated = newsize # new_allocated is a bit more than newsize, enough to ensure an amortized # linear complexity for e.g. repeated usage of l.append(). In case # it overflows sys.maxint, it is guaranteed negative, and the following # malloc() will fail. items = l.items newitems = malloc(typeOf(l).TO.items.TO, new_allocated) before_len = l.length if before_len: # avoids copying GC flags from the prebuilt_empty_array if before_len < newsize: p = before_len else: p = newsize rgc.ll_arraycopy(items, newitems, 0, 0, p) l.items = newitems def _ll_list_resize_ge(l, newsize): """This is called with 'newsize' larger than the current length of the list. If the list storage doesn't have enough space, then really perform a realloc(). In the common case where we already overallocated enough, then this is a very fast operation. """ cond = len(l.items) < newsize if jit.isconstant(len(l.items)) and jit.isconstant(newsize): if cond: _ll_list_resize_hint_really(l, newsize, True) else: jit.conditional_call(cond, _ll_list_resize_hint_really, l, newsize, True) l.length = newsize def ll_items(l): return l.items def ll_setitem_fast(l, index, item): ll_assert(index < l.length, "setitem out of bounds") l.ll_items()[index] = item ll_setitem_fast.oopspec = 'list.setitem(l, index, item)' On Fri, Mar 3, 2017 at 8:20 AM, Frank Wang <fra...@mit.edu> wrote: > Hi, > > I'm trying to figure out the opcodes that the "append" function calls for > arrays. When I use the dis tool, it just says that it looks up a method > "append" using the LOOKUP_METHOD opcode. Is there a tool that allows me to > disassemble built-in functions like "append", or what the best way to do > this is? > > Thanks, > Frank > > _______________________________________________ > pypy-dev mailing list > pypy-dev@python.org > https://mail.python.org/mailman/listinfo/pypy-dev > > -- Ryan (ライアン) Yoko Shimomura > ryo (supercell/EGOIST) > Hiroyuki Sawano >> everyone else http://refi64.com/
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev