Example #1
0
    def write_method(self):
        access = util.get_access_method(self.method.get_access_flags())
        class_name = self.method.get_class_name()
        _, name, proto = self.method.get_triple()

        jni_name = JniLongName(class_name, name, proto)

        self.write("\n/* %s->%s%s */\n" % (class_name, name, proto))

        self.write('extern "C" JNIEXPORT %s JNICALL\n' % get_native_type(self.irmethod.rtype))
        self.write(jni_name)
        params = self.irmethod.params
        if 'static' not in access:
            params = params[1:]
        proto = ''
        if self.irmethod.params_type:
            proto = ', '.join(['%s p%s' % (get_native_type(p_type), param) for p_type,
                                                                               param in
                               zip(self.irmethod.params_type, params)])
        if proto:
            self.write('(JNIEnv *env, jobject thiz, %s)' % proto)
        else:
            self.write('(JNIEnv *env, jobject thiz)')
        self.write('{\n')
        nodes = self.irmethod.irblocks
        for node in nodes:
            self.visit_node(node)

        for lp in self.irmethod.landing_pads:
            self.write('\n')
            self.visit_landing_pad(lp)

        return_type = self.irmethod.rtype
        if return_type[0] != 'V':
            if return_type[0] == 'L':
                self.write("EX_UnwindBlock: return NULL;\n")
            else:
                self.write("EX_UnwindBlock: return (%s)0;\n" % (get_native_type(return_type)))
        else:
            self.write("EX_UnwindBlock: return;\n")

        self.write('}\n')
Example #2
0
 def visit_put_static(self, ins, clsdesc, name, ftype, rhs):
     self.write_trace(ins)
     self.write('{\n')
     self.write_define_ex_handle(ins)
     self.write('jclass &clz = %s;\n' % (self.ca(ins.get_class())))
     self.write('jfieldID &fld = %s;\n' % (self.fa(ins.get_field())))
     self.write('D2C_RESOLVE_STATIC_FIELD(clz, fld, "%s", "%s", "%s");\n' % (get_type(clsdesc), name, ftype))
     self.write('env->SetStatic%sField(clz,fld,(%s) %s);\n' % (
         get_type_descriptor(ftype), get_native_type(ftype), self.get_variable_or_const(rhs)))
     self.write_undefine_ex_handle(ins)
     self.write('}\n')
