Exemple #1
0
STATIC void get_jclass_name(jobject obj, char *buf) {
    jclass obj_class = JJ(GetObjectClass, obj);
    jstring name = JJ(CallObjectMethod, obj_class, Class_getName_mid);
    jint len = JJ(GetStringLength, name);
    JJ(GetStringUTFRegion, name, 0, len, buf);
    check_exception();
}
Exemple #2
0
void *plugin_thread(void *arg)
{
  mrb_value ret;
  Plugin *plugin = (Plugin *)arg;
  
  ret = mrb_funcall(plugin->mrb, plugin->plugin_obj, "cycle", 0);
  check_exception("cycle", plugin->mrb);
  return NULL;
}
Exemple #3
0
void sexp_resume() {
  sexp_gc_var1(tmp);
  sexp_gc_preserve1(sexp_resume_ctx, tmp);
  tmp = sexp_list1(sexp_resume_ctx, SEXP_VOID);
  if (sexp_applicablep(sexp_resume_proc)) {
    sexp_resume_proc = check_exception(sexp_resume_ctx, sexp_apply(sexp_resume_ctx, sexp_resume_proc, tmp));
  }
  sexp_gc_release1(sexp_resume_ctx);
}
Exemple #4
0
STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    mp_obj_jobject_t *self = self_in;
    mp_uint_t idx = mp_obj_get_int(index);
    char class_name[64];
    get_jclass_name(self->obj, class_name);
    //printf("class: %s\n", class_name);

    if (class_name[0] == '[') {
        if (class_name[1] == 'L' || class_name[1] == '[') {
            if (value == MP_OBJ_NULL) {
                // delete
                assert(0);
            } else if (value == MP_OBJ_SENTINEL) {
                // load
                jobject el = JJ(GetObjectArrayElement, self->obj, idx);
                return new_jobject(el);
            } else {
                // store
                jvalue jval;
                const char *t = class_name + 1;
                py2jvalue(&t, value, &jval);
                JJ(SetObjectArrayElement, self->obj, idx, jval.l);
                return mp_const_none;
            }
        }
        mp_not_implemented("");
    }

    if (!JJ(IsInstanceOf, self->obj, List_class)) {
        return MP_OBJ_NULL;
    }


    if (value == MP_OBJ_NULL) {
        // delete
        assert(0);
    } else if (value == MP_OBJ_SENTINEL) {
        // load
        jobject el = JJ(CallObjectMethod, self->obj, List_get_mid, idx);
        check_exception();
        return new_jobject(el);
    } else {
        // store
        assert(0);
    }


    return MP_OBJ_NULL;
}
static void
IDirectFBImageProvider_ANDROID_Destruct( IDirectFBImageProvider *thiz )
{
     JNIEnv *env = 0;

     IDirectFBImageProvider_ANDROID_data *data = (IDirectFBImageProvider_ANDROID_data *)thiz->priv;

     (*m_data->java_vm)->AttachCurrentThread( m_data->java_vm, &env, NULL );
     if (!env) {
          D_DEBUG_AT( imageProviderANDROID, "Destruct: Failed to attach current thread to JVM\n" );
          return;
     }

     if (data->image) {
          (*env)->ReleaseByteArrayElements( env, data->pixels, data->image, JNI_ABORT );
          check_exception( env );
     }

     (*env)->DeleteGlobalRef( env, data->pixels );
     check_exception( env );

     if (data->path)
          D_FREE( data->path );
}
Exemple #6
0
int init_plugin_from_file(Plugin *plugin, const char *path, const char *plugin_name)
{
  int fds[2], flags, buffer_size, n;
  
  printf("Loading plugin %s...\n", path);
  plugin->mrb = mrb_open_allocf(profiler_allocf, (void *)path);
  setup_api(plugin->mrb);
  execute_file(plugin->mrb, path);
  execute_file(plugin->mrb, config_path);
  
  C_CHECK("socketpair", socketpair(PF_UNIX, SOCK_DGRAM, 0, fds));
  
  buffer_size = PIPE_BUFFER_SIZE;
  n = sizeof(buffer_size);
  C_CHECK("setsockopt 0 snd", setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n));
  C_CHECK("setsockopt 0 rcv", setsockopt(fds[0], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n));
  
  C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n));
  C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n));
  
  flags = fcntl(fds[0], F_GETFL);
  flags |= O_NONBLOCK;
  if( fcntl(fds[0], F_SETFL, flags) == -1 ){
    perror("fcntl");
    return -1;
  }
  
  
  plugin->host_pipe = fds[0];
  plugin->plugin_pipe = wrap_io(plugin->mrb, fds[1], "w");
  strncpy(plugin->name, plugin_name, sizeof(plugin->name) - 1);
  
  // set ivs
  // struct RClass *rprobe = mrb_class_get(plugin->mrb, "D3Probe");
  // mrb_value probe_klass = mrb_obj_value(rprobe);
  mrb_sym plugin_iv_sym = mrb_intern_cstr(plugin->mrb, "@plugin");
  
  plugin->plugin_obj = mrb_iv_get(plugin->mrb, mrb_obj_value(plugin->mrb->top_self), plugin_iv_sym);
  // pp(plugin->mrb, plugin->plugin_obj, 0);
  
  // associates the c structure with the ruby object
  DATA_PTR(plugin->plugin_obj)  = (void*)plugin;
  
  mrb_funcall(plugin->mrb, plugin->plugin_obj, "after_config", 0);
  check_exception("after_config", plugin->mrb);
  
  return 0;
}
SWIGEXPORT void JNICALL Java_drawerControllib_DrawerControlJNI_openDrawer(JNIEnv *jenv, jclass jcls) {
  (void)jenv;
  (void)jcls;
  {
    char *err;
    clear_exception();
    
    openDrawer();
    
    err = check_exception();
    
    if (err!=NULL) {
      {
        SWIG_JavaException(jenv, SWIG_IOError, err); return ; 
      };
    }
  }
}
Exemple #8
0
/*
 * Signal an interruption. It is executed in the main CPU loop.
 * is_int is TRUE if coming from the int instruction. next_eip is the
 * env->eip value AFTER the interrupt instruction. It is only relevant if
 * is_int is TRUE.
 */
static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
                                           int is_int, int error_code,
                                           int next_eip_addend)
{
    if (!is_int) {
        cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno,
                                      error_code);
        intno = check_exception(env, intno, &error_code);
    } else {
        cpu_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0);
    }

    env->exception_index = intno;
    env->error_code = error_code;
    env->exception_is_int = is_int;
    env->exception_next_eip = env->eip + next_eip_addend;
    cpu_loop_exit(env);
}
Exemple #9
0
  Variant execute() {
    assert(!m_exception);
    if (m_cp == NULL) {
      return false;
    }
    if (m_emptyPost) {
      // As per curl docs, an empty post must set POSTFIELDSIZE to be 0 or
      // the reader function will be called
      curl_easy_setopt(m_cp, CURLOPT_POSTFIELDSIZE, 0);
    }
    m_write.buf.reset();
    m_write.content.clear();
    m_header.clear();
    memset(m_error_str, 0, sizeof(m_error_str));

    {
      IOStatusHelper io("curl_easy_perform", m_url.data());
      SYNC_VM_REGS_SCOPED();
      m_error_no = curl_easy_perform(m_cp);
      check_exception();
    }
    set_curl_statuses(m_cp, m_url.data());

    /* CURLE_PARTIAL_FILE is returned by HEAD requests */
    if (m_error_no != CURLE_OK && m_error_no != CURLE_PARTIAL_FILE) {
      m_write.buf.reset();
      m_write.content.clear();
      return false;
    }

    if (m_write.method == PHP_CURL_RETURN) {
      if (!m_write.buf.empty()) {
        m_write.content = m_write.buf.detach();
      }
      if (!m_write.content.empty()) {
        return m_write.content;
      }
    }
    if (m_write.method == PHP_CURL_RETURN) {
      return String("");
    }
    return true;
  }
