1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib.debug import make_sure_not_resized
from pypy.interpreter.error import oefmt
from pypy.interpreter.baseobjspace import W_Root
from pypy.objspace.std.listobject import W_ListObject
from pypy.module._hpy_universal.apiset import API
# ~~~ HPyListBuilder ~~~
# note that ListBuilder does not necessarily need to be a W_Root: the object
# is never diretly exposed to the user, because the C HPyListBuilder type is
# basically an opaque integer. However, by making it a W_Root, we can just
# (re)use HandleManager to get this unique index.
class W_ListBuilder(W_Root):
def __init__(self, initial_size):
self.initial_size = initial_size
self.items_w = [None] * initial_size
@API.func("HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t initial_size)",
error_value=0)
def HPyListBuilder_New(space, handles, ctx, initial_size):
w_builder = W_ListBuilder(initial_size)
h = handles.new(w_builder)
return h
@API.func("void HPyListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item)")
def HPyListBuilder_Set(space, handles, ctx, builder, index, h_item):
# XXX if builder==0, there was an error inside _New. The C code just exits
# here, but there is no tests for it. Write it
w_builder = handles.deref(builder)
assert isinstance(w_builder, W_ListBuilder)
w_item = handles.deref(h_item)
w_builder.items_w[index] = w_item
@API.func("HPy HPyListBuilder_Build(HPyContext *ctx, HPyListBuilder builder)")
def HPyListBuilder_Build(space, handles, ctx, builder):
if not builder:
raise oefmt(space.w_MemoryError, "HPyListBuilder called with NULL")
w_builder = handles.deref(builder)
assert isinstance(w_builder, W_ListBuilder)
w_list = space.newlist(w_builder.items_w)
return handles.new(w_list)
@API.func("void HPyListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder)")
def HPyListBuilder_Cancel(space, handles, ctx, builder):
if not builder:
return
w_builder = handles.deref(builder)
assert isinstance(w_builder, W_ListBuilder)
for i in range(w_builder.initial_size):
w_builder.items_w[i] = None
# ~~~ HPyTupleBuilder ~~~
class W_TupleBuilder(W_Root):
def __init__(self, initial_size):
self.items_w = [None] * initial_size
make_sure_not_resized(self.items_w)
self.initial_size = initial_size
@API.func("HPyTupleBuilder HPyTupleBuilder_New(HPyContext *ctx, HPy_ssize_t initial_size)",
error_value=0)
def HPyTupleBuilder_New(space, handles, ctx, initial_size):
w_builder = W_TupleBuilder(initial_size)
h = handles.new(w_builder)
return h
@API.func("void HPyTupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item)")
def HPyTupleBuilder_Set(space, handles, ctx, builder, index, h_item):
# XXX if builder==0, there was an error inside _New. The C code just exits
# here, but there is no tests for it. Write it
w_builder = handles.deref(builder)
assert isinstance(w_builder, W_TupleBuilder)
w_item = handles.deref(h_item)
w_builder.items_w[index] = w_item
@API.func("HPy HPyTupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder)")
def HPyTupleBuilder_Build(space, handles, ctx, builder):
if not builder:
raise oefmt(space.w_MemoryError, "HPyTupleBuilder called with NULL")
w_builder = handles.deref(builder)
assert isinstance(w_builder, W_TupleBuilder)
w_tuple = space.newtuple(w_builder.items_w)
return handles.new(w_tuple)
@API.func("void HPyTupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder)")
def HPyTupleBuilder_Cancel(space, handles, ctx, builder):
if not builder:
return
w_builder = handles.deref(builder)
assert isinstance(w_builder, W_TupleBuilder)
for i in range(w_builder.initial_size):
w_builder.items_w[i] = None
|