Ejemplo n.º 1
0
const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs &params, size_t &size)
{
	ConstByteArrayParameter ivWithLength;
	const byte *iv;
	bool found = false;

	try {found = params.GetValue(Name::IV(), ivWithLength);}
	catch (const NameValuePairs::ValueTypeMismatch &) {}

	if (found)
	{
		iv = ivWithLength.begin();
		ThrowIfInvalidIV(iv);
		size = ThrowIfInvalidIVLength((int)ivWithLength.size());
		return iv;
	}
	else if (params.GetValue(Name::IV(), iv))
	{
		ThrowIfInvalidIV(iv);
		size = IVSize();
		return iv;
	}
	else
	{
		ThrowIfResynchronizable();
		size = 0;
		return NULL;
	}
}
Ejemplo n.º 2
0
size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int size)
{
	if (size < 0)
		return (size_t)IVSize();
	else if ((size_t)size < MinIVLength())
		throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " is less than the minimum of " + IntToString(MinIVLength()));
	else if ((size_t)size > MaxIVLength())
		throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " exceeds the maximum of " + IntToString(MaxIVLength()));
	else
		return (size_t)size;
}
Ejemplo n.º 3
0
void IVGrowValue(intvector *v, int value, size_t size)
{
    int *write;
    int *stop;
    vectorGrow(v, size);
    write = IVGetWritePointer(v, IVSize(v));
    stop = write - size;
    while (write != stop)
    {
        *--write = value;
    }
}
Ejemplo n.º 4
0
static void initStackFrame(VM *vm, const int **ip, int *bp, int functionOffset,
                           uint parameterCount)
{
    const int *bytecode = vmBytecode + functionOffset;
    int i = *bytecode++;
    int localsCount = i >> 8;
    if (DEBUG_TRACE)
    {
        traceLine(vm, functionOffset);
    }
    assert((i & 0xff) == OP_FUNCTION);
    *ip = bytecode;
    *bp = (int)(IVSize(&vm->stack) - parameterCount);
    IVGrowZero(&vm->stack, (size_t)localsCount);
}
Ejemplo n.º 5
0
void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV)
{
	rng.GenerateBlock(IV, IVSize());
}
Ejemplo n.º 6
0
static VM *execute(VM *vm)
{
    int maxInstructions = 100;

    while (maxInstructions--)
    {
        int i = *vm->ip;
        int arg = i >> 8;
        if (DEBUG_TRACE)
        {
            traceLine(vm, (int)(vm->ip - vmBytecode));
            fflush(stdout);
        }
        vm->ip++;
        switch ((Instruction)(i & 0xff))
        {
        case OP_NULL:
            storeValue(vm, vm->bp, arg, VNull);
            break;

        case OP_TRUE:
            storeValue(vm, vm->bp, arg, VTrue);
            break;

        case OP_FALSE:
            storeValue(vm, vm->bp, arg, VFalse);
            break;

        case OP_EMPTY_LIST:
            storeValue(vm, vm->bp, arg, VEmptyList);
            break;

        case OP_LIST:
        {
            vref result;
            vref *array;
            vref *write;
            assert(arg);
            array = VCreateArray((size_t)arg);
            for (write = array; arg--; write++)
            {
                vref value = loadValue(vm, vm->bp, *vm->ip++);
                if (value == VFuture)
                {
                    vm->ip += arg;
                    VAbortArray(array);
                    result = VFuture;
                    goto storeList;
                }
                *write = value;
                assert(HeapGetObjectType(*write) != TYPE_FUTURE);
            }
            result = VFinishArray(array);
    storeList:
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_FILELIST:
        {
            vref string = refFromInt(arg);
            vref result;
            if (string == VFuture)
            {
                result = VFuture;
            }
            else
            {
                result = VCreateFilelistGlob(VGetString(string), VStringLength(string));
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_STORE_CONSTANT:
            storeValue(vm, vm->bp, arg, refFromInt(*vm->ip++));
            break;

        case OP_COPY:
            storeValue(vm, vm->bp, *vm->ip++, loadValue(vm, vm->bp, arg));
            break;

        case OP_NOT:
            storeValue(vm, vm->bp, *vm->ip++,
                       VNot(loadValue(vm, vm->bp, arg)));
            break;

        case OP_NEG:
        {
            vref result = VNeg(vm, loadValue(vm, vm->bp, arg));
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_INV:
        {
            vref result = VInv(vm, loadValue(vm, vm->bp, arg));
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_ITER_NEXT:
        {
            vref collection = loadValue(vm, vm->bp, *vm->ip++);
            int indexVariable = *vm->ip++;
            vref index = loadValue(vm, vm->bp, indexVariable);
            vref step = loadValue(vm, vm->bp, *vm->ip++);
            if (index == VFuture || step == VFuture)
            {
                index = VFuture;
                storeValue(vm, vm->bp, indexVariable, index);
                goto iterNextFuture;
            }
            else
            {
                index = VAdd(vm, index, step);
                storeValue(vm, vm->bp, indexVariable, index);
            }
            if (collection == VFuture)
            {
        iterNextFuture:
                assert(0);
            }
            switch (VGetBool(VValidIndex(vm, collection, index)))
            {
            case TRUTHY:
                storeValue(vm, vm->bp, *vm->ip++, VIndexedAccess(vm, collection, index));
                break;
            case FALSY:
                vm->ip += arg - 2;
                break;
            case FUTURE:
                unreachable;
            }
            break;
        }

        case OP_EQUALS:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VEquals(value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_NOT_EQUALS:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VEquals(value1, value2);
            if (!result)
            {
                return vm;
            }
            switch (VGetBool(result))
            {
            case TRUTHY: result = VFalse; break;
            case FALSY: result = VTrue; break;
            case FUTURE: break;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_LESS_EQUALS:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VLessEquals(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_GREATER_EQUALS:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VLessEquals(vm, value2, value1);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_LESS:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VLess(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_GREATER:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VLess(vm, value2, value1);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_ADD:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VAdd(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_SUB:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VSub(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_MUL:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VMul(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_DIV:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VDiv(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_REM:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VRem(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_CONCAT_LIST:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VConcat(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_CONCAT_STRING:
        {
            vref result;
            assert(!IVSize(&temp));
            for (i = 0; i < arg; i++)
            {
                IVAdd(&temp, intFromRef(loadValue(vm, vm->bp, *vm->ip++)));
            }
            result = VConcatString((size_t)arg, (vref*)IVGetWritePointer(&temp, 0));
            storeValue(vm, vm->bp, *vm->ip++, result);
            IVSetSize(&temp, 0);
            break;
        }

        case OP_INDEXED_ACCESS:
        {
            vref collection = loadValue(vm, vm->bp, arg);
            vref index = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VIndexedAccess(vm, collection, index);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_RANGE:
        {
            vref value1 = loadValue(vm, vm->bp, arg);
            vref value2 = loadValue(vm, vm->bp, *vm->ip++);
            vref result = VRange(vm, value1, value2);
            if (!result)
            {
                return vm;
            }
            storeValue(vm, vm->bp, *vm->ip++, result);
            break;
        }

        case OP_JUMP:
            vm->ip += arg + 1;
            break;

        case OP_BRANCH_TRUE:
        {
            vref value = loadValue(vm, vm->bp, *vm->ip++);
            VBool b = VGetBool(value);
            vm->base.clonePoints++;
            if (vm->child && vm->base.clonePoints >= vm->child->clonePoints)
            {
                if (vm->base.clonePoints > vm->child->clonePoints)
                {
                    VMDispose(vm->child);
                    vm->child = null;
                    goto branchTrueNoChild;
                }
                assert(!vm->child->fullVM);
                if (b == FUTURE)
                {
                    VMReplaceCloneBranch(vm, vm->ip + arg);
                }
                else
                {
                    uint keepChild;
                    if (b == FALSY)
                    {
                        keepChild = 0;
                    }
                    else
                    {
                        vm->ip += arg;
                        keepChild = 1;
                    }
                    vm->child = VMDisposeBranch((VMBranch*)vm->child, keepChild);
                }
            }
            else
            {
        branchTrueNoChild:
                switch (b)
                {
                case FALSY:
                    break;
                case FUTURE:
                    assert(!vm->child);
                    VMCloneBranch(vm, vm->ip);
                    /* fallthrough */
                case TRUTHY:
                    vm->ip += arg;
                    break;
                }
            }
            break;
        }

        case OP_BRANCH_FALSE:
        {
            vref value = loadValue(vm, vm->bp, *vm->ip++);
            VBool b = VGetBool(value);
            vm->base.clonePoints++;
            if (vm->child && vm->base.clonePoints >= vm->child->clonePoints)
            {
                if (vm->base.clonePoints > vm->child->clonePoints)
                {
                    VMDispose(vm->child);
                    vm->child = null;
                    goto branchFalseNoChild;
                }
                assert(!vm->child->fullVM);
                if (b == FUTURE)
                {
                    VMReplaceCloneBranch(vm, vm->ip);
                    vm->ip += arg;
                }
                else
                {
                    uint keepChild;
                    if (b == FALSY)
                    {
                        vm->ip += arg;
                        keepChild = 0;
                    }
                    else
                    {
                        keepChild = 1;
                    }
                    vm->child = VMDisposeBranch((VMBranch*)vm->child, keepChild);
                }
            }
            else
            {
        branchFalseNoChild:
                switch (b)
                {
                case TRUTHY:
                    break;
                case FUTURE:
                    assert(!vm->child);
                    VMCloneBranch(vm, vm->ip);
                    /* fallthrough */
                case FALSY:
                    vm->ip += arg;
                    break;
                }
            }
            break;
        }

        case OP_RETURN:
            assert(IVSize(&vm->callStack));
            popStackFrame(vm, &vm->ip, &vm->bp, (uint)arg);
            break;

        case OP_RETURN_VOID:
            if (!IVSize(&vm->callStack))
            {
                vm->base.clonePoints++;
                VMHalt(vm, 0);
                return vm;
            }
            popStackFrame(vm, &vm->ip, &vm->bp, 0);
            break;

        case OP_INVOKE:
        {
            vref *values;
            int function = *vm->ip++;
            values = (vref*)IVGetAppendPointer(&vm->stack, (size_t)arg);
            for (i = 0; i < arg; i++)
            {
                *values++ = loadValue(vm, vm->bp, *vm->ip++);
            }
            IVAdd(&vm->callStack, (int)(vm->ip - vmBytecode));
            IVAdd(&vm->callStack, vm->bp);
            initStackFrame(vm, &vm->ip, &vm->bp, function, (uint)arg);
            break;
        }

        case OP_INVOKE_NATIVE:
        {
            nativefunctionref nativeFunction = refFromInt(arg);
            vref value;
            int storeAt;
            assert(!vm->job);
            vm->base.clonePoints++;
            if (vm->child && vm->base.clonePoints >= vm->child->clonePoints)
            {
                VM *child = (VM*)vm->child;
                assert(vm->child->fullVM);
                VMReplaceChild(vm, child);
            }
            value = NativeInvoke(vm, nativeFunction);
            if (vm->idle)
            {
                return vm;
            }
            storeAt = *vm->ip++;
            storeValue(vm, vm->bp, storeAt, value);
            if (vm->job)
            {
                vm->job->storeAt = storeAt;
                vm->idle = true;

                /* TODO: Activate speculative execution */
                JobExecute(vm->job);
                if (unlikely(vm->failMessage))
                {
                    return vm;
                }
                /* vm = VMClone(vm, vm->ip); */
            }
            break;
        }

        case OP_FUNCTION:
        case OP_FUNCTION_UNLINKED:
        case OP_LOAD_FIELD:
        case OP_STORE_FIELD:
        case OP_ITER_NEXT_INDEXED:
        case OP_JUMPTARGET:
        case OP_JUMP_INDEXED:
        case OP_BRANCH_TRUE_INDEXED:
        case OP_BRANCH_FALSE_INDEXED:
        case OP_INVOKE_UNLINKED:
        case OP_UNKNOWN_VALUE:
        case OP_FILE:
        case OP_LINE:
        case OP_ERROR:
        default:
            unreachable;
        }
    }
    return vm;
}