Exemplo n.º 1
0
Arquivo: instance.c Projeto: ahua/java
/*
 * Execute the ANEWARRAY instruction
 */
void op_anewarray() {
    Ref type = resolve(u16(1), ID_TYPE);
    if (type == NULL) { return; } // rollback, gc done
    Ref arrayType = getRef(type, TYPE_ARRAY_TYPE);

    // resolve array type
    if (arrayType == NULL) {
        Ref target = getRef(core, OBJECT_TYPE);
        Ref method = getRef(core, CORE_RESOLVE_METHOD);
        executeMethod(target, method, 0);
        return; // rollback
    }

    // allocate space
    int length = peekInt(); // don't pop yet in case gc runs
    int numWords = ARRAY_DATA + length;
    Ref array = allocate(numWords, HEADER_OBJECT_ARRAY);
    if (array == NULL) { return; } // rollback, gc done
    popInt(); // pop length

    // initialise array object and push on stack
    int hash = (char*) array - (char*) core;
    setInt(array, OBJECT_HASHCODE, hash);
    setRef(array, OBJECT_TYPE, arrayType);
    setInt(array, ARRAY_LENGTH, length);
    pushRef(array);
    pc += 3;
}
Exemplo n.º 2
0
/*
 * Search for an appropriate handler in the current method
 * and return true if one is found, false otherwise.
 */
static int searchForHandler(Ref exception, Ref exceptionType) {
    // make sure exception table exists
    Ref exceptionTable = getRef(method, METHOD_EXCEPTIONS);
    if (exceptionTable == NULL) { return FALSE; }

    // loop through exception table entries
    int length = getInt(exceptionTable, ARRAY_LENGTH);
    unsigned short* ps = (unsigned short*) (exceptionTable + ARRAY_DATA);
    int i = 0;
    for (; i < length; i += 4) {
        // read table entry
        int start_pc = ps[i];
        int end_pc = ps[i + 1];
        int handler_pc = ps[i + 2];
        int catch_type = ps[i + 3];

        // check range
        Ref catchTypeEntry = getPoolEntry(catch_type);
        int inRange = (pc >= start_pc) && (pc < end_pc);
        int handled = (catch_type == 0)
                || isSubClassOf(exceptionType, catchTypeEntry);
        if (inRange && handled) {
            pc = handler_pc;
            int frameSize = frame[OBJECT_SIZE].i;

            // clear stack
            Var* max = (Var*) (frame + frameSize);
            for (; stack < max; stack++) { stack->flag = FALSE; }
            pushRef(exception);
            return TRUE;
        }
    }
    return FALSE;
}
//dup
int op_dup( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    StackEntry *entry = popEntry(stack);
    int value = 0;
    value = EntryToInt(entry);
    if ( entry->type == STACK_ENTRY_INT ) {

        pushInt(stack, value);
        pushInt(stack, value);
    } else {
        pushRef(stack, value);
        pushRef(stack, value);
    }
#if SIMPLE_JVM_DEBUG
    printf("dup\n");
#endif
    *opCode = *opCode + 1;
    return 0;
}
//ldc
int op_ldc( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    int value = opCode[0][1];
    pushRef(stack, value);
#if SIMPLE_JVM_DEBUG
    printf("ldc: push a constant index %d onto the stack \n", value);
#endif
    *opCode = *opCode + 2;
    return 0;
}
//0x14 ldc2_w
int op_ldc2_w( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    unsigned char index1 = opCode[0][1];
    unsigned char index2 = opCode[0][2];
    int index = ( index1 << 8 ) | index2;
    pushRef(stack, index);
#if SIMPLE_JVM_DEBUG
    printf("ldc2_w: push a constant index %d onto the stack \n", index);
#endif
    *opCode = *opCode + 3;
    return 0;
}
//getstatic
int op_getstatic( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    u2 field_index ;
    unsigned char tmp[2];
    tmp[0] = opCode[0][1];
    tmp[1] = opCode[0][2];
    field_index = tmp[0] << 8 | tmp[1];
#if SIMPLE_JVM_DEBUG
    printf("getstatic %d\n", field_index );
#endif
    pushRef(stack, field_index);
    *opCode = *opCode + 3;
    return 0;
}
Exemplo n.º 7
0
Arquivo: instance.c Projeto: ahua/java
/*
 * Execute the NEW instruction
 */
