struct expression * convert_args(struct stack *mimic_stack, unsigned long nr_args, struct vm_method *method) { struct expression *args_list = NULL; unsigned long nr_total_args; unsigned long i; nr_total_args = nr_args; if (vm_method_is_jni(method)) { if (vm_method_is_static(method)) nr_total_args++; nr_total_args++; } if (nr_total_args == 0) { args_list = no_args_expr(); goto out; } /* * We scan the args map in reverse order, since the order of arguments * is already reversed. */ for (i = 0; i < nr_args; i++) { struct expression *expr = stack_pop(mimic_stack); if (vm_type_is_pair(expr->vm_type)) i++; if (i >= nr_args) break; args_list = insert_arg(args_list, expr, method, nr_total_args - i - 1); } if (vm_method_is_jni(method)) { struct expression *expr; if (vm_method_is_static(method)) { expr = value_expr(J_REFERENCE, (unsigned long) method->class->object); if (!expr) goto error; args_list = insert_arg(args_list, expr, method, 1); } /* * JNI methods also need a pointer to JNI environment. That's * done in jni_trampoline automagically which is why we never * use method index zero here for JNI methods. */ } out: return args_list; error: expr_put(args_list); return NULL; }
static bool is_this_arg(struct vm_method *method, int index) { if (vm_method_is_static(method)) return false; if (vm_method_is_jni(method)) return index == 1; return index == 0; }
struct expression * insert_arg(struct expression *root, struct expression *expr, struct vm_method *method, int index) { struct expression *_expr; /* Check if we should put @expr in EXPR_ARG_THIS. */ if (!vm_method_is_static(method) && index == 0) _expr = arg_this_expr(expr); else _expr = arg_expr(expr); _expr->bytecode_offset = expr->bytecode_offset; set_expr_arg_reg(_expr, method, index); if (!root) return _expr; return args_list_expr(root, _expr); }