Exemple #10
0
/*
 * Signal an interruption. It is executed in the main CPU loop.
 * is_int is TRUE if coming from the int instruction. next_eip is the
 * env->eip value AFTER the interrupt instruction. It is only relevant if
 * is_int is TRUE.
 */
static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
                                           int is_int, int error_code,
                                           int next_eip_addend,
                                           uintptr_t retaddr)
{
    CPUState *cs = CPU(x86_env_get_cpu(env));

    if (!is_int) {
        cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno,
                                      error_code);
        intno = check_exception(env, intno, &error_code);
    } else {
        cpu_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0);
    }

    cs->exception_index = intno;
    env->error_code = error_code;
    env->exception_is_int = is_int;
    env->exception_next_eip = env->eip + next_eip_addend;
    cpu_loop_exit_restore(cs, retaddr);
}
SWIGEXPORT jint JNICALL Java_drawerControllib_DrawerControlJNI_getStatus(JNIEnv *jenv, jclass jcls) {
  jint jresult = 0 ;
  Status result;
  
  (void)jenv;
  (void)jcls;
  {
    char *err;
    clear_exception();
    
    result = (Status)getStatus();
    
    err = check_exception();
    
    if (err!=NULL) {
      {
        SWIG_JavaException(jenv, SWIG_IOError, err); return 0; 
      };
    }
  }
  jresult = (jint)result; 
  return jresult;
}
Exemple #12
0
static int check_message(struct patterns_data* pdata, const char* message, enum pattern_types type, enum auth_credentials credentials)
{
	sqlite3_stmt *res;
	char query[50];
	int error = 0;
	int found = 0;
	int exception = 0;
	const char *tail;
	enum auth_credentials mincred;
	enum auth_credentials maxcred;

	int n = sprintf(query, "SELECT * FROM patterns WHERE type=%d;", type);

	error = sqlite3_prepare_v2(pdata->db, query, n, &res, &tail);

	while (sqlite3_step(res) == SQLITE_ROW)
	{
		auth_string_to_cred((char*) sqlite3_column_text(res, 3), &mincred);
		auth_string_to_cred((char*) sqlite3_column_text(res, 4), &maxcred);
		
		if (mincred > credentials || maxcred < credentials)
		{
			found |= pattern_match(message, (char*) sqlite3_column_text(res, 1));
			if (found)
			{
				exception |= check_exception(pdata, message, sqlite3_column_int(res, 0), credentials);
			}
		}
	}

	sqlite3_finalize(res);

	if (!exception && found)
		return 1;

	return 0;
}
Exemple #13
0
STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    mp_obj_jobject_t *self = self_in;
    if (!JJ(IsInstanceOf, self->obj, List_class)) {
        return MP_OBJ_NULL;
    }

    mp_uint_t idx = mp_obj_get_int(index);

    if (value == MP_OBJ_NULL) {
        // delete
        assert(0);
    } else if (value == MP_OBJ_SENTINEL) {
        // load
        jobject el = JJ(CallObjectMethod, self->obj, List_get_mid, idx);
        check_exception();
        return new_jobject(el);
    } else {
        // store
        assert(0);
    }


return MP_OBJ_NULL;
}
Exemple #14
0
STATIC mp_obj_t call_method(jobject obj, const char *name, jarray methods, bool is_constr, mp_uint_t n_args, const mp_obj_t *args) {
    jvalue jargs[n_args];
//    printf("methods=%p\n", methods);
    jsize num_methods = JJ(GetArrayLength, methods);
    for (int i = 0; i < num_methods; i++) {
        jobject meth = JJ(GetObjectArrayElement, methods, i);
        jobject name_o = JJ(CallObjectMethod, meth, Object_toString_mid);
        const char *decl = JJ(GetStringUTFChars, name_o, NULL);
        const char *arg_types = strchr(decl, '(') + 1;
        //const char *arg_types_end = strchr(arg_types, ')');
//        printf("method[%d]=%p %s\n", i, meth, decl);

        const char *meth_name = NULL;
        const char *ret_type = NULL;
        if (!is_constr) {
            meth_name = strprev(arg_types, '.') + 1;
            ret_type = strprev(meth_name, ' ') - 1;
            ret_type = strprev(ret_type, ' ') + 1;

            int name_len = strlen(name);
            if (strncmp(name, meth_name, name_len/*arg_types - meth_name - 1*/) || meth_name[name_len] != '('/*(*/) {
                goto next_method;
            }
        }
//        printf("method[%d]=%p %s\n", i, meth, decl);
//        printf("!!!%s\n", arg_types);
//        printf("name=%p meth_name=%s\n", name, meth_name);

        bool found = true;
        for (int i = 0; i < n_args && *arg_types != ')'; i++) {
            if (!py2jvalue(&arg_types, args[i], &jargs[i])) {
                goto next_method;
            }

            if (*arg_types == ',') {
                arg_types++;
            }
        }

        if (*arg_types != ')') {
            goto next_method;
        }

        if (found) {
//            printf("found!\n");
            jmethodID method_id = JJ(FromReflectedMethod, meth);
            jobject res;
            mp_obj_t ret;
            if (is_constr) {
                JJ(ReleaseStringUTFChars, name_o, decl);
                res = JJ(NewObjectA, obj, method_id, jargs);
                return new_jobject(res);
            } else {
                if (MATCH(ret_type, "void")) {
                    JJ(CallVoidMethodA, obj, method_id, jargs);
                    check_exception();
                    ret = mp_const_none;
                } else if (MATCH(ret_type, "int")) {
                    jint res = JJ(CallIntMethodA, obj, method_id, jargs);
                    check_exception();
                    ret = mp_obj_new_int(res);
                } else if (MATCH(ret_type, "boolean")) {
                    jboolean res = JJ(CallBooleanMethodA, obj, method_id, jargs);
                    check_exception();
                    ret = mp_obj_new_bool(res);
                } else if (is_object_type(ret_type)) {
                    res = JJ(CallObjectMethodA, obj, method_id, jargs);
                    check_exception();
                    ret = new_jobject(res);
                } else {
                    JJ(ReleaseStringUTFChars, name_o, decl);
                    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "cannot handle return type"));
                }

                JJ(ReleaseStringUTFChars, name_o, decl);
                JJ(DeleteLocalRef, name_o);
                JJ(DeleteLocalRef, meth);
                return ret;
            }
        }