void op_new() {
    // resolve the type
    Ref type = resolve(u16(1), ID_TYPE);
    if (type == NULL) { return; } // rollback, gc done

    // allocate space
    int numFields = getInt(type, TYPE_INSTANCE_FIELD_COUNT);
    int numWords = OBJECT_FIELDS + numFields;
    Ref object = allocate(numWords, HEADER_INSTANCE);
    if (object == NULL) { return; } // rollback, gc done
    
    // set headers and push on stack
    int hash = (char*) object - (char*) core;
    setInt(object, OBJECT_HASHCODE, hash);
    setRef(object, OBJECT_TYPE, type);
    pushRef(object);
    pc += 3;
}
Exemplo n.º 8
0
Arquivo: field.c Projeto: ahua/java
/*
 * Execute the GETSTATIC instruction
 */
void op_getstatic() {
    Ref field = resolve(u16(1), ID_FIELD);
    if (field == NULL) { return; } // rollback

    // read field values
    Ref type = getRef(field, ENTRY_OWNER);
    Ref statics = getRef(type, TYPE_STATICS);
    Int index = getInt(field, FIELD_INDEX);
    Int flag = getInt(field, FIELD_REFERENCE_FLAG);
    Int size = getInt(field, FIELD_SIZE);
    int offset = STATICS_FIELDS + index;

    // read values and push on stack
    if (flag) { pushRef(getRef(statics, offset)); }
    else { pushInt(getInt(statics, offset)); }
    if (size == 2) { pushInt(getInt(statics, offset + 1)); }
    pc += 3;
}
Exemplo n.º 9
0
Arquivo: field.c Projeto: ahua/java
/*
 * Execute the GETFIELD instruction
 */
void op_getfield() {
    Ref field = resolve(u16(1), ID_FIELD);
    if (field == NULL) { return; } // rollback

    // check for null pointer
    Ref object = popRef();
    if (object == NULL) {
        throwException(CORE_THROW_NULL_POINTER);
        return;
    }

    // push value
    Int index = getInt(field, FIELD_INDEX) + OBJECT_FIELDS;
    Int flag = getInt(field, FIELD_REFERENCE_FLAG);
    Int size = getInt(field, FIELD_SIZE);
    if (flag) { pushRef(getRef(object, index)); }
    else { pushInt(getInt(object, index)); }
    if (size == 2) { pushInt(getInt(object, index + 1)); }
    pc += 3;
}
Exemplo n.º 10
0
Arquivo: instance.c Projeto: ahua/java
/*
 * Execute the NEWARRAY instruction
 */
void op_newarray() {
    // figure out the required size
    int atype = u8(1);
    int width = getWidth(atype);
    int length = peekInt(); // don't pop in case rolled back later
    int numBytes = length * width;
    int extra = ((numBytes % 4) == 0) ? 0 : 1;
    int numDataWords = (numBytes / 4) + extra;
    int numWords = numDataWords + ARRAY_DATA;

    // allocate space
    Ref array = allocate(numWords, HEADER_DATA_ARRAY);
    if (array == NULL) { return; } // rollback, gc done
    popInt(); // can pop the length now

    // initialise new array and push address on stack
    int hash = (char*) array - (char*) core;
    Ref type = getRef(core, CORE_ARRAYS + atype);
    setInt(array, OBJECT_HASHCODE, hash);
    setRef(array, OBJECT_TYPE, type);
    setInt(array, ARRAY_LENGTH, length);
    pushRef(array);
    pc += 2;
}
Exemplo n.º 11
0
Arquivo: invoke.c Projeto: ahua/java
/*
 * Execute the specified native method. Return true if the method
 * is executed, false if it is rolled back for garbage collection.
 */
