mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.0223: some instructions not yet tested
Problem: Some instructions not yet tested. Solution: Disassemble more instructions. Move tests to a new file. Compile call to s:function().
This commit is contained in:
@@ -6,6 +6,7 @@ int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate);
|
|||||||
char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload);
|
char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload);
|
||||||
void emsg_funcname(char *ermsg, char_u *name);
|
void emsg_funcname(char *ermsg, char_u *name);
|
||||||
int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe);
|
int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe);
|
||||||
|
char_u *fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error);
|
||||||
ufunc_T *find_func(char_u *name, cctx_T *cctx);
|
ufunc_T *find_func(char_u *name, cctx_T *cctx);
|
||||||
int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict);
|
int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict);
|
||||||
void save_funccal(funccal_entry_T *entry);
|
void save_funccal(funccal_entry_T *entry);
|
||||||
@@ -26,7 +27,6 @@ int has_varargs(ufunc_T *ufunc);
|
|||||||
int function_exists(char_u *name, int no_deref);
|
int function_exists(char_u *name, int no_deref);
|
||||||
char_u *get_expanded_name(char_u *name, int check);
|
char_u *get_expanded_name(char_u *name, int check);
|
||||||
char_u *get_user_func_name(expand_T *xp, int idx);
|
char_u *get_user_func_name(expand_T *xp, int idx);
|
||||||
void clean_script_functions(int sid);
|
|
||||||
void ex_delfunction(exarg_T *eap);
|
void ex_delfunction(exarg_T *eap);
|
||||||
void func_unref(char_u *name);
|
void func_unref(char_u *name);
|
||||||
void func_ptr_unref(ufunc_T *fp);
|
void func_ptr_unref(ufunc_T *fp);
|
||||||
|
@@ -268,6 +268,7 @@ NEW_TESTS = \
|
|||||||
test_utf8 \
|
test_utf8 \
|
||||||
test_utf8_comparisons \
|
test_utf8_comparisons \
|
||||||
test_vartabs \
|
test_vartabs \
|
||||||
|
test_vim9_disassemble \
|
||||||
test_vim9_expr \
|
test_vim9_expr \
|
||||||
test_vim9_script \
|
test_vim9_script \
|
||||||
test_viminfo \
|
test_viminfo \
|
||||||
@@ -470,6 +471,7 @@ NEW_TESTS_RES = \
|
|||||||
test_user_func.res \
|
test_user_func.res \
|
||||||
test_usercommands.res \
|
test_usercommands.res \
|
||||||
test_vartabs.res \
|
test_vartabs.res \
|
||||||
|
test_vim9_disassemble.res \
|
||||||
test_vim9_expr.res \
|
test_vim9_expr.res \
|
||||||
test_vim9_script.res \
|
test_vim9_script.res \
|
||||||
test_viminfo.res \
|
test_viminfo.res \
|
||||||
|
220
src/testdir/test_vim9_disassemble.vim
Normal file
220
src/testdir/test_vim9_disassemble.vim
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
" Test the :disassemble command, and compilation as a side effect
|
||||||
|
|
||||||
|
func NotCompiled()
|
||||||
|
echo "not"
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
let s:scriptvar = 4
|
||||||
|
let g:globalvar = 'g'
|
||||||
|
|
||||||
|
def s:ScriptFuncLoad(arg: string)
|
||||||
|
let local = 1
|
||||||
|
buffers
|
||||||
|
echo arg
|
||||||
|
echo local
|
||||||
|
echo v:version
|
||||||
|
echo s:scriptvar
|
||||||
|
echo g:globalvar
|
||||||
|
echo &tabstop
|
||||||
|
echo $ENVVAR
|
||||||
|
echo @z
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_disassembleLoad()
|
||||||
|
assert_fails('disass NoFunc', 'E1061:')
|
||||||
|
assert_fails('disass NotCompiled', 'E1062:')
|
||||||
|
|
||||||
|
let res = execute('disass s:ScriptFuncLoad')
|
||||||
|
assert_match('<SNR>\d*_ScriptFuncLoad.*'
|
||||||
|
\ .. 'buffers.*'
|
||||||
|
\ .. ' EXEC \+buffers.*'
|
||||||
|
\ .. ' LOAD arg\[-1\].*'
|
||||||
|
\ .. ' LOAD $0.*'
|
||||||
|
\ .. ' LOADV v:version.*'
|
||||||
|
\ .. ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*'
|
||||||
|
\ .. ' LOADG g:globalvar.*'
|
||||||
|
\ .. ' LOADENV $ENVVAR.*'
|
||||||
|
\ .. ' LOADREG @z.*'
|
||||||
|
\, res)
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def s:ScriptFuncPush()
|
||||||
|
let localbool = true
|
||||||
|
let localspec = v:none
|
||||||
|
let localblob = 0z1234
|
||||||
|
if has('float')
|
||||||
|
let localfloat = 1.234
|
||||||
|
endif
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_disassemblePush()
|
||||||
|
let res = execute('disass s:ScriptFuncPush')
|
||||||
|
assert_match('<SNR>\d*_ScriptFuncPush.*'
|
||||||
|
\ .. 'localbool = true.*'
|
||||||
|
\ .. ' PUSH v:true.*'
|
||||||
|
\ .. 'localspec = v:none.*'
|
||||||
|
\ .. ' PUSH v:none.*'
|
||||||
|
\ .. 'localblob = 0z1234.*'
|
||||||
|
\ .. ' PUSHBLOB 0z1234.*'
|
||||||
|
\, res)
|
||||||
|
if has('float')
|
||||||
|
assert_match('<SNR>\d*_ScriptFuncPush.*'
|
||||||
|
\ .. 'localfloat = 1.234.*'
|
||||||
|
\ .. ' PUSHF 1.234.*'
|
||||||
|
\, res)
|
||||||
|
endif
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def s:ScriptFuncStore()
|
||||||
|
let localnr = 1
|
||||||
|
localnr = 2
|
||||||
|
let localstr = 'abc'
|
||||||
|
localstr = 'xyz'
|
||||||
|
v:char = 'abc'
|
||||||
|
s:scriptvar = 'sv'
|
||||||
|
g:globalvar = 'gv'
|
||||||
|
&tabstop = 8
|
||||||
|
$ENVVAR = 'ev'
|
||||||
|
@z = 'rv'
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_disassembleStore()
|
||||||
|
let res = execute('disass s:ScriptFuncStore')
|
||||||
|
assert_match('<SNR>\d*_ScriptFuncStore.*'
|
||||||
|
\ .. 'localnr = 2.*'
|
||||||
|
\ .. ' STORE 2 in $0.*'
|
||||||
|
\ .. 'localstr = ''xyz''.*'
|
||||||
|
\ .. ' STORE $1.*'
|
||||||
|
\ .. 'v:char = ''abc''.*'
|
||||||
|
\ .. 'STOREV v:char.*'
|
||||||
|
\ .. 's:scriptvar = ''sv''.*'
|
||||||
|
\ .. ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*'
|
||||||
|
\ .. 'g:globalvar = ''gv''.*'
|
||||||
|
\ .. ' STOREG g:globalvar.*'
|
||||||
|
\ .. '&tabstop = 8.*'
|
||||||
|
\ .. ' STOREOPT &tabstop.*'
|
||||||
|
\ .. '$ENVVAR = ''ev''.*'
|
||||||
|
\ .. ' STOREENV $ENVVAR.*'
|
||||||
|
\ .. '@z = ''rv''.*'
|
||||||
|
\ .. ' STOREREG @z.*'
|
||||||
|
\, res)
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def s:ScriptFuncTry()
|
||||||
|
try
|
||||||
|
echo 'yes'
|
||||||
|
catch /fail/
|
||||||
|
echo 'no'
|
||||||
|
finally
|
||||||
|
echo 'end'
|
||||||
|
endtry
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_disassembleTry()
|
||||||
|
let res = execute('disass s:ScriptFuncTry')
|
||||||
|
assert_match('<SNR>\d*_ScriptFuncTry.*'
|
||||||
|
\ .. 'try.*'
|
||||||
|
\ .. 'TRY catch -> \d\+, finally -> \d\+.*'
|
||||||
|
\ .. 'catch /fail/.*'
|
||||||
|
\ .. ' JUMP -> \d\+.*'
|
||||||
|
\ .. ' PUSH v:exception.*'
|
||||||
|
\ .. ' PUSHS "fail".*'
|
||||||
|
\ .. ' COMPARESTRING =\~.*'
|
||||||
|
\ .. ' JUMP_IF_FALSE -> \d\+.*'
|
||||||
|
\ .. ' CATCH.*'
|
||||||
|
\ .. 'finally.*'
|
||||||
|
\ .. ' PUSHS "end".*'
|
||||||
|
\ .. 'endtry.*'
|
||||||
|
\ .. ' ENDTRY.*'
|
||||||
|
\, res)
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def s:ScriptFuncNew()
|
||||||
|
let ll = [1, "two", 333]
|
||||||
|
let dd = #{one: 1, two: "val"}
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_disassembleNew()
|
||||||
|
let res = execute('disass s:ScriptFuncNew')
|
||||||
|
assert_match('<SNR>\d*_ScriptFuncNew.*'
|
||||||
|
\ .. 'let ll = \[1, "two", 333].*'
|
||||||
|
\ .. 'PUSHNR 1.*'
|
||||||
|
\ .. 'PUSHS "two".*'
|
||||||
|
\ .. 'PUSHNR 333.*'
|
||||||
|
\ .. 'NEWLIST size 3.*'
|
||||||
|
\ .. 'let dd = #{one: 1, two: "val"}.*'
|
||||||
|
\ .. 'PUSHS "one".*'
|
||||||
|
\ .. 'PUSHNR 1.*'
|
||||||
|
\ .. 'PUSHS "two".*'
|
||||||
|
\ .. 'PUSHS "val".*'
|
||||||
|
\ .. 'NEWDICT size 2.*'
|
||||||
|
\, res)
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def FuncWithArg(arg)
|
||||||
|
echo arg
|
||||||
|
enddef
|
||||||
|
|
||||||
|
func UserFunc()
|
||||||
|
echo 'nothing'
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func UserFuncWithArg(arg)
|
||||||
|
echo a:arg
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
def s:ScriptFuncCall(): string
|
||||||
|
changenr()
|
||||||
|
char2nr("abc")
|
||||||
|
Test_disassembleNew()
|
||||||
|
FuncWithArg(343)
|
||||||
|
ScriptFuncNew()
|
||||||
|
s:ScriptFuncNew()
|
||||||
|
UserFunc()
|
||||||
|
UserFuncWithArg("foo")
|
||||||
|
let FuncRef = function("UserFunc")
|
||||||
|
FuncRef()
|
||||||
|
let FuncRefWithArg = function("UserFuncWithArg")
|
||||||
|
FuncRefWithArg("bar")
|
||||||
|
return "yes"
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_disassembleCall()
|
||||||
|
let res = execute('disass s:ScriptFuncCall')
|
||||||
|
assert_match('<SNR>\d\+_ScriptFuncCall.*'
|
||||||
|
\ .. 'changenr().*'
|
||||||
|
\ .. ' BCALL changenr(argc 0).*'
|
||||||
|
\ .. 'char2nr("abc").*'
|
||||||
|
\ .. ' PUSHS "abc".*'
|
||||||
|
\ .. ' BCALL char2nr(argc 1).*'
|
||||||
|
\ .. 'Test_disassembleNew().*'
|
||||||
|
\ .. ' DCALL Test_disassembleNew(argc 0).*'
|
||||||
|
\ .. 'FuncWithArg(343).*'
|
||||||
|
\ .. ' PUSHNR 343.*'
|
||||||
|
\ .. ' DCALL FuncWithArg(argc 1).*'
|
||||||
|
\ .. 'ScriptFuncNew().*'
|
||||||
|
\ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
|
||||||
|
\ .. 's:ScriptFuncNew().*'
|
||||||
|
\ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
|
||||||
|
\ .. 'UserFunc().*'
|
||||||
|
\ .. ' UCALL UserFunc(argc 0).*'
|
||||||
|
\ .. 'UserFuncWithArg("foo").*'
|
||||||
|
\ .. ' PUSHS "foo".*'
|
||||||
|
\ .. ' UCALL UserFuncWithArg(argc 1).*'
|
||||||
|
\ .. 'let FuncRef = function("UserFunc").*'
|
||||||
|
\ .. 'FuncRef().*'
|
||||||
|
\ .. ' LOAD $\d.*'
|
||||||
|
\ .. ' PCALL (argc 0).*'
|
||||||
|
\ .. 'let FuncRefWithArg = function("UserFuncWithArg").*'
|
||||||
|
\ .. 'FuncRefWithArg("bar").*'
|
||||||
|
\ .. ' PUSHS "bar".*'
|
||||||
|
\ .. ' LOAD $\d.*'
|
||||||
|
\ .. ' PCALL (argc 1).*'
|
||||||
|
\ .. 'return "yes".*'
|
||||||
|
\ .. ' PUSHS "yes".*'
|
||||||
|
\ .. ' RETURN.*'
|
||||||
|
\, res)
|
||||||
|
enddef
|
||||||
|
|
||||||
|
|
||||||
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
@@ -489,215 +489,5 @@ def Test_compile_const_expr()
|
|||||||
assert_notmatch('JUMP', instr)
|
assert_notmatch('JUMP', instr)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
func NotCompiled()
|
|
||||||
echo "not"
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
let s:scriptvar = 4
|
|
||||||
let g:globalvar = 'g'
|
|
||||||
|
|
||||||
def s:ScriptFuncLoad(arg: string)
|
|
||||||
let local = 1
|
|
||||||
buffers
|
|
||||||
echo arg
|
|
||||||
echo local
|
|
||||||
echo v:version
|
|
||||||
echo s:scriptvar
|
|
||||||
echo g:globalvar
|
|
||||||
echo &tabstop
|
|
||||||
echo $ENVVAR
|
|
||||||
echo @z
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def Test_disassembleLoad()
|
|
||||||
assert_fails('disass NoFunc', 'E1061:')
|
|
||||||
assert_fails('disass NotCompiled', 'E1062:')
|
|
||||||
|
|
||||||
let res = execute('disass s:ScriptFuncLoad')
|
|
||||||
assert_match('<SNR>\d*_ScriptFuncLoad.*'
|
|
||||||
\ .. 'buffers.*'
|
|
||||||
\ .. ' EXEC \+buffers.*'
|
|
||||||
\ .. ' LOAD arg\[-1\].*'
|
|
||||||
\ .. ' LOAD $0.*'
|
|
||||||
\ .. ' LOADV v:version.*'
|
|
||||||
\ .. ' LOADS s:scriptvar from .*test_vim9_script.vim.*'
|
|
||||||
\ .. ' LOADG g:globalvar.*'
|
|
||||||
\ .. ' LOADENV $ENVVAR.*'
|
|
||||||
\ .. ' LOADREG @z.*'
|
|
||||||
\, res)
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def s:ScriptFuncPush()
|
|
||||||
let localbool = true
|
|
||||||
let localspec = v:none
|
|
||||||
let localblob = 0z1234
|
|
||||||
if has('float')
|
|
||||||
let localfloat = 1.234
|
|
||||||
endif
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def Test_disassemblePush()
|
|
||||||
let res = execute('disass s:ScriptFuncPush')
|
|
||||||
assert_match('<SNR>\d*_ScriptFuncPush.*'
|
|
||||||
\ .. 'localbool = true.*'
|
|
||||||
\ .. ' PUSH v:true.*'
|
|
||||||
\ .. 'localspec = v:none.*'
|
|
||||||
\ .. ' PUSH v:none.*'
|
|
||||||
\ .. 'localblob = 0z1234.*'
|
|
||||||
\ .. ' PUSHBLOB 0z1234.*'
|
|
||||||
\, res)
|
|
||||||
if has('float')
|
|
||||||
assert_match('<SNR>\d*_ScriptFuncPush.*'
|
|
||||||
\ .. 'localfloat = 1.234.*'
|
|
||||||
\ .. ' PUSHF 1.234.*'
|
|
||||||
\, res)
|
|
||||||
endif
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def s:ScriptFuncStore()
|
|
||||||
let localnr = 1
|
|
||||||
localnr = 2
|
|
||||||
let localstr = 'abc'
|
|
||||||
localstr = 'xyz'
|
|
||||||
v:char = 'abc'
|
|
||||||
s:scriptvar = 'sv'
|
|
||||||
g:globalvar = 'gv'
|
|
||||||
&tabstop = 8
|
|
||||||
$ENVVAR = 'ev'
|
|
||||||
@z = 'rv'
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def Test_disassembleStore()
|
|
||||||
let res = execute('disass s:ScriptFuncStore')
|
|
||||||
assert_match('<SNR>\d*_ScriptFuncStore.*'
|
|
||||||
\ .. 'localnr = 2.*'
|
|
||||||
\ .. ' STORE 2 in $0.*'
|
|
||||||
\ .. 'localstr = ''xyz''.*'
|
|
||||||
\ .. ' STORE $1.*'
|
|
||||||
\ .. 'v:char = ''abc''.*'
|
|
||||||
\ .. 'STOREV v:char.*'
|
|
||||||
\ .. 's:scriptvar = ''sv''.*'
|
|
||||||
\ .. ' STORES s:scriptvar in .*test_vim9_script.vim.*'
|
|
||||||
\ .. 'g:globalvar = ''gv''.*'
|
|
||||||
\ .. ' STOREG g:globalvar.*'
|
|
||||||
\ .. '&tabstop = 8.*'
|
|
||||||
\ .. ' STOREOPT &tabstop.*'
|
|
||||||
\ .. '$ENVVAR = ''ev''.*'
|
|
||||||
\ .. ' STOREENV $ENVVAR.*'
|
|
||||||
\ .. '@z = ''rv''.*'
|
|
||||||
\ .. ' STOREREG @z.*'
|
|
||||||
\, res)
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def s:ScriptFuncTry()
|
|
||||||
try
|
|
||||||
echo 'yes'
|
|
||||||
catch /fail/
|
|
||||||
echo 'no'
|
|
||||||
finally
|
|
||||||
echo 'end'
|
|
||||||
endtry
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def Test_disassembleTry()
|
|
||||||
let res = execute('disass s:ScriptFuncTry')
|
|
||||||
assert_match('<SNR>\d*_ScriptFuncTry.*'
|
|
||||||
\ .. 'try.*'
|
|
||||||
\ .. 'TRY catch -> \d\+, finally -> \d\+.*'
|
|
||||||
\ .. 'catch /fail/.*'
|
|
||||||
\ .. ' JUMP -> \d\+.*'
|
|
||||||
\ .. ' PUSH v:exception.*'
|
|
||||||
\ .. ' PUSHS "fail".*'
|
|
||||||
\ .. ' COMPARESTRING =\~.*'
|
|
||||||
\ .. ' JUMP_IF_FALSE -> \d\+.*'
|
|
||||||
\ .. ' CATCH.*'
|
|
||||||
\ .. 'finally.*'
|
|
||||||
\ .. ' PUSHS "end".*'
|
|
||||||
\ .. 'endtry.*'
|
|
||||||
\ .. ' ENDTRY.*'
|
|
||||||
\, res)
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def s:ScriptFuncNew()
|
|
||||||
let ll = [1, "two", 333]
|
|
||||||
let dd = #{one: 1, two: "val"}
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def Test_disassembleNew()
|
|
||||||
let res = execute('disass s:ScriptFuncNew')
|
|
||||||
assert_match('<SNR>\d*_ScriptFuncNew.*'
|
|
||||||
\ .. 'let ll = \[1, "two", 333].*'
|
|
||||||
\ .. 'PUSHNR 1.*'
|
|
||||||
\ .. 'PUSHS "two".*'
|
|
||||||
\ .. 'PUSHNR 333.*'
|
|
||||||
\ .. 'NEWLIST size 3.*'
|
|
||||||
\ .. 'let dd = #{one: 1, two: "val"}.*'
|
|
||||||
\ .. 'PUSHS "one".*'
|
|
||||||
\ .. 'PUSHNR 1.*'
|
|
||||||
\ .. 'PUSHS "two".*'
|
|
||||||
\ .. 'PUSHS "val".*'
|
|
||||||
\ .. 'NEWDICT size 2.*'
|
|
||||||
\, res)
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def FuncWithArg(arg)
|
|
||||||
echo arg
|
|
||||||
enddef
|
|
||||||
|
|
||||||
func UserFunc()
|
|
||||||
echo 'nothing'
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
func UserFuncWithArg(arg)
|
|
||||||
echo a:arg
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
def s:ScriptFuncCall(): string
|
|
||||||
changenr()
|
|
||||||
char2nr("abc")
|
|
||||||
Test_disassembleNew()
|
|
||||||
FuncWithArg(343)
|
|
||||||
UserFunc()
|
|
||||||
UserFuncWithArg("foo")
|
|
||||||
let FuncRef = function("UserFunc")
|
|
||||||
FuncRef()
|
|
||||||
let FuncRefWithArg = function("UserFuncWithArg")
|
|
||||||
FuncRefWithArg("bar")
|
|
||||||
return "yes"
|
|
||||||
enddef
|
|
||||||
|
|
||||||
def Test_disassembleCall()
|
|
||||||
let res = execute('disass s:ScriptFuncCall')
|
|
||||||
assert_match('<SNR>\d*_ScriptFuncCall.*'
|
|
||||||
\ .. 'changenr().*'
|
|
||||||
\ .. ' BCALL changenr(argc 0).*'
|
|
||||||
\ .. 'char2nr("abc").*'
|
|
||||||
\ .. ' PUSHS "abc".*'
|
|
||||||
\ .. ' BCALL char2nr(argc 1).*'
|
|
||||||
\ .. 'Test_disassembleNew().*'
|
|
||||||
\ .. ' DCALL Test_disassembleNew(argc 0).*'
|
|
||||||
\ .. 'FuncWithArg(343).*'
|
|
||||||
\ .. ' PUSHNR 343.*'
|
|
||||||
\ .. ' DCALL FuncWithArg(argc 1).*'
|
|
||||||
\ .. 'UserFunc().*'
|
|
||||||
\ .. ' UCALL UserFunc(argc 0).*'
|
|
||||||
\ .. 'UserFuncWithArg("foo").*'
|
|
||||||
\ .. ' PUSHS "foo".*'
|
|
||||||
\ .. ' UCALL UserFuncWithArg(argc 1).*'
|
|
||||||
\ .. 'let FuncRef = function("UserFunc").*'
|
|
||||||
\ .. 'FuncRef().*'
|
|
||||||
\ .. ' LOAD $\d.*'
|
|
||||||
\ .. ' PCALL (argc 0).*'
|
|
||||||
\ .. 'let FuncRefWithArg = function("UserFuncWithArg").*'
|
|
||||||
\ .. 'FuncRefWithArg("bar").*'
|
|
||||||
\ .. ' PUSHS "bar".*'
|
|
||||||
\ .. ' LOAD $\d.*'
|
|
||||||
\ .. ' PCALL (argc 1).*'
|
|
||||||
\ .. 'return "yes".*'
|
|
||||||
\ .. ' PUSHS "yes".*'
|
|
||||||
\ .. ' RETURN.*'
|
|
||||||
\, res)
|
|
||||||
enddef
|
|
||||||
|
|
||||||
|
|
||||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
@@ -573,8 +573,6 @@ get_func_tv(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FLEN_FIXED 40
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if "p" starts with "<SID>" or "s:".
|
* Return TRUE if "p" starts with "<SID>" or "s:".
|
||||||
* Only works if eval_fname_script() returned non-zero for "p"!
|
* Only works if eval_fname_script() returned non-zero for "p"!
|
||||||
@@ -591,7 +589,7 @@ eval_fname_sid(char_u *p)
|
|||||||
* Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory
|
* Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory
|
||||||
* (slow).
|
* (slow).
|
||||||
*/
|
*/
|
||||||
static char_u *
|
char_u *
|
||||||
fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
|
fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
|
||||||
{
|
{
|
||||||
int llen;
|
int llen;
|
||||||
|
@@ -742,6 +742,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
223,
|
||||||
/**/
|
/**/
|
||||||
222,
|
222,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2574,6 +2574,9 @@ typedef enum {
|
|||||||
#define FCERR_DELETED 7
|
#define FCERR_DELETED 7
|
||||||
#define FCERR_NOTMETHOD 8 // function cannot be used as a method
|
#define FCERR_NOTMETHOD 8 // function cannot be used as a method
|
||||||
|
|
||||||
|
// fixed buffer length for fname_trans_sid()
|
||||||
|
#define FLEN_FIXED 40
|
||||||
|
|
||||||
// flags for find_name_end()
|
// flags for find_name_end()
|
||||||
#define FNE_INCL_BR 1 // include [] in name
|
#define FNE_INCL_BR 1 // include [] in name
|
||||||
#define FNE_CHECK_START 2 // check name starts with valid character
|
#define FNE_CHECK_START 2 // check name starts with valid character
|
||||||
|
@@ -1686,49 +1686,60 @@ compile_call(char_u **arg, size_t varlen, cctx_T *cctx, int argcount_init)
|
|||||||
char_u *p;
|
char_u *p;
|
||||||
int argcount = argcount_init;
|
int argcount = argcount_init;
|
||||||
char_u namebuf[100];
|
char_u namebuf[100];
|
||||||
|
char_u fname_buf[FLEN_FIXED + 1];
|
||||||
|
char_u *tofree = NULL;
|
||||||
|
int error = FCERR_NONE;
|
||||||
ufunc_T *ufunc;
|
ufunc_T *ufunc;
|
||||||
|
int res = FAIL;
|
||||||
|
|
||||||
if (varlen >= sizeof(namebuf))
|
if (varlen >= sizeof(namebuf))
|
||||||
{
|
{
|
||||||
semsg(_("E1011: name too long: %s"), name);
|
semsg(_("E1011: name too long: %s"), name);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
vim_strncpy(namebuf, name, varlen);
|
vim_strncpy(namebuf, *arg, varlen);
|
||||||
|
name = fname_trans_sid(namebuf, fname_buf, &tofree, &error);
|
||||||
|
|
||||||
*arg = skipwhite(*arg + varlen + 1);
|
*arg = skipwhite(*arg + varlen + 1);
|
||||||
if (compile_arguments(arg, cctx, &argcount) == FAIL)
|
if (compile_arguments(arg, cctx, &argcount) == FAIL)
|
||||||
return FAIL;
|
goto theend;
|
||||||
|
|
||||||
if (ASCII_ISLOWER(*name))
|
if (ASCII_ISLOWER(*name) && name[1] != ':')
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
// builtin function
|
// builtin function
|
||||||
idx = find_internal_func(namebuf);
|
idx = find_internal_func(name);
|
||||||
if (idx >= 0)
|
if (idx >= 0)
|
||||||
return generate_BCALL(cctx, idx, argcount);
|
{
|
||||||
|
res = generate_BCALL(cctx, idx, argcount);
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
semsg(_(e_unknownfunc), namebuf);
|
semsg(_(e_unknownfunc), namebuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// User defined function or variable must start with upper case.
|
|
||||||
if (!ASCII_ISUPPER(*name))
|
|
||||||
{
|
|
||||||
semsg(_("E1012: Invalid function name: %s"), namebuf);
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we can find the function by name generate the right call.
|
// If we can find the function by name generate the right call.
|
||||||
ufunc = find_func(namebuf, cctx);
|
ufunc = find_func(name, cctx);
|
||||||
if (ufunc != NULL)
|
if (ufunc != NULL)
|
||||||
return generate_CALL(cctx, ufunc, argcount);
|
{
|
||||||
|
res = generate_CALL(cctx, ufunc, argcount);
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
|
||||||
// If the name is a variable, load it and use PCALL.
|
// If the name is a variable, load it and use PCALL.
|
||||||
p = namebuf;
|
p = namebuf;
|
||||||
if (compile_load(&p, namebuf + varlen, cctx, FALSE) == OK)
|
if (compile_load(&p, namebuf + varlen, cctx, FALSE) == OK)
|
||||||
return generate_PCALL(cctx, argcount, FALSE);
|
{
|
||||||
|
res = generate_PCALL(cctx, argcount, FALSE);
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
|
||||||
// The function may be defined only later. Need to figure out at runtime.
|
// The function may be defined only later. Need to figure out at runtime.
|
||||||
return generate_UCALL(cctx, namebuf, argcount);
|
res = generate_UCALL(cctx, name, argcount);
|
||||||
|
|
||||||
|
theend:
|
||||||
|
vim_free(tofree);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// like NAMESPACE_CHAR but with 'a' and 'l'.
|
// like NAMESPACE_CHAR but with 'a' and 'l'.
|
||||||
|
Reference in New Issue
Block a user