next_method:
        JJ(ReleaseStringUTFChars, name_o, decl);
        JJ(DeleteLocalRef, name_o);
        JJ(DeleteLocalRef, meth);
    }

    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "method not found"));
}
Exemple #15
0
sexp run_main (int argc, char **argv) {
#if SEXP_USE_MODULES
  char *impmod;
#endif
  char *arg;
  const char *prefix=NULL, *suffix=NULL, *main_symbol=NULL, *main_module=NULL;
  sexp_sint_t i, j, c, quit=0, print=0, init_loaded=0, mods_loaded=0,
    fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS, nonblocking=0;
  sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE;
  sexp out=SEXP_FALSE, ctx=NULL, ls;
  sexp_gc_var4(tmp, sym, args, env);
  args = SEXP_NULL;
  env = NULL;

  /* SRFI 22: invoke `main` procedure by default if the interpreter is */
  /* invoked as `scheme-r7rs`. */
  arg = strrchr(argv[0], '/');
  if (strncmp((arg == NULL ? argv[0] : arg + 1), "scheme-r7rs", strlen("scheme-r7rs")) == 0) {
    main_symbol = "main";
    /* skip option parsing since we can't pass `--` before the name of script */
    /* to avoid misinterpret the name as options when the interpreter is */
    /* executed via `#!/usr/env/bin scheme-r7rs` shebang.  */
    i = 1;
    goto done_options;
  }

  /* parse options */
  for (i=1; i < argc && argv[i][0] == '-'; i++) {
    switch ((c=argv[i][1])) {
    case 'D':
      init_context();
      arg = (argv[i][2] == '\0') ? argv[++i] : argv[i]+2;
      sym = sexp_intern(ctx, arg, -1);
      ls = sexp_global(ctx, SEXP_G_FEATURES);
      if (sexp_pairp(ls)) {
        for (; sexp_pairp(sexp_cdr(ls)); ls=sexp_cdr(ls))
          ;
        sexp_cdr(ls) = sexp_cons(ctx, sym, SEXP_NULL);
      }
      break;
    case 'e':
    case 'p':
      mods_loaded = 1;
      load_init(0);
      print = (argv[i][1] == 'p');
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('e', arg);
      tmp = check_exception(ctx, sexp_eval_string(ctx, arg, -1, env));
      if (print) {
        if (! sexp_oportp(out))
          out = sexp_eval_string(ctx, "(current-output-port)", -1, env);
        sexp_write(ctx, tmp, out);
        sexp_write_char(ctx, '\n', out);
      }
      quit = 1;
      break;
    case 'l':
      mods_loaded = 1;
      load_init(0);
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('l', arg);
      check_exception(ctx, sexp_load_module_file(ctx, arg, env));
      break;
    case 'x':
      prefix = sexp_environment_prefix;
      suffix = sexp_environment_suffix;
    case 'm':
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      if (c == 'x') {
        if (strcmp(arg, "chibi.primitive") == 0) {
          goto load_primitive;
        } else if (strcmp(arg, "scheme.small") == 0) {
          load_init(0);
          break;
        }
      } else {
        prefix = sexp_import_prefix;
        suffix = sexp_import_suffix;
      }
      mods_loaded = 1;
      load_init(c == 'x');
#if SEXP_USE_MODULES
      check_nonull_arg(c, arg);
      impmod = make_import(prefix, arg, suffix);
      tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, (c=='x' ? sexp_global(ctx, SEXP_G_META_ENV) : env)));
      free(impmod);
      if (c == 'x') {
        sexp_set_parameter(ctx, sexp_global(ctx, SEXP_G_META_ENV), sexp_global(ctx, SEXP_G_INTERACTION_ENV_SYMBOL), tmp);
        sexp_context_env(ctx) = env = tmp;
        sexp_add_import_binding(ctx, env);
        tmp = sexp_param_ref(ctx, env, sexp_global(ctx, SEXP_G_CUR_OUT_SYMBOL));
        if (tmp != NULL && !sexp_oportp(tmp)) {
          sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0);
        }
      }
#endif
      break;
    load_primitive:
    case 'Q':
      init_context();
      mods_loaded = 1;
      if (! init_loaded++)
        sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0);
      handle_noarg();
      break;
    case 'q':
      argv[i--] = (char*)"-xchibi";
      break;
    case 'A':
      init_context();
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('A', arg);
      sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_TRUE);
      break;
    case 'I':
      init_context();
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('I', arg);
      sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_FALSE);
      break;
#if SEXP_USE_GREEN_THREADS
    case 'b':
      nonblocking = 1;
      break;
#endif
    case '-':
      if (argv[i][2] == '\0') {
        i++;
        goto done_options;
      }
      sexp_usage(1);
    case 'h':
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('h', arg);
#if ! SEXP_USE_BOEHM
      heap_size = strtoul(arg, &arg, 0);
      if (sexp_isalpha((unsigned char)*arg)) heap_size *= multiplier(*arg++);
      if (*arg == '/') {
        heap_max_size = strtoul(arg+1, &arg, 0);
        if (sexp_isalpha((unsigned char)*arg)) heap_max_size *= multiplier(*arg++);
      }
#endif
      break;
#if SEXP_USE_IMAGE_LOADING
    case 'i':
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      if (ctx) {
        fprintf(stderr, "-:i <file>: image files must be loaded first\n");
        exit_failure();
      }
      ctx = sexp_load_image(arg, 0, heap_size, heap_max_size);
      if (!ctx || !sexp_contextp(ctx)) {
        fprintf(stderr, "-:i <file>: couldn't open image file for reading: %s\n", arg);
        fprintf(stderr, "            %s\n", sexp_load_image_err());
        ctx = NULL;
      } else {
        env = sexp_load_standard_params(ctx, sexp_context_env(ctx), nonblocking);
        init_loaded++;
      }
      break;
    case 'd':
      if (! init_loaded++) {
        init_context();
        env = sexp_load_standard_env(ctx, env, SEXP_SEVEN);
      }
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      if (sexp_save_image(ctx, arg) != SEXP_TRUE) {
        fprintf(stderr, "-d <file>: couldn't save image to file: %s\n", arg);
        fprintf(stderr, "           %s\n", sexp_load_image_err());
        exit_failure();
      }
      quit = 1;
      break;
#endif
    case 'V':
      load_init(1);
      if (! sexp_oportp(out))
        out = sexp_eval_string(ctx, "(current-output-port)", -1, env);
      sexp_write_string(ctx, sexp_version_string, out);
      tmp = sexp_env_ref(ctx, env, sym=sexp_intern(ctx, "*features*", -1), SEXP_NULL);
      sexp_write(ctx, tmp, out);
      sexp_newline(ctx, out);
      return SEXP_TRUE;
#if SEXP_USE_FOLD_CASE_SYMS
    case 'f':
      fold_case = 1;
      init_context();
      sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE;
      handle_noarg();
      break;
#endif
    case 'R':
      main_module = argv[i][2] != '\0' ? argv[i]+2 :
        (i+1 < argc && argv[i+1][0] != '-') ? argv[++i] : "chibi.repl";
      if (main_symbol == NULL) main_symbol = "main";
      break;
    case 'r':
      main_symbol = argv[i][2] == '\0' ? "main" : argv[i]+2;
      break;
    case 's':
      init_context(); sexp_global(ctx, SEXP_G_STRICT_P) = SEXP_TRUE;
      handle_noarg();
      break;
    case 'T':
      init_context(); sexp_global(ctx, SEXP_G_NO_TAIL_CALLS_P) = SEXP_TRUE;
      handle_noarg();
      break;
    case 't':
      mods_loaded = 1;
      load_init(1);
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
#if SEXP_USE_MODULES
      check_nonull_arg('t', arg);
      suffix = strrchr(arg, '.');
      sym = sexp_intern(ctx, suffix + 1, -1);
      *(char*)suffix = '\0';
      impmod = make_import(sexp_trace_prefix, arg, sexp_trace_suffix);
      tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, sexp_meta_env(ctx)));
      if (!(tmp && sexp_envp(tmp))) {
        fprintf(stderr, "couldn't find library to trace: %s\n", impmod);
      } else if (!((sym = sexp_env_cell(ctx, tmp, sym, 0)))) {
        fprintf(stderr, "couldn't find binding to trace: %s in %s\n", suffix + 1, impmod);
      } else {
        sym = sexp_list1(ctx, sym);
        tmp = check_exception(ctx, sexp_eval_string(ctx, "(environment '(chibi trace))", -1, sexp_meta_env(ctx)));
        tmp = sexp_env_ref(ctx, tmp, sexp_intern(ctx, "trace-cell", -1), 0);
        if (tmp && sexp_procedurep(tmp))
          check_exception(ctx, sexp_apply(ctx, tmp, sym));
      }
      free(impmod);
