⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bytecodes.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 5 页
字号:
NOTIMPLEMENTED(JSR)              /* Jump and stack return *//***** JSR AND RET ARE NOT NEEDED IN KVMSELECT(JSR)        pushStackAsType(BYTE*, (ip + 3));        ip += getShort(ip + 1);DONE(0)*****/#endif/* --------------------------------------------------------------------- */#if STANDARDBYTECODESNOTIMPLEMENTED(RET)             /* Return from subroutine *//***** JSR AND RET ARE NOT NEEDED IN KVMSELECT(RET)        unsigned int index = ip[1];        ip = *(BYTE**)&lp[index];DONE(0)*****/#endif/* --------------------------------------------------------------------- */#if STANDARDBYTECODESSELECT(TABLESWITCH)               /* Access jump table by index and jump */        long index = popStack();        /* Align instruction pointer to the next 32-bit word boundary */        unsigned char *base = (unsigned char *) (((long)ip + 4) & ~3);        long lowValue = getAlignedCell(base + 4);        long highValue = getAlignedCell(base + 8);        if ((index < lowValue) || (index > highValue)) {            ip += getAlignedCell(base); /* default value */        } else {            ip += getAlignedCell(base + CELL*(index-lowValue+3));        }DONE_R#endif/* --------------------------------------------------------------------- */#if STANDARDBYTECODESSELECT(LOOKUPSWITCH)          /* Access jump table by key match and jump */        struct pair { cell value; cell offset; };        long key = popStack();        cell *base = (cell *)(((long)ip + 4) & ~3);        long numberOfPairs = getAlignedCell(base + 1);        long delta = numberOfPairs - 1;        struct pair *firstPair = (struct pair *)(base + 2);        for (;;) {            /* ASSERT:  The item we are looking for, if it is in the table,             * is in between firstPair and firstPair + delta, inclusive.             */            if (delta < 0) {                /* Item not found, use default at base */                break;            } else {                long halfDelta = (delta >> 1);                struct pair *middlePair = firstPair + halfDelta;                /* Don't use cell.  It's unsigned */                long middleValue = getAlignedCell(&middlePair->value);                if (middleValue < key) {                    /* Item is second half of the table */                    firstPair = middlePair + 1;                    delta = delta - halfDelta - 1;                } else if (middleValue > key) {                    /* Item is at the beginning of the table. */                    delta = halfDelta - 1;                } else {                    /* We have it.  Set base to point to the location of the                     * offset.                     */                    base = &middlePair->offset;                    break;                }            }        }        /* base points at the offset by which we increment the ip */        ip += getAlignedCell(base);DONE_R#endif/* --------------------------------------------------------------------- */#if STANDARDBYTECODESSELECT6(IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN)        /* Return from method */        BYTE*  previousIp    = fp->previousIp;        OBJECT synchronized  = fp->syncObject;        TRACE_METHOD_EXIT(fp->thisMethod);        if (synchronized != NULL) {            char*  exitError;            if (monitorExit(synchronized, &exitError) == MonitorStatusError) {                exception = exitError;                goto handleException;            }        }        /* Special case where we are killing a thread */        if (previousIp == KILLTHREAD) {            VMSAVE            stopThread();            VMRESTORE            if (areAliveThreads()) {                goto reschedulePoint;            } else {                return; /* Must be the end of the program */            }        }        /* Regular case where we pop the stack frame and return data */        if ((TOKEN & 1) == 0) {            /* The even ones are all the return of a single value */            cell data = topStack;            POP_FRAME            pushStack(data);        } else if (TOKEN == RETURN) {            POP_FRAME        } else {            /* We don't care whether it's little or big endian. . . */            long t2 = sp[0];            long t1 = sp[-1];            POP_FRAME            pushStack(t1);            pushStack(t2);        }        goto reschedulePoint;DONEX#endif/* --------------------------------------------------------------------- */#if INFREQUENTSTANDARDBYTECODESSELECT(GETSTATIC)                       /* Get static field from class */        /* Get the CONSTANT_Fieldref index */        unsigned int cpIndex;        FIELD field;        int currentToken = TOKEN;        /* Get the constant pool index */        cpIndex = getUShort(ip + 1);        /* Resolve constant pool reference */        VMSAVE        field = resolveFieldReference(cp_global, cpIndex, TRUE, currentToken,                                      fp_global->thisMethod->ofClass);        VMRESTORE       /*        * If the class in question has not been initialized, do it now.        * The system used in KVM is to push a special frame onto the        * callers stack which is used to execute the CUSTOMCODE bytecode.        * This is done repeatedly using an internal finite state machine        * until all the stages are complete. When the class is initialized        * the frame will be popped off and the calling frame will then        * execute this bytecode again because the ip was not incremented.        */        if (field && field->ofClass->status == CLASS_ERROR) {            goto handleJavaLangError;        }        if (field && !CLASS_INITIALIZED(field->ofClass)) {            VMSAVE            /* Push class initialization frame */            initializeClass(field->ofClass);            VMRESTORE            goto reschedulePoint;        }        if (field) {            void *location = field->u.staticAddress;#if ENABLEFASTBYTECODES                REPLACE_BYTECODE(ip, ((field->accessFlags & ACC_DOUBLE)                         ? GETSTATIC2_FAST                         : (field->accessFlags & ACC_POINTER)                         ? GETSTATICP_FAST : GETSTATIC_FAST))#endif            /* Load either one or two cells depending on field type */            if (field->accessFlags & ACC_DOUBLE) {                oneMore;                COPY_LONG(sp, location);                oneMore;            } else {                pushStack(*(cell *)location);            }        } else {            fatalSlotError(cp, cpIndex);        }DONE(3)#endif/* --------------------------------------------------------------------- */#if INFREQUENTSTANDARDBYTECODESSELECT(PUTSTATIC)                           /* Set static field in class */        /* Get the CONSTANT_Fieldref index */        unsigned int cpIndex;        FIELD field;        int currentToken = TOKEN;        /* Get the constant pool index */        cpIndex = getUShort(ip + 1);        /* Resolve constant pool reference */        VMSAVE        field = resolveFieldReference(cp_global, cpIndex, TRUE, currentToken,                                      fp_global->thisMethod->ofClass);        VMRESTORE       /*        * If the class in question has not been initialized, do it now.        * The system used in KVM is to push a special frame onto the        * callers stack which is used to execute the CUSTOMCODE bytecode.        * This is done repeatedly using an internal finite state machine        * until all the stages are complete. When the class is initialized        * the frame will be popped off and the calling frame will then        * execute this bytecode again because the ip was not incremented.        */        if (field && field->ofClass->status == CLASS_ERROR) {            goto handleJavaLangError;        }       if (field && !CLASS_INITIALIZED(field->ofClass)) {            VMSAVE/* Push class initialization frame */            initializeClass(field->ofClass);            VMRESTORE            goto reschedulePoint;        }        if (field) {            void *location = field->u.staticAddress;#if ENABLEFASTBYTECODES            REPLACE_BYTECODE(ip, ((field->accessFlags & ACC_DOUBLE)                          ? PUTSTATIC2_FAST : PUTSTATIC_FAST))#endif            /* Store either one or two cells depending on field type */            if (field->accessFlags & ACC_DOUBLE) {                oneLess;                COPY_LONG(location, sp);                oneLess;            }            else *(cell *)location = popStack();        } else {            fatalSlotError(cp, cpIndex);            /* RAISE_EXCEPTION(NoSuchFieldError); */        }DONE(3)#endif/* --------------------------------------------------------------------- */#if INFREQUENTSTANDARDBYTECODESSELECT(GETFIELD)            /* Get field (instance variable) from object */        /* Get the CONSTANT_Fieldref index */        unsigned int cpIndex;        FIELD field;        int currentToken = TOKEN;        /* Get the constant pool index */        cpIndex = getUShort(ip + 1);        /* Resolve constant pool reference */        VMSAVE        field = resolveFieldReference(cp_global, cpIndex, FALSE, currentToken,                                      fp_global->thisMethod->ofClass);        VMRESTORE        if (field) {            /* Get slot index */            int offset = field->u.offset;#if ENABLEFASTBYTECODES            REPLACE_BYTECODE(ip, ((field->accessFlags & ACC_DOUBLE)                          ? GETFIELD2_FAST                          :  (field->accessFlags & ACC_POINTER)                                   ? GETFIELDP_FAST : GETFIELD_FAST))            putShort(ip + 1, offset);            goto reschedulePoint;#else            INSTANCE instance = popStackAsType(INSTANCE);            CHECK_NOT_NULL(instance);            /* Load either one or two cells depending on field type */            if (field->accessFlags & ACC_DOUBLE) {                pushStack(instance->data[offset].cell);                pushStack(instance->data[offset + 1].cell);            } else {                pushStack(instance->data[offset].cell);            }#endif        } else {            fatalSlotError(cp, cpIndex);        }DONE(3)#endif/* --------------------------------------------------------------------- */#if INFREQUENTSTANDARDBYTECODESSELECT(PUTFIELD)                                /* Set field in object */        /* Get the CONSTANT_Fieldref index */        unsigned int cpIndex;        FIELD field;        int currentToken = TOKEN;        /* Get the constant pool index */        cpIndex = getUShort(ip + 1);        /* Resolve constant pool reference */        VMSAVE        field = resolveFieldReference(cp_global, cpIndex, FALSE, currentToken,                                      fp_global->thisMethod->ofClass);        VMRESTORE        if (field) {            /* Get slot index */            int offset = field->u.offset;#if ENABLEFASTBYTECODES            /* If feasible, replace the current bytecode sequence             * with a faster one             */            REPLACE_BYTECODE(ip, ((field->accessFlags & ACC_DOUBLE)                      ? PUTFIELD2_FAST : PUTFIELD_FAST))            putShort(ip + 1, offset);            goto reschedulePoint;#else            /* Store either one or two cells depending on field type */            if (field->accessFlags & ACC_DOUBLE) {                cell  first       = popStack();                cell  second      = popStack();                INSTANCE instance = popStackAsType(INSTANCE);                CHECK_NOT_NULL(instance);                instance->data[offset].cell = second;                instance->data[offset + 1].cell = first;            } else {                cell data         = popStack();                INSTANCE instance = popStackAsType(INSTANCE);                CHECK_NOT_NULL(instance)                instance->data[offset].cell = data;            }#endif        } else {            fatalSlotError(cp, cpIndex);        }DONE(3)#endif/* --------------------------------------------------------------------- */#if INFREQUENTSTANDARDBYTECODESSELECT(INVOKEVIRTUAL)        /* Invoke instance method; dispatch based on dynamic class */        /* Get the CONSTANT_Methodref index */        unsigned int cpIndex;        METHOD cpMethod;        /* Get the constant pool index */        cpIndex = getUShort(ip + 1);        /* Resolve constant pool reference */        VMSAVE        cpMethod = resolveMethodReference(cp_global, cpIndex, FALSE,                                          fp_global->thisMethod->ofClass);        VMRESTORE        if (cpMethod) {            CLASS dynamicClass;            /* Calculate the number of parameters  from signature */            int argCount = cpMethod->argCount;            /* Get this */            thisObject = *(OBJECT*)(sp-argCount+1);            CHECK_NOT_NULL(thisObject);            /* Get the dynamic class of the object */            dynamicClass = thisObject->ofClass;            /* Find the actual method */            VMSAVE            thisMethod = lookupDynamicMethod(dynamicClass, cpMethod);            VMRESTORE            if (thisMethod) {#if ENABLEFASTBYTECODES                if (   (cpMethod->accessFlags & (ACC_PRIVATE | ACC_FINAL))                    || (cpMethod->ofClass->clazz.accessFlags & ACC_FINAL)                   ) {                    REPLACE_BYTECODE(ip, INVOKESPECIAL_FAST)                } else {                    int iCacheIndex;                    /* Replace the current bytecode sequence */                    CREATE_CACHE_ENTRY((cell*)thisMethod, ip)                    REPLACE_BYTECODE(ip, INVOKEVIRTUAL_FAST)                    putShort(ip + 1, iCacheIndex);                }#endif /* ENABLEFASTBYTECODES */                TRACE_METHOD_ENTRY(thisMethod, "virtual");                CALL_VIRTUAL_METHOD            } else {                fatalSlotError(cp, cpIndex);            }        } else {            fatalSlotError(cp, cpIndex);        }DONE(0)#endif/* --------------------------------------------------------------------- */#if INFREQUENTSTANDARDBYTECODESSELECT(INVOKESPECIAL)        /* Invoke instance method; special handling for superclass, */        /* private and instance initialization method invocations */        /* Get the CONSTANT_Methodref index */        unsigned int cpIndex;        /* Get the constant pool index */        cpIndex = getUShort(ip + 1);        /* Resolve constant pool reference */        VMSAVE        thisMethod = resolveMethodReference(cp_global, cpIndex, FALSE,                                            fp_global->thisMethod->ofClass);        VMRESTORE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -