Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

193 lines (148 sloc) 4.0 kb
/*
* Copyright (c) 2008 Pekka Enberg
*
* This file is released under the 2-clause BSD license. Please refer to the
* file LICENSE for details.
*/
#include <assert.h>
#include "jit/expression.h"
#include "jit/args.h"
#include "vm/method.h"
#include "lib/stack.h"
#ifdef CONFIG_ARGS_MAP
static inline void set_expr_arg_reg(struct expression *expr,
struct vm_method *method,
int index)
{
expr->arg_reg = method->args_map[index].reg;
}
#else /* CONFIG_ARGS_MAP */
static void set_expr_arg_reg(struct expression *expr,
struct vm_method *method,
int index)
{
}
#endif /* CONFIG_ARGS_MAP */
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;
}
static 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 (is_this_arg(method, index))
_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);
}
struct expression **pop_args(struct stack *mimic_stack, unsigned long nr_args)
{
struct expression **args_array;
unsigned long i;
args_array = malloc(nr_args * sizeof(void *));
if (!args_array)
return NULL;
/*
* 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);
args_array[i] = expr;
if (vm_type_is_pair(expr->vm_type))
i++;
if (i >= nr_args)
break;
}
return args_array;
}
struct expression *
convert_args(struct expression **args_array, 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;
}
for (i = 0; i < nr_args; i++) {
struct expression *expr = args_array[i];
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 struct expression *
insert_native_arg(struct expression *root, struct expression *expr, unsigned long idx)
{
struct expression *_expr;
_expr = arg_expr(expr);
_expr->bytecode_offset = expr->bytecode_offset;
#ifdef CONFIG_ARGS_MAP
_expr->arg_reg = args_map_alloc_gpr(idx);
#endif
if (!root)
return _expr;
return args_list_expr(root, _expr);
}
/**
* This function prepares argument list that will be used
* with the native VM call. All arguments are passed on stack.
*/
struct expression *
convert_native_args(struct stack *mimic_stack, unsigned long start_arg, unsigned long nr_args)
{
struct expression *args_list = NULL;
unsigned long i;
if (nr_args == 0) {
args_list = no_args_expr();
goto out;
}
for (i = 0; i < nr_args; i++) {
struct expression *expr = stack_pop(mimic_stack);
assert(expr->vm_type != J_FLOAT);
assert(expr->vm_type != J_DOUBLE);
args_list = insert_native_arg(args_list, expr, nr_args + start_arg - i - 1);
}
out:
return args_list;
}
Jump to Line
Something went wrong with that request. Please try again.