#endif
      break;
    default:
      fprintf(stderr, "unknown option: %s\n", argv[i]);
      /* ... FALLTHROUGH ... */
    case '?':
      sexp_usage(1);
    }
  }

 done_options:
  if (!quit || main_symbol != NULL) {
    init_context();
    /* build argument list */
    if (i < argc)
      for (j=argc-1; j>=i; j--)
        args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[j],-1), args);
    if (i >= argc || main_symbol != NULL)
      args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[0],-1), args);
    load_init(i < argc || main_symbol != NULL);
    sexp_set_parameter(ctx, sexp_meta_env(ctx), sym=sexp_intern(ctx, sexp_argv_symbol, -1), args);
    if (i >= argc && main_symbol == NULL) {
      /* no script or main, run interactively */
      repl(ctx, env);
    } else {
#if SEXP_USE_MODULES
      /* load the module or script */
      if (main_module != NULL) {
        impmod = make_import("(load-module '(", main_module, "))");
        env = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, sexp_meta_env(ctx)));
        if (sexp_vectorp(env)) env = sexp_vector_ref(env, SEXP_ONE);
        free(impmod);
        check_exception(ctx, env);
        if (!sexp_envp(env)) {
          fprintf(stderr, "couldn't find module: %s\n", main_module);
          exit_failure();
        }
      } else
