| 3833 | } |
| 3834 | |
| 3835 | LIST * function_get_variables( FUNCTION * f ) |
| 3836 | { |
| 3837 | if ( f->type == FUNCTION_BUILTIN ) |
| 3838 | return L0; |
| 3839 | #ifdef HAVE_PYTHON |
| 3840 | if ( f->type == FUNCTION_PYTHON ) |
| 3841 | return L0; |
| 3842 | #endif |
| 3843 | { |
| 3844 | JAM_FUNCTION * func = (JAM_FUNCTION *)f; |
| 3845 | LIST * result = L0; |
| 3846 | instruction * code; |
| 3847 | int32_t i; |
| 3848 | assert( f->type == FUNCTION_JAM ); |
| 3849 | if ( func->generic ) func = ( JAM_FUNCTION * )func->generic; |
| 3850 | |
| 3851 | for ( i = 0; ; ++i ) |
| 3852 | { |
| 3853 | OBJECT * var; |
| 3854 | code = func->code + i; |
| 3855 | switch ( code->op_code ) |
| 3856 | { |
| 3857 | case INSTR_PUSH_LOCAL: break; |
| 3858 | case INSTR_RETURN: return result; |
| 3859 | case INSTR_CALL_MEMBER_RULE: |
| 3860 | case INSTR_CALL_RULE: ++i; continue; |
| 3861 | case INSTR_PUSH_MODULE: |
| 3862 | { |
| 3863 | int32_t depth = 1; |
| 3864 | ++i; |
| 3865 | while ( depth > 0 ) |
| 3866 | { |
| 3867 | code = func->code + i; |
| 3868 | switch ( code->op_code ) |
| 3869 | { |
| 3870 | case INSTR_PUSH_MODULE: |
| 3871 | case INSTR_CLASS: |
| 3872 | ++depth; |
| 3873 | break; |
| 3874 | case INSTR_POP_MODULE: |
| 3875 | --depth; |
| 3876 | break; |
| 3877 | case INSTR_CALL_RULE: |
| 3878 | ++i; |
| 3879 | break; |
| 3880 | } |
| 3881 | ++i; |
| 3882 | } |
| 3883 | --i; |
| 3884 | } |
| 3885 | default: continue; |
| 3886 | } |
| 3887 | var = func->constants[ code->arg ]; |
| 3888 | if ( !( object_equal( var, constant_TMPDIR ) || |
| 3889 | object_equal( var, constant_TMPNAME ) || |
| 3890 | object_equal( var, constant_TMPFILE ) || |
| 3891 | object_equal( var, constant_STDOUT ) || |
| 3892 | object_equal( var, constant_STDERR ) ) ) |
no test coverage detected