Search in sources :

Example 61 with ObjectRef

use of io.nuls.contract.vm.ObjectRef in project nuls by nuls-io.

the class JsonUtils method decodeArray.

public static Object decodeArray(String value, Class<?> elementType, BiMap<String, String> classNames) {
    if (elementType == ObjectRef.class) {
        Object array = toArray(value, String.class);
        int length = Array.getLength(array);
        ObjectRef[] objectRefs = new ObjectRef[length];
        for (int i = 0; i < length; i++) {
            String s = (String) Array.get(array, i);
            if (s != null) {
                objectRefs[i] = new ObjectRef(s, classNames);
            }
        }
        return objectRefs;
    } else {
        return toArray(value, elementType);
    }
}
Also used : ObjectRef(io.nuls.contract.vm.ObjectRef)

Example 62 with ObjectRef

use of io.nuls.contract.vm.ObjectRef in project nuls by nuls-io.

the class ProgramExecutorImpl method execute.

private ProgramResult execute(ProgramInvoke programInvoke) {
    if (programInvoke.getPrice() < 1) {
        return revert("gas price must be greater than zero");
    }
    if (programInvoke.getGasLimit() < 1) {
        return revert("gas must be greater than zero");
    }
    long maxGas;
    if (programInvoke.isViewMethod()) {
        maxGas = VMContext.getCustomMaxViewGasLimit();
    } else {
        maxGas = VM.MAX_GAS;
    }
    if (programInvoke.getGasLimit() > maxGas) {
        return revert("gas must be less than " + maxGas);
    }
    if (programInvoke.getValue().compareTo(BigInteger.ZERO) < 0) {
        return revert("value can't be less than zero");
    }
    blockNumber = programInvoke.getNumber();
    logTime("start");
    try {
        Map<String, ClassCode> classCodes;
        if (programInvoke.isCreate()) {
            if (programInvoke.getData() == null) {
                return revert("contract code can't be null");
            }
            classCodes = ClassCodeLoader.loadJarCache(programInvoke.getData());
            logTime("load new code");
            ProgramChecker.check(classCodes);
            logTime("check code");
            AccountState accountState = repository.getAccountState(programInvoke.getContractAddress());
            if (accountState != null) {
                return revert(String.format("contract[%s] already exists", programInvoke.getAddress()));
            }
            accountState = repository.createAccount(programInvoke.getContractAddress(), programInvoke.getSender());
            logTime("new account state");
            repository.saveCode(programInvoke.getContractAddress(), programInvoke.getData());
            logTime("save code");
        } else {
            if ("<init>".equals(programInvoke.getMethodName())) {
                return revert("can't invoke <init> method");
            }
            AccountState accountState = repository.getAccountState(programInvoke.getContractAddress());
            if (accountState == null) {
                return revert(String.format("contract[%s] does not exist", programInvoke.getAddress()));
            }
            logTime("load account state");
            if (accountState.getNonce().compareTo(BigInteger.ZERO) <= 0) {
                return revert(String.format("contract[%s] has stopped", programInvoke.getAddress()));
            }
            byte[] codes = repository.getCode(programInvoke.getContractAddress());
            classCodes = ClassCodeLoader.loadJarCache(codes);
            logTime("load code");
        }
        VM vm = VMFactory.createVM();
        logTime("load vm");
        vm.heap.loadClassCodes(classCodes);
        vm.methodArea.loadClassCodes(classCodes);
        logTime("load classes");
        ClassCode contractClassCode = getContractClassCode(classCodes);
        String methodDesc = ProgramDescriptors.parseDesc(programInvoke.getMethodDesc());
        MethodCode methodCode = vm.methodArea.loadMethod(contractClassCode.name, programInvoke.getMethodName(), methodDesc);
        if (methodCode == null) {
            return revert(String.format("can't find method %s%s", programInvoke.getMethodName(), programInvoke.getMethodDesc() == null ? "" : programInvoke.getMethodDesc()));
        }
        if (!methodCode.isPublic) {
            return revert("can only invoke public method");
        }
        if (!methodCode.hasPayableAnnotation() && programInvoke.getValue().compareTo(BigInteger.ZERO) > 0) {
            return revert("not a payable method");
        }
        if (methodCode.argsVariableType.size() != programInvoke.getArgs().length) {
            return revert(String.format("require %s parameters in method [%s%s]", methodCode.argsVariableType.size(), methodCode.name, methodCode.normalDesc));
        }
        logTime("load method");
        ObjectRef objectRef;
        if (programInvoke.isCreate()) {
            objectRef = vm.heap.newContract(programInvoke.getContractAddress(), contractClassCode, repository);
        } else {
            objectRef = vm.heap.loadContract(programInvoke.getContractAddress(), contractClassCode, repository);
        }
        logTime("load contract ref");
        if (programInvoke.getValue().compareTo(BigInteger.ZERO) > 0) {
            getAccount(programInvoke.getContractAddress()).addBalance(programInvoke.getValue());
        }
        vm.setProgramExecutor(this);
        vm.setRepository(repository);
        vm.setGas(programInvoke.getGasLimit());
        vm.addGasUsed(programInvoke.getData() == null ? 0 : programInvoke.getData().length);
        logTime("load end");
        vm.run(objectRef, methodCode, vmContext, programInvoke);
        logTime("run");
        ProgramResult programResult = new ProgramResult();
        programResult.setGasUsed(vm.getGasUsed());
        Result vmResult = vm.getResult();
        Object resultValue = vmResult.getValue();
        if (vmResult.isError() || vmResult.isException()) {
            if (resultValue != null && resultValue instanceof ObjectRef) {
                vm.setResult(new Result());
                String error = vm.heap.runToString((ObjectRef) resultValue);
                String stackTrace = vm.heap.stackTrace((ObjectRef) resultValue);
                programResult.error(error);
                programResult.setStackTrace(stackTrace);
            } else {
                programResult.error(null);
            }
            logTime("contract exception");
            this.revert = true;
            programResult.setGasUsed(vm.getGasUsed());
            return programResult;
        }
        programResult.setTransfers(vm.getTransfers());
        programResult.setEvents(vm.getEvents());
        programResult.setBalance(getAccount(programInvoke.getContractAddress()).getBalance());
        if (resultValue != null) {
            if (resultValue instanceof ObjectRef) {
                String result = vm.heap.runToString((ObjectRef) resultValue);
                programResult.setResult(result);
            } else {
                programResult.setResult(resultValue.toString());
            }
        }
        if (methodCode.isPublic && methodCode.hasViewAnnotation()) {
            this.revert = true;
            programResult.view();
            programResult.setGasUsed(vm.getGasUsed());
            return programResult;
        }
        logTime("contract return");
        Map<DataWord, DataWord> contractState = vm.heap.contractState();
        logTime("contract state");
        for (Map.Entry<DataWord, DataWord> entry : contractState.entrySet()) {
            DataWord key = entry.getKey();
            DataWord value = entry.getValue();
            repository.addStorageRow(programInvoke.getContractAddress(), key, value);
        }
        logTime("add contract state");
        repository.increaseNonce(programInvoke.getContractAddress());
        programResult.setNonce(repository.getNonce(programInvoke.getContractAddress()));
        programResult.setGasUsed(vm.getGasUsed());
        return programResult;
    } catch (ErrorException e) {
        this.revert = true;
        // log.error("", e);
        ProgramResult programResult = new ProgramResult();
        programResult.setGasUsed(e.getGasUsed());
        // programResult.setStackTrace(e.getStackTraceMessage());
        logTime("error");
        return programResult.error(e.getMessage());
    } catch (Exception e) {
        log.error("", e);
        ProgramResult programResult = revert(e.getMessage());
        // programResult.setStackTrace(ExceptionUtils.getStackTrace(e));
        return programResult;
    }
}
Also used : DataWord(org.ethereum.vm.DataWord) AccountState(org.ethereum.core.AccountState) ErrorException(io.nuls.contract.vm.exception.ErrorException) Result(io.nuls.contract.vm.Result) ClassCode(io.nuls.contract.vm.code.ClassCode) VM(io.nuls.contract.vm.VM) MethodCode(io.nuls.contract.vm.code.MethodCode) ObjectRef(io.nuls.contract.vm.ObjectRef) ErrorException(io.nuls.contract.vm.exception.ErrorException)