#endif
      if (i < argc) {   /* script usage */
#if SEXP_USE_MODULES
        /* reset the environment to have only the `import' and */
        /* `cond-expand' bindings */
        if (!mods_loaded) {
          env = sexp_make_env(ctx);
          sexp_set_parameter(ctx, sexp_meta_env(ctx),
                             sexp_global(ctx, SEXP_G_INTERACTION_ENV_SYMBOL), env);
          sexp_context_env(ctx) = env;
          sym = sexp_intern(ctx, "repl-import", -1);
          tmp = sexp_env_ref(ctx, sexp_meta_env(ctx), sym, SEXP_VOID);
          sym = sexp_intern(ctx, "import", -1);
          check_exception(ctx, sexp_env_define(ctx, env, sym, tmp));
          sym = sexp_intern(ctx, "cond-expand", -1);
          tmp = sexp_env_cell(ctx, sexp_meta_env(ctx), sym, 0);
#if SEXP_USE_RENAME_BINDINGS
          sexp_env_rename(ctx, env, sym, tmp);
#endif
          sexp_env_define(ctx, env, sym, sexp_cdr(tmp));
        }
#endif
        sexp_context_tracep(ctx) = 1;
        tmp = sexp_env_bindings(env);
#if SEXP_USE_MODULES
        /* use scheme load if possible for better stack traces */
        sym = sexp_intern(ctx, "load", -1);
        tmp = sexp_env_ref(ctx, sexp_meta_env(ctx), sym, SEXP_FALSE);
        if (sexp_procedurep(tmp)) {
          sym = sexp_c_string(ctx, argv[i], -1);
          sym = sexp_list2(ctx, sym, env);
          tmp = check_exception(ctx, sexp_apply(ctx, tmp, sym));
        } else
#endif
          tmp = check_exception(ctx, sexp_load(ctx, sym=sexp_c_string(ctx, argv[i], -1), env));
#if SEXP_USE_WARN_UNDEFS
        sexp_warn_undefs(ctx, env, tmp, SEXP_VOID);
#endif
#ifdef EMSCRIPTEN
        if (sexp_applicablep(tmp)) {
          sexp_resume_ctx = ctx;
          sexp_resume_proc = tmp;
          sexp_preserve_object(ctx, sexp_resume_proc);
          emscripten_exit_with_live_runtime();
        }
#endif
      }
      /* SRFI-22: run main if specified */
      if (main_symbol) {
        sym = sexp_intern(ctx, main_symbol, -1);
        tmp = sexp_env_ref(ctx, env, sym, SEXP_FALSE);
        if (sexp_procedurep(tmp)) {
          args = sexp_list1(ctx, sexp_cdr(args));
          check_exception(ctx, sexp_apply(ctx, tmp, args));
        } else {
          fprintf(stderr, "couldn't find main binding: %s in %s\n", main_symbol, main_module ? main_module : argv[i]);
        }
      }
    }
  }

  sexp_gc_release4(ctx);
  if (sexp_destroy_context(ctx) == SEXP_FALSE) {
    fprintf(stderr, "destroy_context error\n");
    return SEXP_FALSE;
  }
  return SEXP_TRUE;
}
Exemple #16
0
int invoke_dex_method(const char* dexPath, const char* dexOptDir, const char *libraryDir, const char* className, const char* methodName) {
	int ret = 0;
	const char *err = NULL;

    //获取JNIEnv
    void* handle = dlopen("/system/lib/libandroid_runtime.so", RTLD_NOW);
    getJNIEnv = (JNIEnv* (*)())dlsym(handle, "_ZN7android14AndroidRuntime9getJNIEnvEv");
	LOGD("Runtime handle: %lx, getJNIEnv: %lx\n", (unsigned long)handle, (unsigned long)getJNIEnv);
    JNIEnv* env = getJNIEnv();

    //调用ClassLoader中的getSystemClassLoader方法获取当前进程的ClassLoader
    jclass classloaderClass = env->FindClass("java/lang/ClassLoader");
	if ( (err=check_exception(env)) != NULL ) {
		//return ERR_FIND_CLASS_FAILED;
		LOGW("error find class, err: %s\n", err);
		return -1;
	}
    jmethodID getsysloaderMethod = env->GetStaticMethodID(classloaderClass, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error get class getSystemClassLoader, err: %s\n", err);
		return -1;
	}
    jobject loader = env->CallStaticObjectMethod(classloaderClass, getsysloaderMethod);
	if ( loader == NULL ) {
		LOGW("call getSystemClassLoader return NULL!!\n");
		return -1;
	}
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error call getSystemClassLoader, err: %s\n", err);
		return -1;
	}
	LOGD("get system class loader\n");

    //以进程现有的ClassLoader、要注入的dex路径为参数构造注入后的DexClassLoader
    jstring dexpath = env->NewStringUTF(dexPath);
    jstring dex_odex_path = env->NewStringUTF(dexOptDir);
    jstring library_path = env->NewStringUTF(libraryDir);
    jclass dexLoaderClass = env->FindClass("dalvik/system/DexClassLoader");
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error find class dalvik/system/DexClassLoader, err: %s\n", err);
		return -1;
	}

	LOGD("get dexClassLoader init\n");
    jmethodID initDexLoaderMethod = env->GetMethodID(dexLoaderClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error get DexClassLoader init method, err: %s\n", err);
		return -1;
	}
	LOGD("dexClassLoader init, dexLoaderClass: %lx, initDexLoaderMethod: %lx, dexpath: %lx, dex_odex_path: %lx, loader: %lx\n", 
		(unsigned long)dexLoaderClass, (unsigned long)initDexLoaderMethod, (unsigned long)dexpath, (unsigned long)dex_odex_path, (unsigned long)loader);
    jobject dexLoader = env->NewObject(dexLoaderClass, initDexLoaderMethod, dexpath, dex_odex_path, library_path, loader);
    //jobject dexLoader = env->NewObject(dexLoaderClass, initDexLoaderMethod, dexpath, dex_odex_path, NULL, loader);
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error call DexClassLoader init, dexLoader: %lx, err: %s\n", (unsigned long)dexLoader, err);
		return -1;
	}
	LOGD("create dexClassLoader\n");

    //获取新出炉的DexClassLoader中findClass方法加载dex中要执行代码所在类
    jmethodID findclassMethod = env->GetMethodID(dexLoaderClass,"loadClass","(Ljava/lang/String;)Ljava/lang/Class;");
    //jmethodID findclassMethod = env->GetMethodID(dexLoaderClass,"findClass","(Ljava/lang/String;)Ljava/lang/Class;");
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error get DexClassLoader findClass, err: %s \n", err);
		return -1;
	}
    jstring javaClassName = env->NewStringUTF(className);
    jclass javaClientClass = (jclass)env->CallObjectMethod(dexLoader,findclassMethod,javaClassName);
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error call DexClassLoader findClass, err: %s \n", err);
		return -1;
	}
	LOGD("find class: %s\n", className);

    //获取注入dex中要执行的方法
    jmethodID start_inject_method = env->GetStaticMethodID(javaClientClass, methodName, "(Ljava/lang/String;Ljava/lang/String;)Z");
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error get class method, err: %s\n", err);
		return -1;
	}
	LOGD("get static method: %s\n", methodName);
    //执行之注意目标方法必须是静态公有的
    //env->CallStaticVoidMethod(javaClientClass,start_inject_method);
    bool inject_ret = env->CallStaticBooleanMethod(javaClientClass,start_inject_method, dexpath, library_path);
	if ( (err=check_exception(env)) != NULL ) {
		LOGW("error call class method, inject_ret: %d, err: %s\n", inject_ret, err);
		return -1;
	}
	LOGD("call static method: %s, inject_ret: %d\n", methodName, inject_ret);

	ret = inject_ret ? 0 : -1;
	return ret;
}
Exemple #17
0
void run_main (int argc, char **argv) {
  char *arg, *impmod, *p;
  sexp out=SEXP_FALSE, env=NULL, ctx=NULL;
  sexp_sint_t i, j, len, quit=0, print=0, init_loaded=0, fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS;
  sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE;
  sexp_gc_var2(tmp, args);
  args = SEXP_NULL;

  /* parse options */
  for (i=1; i < argc && argv[i][0] == '-'; i++) {
    switch (argv[i][1]) {
    case 'e':
    case 'p':
      load_init();
      print = (argv[i][1] == 'p');
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('e', arg);
      tmp = check_exception(ctx, sexp_eval_string(ctx, arg, -1, env));
      if (print) {
        if (! sexp_oportp(out))
          out = sexp_eval_string(ctx, "(current-output-port)", -1, env);
        sexp_write(ctx, tmp, out);
        sexp_write_char(ctx, '\n', out);
      }
      quit = 1;
      break;
    case 'l':
      load_init();
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('l', arg);
      check_exception(ctx, sexp_load_module_file(ctx, arg, env));
      break;
    case 'm':
      load_init();
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('m', arg);
      len = strlen(arg)+strlen(sexp_import_prefix)+strlen(sexp_import_suffix);
      impmod = (char*) malloc(len+1);
      strcpy(impmod, sexp_import_prefix);
      strcpy(impmod+strlen(sexp_import_prefix), arg);
      strcpy(impmod+len-+strlen(sexp_import_suffix), sexp_import_suffix);
      impmod[len] = '\0';
      for (p=impmod; *p; p++)
        if (*p == '.') *p=' ';
      check_exception(ctx, sexp_eval_string(ctx, impmod, -1, env));
      free(impmod);
      break;
    case 'q':
      init_context();
      if (! init_loaded++)
        sexp_load_standard_ports(ctx, env, stdin, stdout, stderr, 0);
      break;
    case 'A':
      init_context();
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('A', arg);
      sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_TRUE);
      break;
    case 'I':
      init_context();
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('I', arg);
      sexp_add_module_directory(ctx, tmp=sexp_c_string(ctx,arg,-1), SEXP_FALSE);
      break;
    case '-':
      i++;
      goto done_options;
    case 'h':
      arg = ((argv[i][2] == '\0') ? argv[++i] : argv[i]+2);
      check_nonull_arg('h', arg);
      heap_size = strtoul(arg, &arg, 0);
      if (sexp_isalpha(*arg)) heap_size *= multiplier(*arg++);
      if (*arg == '/') {
        heap_max_size = strtoul(arg+1, &arg, 0);
        if (sexp_isalpha(*arg)) heap_max_size *= multiplier(*arg++);
      }
      break;
    case 'V':
      load_init();
      if (! sexp_oportp(out))
        out = sexp_eval_string(ctx, "(current-output-port)", -1, env);
      sexp_write_string(ctx, sexp_version_string, out);
      tmp = sexp_env_ref(env, sexp_intern(ctx, "*features*", -1), SEXP_NULL);
      sexp_write(ctx, tmp, out);
      sexp_newline(ctx, out);
      return;
#if SEXP_USE_FOLD_CASE_SYMS
    case 'f':
      fold_case = 1;
      if (ctx) sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE;
      break;
#endif
    default:
      fprintf(stderr, "unknown option: %s\n", argv[i]);
      exit_failure();
    }
  }

 done_options:
  if (! quit) {
    load_init();
    if (i < argc)
      for (j=argc-1; j>i; j--)
        args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[j],-1), args);
    else
      args = sexp_cons(ctx, tmp=sexp_c_string(ctx,argv[0],-1), args);
    sexp_env_define(ctx, env, sexp_intern(ctx, sexp_argv_symbol, -1), args);
    sexp_eval_string(ctx, sexp_argv_proc, -1, env);
    if (i < argc) {             /* script usage */
      sexp_context_tracep(ctx) = 1;
      check_exception(ctx, sexp_load(ctx, tmp=sexp_c_string(ctx, argv[i], -1), env));
      tmp = sexp_intern(ctx, "main", -1);
      tmp = sexp_env_ref(env, tmp, SEXP_FALSE);
      if (sexp_procedurep(tmp)) {
        args = sexp_list1(ctx, args);
        check_exception(ctx, sexp_apply(ctx, tmp, args));
      }
    } else {
      repl(ctx, env);
    }
  }

  sexp_gc_release2(ctx);
  sexp_destroy_context(ctx);
}
Exemple #18
0
int main(int argc, char const *argv[])
{
#ifdef _MEM_PROFILER
  uint8_t checkpoint_set = 0;
#endif
  fd_set rfds;
  char buffer[PIPE_BUFFER_SIZE];
  int i, n;
  Plugin plugins[MAX_PLUGINS];
  int plugins_count = 0;
  mrb_state *mrb;
  mrb_value r_output, r_plugins_list;
  mrb_sym output_gv_sym, plugins_to_load_gv_sym;
  
  printf("Version: %s\n", PROBE_VERSION);
  
  if( argc != 2 ){
    printf("Usage: %s <config_path>\n", argv[0]);
    exit(1);
  }
  
#ifdef _MEM_PROFILER
  init_profiler();
#endif
  
  config_path = argv[1];
  
  printf("Initializing core...\n");
  mrb = mrb_open_allocf(profiler_allocf, "main");
  output_gv_sym = mrb_intern_cstr(mrb, "$output");
  plugins_to_load_gv_sym = mrb_intern_cstr(mrb, "$plugins_to_load");
  setup_api(mrb);
  execute_file(mrb, "plugins/main.rb");
  execute_file(mrb, config_path);
  
  printf("Loading plugins...\n");
  r_plugins_list = mrb_gv_get(mrb, plugins_to_load_gv_sym);
  for(i = 0; i< mrb_ary_len(mrb, r_plugins_list); i++){
    char *path, tmp[100];
    int ssize;
    
    mrb_value r_plugin_name = mrb_ary_ref(mrb, r_plugins_list, i);
    const char *plugin_name = mrb_string_value_cstr(mrb, &r_plugin_name);
    
    snprintf(tmp, sizeof(tmp) - 1, "plugins/%s.rb", plugin_name);
    ssize = strlen(tmp);
    
    path = malloc(ssize + 1);
    strncpy(path, tmp, ssize);
    path[ssize] = '\0';
    
    if( access(path, F_OK) == -1 ){
      printf("cannot open plugin file \"%s\": %s\n", path, strerror(errno));
      exit(1);
    }
    
    init_plugin_from_file(&plugins[plugins_count], path, plugin_name); plugins_count++;
  }
  
  printf("Instanciating output class...\n");
  r_output = mrb_gv_get(mrb, output_gv_sym);
  interval = mrb_fixnum(mrb_funcall(mrb, r_output, "interval", 0));
  
  printf("Interval set to %dms\n", (int)interval);
  
  printf("Sending initial report...\n");
  mrb_funcall(mrb, r_output, "send_report", 0);
  
  if (mrb->exc) {
    mrb_print_error(mrb);
    
    exit(1);
  }

  
  // start all the threads
  for(i= 0; i< plugins_count; i++){
    // printf("== plugin %d\n", i);
    n = pthread_create(&plugins[i].thread, NULL, plugin_thread, (void *)&plugins[i]);
    if( n < 0 ){
      fprintf(stderr, "create failed\n");
    }
  }
  
  if( signal(SIGINT, clean_exit) == SIG_ERR){
    perror("signal");
    exit(1);
  }
  
  while(running){
    int fds[MAX_PLUGINS];
    int maxfd = 0, ai;
    struct timeval tv;
    mrb_value r_buffer;
    struct timeval cycle_started_at, cycle_completed_at;
    
    gettimeofday(&cycle_started_at, NULL);
    
    bzero(fds, sizeof(int) * MAX_PLUGINS);
    
    // ask every plugin to send their data
    for(i= 0; i< plugins_count; i++){
      strcpy(buffer, "request");
      if( send(plugins[i].host_pipe, buffer, strlen(buffer), 0) == -1 ){
        printf("send error when writing in pipe connected to plugin '%s'\n", plugins[i].name);
      }
      fds[i] = plugins[i].host_pipe;
      // printf("sent request to %d\n", i);
    }
    
    // printf("waiting answers...\n");
    // and now wait for each answer
    while(1){
      int left = 0;
      
      FD_ZERO(&rfds);
      
      for(i = 0; i< MAX_PLUGINS; i++){
        if( fds[i] != NOPLUGIN_VALUE ){
          FD_SET(fds[i], &rfds);
          left++;
          if( fds[i] > maxfd )
            maxfd = fds[i];
        }
      }
      
      // printf("left: %d %d\n", left, left <= 0);
      
      if( !running || (0 == left) )
        break;
      
      // substract 20ms to stay below the loop delay
      fill_timeout(&tv, cycle_started_at, interval - 20);
      // printf("before select\n");
      n = select(maxfd + 1, &rfds, NULL, NULL, &tv);
      // printf("after select: %d\n", n);
      if( n > 0 ){
        // find out which pipes have data
        for(i = 0; i< MAX_PLUGINS; i++){
          if( (fds[i] != NOPLUGIN_VALUE) && FD_ISSET(fds[i], &rfds) ){
            while (1){
              struct timeval answered_at;
              n = read(fds[i], buffer, sizeof(buffer));
              if( n == -1 ){
                if( errno != EAGAIN )
                  perror("read");
                break;
              }
              
              if( n == PIPE_BUFFER_SIZE ){
                printf("PIPE_BUFFER_SIZE is too small, increase it ! (value: %d)\n", PIPE_BUFFER_SIZE);
                continue;
              }
              
              gettimeofday(&answered_at, NULL);
              // printf("received answer from %s in %u ms\n", (const char *) plugins[i].mrb->ud,
              //     (uint32_t)((answered_at.tv_sec - cycle_started_at.tv_sec) * 1000 +
              //     (answered_at.tv_usec - cycle_started_at.tv_usec) / 1000)
              //   );
              
              buffer[n] = 0x00;
              
              ai = mrb_gc_arena_save(mrb);
              r_buffer = mrb_str_buf_new(mrb, n);
              mrb_str_buf_cat(mrb, r_buffer, buffer, n);
              
              // mrb_funcall(mrb, r_output, "tick", 0);
              mrb_funcall(mrb, r_output, "add", 1, r_buffer);
              check_exception("add", mrb);
              
              // pp(mrb, r_output, 0);
              
              mrb_gc_arena_restore(mrb, ai);
            }
            
            fds[i] = 0;
          }
        }
      }
      else if( n == 0 )  {
        printf("no responses received from %d plugins.\n", left);
        break;
        // timeout
      }
      else {
        perror("select");
      }
    }
    
    int idx = mrb_gc_arena_save(mrb);
    mrb_funcall(mrb, r_output, "flush", 0);
    check_exception("flush", mrb);
    mrb_gc_arena_restore(mrb, idx);
    
    // and now sleep until the next cycle
    gettimeofday(&cycle_completed_at, NULL);
    
  #ifdef _MEM_PROFILER
    if( checkpoint_set ){
      print_allocations();
    }
  #endif
    
    // force a gc run at the end of each cycle
    mrb_full_gc(mrb);
    // printf("[main] capa: %d / %d\n", mrb->arena_idx, mrb->arena_capa);
    // for(i= 0; i< plugins_count; i++){
    //   printf("[%s] capa: %d / %d\n", plugins[i].name, plugins[i].mrb->arena_idx, plugins[i].mrb->arena_capa);
    // }
  
  #ifdef _MEM_PROFILER
    checkpoint_set = 1;
    // and set starting point
    profiler_set_checkpoint();
  #endif

    
  #ifdef _MEM_PROFILER_RUBY
    // dump VMS state
    dump_state(mrb);
    for(i= 0; i< plugins_count; i++){
      dump_state(plugins[i].mrb);
    }
  #endif
    
    fflush(stdout);
    sleep_delay(&cycle_started_at, &cycle_completed_at, interval);
  }
  
  printf("Sending exit signal to all plugins...\n");
  strcpy(buffer, "exit");
  for(i= 0; i< plugins_count; i++){
    C_CHECK("send", send(plugins[i].host_pipe, buffer, strlen(buffer), 0) );
  }
  
  printf("Giving some time for threads to exit...\n\n");
  really_sleep(2000);
  
  
  for(i= 0; i< plugins_count; i++){
    int ret = pthread_kill(plugins[i].thread, 0);
    
    // if a success is returned then the thread is still alive
    // which means the thread did not acknoledged the exit message
    // kill it.
    if( ret == 0 ){
      printf("    - plugin \"%s\" failed to exit properly, killing it...\n", (const char *) plugins[i].mrb->ud);
      pthread_cancel(plugins[i].thread);
    }
    else {
      printf("    - plugin \"%s\" exited properly.\n", (const char *) plugins[i].mrb->allocf_ud);
    }
    
    if( pthread_join(plugins[i].thread, NULL) < 0){
      fprintf(stderr, "join failed\n");
    }
    
    mrb_close(plugins[i].mrb);
  }
  
  mrb_close(mrb);
  
  printf("Exited !\n");
  return 0;
}
Exemple #19
0
Fichier : ocode.c Projet : pcpa/owl
void
oeval_ast(oast_t *ast)
{
    oast_t		*temp;
    orecord_t		*record;
    osymbol_t		*symbol;

    switch (ast->token) {
	case tok_set:		case tok_andset:
	case tok_orset:		case tok_xorset:
	case tok_mul2set:	case tok_div2set:
	case tok_shlset:	case tok_shrset:
	case tok_addset:	case tok_subset:
	case tok_mulset:	case tok_divset:
	case tok_trunc2set:	case tok_remset:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    break;
	case tok_vector:
	    oeval_ast(ast->l.ast);
	    if (ast->r.ast == null)
		oparse_error(ast, "expecting offset");
	    oeval_ast(ast->r.ast);
	    /* validate element reference */
	    oeval_ast_tag(ast);
	    break;
	case tok_dot:
	    oeval_ast(ast->l.ast);
	    /* validate field reference */
	    oeval_ast_tag(ast);
	    break;
	case tok_explicit:
	    oeval_ast_tag(ast);
	    break;
	case tok_andand:	case tok_oror:
	case tok_ne:		case tok_lt:
	case tok_le:		case tok_eq:
	case tok_ge:		case tok_gt:
	case tok_and:		case tok_or:
	case tok_xor:		case tok_mul2:
	case tok_div2:		case tok_shl:
	case tok_shr:		case tok_add:
	case tok_sub:		case tok_mul:
	case tok_div:		case tok_trunc2:
	case tok_rem:		case tok_complex:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    ofold(ast);
	    break;
	case tok_inc:		case tok_dec:
	case tok_postinc:	case tok_postdec:
	case tok_new:		case tok_thread:
	    oeval_ast(ast->l.ast);
	    break;
	case tok_init:		case tok_vecnew:
	    oeval_ast(ast->r.ast);
	    break;
	case tok_com:		case tok_plus:
	case tok_neg:		case tok_not:
	case tok_integer_p:	case tok_rational_p:
	case tok_float_p:	case tok_real_p:
	case tok_complex_p:	case tok_number_p:
	case tok_finite_p:	case tok_inf_p:
	case tok_nan_p:		case tok_num:
	case tok_den:		case tok_real:
	case tok_imag:		case tok_signbit:
	case tok_abs:		case tok_signum:
	case tok_rational:	case tok_arg:
	case tok_conj:		case tok_floor:
	case tok_trunc:		case tok_round:
	case tok_ceil:		case tok_sqrt:
	case tok_cbrt:		case tok_sin:
	case tok_cos:		case tok_tan:
	case tok_asin:		case tok_acos:
	case tok_atan:		case tok_sinh:
	case tok_cosh:		case tok_tanh:
	case tok_asinh:		case tok_acosh:
	case tok_atanh:		case tok_proj:
	case tok_exp:		case tok_log:
	case tok_log2:		case tok_log10:
	    oeval_ast(ast->l.ast);
	    ofold(ast);
	    break;
	case tok_atan2:		case tok_pow:
	case tok_hypot:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    ofold(ast);
	    break;
	case tok_subtypeof:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    break;
	case tok_sizeof:
	    eval_ast_sizeof(ast);
	    break;
	case tok_typeof:
	    eval_ast_typeof(ast);
	    break;
	case tok_renew:
	    eval_ast_renew(ast);
	    break;
	case tok_question:
	    oeval_ast(ast->t.ast);
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    break;
	case tok_if:
	    eval_ast_stat(ast->t.ast);
	    eval_ast_stat(ast->l.ast);
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_return:
	    check_exception(ast);
	case tok_throw:
	    if (ast->l.ast)
		oeval_ast(ast->l.ast);
	    break;
	case tok_switch:
	    eval_ast_stat(ast->t.ast);
	    eval_ast_stat(ast->c.ast);
	    break;
	case tok_for:
	    eval_ast_stat(ast->l.ast);
	    eval_ast_stat(ast->t.ast);
	    eval_ast_stat(ast->r.ast);
	    eval_ast_stat(ast->c.ast);
	    break;
	case tok_do:		case tok_while:
	    eval_ast_stat(ast->c.ast);
	    eval_ast_stat(ast->t.ast);
	    break;
	case tok_list:
	    temp = ast->l.ast;
	    eval_ast_stat(temp);
	    /*   Check inner fields for the sake of clean debug output. */
	    if (temp->next == null && temp->r.value == null &&
		temp->t.value == null && temp->c.value == null)
		omove_ast_up_full(ast, temp);
	    break;
	case tok_call:
	    if (ast->l.ast->token != tok_symbol)
		oeval_ast(ast->l.ast);
	    else
		update_symbol(ast->l.ast, true);
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_stat:		case tok_code:
	case tok_data:		case tok_finally:
	    eval_ast_stat(ast->l.ast);
	    break;
	case tok_decl:
	    oeval_ast(ast->l.ast);
	    eval_ast_decl(ast->r.ast);
	    break;
	case tok_symbol:
	    update_symbol(ast, false);
	    break;
	case tok_goto:
	    eval_ast_goto(ast);
	    break;
	case tok_try:
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_catch:
	    eval_ast_decl(ast->l.ast->r.ast);
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_break:		case tok_continue:
	    check_exception(ast);
	case tok_type:		case tok_number:	case tok_string:
	case tok_class:		case tok_label:		case tok_case:
	case tok_default:	case tok_function:	case tok_ellipsis:
	case tok_this:		case tok_enum:
	    break;
	case tok_namespace:
	    record = current_record;
	    assert(ast->l.ast->token == tok_symbol);
	    symbol = ast->l.ast->l.value;
	    current_record = symbol->value;
	    assert(otype(current_record) == t_namespace);
	    eval_ast_stat(ast->c.ast);
	    current_record = record;
	    break;
	default:
#if DEBUG
	    oparse_warn(ast,
			"code: not handling %s", otoken_to_charp(ast->token));
#endif
	    break;
    }
}
static DFBResult
decodeImage( IDirectFBImageProvider_ANDROID_data *data )
{
     DFBResult   ret;
     JNIEnv     *env     = 0;
     jclass      clazz   = 0;
     jclass      clazz2  = 0;
     jmethodID   method  = 0;
     jstring     path    = 0;
     jobject     buffer  = 0;
     jbyteArray  pixels  = 0;
     jobject     bitmap  = 0;
     jobject     convert = 0;
     jobject     config  = 0;
     jstring     format  = 0;
     const char *fvalue  = 0;
     char       *sdata   = 0;
     int         ssize   = 0;

     if (data->image)
          return DFB_OK;

     (*m_data->java_vm)->AttachCurrentThread( m_data->java_vm, &env, NULL );
     if (!env) {
          D_DEBUG_AT( imageProviderANDROID, "decodeImage: Failed to attach current thread to JVM\n" );
          return DFB_INIT;
     }

     clazz = (*env)->FindClass( env, "android/graphics/BitmapFactory" );
     if (check_exception( env ) || !clazz)
          return DFB_INIT;

     if (data->path) {
          method = (*env)->GetStaticMethodID( env, clazz, "decodeFile", "(Ljava/lang/String;)Landroid/graphics/Bitmap;" );
          if (check_exception( env ) || !method)
               return DFB_INIT;

          path = (*env)->NewStringUTF( env, data->path );
          if (check_exception( env ) || !path)
               return DFB_NOSYSTEMMEMORY;

          bitmap = (*env)->CallStaticObjectMethod( env, clazz, method, path );
          if (check_exception( env ) || !bitmap) {
               (*env)->DeleteLocalRef( env, path );
               check_exception( env );
               return DFB_INIT;
          }

          (*env)->DeleteLocalRef( env, path );
          if (check_exception( env ))
               return DFB_INIT;
     }
     else {
          jbyteArray jArray = 0;

          ret = readBufferStream( data, &sdata, &ssize );
          if (ret)
               return ret;

          method = (*env)->GetStaticMethodID( env, clazz, "decodeByteArray", "([BII)Landroid/graphics/Bitmap;" );
          if (check_exception( env ) || !method) {
               free( sdata );
               return DFB_INIT;
          }

          jArray = (*env)->NewByteArray( env, ssize );
          if (check_exception( env ) || !jArray) {
               free( sdata );
               return DFB_NOSYSTEMMEMORY;
          }

          (*env)->SetByteArrayRegion(env, jArray, 0, ssize, sdata);
          if (check_exception( env )) {
               (*env)->DeleteLocalRef( env, jArray );
               check_exception( env );
               free( sdata );
               return DFB_INIT;
          }

          bitmap = (*env)->CallStaticObjectMethod( env, clazz, method, jArray, 0, ssize );
          if (check_exception( env ) || !bitmap) {
               free( sdata );
               (*env)->DeleteLocalRef( env, jArray );
               check_exception( env );
               return DFB_INIT;
          }

          (*env)->DeleteLocalRef( env, jArray );
          if (check_exception( env )) {
               free( sdata );
               return DFB_INIT;
          }

          free( sdata );
     }

     clazz = (*env)->GetObjectClass(env, bitmap);
     if (check_exception( env ) || !clazz)
          return DFB_INIT;

     method = (*env)->GetMethodID( env, clazz, "getWidth", "()I" );
     if (check_exception( env ) || !method)
          return DFB_INIT;

     data->width = (*env)->CallIntMethod( env, bitmap, method );
     if (check_exception( env ))
          return DFB_INIT;

     method = (*env)->GetMethodID( env, clazz, "getHeight", "()I" );
     if (check_exception( env ) || !method)
          return DFB_INIT;

     data->height = (*env)->CallIntMethod( env, bitmap, method );
     if (check_exception( env ))
          return DFB_INIT;

     method = (*env)->GetMethodID( env, clazz, "hasAlpha", "()Z" );
     if (check_exception( env ) || !method)
          return DFB_INIT;

     data->alpha = (*env)->CallBooleanMethod( env, bitmap, method );
     if (check_exception( env ))
          return DFB_INIT;

     method = (*env)->GetMethodID( env, clazz, "getRowBytes", "()I" );
     if (check_exception( env ) || !method)
          return DFB_INIT;

     data->pitch = (*env)->CallIntMethod( env, bitmap, method );
     if (check_exception( env ))
          return DFB_INIT;

     method = (*env)->GetMethodID( env, clazz, "getConfig", "()Landroid/graphics/Bitmap$Config;" );
     if (check_exception( env ) || !method)
          return DFB_INIT;

     config = (*env)->CallObjectMethod( env, bitmap, method );
     if (check_exception( env ))
          return DFB_INIT;

     if (config) {
          clazz2 = (*env)->FindClass( env, "android/graphics/Bitmap$Config" );
          if (check_exception( env ) || !clazz2)
               return DFB_INIT;

          method = (*env)->GetMethodID( env, clazz2, "name", "()Ljava/lang/String;" );
          if (check_exception( env ) || !method)
               return DFB_INIT;

          format = (jstring)(*env)->CallObjectMethod( env, config, method );
          if (check_exception( env ) || !format)
               return DFB_INIT;

          fvalue = (*env)->GetStringUTFChars( env, format, 0 );
          if (check_exception( env ) || !fvalue)
               return DFB_NOSYSTEMMEMORY;

          if (!strcmp( fvalue, "ALPHA_8" )) {
               data->format = DSPF_A8;
          }
          else if (!strcmp( fvalue, "ARGB_4444" )) {
               data->format = DSPF_ARGB4444;
          }
          else if (!strcmp( fvalue, "ARGB_8888" )) {
               data->format = DSPF_ARGB;
          }
          else if (!strcmp( fvalue, "RGB_565" )) {
               data->format = DSPF_RGB16;
          }
          else {
               data->format = DSPF_UNKNOWN;
          }

          (*env)->ReleaseStringUTFChars( env, format, fvalue );
          if (check_exception( env ))
               return DFB_INIT;
     }
     else {
          // config is not known, so force conversion
          data->format = DSPF_UNKNOWN;
     }

     if (DSPF_ARGB != data->format) {
          const char *nconfig_name  = "ARGB_8888";
          jstring     jconfig_name  = 0;
          jclass      config_clazz  = 0;
          jobject     bitmap_config = 0;

          jconfig_name = (*env)->NewStringUTF( env, nconfig_name );
          if (check_exception( env ) || !jconfig_name)
               return DFB_INIT;

          config_clazz = (*env)->FindClass( env, "android/graphics/Bitmap$Config" );
          if (check_exception( env ) || !config_clazz) {
               (*env)->DeleteLocalRef( env, jconfig_name );
               check_exception( env );
               return DFB_INIT;
          }

          method = (*env)->GetStaticMethodID( env, config_clazz, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;" );
          if (check_exception( env ) || !method) {
               (*env)->DeleteLocalRef( env, jconfig_name );
               check_exception( env );
               return DFB_INIT;
          }

          bitmap_config = (*env)->CallStaticObjectMethod( env, config_clazz, method, jconfig_name );
          if (check_exception( env ) || !bitmap_config) {
               (*env)->DeleteLocalRef( env, jconfig_name );
               check_exception( env );
               return DFB_INIT;
          }

          method = (*env)->GetMethodID( env, clazz, "copy", "(Landroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;" );
          if (check_exception( env ) || !method) {
               (*env)->DeleteLocalRef( env, jconfig_name );
               check_exception( env );
               return DFB_INIT;
          }

          convert = (*env)->CallObjectMethod( env, bitmap, method,  bitmap_config, 0 );
          if (check_exception( env ) || !convert) {
               (*env)->DeleteLocalRef( env, jconfig_name );
               check_exception( env );
               return DFB_INIT;
          }

          (*env)->DeleteLocalRef( env, jconfig_name );
          if (check_exception( env ))
               return DFB_INIT;

          bitmap = convert;

          data->format = DSPF_ARGB;

          method = (*env)->GetMethodID( env, clazz, "getRowBytes", "()I" );
          if (check_exception( env ) || !method)
               return DFB_INIT;

          data->pitch = (*env)->CallIntMethod( env, bitmap, method );
          if (check_exception( env ))
               return DFB_INIT;
     }

     pixels = (*env)->NewByteArray( env, data->pitch * data->height);
     if (check_exception( env ) || !pixels)
          return DFB_NOSYSTEMMEMORY;

     clazz2 = (*env)->FindClass( env, "java/nio/ByteBuffer" );
     if (check_exception( env ) || !clazz2) {
          (*env)->DeleteLocalRef( env, pixels );
          check_exception( env );
          return DFB_INIT;
     }

     method = (*env)->GetStaticMethodID( env, clazz2, "wrap", "([B)Ljava/nio/ByteBuffer;" );
     if (check_exception( env ) || !method) {
          (*env)->DeleteLocalRef( env, pixels );
          check_exception( env );
          return DFB_INIT;
     }

     buffer = (*env)->CallStaticObjectMethod( env, clazz2, method, pixels );
     if (check_exception( env ) || !buffer) {
          (*env)->DeleteLocalRef( env, pixels );
          check_exception( env );
          return DFB_INIT;
     }

     method = (*env)->GetMethodID( env, clazz, "copyPixelsToBuffer", "(Ljava/nio/Buffer;)V" );
     if (check_exception( env ) || !method) {
          (*env)->DeleteLocalRef( env, pixels );
          check_exception( env );
          return DFB_INIT;
     }

     (*env)->CallVoidMethod( env, bitmap, method, buffer );
     if (check_exception( env )) {
          (*env)->DeleteLocalRef( env, pixels );
          check_exception( env );
          return DFB_INIT;
     }

     data->pixels = (*env)->NewGlobalRef( env, pixels );
     if (check_exception( env )) {
          (*env)->DeleteLocalRef( env, pixels );
          check_exception( env );
          return DFB_INIT;
     }

     data->image = (*env)->GetByteArrayElements( env, pixels, 0 );
     if (check_exception( env ) || !data->image) {
          (*env)->DeleteLocalRef( env, pixels );
          check_exception( env );
          return DFB_INIT;
     }

     return DFB_OK;
}