Example #3
0
    def _invoke_common(self, ins, invoke_type, name, base, ptype, rtype, args, clsdesc):
        self.write('{\n')
        self.write_define_ex_handle(ins)
        if invoke_type != 'static':
            self.write("D2C_NOT_NULL(v%s);\n" % (self.ra(base)))
        self.write('jclass &clz = %s;\n' % (self.ca(ins.get_class())))
        self.write('jmethodID &mid = %s;\n' % (self.ma(ins.get_call_method())))
        if invoke_type != 'static':
            self.write('D2C_RESOLVE_METHOD(clz, mid, "%s", "%s", "(%s)%s");\n' % (get_type(clsdesc), name, ''.join(ptype), rtype))
        else:
            self.write('D2C_RESOLVE_STATIC_METHOD(clz, mid, "%s", "%s", "(%s)%s");\n' % (get_type(clsdesc), name, ''.join(ptype), rtype))
        self.write('jvalue args[] = {')
        vars = []
        for arg, atype in zip(args, ptype):
            if atype[0] == 'L' or atype[0] == '[':
                vars.append('{.l = %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'Z':
                vars.append('{.z = (jboolean) %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'B':
                vars.append('{.b = (jbyte) %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'C':
                vars.append('{.c = (jchar) %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'S':
                vars.append('{.s = (jshort) %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'I':
                vars.append('{.i = %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'J':
                vars.append('{.j = (jlong) %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'F':
                vars.append('{.f = %s}' % (self.get_variable_or_const(arg)))
            elif atype[0] == 'D':
                vars.append('{.d = %s}' % (self.get_variable_or_const(arg)))
            else:
                raise Exception("Unknow signuare type %s" % (atype))
        self.write(','.join(vars))
        self.write('};\n')
        if rtype != 'V':
            self.write_kill_local_reference(ins.get_value())
            ins.get_value().visit(self)
            self.write(' = ')
            self.write("(%s) " % (get_native_type(ins.get_value().get_type())))

        if invoke_type == 'super':
            self.write(
                'env->CallNonvirtual%sMethodA(v%s, clz, mid, args);\n' % (get_type_descriptor(rtype), self.ra(base)))
        elif invoke_type == 'static':
            self.write('env->CallStatic%sMethodA(clz, mid, args);\n' % (get_type_descriptor(rtype)))
        else:
            self.write('env->Call%sMethodA(v%s, mid, args);\n' % (get_type_descriptor(rtype), self.ra(base)))

        self.write_undefine_ex_handle(ins)
        self.write('}\n')
        if rtype != 'V':
            self.write_delete_dead_local_reference(ins.get_value())
Example #4
0
 def visit_astore(self, ins, array, index, rhs):
     self.write_trace(ins)
     self.write('{\n')
     self.write_define_ex_handle(ins)
     self.write_not_null(array)
     elem_type = ins.get_elem_type()
     if is_primitive_type(elem_type):
         self.write('{%s val = %s;' % (get_native_type(elem_type), self.get_variable_or_const(rhs)))
         self.write('env->Set%sArrayRegion((%sArray) v%s, (jint) %s, 1, &val);' %
                    (get_type_descriptor(elem_type), get_native_type(elem_type),
                     self.ra(array),
                     self.get_variable_or_const(index)))
         self.write('}\n')
     else:
         self.write('env->SetObjectArrayElement((jobjectArray) v%s, (jint) %s, v%s);' %
                    (self.ra(array),
                     self.get_variable_or_const(index),
                     self.ra(rhs)))
     self.write_undefine_ex_handle(ins)
     self.write('}\n')
Example #5
0
    def write_kill_local_reference(self, val, tmp=False):
        if val is None:
            return

        if get_native_type(val.get_type()) in ('jarray', 'jobject', 'jstring'):
            if tmp or val.get_register() >= 0:
                reg = self.ra(val)
                self.write('if (v%s) {\n' % (reg))
                self.write('LOGD("env->DeleteLocalRef(%%p):v%s", v%s);\n' % (reg, reg))
                self.write('env->DeleteLocalRef(v%s);\n' % reg)
                self.write('}\n')
Example #6
0
 def visit_aload(self, ins, result, array, index):
     self.write_trace(ins)
     self.write('{\n')
     self.write_define_ex_handle(ins)
     self.write_not_null(array)
     elem_type = ins.get_elem_type()
     if is_primitive_type(elem_type):
         self.write('{%s val;' % (get_native_type(elem_type)))
         self.write('env->Get%sArrayRegion((%sArray) v%s, (jint) %s, 1, &val);' %
                    (get_type_descriptor(elem_type), get_native_type(elem_type), self.ra(array),
                     self.get_variable_or_const(index)))
         self.write('v%s = val;}' % (self.ra(result)))
     else:
         self.write_kill_local_reference(result)
         self.write('v%s = (%s) env->GetObjectArrayElement((jobjectArray) v%s, (jint) %s);' %
                    (self.ra(result), get_native_type(result.get_type()),
                     self.ra(array),
                     self.get_variable_or_const(index)))
     self.write('\n')
     self.write_undefine_ex_handle(ins)
     self.write('}\n')
Example #7
0
 def visit_new(self, ins, result, atype):
     self.write_trace(ins)
     self.write('{\n')
     self.write_define_ex_handle(ins)
     # should kill local reference after D2C_RESOLVE_CLASS, since D2C_RESOLVE_CLASS may throw exception,
     # so this ref may be double killed in exception handle.
     self.write_kill_local_reference(ins.get_value())
     self.write('jclass &clz = %s;\n' % (self.ca(ins.get_class())))
     self.write('D2C_RESOLVE_CLASS(clz,"%s");\n' % (get_type(atype)))
     self.write('v%s = (%s) env->AllocObject(clz);\n' % (self.ra(result), get_native_type(result.get_type())))
     self.write_undefine_ex_handle(ins)
     self.write('}\n')
Example #8
0
 def visit_get_static(self, ins, result, ftype, clsdesc, name):
     self.write_trace(ins)
     self.write('{\n')
     self.write_define_ex_handle(ins)
     self.write_kill_local_reference(result)
     self.write('jclass &clz = %s;\n' % (self.ca(ins.get_class())))
     self.write('jfieldID &fld = %s;\n' % (self.fa(ins.get_field())))
     self.write('D2C_RESOLVE_STATIC_FIELD(clz, fld, "%s", "%s", "%s");\n' % (get_type(clsdesc), name, ftype))
     result.visit(self)
     self.write(' = (%s) env->GetStatic%sField(clz,fld);\n' % (
         get_native_type(result.get_type()), get_type_descriptor(ftype)))
     self.write_undefine_ex_handle(ins)
     self.write('}\n')
Example #9
0
    def visit_fill_array(self, ins, array, value):
        self.write_trace(ins)
        self.write('{\n')
        self.write('static const unsigned char data[] = {')
        data = value.get_data()
        tab = []
        elem_id = 'B'
        elem_size = 1

        for i in range(0, value.size * value.element_width, elem_size):
            tab.append('%s' % unpack(elem_id, data[i:i + elem_size])[0])
        self.write(', '.join(tab))
        self.write('};\n')

        elem_type = array.get_type()[1:]
        array_size = value.size

        self.write(
            'env->Set%sArrayRegion((%sArray) v%s, 0, %d, (const %s *) data);\n' % (get_type_descriptor(elem_type), \
                                                                                   get_native_type(elem_type),
                                                                                   self.ra(array), \
                                                                                   array_size,
                                                                                   get_native_type(elem_type)))
        self.write('}\n')
Example #10
0
 def visit_new_array(self, ins, result, atype, size):
     self.write_trace(ins)
     elem_type = ins.get_elem_type()
     self.write('{\n')
     self.write_define_ex_handle(ins)
     self.write_check_array_size(size)
     self.write_kill_local_reference(ins.get_value())
     if is_primitive_type(elem_type):
         result.visit(self)
         self.write(
             ' = (%s) env->New%sArray((jint) %s);\n' % (
             get_native_type(result.get_type()), get_type_descriptor(elem_type), self.get_variable_or_const(size)))
     else:
         self.write('jclass &clz = %s;\n' % (self.ca(ins.get_class())))
         self.write('D2C_RESOLVE_CLASS(clz,"%s");\n' % (get_type(elem_type)))
         result.visit(self)
         self.write(' = env->NewObjectArray((jint) %s, clz, NULL);\n' % (self.get_variable_or_const(size)))
     self.write_undefine_ex_handle(ins)
     self.write('}\n')
Example #11
0
 def visit_load_constant(self, ins):
     val = ins.get_value()
     atype = val.get_type()
     self.write_trace(ins)
     self.write_kill_local_reference(val)
     cst = ins.get_cst().get_constant()
     cst_type = ins.get_cst().get_type()
     if atype == 'F':
         self.write('v%s = d2c_bitcast_to_float(%r);\n' % (self.ra(val), cst))
     elif atype == 'D':
         self.write('v%s = d2c_bitcast_to_double(%r);\n' % (self.ra(val), cst))
     elif cst_type == 'Ljava/lang/String;':
         self.write(
             'v%s = (%s) env->NewStringUTF("%s");\n' % (self.ra(val), get_native_type(atype), cst))
     elif cst_type == 'Ljava/lang/Class;':
         self.write('{\n')
         self.write_define_ex_handle(ins)
         self.write('jclass &clz = %s;\n' % (self.ca(ins.get_class())))
         self.write('D2C_RESOLVE_CLASS(clz,"%s");\n' % (cst))
         self.write('v%s = env->NewLocalRef(clz);\n' % (self.ra(val)))
         self.write_undefine_ex_handle(ins)
         self.write('}\n')
     else:
         self.write('v%s = %r;\n' % (self.ra(val), cst))
Example #12
0
 def visit_return(self, arg):
     return_type = self.irmethod.rtype
     if return_type[0] != 'V':
         self.write("return (%s) %s;\n" % (get_native_type(return_type), self.get_variable_or_const(arg)))
     else:
         self.write('return;')
Example #13
0
 def visit_param(self, param):
     decl_type = get_native_type(param.get_type())
     if decl_type in ('jstring', 'jobject', 'jarray'):
         self.write('env->NewLocalRef(p%s)' % (param.get_register()))
     else:
         self.write('p%s' % param.get_register())