Example 63 with ObjectRef

use of io.nuls.contract.vm.ObjectRef in project nuls by nuls-io.

the class Astore method astore.

public static void astore(final Frame frame) {
    int index = frame.varInsnNode().var;
    ObjectRef objectRef = frame.operandStack.popRef();
    frame.localVariables.setRef(index, objectRef);
// Log.result(frame.getCurrentOpCode(), objectRef, index);
}
Also used : ObjectRef(io.nuls.contract.vm.ObjectRef)

Example 64 with ObjectRef

use of io.nuls.contract.vm.ObjectRef in project nuls by nuls-io.

the class Anewarray method anewarray.

public static void anewarray(Frame frame) {
    TypeInsnNode typeInsnNode = frame.typeInsnNode();
    String className = typeInsnNode.desc;
    int length = frame.operandStack.popInt();
    if (length < 0) {
        frame.throwNegativeArraySizeException();
        return;
    } else {
        ObjectRef arrayRef;
        if (className.contains(Constants.ARRAY_START)) {
            VariableType type = VariableType.valueOf(className);
            int[] dimensions = new int[type.getDimensions() + 1];
            dimensions[0] = length;
            VariableType variableType = VariableType.valueOf(Constants.ARRAY_START + className);
            arrayRef = frame.heap.newArray(variableType, dimensions);
        } else {
            VariableType variableType = VariableType.valueOf(Constants.ARRAY_PREFIX + className + Constants.ARRAY_SUFFIX);
            arrayRef = frame.heap.newArray(variableType, length);
        }
        frame.operandStack.pushRef(arrayRef);
    // Log.opcode(frame.getCurrentOpCode(), arrayRef);
    }
}
Also used : VariableType(io.nuls.contract.vm.code.VariableType) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) ObjectRef(io.nuls.contract.vm.ObjectRef)

