void rb_vmdebug_proc_dump_raw(rb_proc_t *proc) { rb_env_t *env; char *selfstr; VALUE val = rb_inspect(proc->block.self); selfstr = StringValueCStr(val); fprintf(stderr, "-- proc -------------------\n"); fprintf(stderr, "self: %s\n", selfstr); GetEnvPtr(proc->envval, env); rb_vmdebug_env_dump_raw(env, proc->block.lfp, proc->block.dfp); }
static int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary) { if (ENV_IN_HEAP_P(th, dfp)) { rb_env_t *env; GetEnvPtr(ENV_VAL(dfp), env); collect_local_variables_in_env(env, ary); return 1; } else { return 0; } }
static VALUE env_references(VALUE rbenv) { rb_env_t* env; VALUE result = rb_ary_new(); GetEnvPtr(rbenv, env); if (env->env) { int i; for (i = 0; i < env->env_size; ++i) rb_ary_push(result, rb_obj_id(env->env[i])); } return result; }
static int GetSignHashCode() { JNIEnv* envPtr = GetEnvPtr(); jobject packageManager = CallObjectMethod ( nativeActivity->clazz, "getPackageManager", "()Landroid/content/pm/PackageManager;" ).l; jstring packageName = (jstring) CallObjectMethod ( nativeActivity->clazz, "getPackageName", "()Ljava/lang/String;" ).l; jobject packageInfo = CallObjectMethod ( packageManager, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;", packageName, 64 ).l; jclass packageInfoCls = (*envPtr)->GetObjectClass(envPtr, packageInfo); jfieldID signaturesFid = (*envPtr)->GetFieldID ( envPtr, packageInfoCls, "signatures", "[Landroid/content/pm/Signature;" ); jobjectArray signatureArr = (*envPtr)->GetObjectField (envPtr, packageInfo, signaturesFid); jobject signature = (*envPtr)->GetObjectArrayElement(envPtr, signatureArr, 0); return CallObjectMethod(signature, "hashCode", "()I").i; }
static void vm_set_main_stack(rb_thread_t *th, VALUE iseqval) { VALUE toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")); rb_binding_t *bind; rb_iseq_t *iseq; rb_env_t *env; GetBindingPtr(toplevel_binding, bind); GetEnvPtr(bind->env, env); th->base_block = &env->block; vm_set_eval_stack(th, iseqval, 0); th->base_block = 0; /* save binding */ GetISeqPtr(iseqval, iseq); if (bind && iseq->local_size > 0) { bind->env = rb_vm_make_env_object(th, th->cfp); } CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max); }
static inline jclass GetClass(char *className) { JNIEnv* envPtr = GetEnvPtr(); static jobject classLoaderObj = NULL; static jmethodID loadClassId = NULL; if (classLoaderObj == NULL) { jclass activityCls = (*envPtr)->FindClass(envPtr, "android/app/NativeActivity"); jclass loaderCls = (*envPtr)->FindClass(envPtr, "java/lang/ClassLoader"); jmethodID getClassLoaderId = (*envPtr)->GetMethodID ( envPtr, activityCls, "getClassLoader", "()Ljava/lang/ClassLoader;" ); classLoaderObj = (*envPtr)->CallObjectMethod(envPtr, nativeActivity->clazz, getClassLoaderId); loadClassId = (*envPtr)->GetMethodID ( envPtr, loaderCls, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;" ); } jstring classNameStr = (*envPtr)->NewStringUTF (envPtr, className); jclass cls = (jclass) (*envPtr)->CallObjectMethod(envPtr, classLoaderObj, loadClassId, classNameStr); ALog_A(cls != NULL, "AJniTool GetClass can not load class = %s", className); (*envPtr)->DeleteLocalRef(envPtr, classNameStr); return cls; }
/*RHO static*/ VALUE eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *file, int line) { int state; VALUE result = Qundef; VALUE envval; rb_binding_t *bind = 0; rb_thread_t *th = GET_THREAD(); rb_env_t *env = NULL; rb_block_t block; volatile int parse_in_eval; volatile int mild_compile_error; if (file == 0) { file = rb_sourcefile(); line = rb_sourceline(); } parse_in_eval = th->parse_in_eval; mild_compile_error = th->mild_compile_error; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { rb_iseq_t *iseq; volatile VALUE iseqval; if (scope != Qnil) { if (rb_obj_is_kind_of(scope, rb_cBinding)) { GetBindingPtr(scope, bind); envval = bind->env; } else { rb_raise(rb_eTypeError, "wrong argument type %s (expected Binding)", rb_obj_classname(scope)); } GetEnvPtr(envval, env); th->base_block = &env->block; } else { rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); if (cfp != 0) { block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp); th->base_block = █ th->base_block->self = self; th->base_block->iseq = cfp->iseq; /* TODO */ } else { rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread"); } } //RHO if ( TYPE(src) != T_STRING ){ iseqval = src; }else //RHO { /* make eval iseq */ th->parse_in_eval++; th->mild_compile_error++; iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line)); th->mild_compile_error--; th->parse_in_eval--; } vm_set_eval_stack(th, iseqval, cref); th->base_block = 0; if (0) { /* for debug */ printf("%s\n", RSTRING_PTR(rb_iseq_disasm(iseqval))); } /* save new env */ GetISeqPtr(iseqval, iseq); if (bind && iseq->local_size > 0) { bind->env = rb_vm_make_env_object(th, th->cfp); } /* kick */ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max); result = vm_exec(th); } POP_TAG(); th->mild_compile_error = mild_compile_error; th->parse_in_eval = parse_in_eval; if (state) { if (state == TAG_RAISE) { VALUE errinfo = th->errinfo; if (strcmp(file, "(eval)") == 0) { VALUE mesg, errat, bt2; extern VALUE rb_get_backtrace(VALUE info); ID id_mesg; CONST_ID(id_mesg, "mesg"); errat = rb_get_backtrace(errinfo); mesg = rb_attr_get(errinfo, id_mesg); if (!NIL_P(errat) && TYPE(errat) == T_ARRAY && (bt2 = vm_backtrace(th, -2), RARRAY_LEN(bt2) > 0)) { if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_LEN(mesg)) { if (OBJ_FROZEN(mesg)) { VALUE m = rb_str_cat(rb_str_dup(RARRAY_PTR(errat)[0]), ": ", 2); rb_ivar_set(errinfo, id_mesg, rb_str_append(m, mesg)); } else { rb_str_update(mesg, 0, 0, rb_str_new2(": ")); rb_str_update(mesg, 0, 0, RARRAY_PTR(errat)[0]); } } RARRAY_PTR(errat)[0] = RARRAY_PTR(bt2)[0]; } } rb_exc_raise(errinfo); } JUMP_TAG(state); } return result; }
static inline jvalue CallClassMethodV(jclass cls, char* methodName, char* paramCode, va_list args) { JNIEnv* envPtr = GetEnvPtr(); jmethodID methodId = (*envPtr)->GetStaticMethodID(envPtr, cls, methodName, paramCode); ALog_A ( methodId != NULL, "AJniTool CallClassMethodV can not get methodID, methodName = %s, paramCode = %s", methodName, paramCode ); char* p = paramCode; // skip '()' to find out the return type while (*p != ')') { p++; } // skip ')' p++; jvalue value; switch (*p) { case 'V': (*envPtr)->CallStaticVoidMethodV (envPtr, cls, methodId, args); break; case '[': case 'L': value.l = (*envPtr)->CallStaticObjectMethodV (envPtr, cls, methodId, args); break; case 'Z': value.z = (*envPtr)->CallStaticBooleanMethodV(envPtr, cls, methodId, args); break; case 'B': value.b = (*envPtr)->CallStaticByteMethodV (envPtr, cls, methodId, args); break; case 'C': value.c = (*envPtr)->CallStaticCharMethodV (envPtr, cls, methodId, args); break; case 'S': value.s = (*envPtr)->CallStaticShortMethodV (envPtr, cls, methodId, args); break; case 'I': value.i = (*envPtr)->CallStaticIntMethodV (envPtr, cls, methodId, args); break; case 'J': value.j = (*envPtr)->CallStaticLongMethodV (envPtr, cls, methodId, args); break; case 'F': value.f = (*envPtr)->CallStaticFloatMethodV (envPtr, cls, methodId, args); break; case 'D': value.d = (*envPtr)->CallStaticDoubleMethodV (envPtr, cls, methodId, args); break; default: ALog_A(false, "AJniTool CallClassMethod paramCode = %s, illegal", paramCode); } return value; }
static jvalue CallObjectMethod(jobject object, char* methodName, char* paramCode, ...) { JNIEnv* envPtr = GetEnvPtr(); jclass cls = (*envPtr)->GetObjectClass(envPtr, object); jmethodID methodId = (*envPtr)->GetMethodID (envPtr, cls, methodName, paramCode); ALog_A ( methodId != NULL, "AJniTool CallObjectMethod can not get methodID, methodName = %s, paramCode = %s", methodName, paramCode ); char* p = paramCode; // skip '()' to find out the return type while (*p != ')') { p++; } // skip ')' p++; va_list args; va_start(args, paramCode); jvalue value; switch (*p) { case 'V': (*envPtr)->CallVoidMethodV (envPtr, object, methodId, args); break; case '[': case 'L': value.l = (*envPtr)->CallObjectMethodV (envPtr, object, methodId, args); break; case 'Z': value.z = (*envPtr)->CallBooleanMethodV(envPtr, object, methodId, args); break; case 'B': value.b = (*envPtr)->CallByteMethodV (envPtr, object, methodId, args); break; case 'C': value.c = (*envPtr)->CallCharMethodV (envPtr, object, methodId, args); break; case 'S': value.s = (*envPtr)->CallShortMethodV (envPtr, object, methodId, args); break; case 'I': value.i = (*envPtr)->CallIntMethodV (envPtr, object, methodId, args); break; case 'J': value.j = (*envPtr)->CallLongMethodV (envPtr, object, methodId, args); break; case 'F': value.f = (*envPtr)->CallFloatMethodV (envPtr, object, methodId, args); break; case 'D': value.d = (*envPtr)->CallDoubleMethodV (envPtr, object, methodId, args); break; default: ALog_A(false, "AJniTool CallObjectMethod paramCode = %s, illegal", paramCode); } va_end(args); return value; }
static VALUE vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp, VALUE *envptr, VALUE * const endptr) { VALUE envval, penvval = 0; rb_env_t *env; VALUE *nenvptr; int i, local_size; if (ENV_IN_HEAP_P(th, envptr)) { return ENV_VAL(envptr); } if (envptr != endptr) { VALUE *penvptr = GC_GUARDED_PTR_REF(*envptr); rb_control_frame_t *pcfp = cfp; if (ENV_IN_HEAP_P(th, penvptr)) { penvval = ENV_VAL(penvptr); } else { while (pcfp->dfp != penvptr) { pcfp++; if (pcfp->dfp == 0) { SDR(); rb_bug("invalid dfp"); } } penvval = vm_make_env_each(th, pcfp, penvptr, endptr); cfp->lfp = pcfp->lfp; *envptr = GC_GUARDED_PTR(pcfp->dfp); } } /* allocate env */ envval = env_alloc(); GetEnvPtr(envval, env); if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { local_size = 2; } else { local_size = cfp->iseq->local_size; } env->env_size = local_size + 1 + 2; env->local_size = local_size; env->env = ALLOC_N(VALUE, env->env_size); env->prev_envval = penvval; for (i = 0; i <= local_size; i++) { env->env[i] = envptr[-local_size + i]; #if 0 fprintf(stderr, "%2d ", &envptr[-local_size + i] - th->stack); dp(env->env[i]); if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { /* clear value stack for GC */ envptr[-local_size + i] = 0; } #endif } *envptr = envval; /* GC mark */ nenvptr = &env->env[i - 1]; nenvptr[1] = envval; /* frame self */ nenvptr[2] = penvval; /* frame prev env object */ /* reset lfp/dfp in cfp */ cfp->dfp = nenvptr; if (envptr == endptr) { cfp->lfp = nenvptr; } /* as Binding */ env->block.self = cfp->self; env->block.lfp = cfp->lfp; env->block.dfp = cfp->dfp; env->block.iseq = cfp->iseq; if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { /* TODO */ env->block.iseq = 0; } return envval; }