int executeNativeMethod(Ref target, Ref method, int offset) {
    int magic = getInt(method, METHOD_MAGIC);
    if (magic == 0) {
        printf("Native method not supported\n");
        debugTrace();
        exit(1);
    }
    switch (magic) {
        // print a debug message
        case MAGIC_RUNTIME_CORE_DEBUG:
            debugLine(popRef());
            pc += offset;
            break;

        // execute the given static method
        case MAGIC_RUNTIME_CORE_EXECUTE_STATIC:
            {
                Ref staticMethod = popRef();
                if (staticMethod  == NULL) {
                    throwException(CORE_THROW_NULL_POINTER);
                    return;
                }
                Ref owner = getRef(staticMethod, ENTRY_OWNER);
                if (!executeMethod(owner, staticMethod, offset)) {
                    // restore stack if rolled back for gc
                    pushRef(staticMethod); 
                }
            }
            break;

        // return the current frame
        case MAGIC_RUNTIME_FRAME_CURRENT:
            pushRef(frame);
            pc += offset;
            break;

        // return the core object
        case MAGIC_RUNTIME_CORE_GET:
            pushRef(core);
            pc += offset;
            break;

        // create a statics object
        case MAGIC_RUNTIME_STATICS_CREATE:
            {
                // allocate space for statics object
                Ref type = popRef();
                Int numStaticFields = getInt(type, TYPE_STATIC_FIELD_COUNT);
                Int numWords = STATICS_FIELDS + numStaticFields;
                Ref statics = allocate(numWords, HEADER_STATIC_FIELDS);
                if (statics == NULL) {
                    pushRef(type); // restore stack
                    return; // rollback, gc done
                }

                // initialise statics object and set in type object
                int hash = (char*) statics - (char*) core;
                setInt(statics, OBJECT_HASHCODE, hash);
                Ref staticsType = getRef(core, CORE_STATICS_TYPE);
                setRef(statics, OBJECT_TYPE, staticsType);
                Ref map = getRef(type, TYPE_STATIC_MAP);
                setRef(statics, STATICS_MAP, map);
                setRef(type, TYPE_STATICS, statics);
            }
            pc += offset;
            break;

        // read the type from a class
        case MAGIC_RUNTIME_CORE_GET_TYPE:
            {
                Ref class = popRef();
                // type is first field in class...
                Ref type = getRef(class, OBJECT_FIELDS);
                pushRef(type);
            }
            pc += offset;
            break;

        // put system to sleep to avoid wasting processor time while idle
        case MAGIC_RUNTIME_IDLE_SLEEP:
            idleSleep();
            pc += offset;
            break;

        // return the currently executing thread
        case MAGIC_RUNTIME_THREAD_CURRENT:
            pushRef(thread);
            pc += offset;
            break;

        // start a new thread
        case MAGIC_RUNTIME_THREAD_START_HOOK:
            startNewThread(offset);
            break;

        // return an object's class
        case MAGIC_JAVA_OBJECT_GET_CLASS:
            {
                Ref obj = popRef();
                Ref type = getRef(obj, OBJECT_TYPE);
                Ref peer = getRef(type, TYPE_PEER);
                pushRef(peer);
            }
            pc += offset;
            break;

        // set system output stream
        case MAGIC_JAVA_SYSTEM_SET_OUT:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_OUT, arg);
            }
            pc += offset;
            break;

        // set system error stream
        case MAGIC_JAVA_SYSTEM_SET_ERR:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_ERR, arg);
            }
            pc += offset;
            break;

        // set system input stream
        case MAGIC_JAVA_SYSTEM_SET_IN:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_IN, arg);
            }
            pc += offset;
            break;

        // read an ascii character from the console
        case MAGIC_TEST_READ_FROM_CONSOLE:
            {
                char c = readFromConsole();
                pushInt(c);
            }
            pc += offset;
            break;
            
        // write an ascii character to the console
        case MAGIC_TEST_WRITE_TO_CONSOLE:
            {
                char c = popInt() & 0xFF;
                printf("%c", c);
            }
            pc += offset;
            break;

        // read a byte from the floppy drive
        case MAGIC_TEST_READ_FROM_FLOPPY:
            {
                Int pos = popInt();
                pushInt(readFromFloppy(pos));
            }
            pc += offset;
            break;
			
        // magic id not recognised
        default:
            printf("Invalid magic method id: %d\n", magic);
            exit(1);
            break;
    }
}
Exemplo n.º 12
0
	void VirtualMachine::execute(const InstructionList& script)
	{
	ScriptValue emptyVar;
	emptyVar.Flags   = ScriptValue::VariableRef;
	emptyVar.Type    = -2;
	emptyVar.Pointer = 0x0;
	std::map<std::string, ScriptValue>::iterator it;

	for(int i = 0; i < script.size(); ++i)
	{
		const Instruction& cmd = script[i];
		bool jump = true;
		switch(cmd.Type)
		{
			case PUSH:
				push(cmd.Value);
				break;
			case GETVAR:
				it = Variables.find(cmd.Name);
				if(it == Variables.end())
					it = Variables.emplace(cmd.Name, emptyVar).first;

				pushRef(&((*it).second));
				break;
			case EOL:
				//clearStack();
				break;
			case FUNCALL:
			{
				std::vector<int> arguments;
				arguments.reserve(cmd.NumArguments);
				for(int i = 0; i < cmd.NumArguments; ++i)
					arguments.push_back(peek(i).Type);
				
				FunctionDeclaration* fn = Environment->resolveFunctionCall(cmd.Name, arguments);
				
				if(fn)
					(*(fn->FnPtr))(this);
				else
				{
					std::cout << "RUNTIME ERROR: No function matching " <<  cmd.Name << "(";
					for(int i = 0; i < cmd.NumArguments; ++i)
					{
						if(i != 0) std::cout << ", ";
						std::cout << Config->NativeTypes[peek(i).Type].Name;
					}
					std::cout << ")" << std::endl;
				}
				break;
			}
			case OBJCALL:
			{
				std::vector<int> arguments;
				arguments.reserve(cmd.NumArguments);
				for(int i = 0; i < cmd.NumArguments; ++i)
					arguments.push_back(peek(i+1).Type);
				
				FunctionDeclaration* fn = Environment->resolveMethodCall(peek(0).Type, cmd.Name, arguments);
				
				if(fn)
					(*(fn->FnPtr))(this);
				else
				{
					std::cout << "RUNTIME ERROR: No function matching " <<  cmd.Name << "(";
					for(int i = 0; i < cmd.NumArguments; ++i)
					{
						if(i != 0) std::cout << ", ";
						std::cout << Config->NativeTypes[peek(1+i).Type].Name;
					}
					std::cout << ") in " << Config->NativeTypes[peek(0).Type].Name << std::endl;
				}
				break;
			}
			case SUBCALL:
			{
				int targetPos = -1;
				for(int j = 0; j < script.size(); ++j)
				{
					if(script[j].Type    == LABEL)
					if(script[j].LabelID == cmd.LabelID)
					{
						targetPos = j;
						break;
					}
				}
				if(targetPos != -1)
				{
					CallStack[CallStackPosition].ReturnAddress = i;
					CallStack[CallStackPosition].StackPosition = StackPosition;
					CallStackPosition++;
					i = targetPos;
				}
				break;
			}
			case SUBENTER:
			{
				int targetPos = -1;
				for(int j = i; j < script.size(); ++j)
				{
					if(script[j].Type    == LABEL)
					if(script[j].LabelID == cmd.LabelID)
					{
						targetPos = j;
						break;
					}
				}
				if(targetPos != -1)
				{
					CallStack[CallStackPosition].ReturnAddress = targetPos;
					CallStack[CallStackPosition].StackPosition = StackPosition;
					CallStackPosition++;
				}
				break;
			}
			case RETURN:
				if(CallStackPosition > 0)
				{
					ScriptValue retValue = pop();
					CallStackPosition--;
					i = CallStack[CallStackPosition].ReturnAddress;
					StackPosition = CallStack[CallStackPosition].StackPosition;
					push(retValue);
				}
				break;
			case JUMPTO:
			case JUMPIF:
			case JUMPIFN:
				     if(cmd.Type == JUMPTO ) jump =  true;
				else if(cmd.Type == JUMPIF ) jump =  pop().as<int>();
				else if(cmd.Type == JUMPIFN) jump = !pop().as<int>();
				if(jump)
				{
					int targetPos = -1;
					for(int j = 0; j < script.size(); ++j)
					{
						if(script[j].Type    == LABEL)
						if(script[j].LabelID == cmd.LabelID)
						{
							targetPos = j;
							break;
						}
					}
					if(targetPos != -1)
						i = targetPos;
				}
				break;
			case LABEL:
				// Ignore.
				break;
			default:
				std::cout << "Unimplemented Instruction " << cmd.Type << std::endl;
				break;
		}
	}
	}