Example 65 with ObjectRef

use of io.nuls.contract.vm.ObjectRef in project nuls by nuls-io.

the class Invokeinterface method invokeinterface.

public static void invokeinterface(Frame frame) {
    MethodInsnNode methodInsnNode = frame.methodInsnNode();
    String interfaceName = methodInsnNode.owner;
    String interfaceMethodName = methodInsnNode.name;
    String interfaceMethodDesc = methodInsnNode.desc;
    List<VariableType> variableTypes = VariableType.parseArgs(interfaceMethodDesc);
    MethodArgs methodArgs = new MethodArgs(variableTypes, frame.operandStack, false);
    ObjectRef objectRef = methodArgs.objectRef;
    if (objectRef == null) {
        frame.throwNullPointerException();
        return;
    }
    String className = objectRef.getVariableType().getType();
    MethodCode methodCode = frame.methodArea.loadMethod(className, interfaceMethodName, interfaceMethodDesc);
    // Log.opcode(frame.getCurrentOpCode(), className, interfaceMethodName, interfaceMethodDesc);
    frame.vm.run(methodCode, methodArgs.frameArgs, true);
}
Also used : VariableType(io.nuls.contract.vm.code.VariableType) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) ObjectRef(io.nuls.contract.vm.ObjectRef) MethodCode(io.nuls.contract.vm.code.MethodCode) MethodArgs(io.nuls.contract.vm.MethodArgs)

Aggregations

ObjectRef (io.nuls.contract.vm.ObjectRef)74 Result (io.nuls.contract.vm.Result)35 VariableType (io.nuls.contract.vm.code.VariableType)18 MethodCode (io.nuls.contract.vm.code.MethodCode)6 ClassCode (io.nuls.contract.vm.code.ClassCode)5 MethodArgs (io.nuls.contract.vm.MethodArgs)3 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)3 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)3 Frame (io.nuls.contract.vm.Frame)2 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)2 BiMap (com.google.common.collect.BiMap)1 BlockHeaderDto (io.nuls.contract.entity.BlockHeaderDto)1 VM (io.nuls.contract.vm.VM)1 ErrorException (io.nuls.contract.vm.exception.ErrorException)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 AccountState (org.ethereum.core.AccountState)1 DataWord (org.ethereum.vm.DataWord)1 Type (org.objectweb.asm.Type)1