Merge pull request #13107 from arendst/revert-13101-berry_call

Revert "Berry move introspect.vcall to call"
This commit is contained in:
s-hadinger 2021-09-11 11:30:56 +02:00 committed by GitHub
commit f598f5f79f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1843 additions and 1847 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,14 @@
static be_define_const_map_slots(m_libintrospect_map) {
{ be_const_key(members, -1), be_const_func(m_attrlist) },
{ be_const_key(set, -1), be_const_func(m_setmember) },
{ be_const_key(vcall, -1), be_const_func(m_vcall) },
{ be_const_key(get, -1), be_const_func(m_findmember) },
{ be_const_key(set, 2), be_const_func(m_setmember) },
};
static be_define_const_map(
m_libintrospect_map,
3
4
);
static be_define_const_module(

View File

@ -1,41 +1,39 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_builtin_map) {
{ be_const_key(number, 16), be_const_int(14) },
{ be_const_key(map, -1), be_const_int(12) },
{ be_const_key(classname, 22), be_const_int(4) },
{ be_const_key(bytes, 2), be_const_int(2) },
{ be_const_key(int, 12), be_const_int(8) },
{ be_const_key(module, -1), be_const_int(13) },
{ be_const_key(print, 20), be_const_int(16) },
{ be_const_key(issubclass, -1), be_const_int(10) },
{ be_const_key(assert, -1), be_const_int(1) },
{ be_const_key(list, -1), be_const_int(11) },
{ be_const_key(print, 19), be_const_int(15) },
{ be_const_key(isinstance, -1), be_const_int(8) },
{ be_const_key(classname, -1), be_const_int(3) },
{ be_const_key(module, -1), be_const_int(12) },
{ be_const_key(size, -1), be_const_int(18) },
{ be_const_key(type, 9), be_const_int(21) },
{ be_const_key(compile, -1), be_const_int(5) },
{ be_const_key(open, -1), be_const_int(14) },
{ be_const_key(real, -1), be_const_int(17) },
{ be_const_key(__iterator__, -1), be_const_int(0) },
{ be_const_key(real, -1), be_const_int(18) },
{ be_const_key(super, 21), be_const_int(21) },
{ be_const_key(isinstance, 8), be_const_int(9) },
{ be_const_key(classof, 4), be_const_int(5) },
{ be_const_key(input, -1), be_const_int(7) },
{ be_const_key(call, 19), be_const_int(3) },
{ be_const_key(compile, -1), be_const_int(6) },
{ be_const_key(open, -1), be_const_int(15) },
{ be_const_key(size, -1), be_const_int(19) },
{ be_const_key(range, -1), be_const_int(17) },
{ be_const_key(str, -1), be_const_int(20) },
{ be_const_key(type, -1), be_const_int(22) },
{ be_const_key(super, -1), be_const_int(20) },
{ be_const_key(issubclass, -1), be_const_int(9) },
{ be_const_key(classof, -1), be_const_int(4) },
{ be_const_key(map, 8), be_const_int(11) },
{ be_const_key(int, 2), be_const_int(7) },
{ be_const_key(input, 3), be_const_int(6) },
{ be_const_key(number, -1), be_const_int(13) },
{ be_const_key(list, 7), be_const_int(10) },
{ be_const_key(str, 1), be_const_int(19) },
{ be_const_key(range, -1), be_const_int(16) },
{ be_const_key(bytes, -1), be_const_int(2) },
{ be_const_key(assert, -1), be_const_int(1) },
};
static be_define_const_map(
m_builtin_map,
23
22
);
static const bvalue __vlist_array[] = {
be_const_func(l_iterator),
be_const_func(l_assert),
be_const_class(be_class_bytes),
be_const_func(l_call),
be_const_func(l_classname),
be_const_func(l_classof),
be_const_func(l_compile),
@ -60,5 +58,5 @@ static const bvalue __vlist_array[] = {
static be_define_const_vector(
m_builtin_vector,
__vlist_array,
23
22
);

View File

@ -277,55 +277,6 @@ static int l_iterator(bvm *vm)
be_return_nil(vm);
}
/* call a function with variable number of arguments */
/* first argument is a callable object (function, closure, native function, native closure) */
/* then all subsequent arguments are pushed except the last one */
/* If the last argument is a 'list', then all elements are pushed as arguments */
/* otherwise the last argument is pushed as well */
static int l_call(bvm *vm)
{
int top = be_top(vm);
if (top >= 1 && be_isfunction(vm, 1)) {
size_t arg_count = top - 1; /* we have at least 'top - 1' arguments */
/* test if last argument is a list */
if (top > 1 && be_isinstance(vm, top) && be_getmember(vm, top, ".p") && be_islist(vm, top + 1)) {
int32_t list_size = be_data_size(vm, top + 1);
if (list_size > 0) {
be_stack_require(vm, list_size + 3); /* make sure we don't overflow the stack */
for (int i = 0; i < list_size; i++) {
be_pushnil(vm);
}
be_moveto(vm, top + 1, top + 1 + list_size);
be_moveto(vm, top, top + list_size);
be_refpush(vm, -2);
be_pushiter(vm, -1);
while (be_iter_hasnext(vm, -2)) {
be_iter_next(vm, -2);
be_moveto(vm, -1, top);
top++;
be_pop(vm, 1);
}
be_pop(vm, 1); /* remove iterator */
be_refpop(vm);
}
be_pop(vm, 2);
arg_count = arg_count - 1 + list_size;
}
/* actual call */
be_call(vm, arg_count);
/* remove args */
be_pop(vm, arg_count);
/* return value */
be_return(vm);
}
be_raise(vm, "value_error", "first argument must be a function");
be_return_nil(vm);
}
static int l_str(bvm *vm)
{
if (be_top(vm)) {
@ -455,7 +406,6 @@ void be_load_baselib(bvm *vm)
be_regfunc(vm, "issubclass", l_issubclass);
be_regfunc(vm, "isinstance", l_isinstance);
be_regfunc(vm, "__iterator__", l_iterator);
be_regfunc(vm, "call", l_call);
}
#else
extern const bclass be_class_list;
@ -482,7 +432,6 @@ vartab m_builtin (scope: local) {
issubclass, func(l_issubclass)
isinstance, func(l_isinstance)
__iterator__, func(l_iterator)
call, func(l_call)
open, func(be_nfunc_open)
list, class(be_class_list)
map, class(be_class_map)

View File

@ -76,12 +76,62 @@ static int m_setmember(bvm *vm)
be_return_nil(vm);
}
/* call a function with variable number of arguments */
/* first argument is a callable object (function, closure, native function, native closure) */
/* then all subsequent arguments are pushed except the last one */
/* If the last argument is a 'list', then all elements are pushed as arguments */
/* otherwise the last argument is pushed as well */
static int m_vcall(bvm *vm)
{
int top = be_top(vm);
if (top >= 1 && be_isfunction(vm, 1)) {
size_t arg_count = top - 1; /* we have at least 'top - 1' arguments */
/* test if last argument is a list */
if (top > 1 && be_isinstance(vm, top) && be_getmember(vm, top, ".p") && be_islist(vm, top + 1)) {
int32_t list_size = be_data_size(vm, top + 1);
if (list_size > 0) {
be_stack_require(vm, list_size + 3); /* make sure we don't overflow the stack */
for (int i = 0; i < list_size; i++) {
be_pushnil(vm);
}
be_moveto(vm, top + 1, top + 1 + list_size);
be_moveto(vm, top, top + list_size);
be_refpush(vm, -2);
be_pushiter(vm, -1);
while (be_iter_hasnext(vm, -2)) {
be_iter_next(vm, -2);
be_moveto(vm, -1, top);
top++;
be_pop(vm, 1);
}
be_pop(vm, 1); /* remove iterator */
be_refpop(vm);
}
be_pop(vm, 2);
arg_count = arg_count - 1 + list_size;
}
/* actual call */
be_call(vm, arg_count);
/* remove args */
be_pop(vm, arg_count);
/* return value */
be_return(vm);
}
be_raise(vm, "value_error", "first argument must be a function");
be_return_nil(vm);
}
#if !BE_USE_PRECOMPILED_OBJECT
be_native_module_attr_table(introspect) {
be_native_module_function("members", m_attrlist),
be_native_module_function("get", m_findmember),
be_native_module_function("set", m_setmember),
be_native_module_function("vcall", m_vcall),
};
be_define_native_module(introspect, NULL);
@ -92,6 +142,7 @@ module introspect (scope: global, depend: BE_USE_INTROSPECT_MODULE) {
get, func(m_findmember)
set, func(m_setmember)
vcall, func(m_vcall)
}
@const_object_info_end */
#include "../generate/be_fixed_introspect.h"

View File

@ -1,102 +0,0 @@
#- -#
#- witness function dumping first 3 args -#
#- -#
def f(a,b,c) return [a,b,c] end
#- simple calls with fixed args -#
assert(call(f) == [nil, nil, nil])
assert(call(f, 1) == [1, nil, nil])
assert(call(f, 1, 2) == [1, 2, nil])
assert(call(f, 1, 2, 3, 4) == [1, 2, 3])
#- call with var args -#
assert(call(f, []) == [nil, nil, nil])
assert(call(f, [1]) == [1, nil, nil])
assert(call(f, [1, 2]) == [1, 2, nil])
assert(call(f, [1, 2, 3, 4]) == [1, 2, 3])
#- mixed args -#
assert(call(f, 1, []) == [1, nil, nil])
assert(call(f, 1, [2]) == [1, 2, nil])
assert(call(f, 1, [2, "foo", 4]) == [1, 2, "foo"])
#- non terminal list -#
assert(call(f, 1, [2, 3, 4], "foo") == [1, [2, 3, 4], "foo"])
#- -#
#- same tests with vararg function -#
#- -#
def g(a, *b)
if size(b) == 0 return [a, nil, nil]
elif size(b) == 1 return [a, b[0], nil]
elif size(b) > 1 return [a, b[0], b[1]]
end
end
#- simple calls with fixed args -#
assert(call(g) == [nil, nil, nil])
assert(call(g, 1) == [1, nil, nil])
assert(call(g, 1, 2) == [1, 2, nil])
assert(call(g, 1, 2, 3, 4) == [1, 2, 3])
#- call with var args -#
assert(call(g, []) == [nil, nil, nil])
assert(call(g, [1]) == [1, nil, nil])
assert(call(g, [1, 2]) == [1, 2, nil])
assert(call(g, [1, 2, 3, 4]) == [1, 2, 3])
#- mixed args -#
assert(call(g, 1, []) == [1, nil, nil])
assert(call(g, 1, [2]) == [1, 2, nil])
assert(call(g, 1, [2, "foo", 4]) == [1, 2, "foo"])
#- non terminal list -#
assert(call(g, 1, [2, 3, 4], "foo") == [1, [2, 3, 4], "foo"])
#- -#
#- test with vararg only -#
#- -#
def c(*a) return size(a) end
#- simple calls with fixed args -#
assert(call(c) == 0)
assert(call(c, 1) == 1)
assert(call(c, 1, 2) == 2)
assert(call(c, 1, 2, 3, 4) == 4)
#- call with var args -#
assert(call(c, []) == 0)
assert(call(c, [1]) == 1)
assert(call(c, [1, 2]) == 2)
assert(call(c, [1, 2, 3, 4]) == 4)
#- mixed args -#
assert(call(c, 1, []) == 1)
assert(call(c, 1, [2]) == 2)
assert(call(c, 1, [2, "foo", 4]) == 4)
#- non terminal list -#
assert(call(c, 1, [2, 3, 4], "foo") == 3)
#- -#
#- test with native function -#
#- -#
import string
assert(call(string.format, "a") == "a")
assert(call(string.format, "%i", 1) == "1")
assert(call(string.format, "%i - %i", 1, 2) == "1 - 2")
assert(call(string.format, "%i - %i", [1, 2]) == "1 - 2")
assert(call(string.format, "%i - %i", [1, 2, 3]) == "1 - 2")
assert(call(string.format, "%i - %i", 1, [1, 2, 3]) == "1 - 1")
#- -#
#- try with an insanely high number of arguments to check that we don't blow up the stack -#
#- -#
l50 = []
for i:1..50 l50.push(i) end
assert(call(g, l50) == [1, 2, 3])
assert(call(c, l50) == 50)

View File

@ -0,0 +1,96 @@
#- introspect vcall -#
import introspect
#- -#
#- witness function dumping first 3 args -#
#- -#
def f(a,b,c) return [a,b,c] end
#- simple calls with fixed args -#
assert(introspect.vcall(f) == [nil, nil, nil])
assert(introspect.vcall(f, 1) == [1, nil, nil])
assert(introspect.vcall(f, 1, 2) == [1, 2, nil])
assert(introspect.vcall(f, 1, 2, 3, 4) == [1, 2, 3])
#- call with var args -#
assert(introspect.vcall(f, []) == [nil, nil, nil])
assert(introspect.vcall(f, [1]) == [1, nil, nil])
assert(introspect.vcall(f, [1, 2]) == [1, 2, nil])
assert(introspect.vcall(f, [1, 2, 3, 4]) == [1, 2, 3])
#- mixed args -#
assert(introspect.vcall(f, 1, []) == [1, nil, nil])
assert(introspect.vcall(f, 1, [2]) == [1, 2, nil])
assert(introspect.vcall(f, 1, [2, "foo", 4]) == [1, 2, "foo"])
#- non terminal list -#
assert(introspect.vcall(f, 1, [2, 3, 4], "foo") == [1, [2, 3, 4], "foo"])
#- -#
#- same tests with vararg function -#
#- -#
def g(a, *b)
if size(b) == 0 return [a, nil, nil]
elif size(b) == 1 return [a, b[0], nil]
elif size(b) > 1 return [a, b[0], b[1]]
end
end
#- simple calls with fixed args -#
assert(introspect.vcall(g) == [nil, nil, nil])
assert(introspect.vcall(g, 1) == [1, nil, nil])
assert(introspect.vcall(g, 1, 2) == [1, 2, nil])
assert(introspect.vcall(g, 1, 2, 3, 4) == [1, 2, 3])
#- call with var args -#
assert(introspect.vcall(g, []) == [nil, nil, nil])
assert(introspect.vcall(g, [1]) == [1, nil, nil])
assert(introspect.vcall(g, [1, 2]) == [1, 2, nil])
assert(introspect.vcall(g, [1, 2, 3, 4]) == [1, 2, 3])
#- mixed args -#
assert(introspect.vcall(g, 1, []) == [1, nil, nil])
assert(introspect.vcall(g, 1, [2]) == [1, 2, nil])
assert(introspect.vcall(g, 1, [2, "foo", 4]) == [1, 2, "foo"])
#- non terminal list -#
assert(introspect.vcall(g, 1, [2, 3, 4], "foo") == [1, [2, 3, 4], "foo"])
#- -#
#- test with vararg only -#
#- -#
def c(*a) return size(a) end
#- simple calls with fixed args -#
assert(introspect.vcall(c) == 0)
assert(introspect.vcall(c, 1) == 1)
assert(introspect.vcall(c, 1, 2) == 2)
assert(introspect.vcall(c, 1, 2, 3, 4) == 4)
#- call with var args -#
assert(introspect.vcall(c, []) == 0)
assert(introspect.vcall(c, [1]) == 1)
assert(introspect.vcall(c, [1, 2]) == 2)
assert(introspect.vcall(c, [1, 2, 3, 4]) == 4)
#- mixed args -#
assert(introspect.vcall(c, 1, []) == 1)
assert(introspect.vcall(c, 1, [2]) == 2)
assert(introspect.vcall(c, 1, [2, "foo", 4]) == 4)
#- non terminal list -#
assert(introspect.vcall(c, 1, [2, 3, 4], "foo") == 3)
#- -#
#- test with native function -#
#- -#
import string
assert(introspect.vcall(string.format, "a") == "a")
assert(introspect.vcall(string.format, "%i", 1) == "1")
assert(introspect.vcall(string.format, "%i - %i", 1, 2) == "1 - 2")
assert(introspect.vcall(string.format, "%i - %i", [1, 2]) == "1 - 2")
assert(introspect.vcall(string.format, "%i - %i", [1, 2, 3]) == "1 - 2")
assert(introspect.vcall(string.format, "%i - %i", 1, [1, 2, 3]) == "1 - 1")