I "solved" the shell problem (really it's more like a workaround, it still kind of prints character by character, but I have no idea how to avoid that).
Basically I first reprogrammed shell_draw() to only execute in case of a new line (\n or character wrapping). This works fine, but now I also have to draw in case of a \0.
- First, reprogram readline() at /lib/mp-readline/readline.c to also send the \0 (I removed some fluff):
Code: Select all
int readline(vstr_t *line, const char *prompt, char *text) {
readline_init(line, prompt);
for (;;) {
for (int i = 0; str[i]; i++) {
int r = readline_process_char(c);
if (r >= 0) {
return r;
}
}
readline_process_char('\0');
}
}
Obviously reprogram readline_process_char() to call shell_draw() when it receives a \0.
- Second, simply make mp_hal_stdout_tx_str (/lib/utils/stdout_helpers.c) also send the \0:
Code: Select all
void mp_hal_stdout_tx_str(const char *str) {
mp_hal_stdout_tx_strn(str, strlen(str)+1);
}
This normally takes care of all prints, and now the shell only updates the display line by line (which makes printing a long string MUCH faster).
Now, I have another bug (which could be a bug in MPy itself).
The following script enumerates all functions of a given module:
Code: Select all
#platforms: (0)TI-Nspire (1)NumWorks (2)Graph 90+E (3)Graph 75+E (4)TI-Python
plines=[29,12, 7, 9,11]
pcols =[53,99,509,32,32]
try:
import sys
try:
if sys.platform=='nspire': platform=0
if sys.platform=='TI-Python Adapter': platform=4
platform=0
except: platform=3
except:
try:
import kandinsky
platform=1
except:
platform=2
nlines=plines[platform]
ncols=pcols[platform]
curline=0
def mprint(*ls):
global curline
st=""
for s in ls:
if not(isinstance(s,str)):
s=str(s)
st=st+s
stlines=1+int(len(st)/ncols)
if curline+stlines>=nlines:
input("Input to continue:")
curline=0
print(st)
curline+=stlines
def sstr(obj):
try:
s=obj.__name__
except:
s=str(obj)
a=s.find("'")
b=s.rfind("'")
if a>=0 and b!=a:
s=s[s.find("'")+1:s.rfind("'")]
return s
def explmod(pitm,pitmsl=[],reset=True):
global curline
if(reset):
curline=0
pitmsl=[sstr(pitm)]
hd="."*(len(pitmsl)-1)
spath=".".join(pitmsl)
c=0
for itms in sorted(dir(pitm)):
c=c+1
try:
itm=eval(spath+"."+itms)
mprint(hd+itms+"="+str(itm))
if spath.rfind(itms)<0:
pitmsl2=pitmsl.copy()
pitmsl2.append(itms)
c=c+explmod(itm,pitmsl2,False)
except:
mprint(hd+itms)
if c>0:
mprint(hd+"Total: "+str(c)+" item(s)")
return c
Output sample:
The script works fine, however if I enable function attributes (MICROPY_PY_FUNCTION_ATTRS) the script crashes almost immediately:
The address 0x310A30 is the function bound_meth_attr():
Code: Select all
00310a14 <_bound_meth_attr>:
310a14: 61 62 mov.l @r6,r1
310a16: 21 18 tst r1,r1
310a18: 8f 02 bf.s 310a20 <_bound_meth_attr+0xc>
310a1a: 60 53 mov r5,r0
310a1c: 88 31 cmp/eq #49,r0
310a1e: 89 01 bt 310a24 <_bound_meth_attr+0x10>
310a20: 00 0b rts
310a22: 00 09 nop
310a24: 4f 22 sts.l pr,@-r15
310a26: d0 06 mov.l 310a40 <_bound_meth_attr+0x2c>,r0 ! 31358c <_mp_obj_fun_get_name>
310a28: 7f fc add #-4,r15
310a2a: 54 41 mov.l @(4,r4),r4
310a2c: 40 0b jsr @r0
310a2e: 2f 62 mov.l r6,@r15
310a30: 66 f2 mov.l @r15,r6
310a32: 40 08 shll2 r0
310a34: cb 02 or #2,r0
310a36: 26 02 mov.l r0,@r6
310a38: 7f 04 add #4,r15
310a3a: 4f 26 lds.l @r15+,pr
310a3c: 00 0b rts
310a3e: 00 09 nop
310a40: 00 31 .word 0x0031
310a42: 35 8c add r8,r5
Code: Select all
STATIC void bound_meth_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
if (dest[0] != MP_OBJ_NULL) {
// not load attribute
return;
}
if (attr == MP_QSTR___name__) {
mp_obj_bound_meth_t *o = MP_OBJ_TO_PTR(self_in);
dest[0] = MP_OBJ_NEW_QSTR(mp_obj_fun_get_name(o->meth));
}
}
Any idea of what causes this crash?