Ejemplo n.º 1
0
 public override JsonValue Evaluate(
     QueryExecutor executor,
     ExecutionFrame frame
     )
 {
     return(Value);
 }
        public void ItEvaluatesUnaryOperators()
        {
            frame = frame
                    .AddVariable("x2", 2)
                    .AddVariable("t", true);

            Assert.AreEqual(
                "2".Replace("'", "\""),
                parser
                .Parse((x2) => + x2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "-2".Replace("'", "\""),
                parser
                .Parse((x2) => - x2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "false".Replace("'", "\""),
                parser
                .Parse((t) => !t)
                .Evaluate(executor, frame)
                .ToString()
                );
        }
            public override void ExitIfDef(VariableStateCalculatorGrammarParser.IfDefContext context)
            {
                ExecutionFrame frame = FrameStack.Pop();

                FrameStack.Peek().Merge(frame);
                base.ExitIfDef(context);
            }
        public void ItEvaluatesMemberAccess()
        {
            frame = frame
                    .AddVariable("o", new JsonObject()
                                 .Add("foo", 42)
                                 )
                    .AddVariable("a", new JsonArray(
                                     "a", "b", "c"
                                     ));

            Assert.AreEqual(
                "42".Replace("'", "\""),
                parser
                .Parse((o) => o["foo"])
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "'a'".Replace("'", "\""),
                parser
                .Parse((a) => a[0])
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "'c'".Replace("'", "\""),
                parser
                .Parse((a) => a[-1])
                .Evaluate(executor, frame)
                .ToString()
                );
        }
        public void SetUp()
        {
            parser = new LinqToAqlExpressionParser();

            arango   = new ArangoInMemory();
            executor = arango.Executor;

            frame = new ExecutionFrame();
        }
        private IEnumerable <ExecutionFrame> MultiplyFrameByCollection(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            IEnumerable <JsonValue> collection = CollectionExpression
                                                 .Evaluate(executor, frame)
                                                 .AsJsonArray;

            return(collection.Select(
                       item => frame.AddVariable(VariableName, item)
                       ));
        }
        public override JsonValue Evaluate(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            var result = new JsonArray();

            foreach (var item in Items)
            {
                result.Add(item.Evaluate(executor, frame));
            }

            return(result);
        }
Ejemplo n.º 8
0
        public override JsonValue Evaluate(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            var result = new JsonObject();

            foreach (var pair in Items)
            {
                result.Add(pair.Key, pair.Value.Evaluate(executor, frame));
            }

            return(result);
        }
        public override JsonValue Evaluate(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            JsonValue[] evaluatedArguments = Arguments.Select(
                a => a.Evaluate(executor, frame)
                ).ToArray();

            return(executor.FunctionRepository.EvaluateFunction(
                       FunctionName,
                       evaluatedArguments
                       ));
        }
            public override void VisitIfStatement(IfStatementSyntax node)
            {
                if (node.Else != null)
                {
                    // unexpected case
                    throw new NotSupportedException();
                }
                Int32 usedParameter = ExtractParameterFromCondition(node.Condition);

                FrameStack.Push(new ExecutionFrame(usedParameter));
                base.VisitIfStatement(node);
                ExecutionFrame frame = FrameStack.Pop();

                FrameStack.Peek().Merge(frame);
            }
Ejemplo n.º 11
0
        public override JsonValue Evaluate(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            if (!frame.Variables.ContainsKey(Name))
            {
                throw new QueryExecutionException(
                          $"Parameter {Name} cannot be found. Available variables: "
                          + string.Join(", ", frame.Variables.Keys)
                          );
            }

            return(frame.Variables[Name]);
        }
Ejemplo n.º 12
0
        private void ProcessIf(IfStatementSyntax ifStatement, Stack <ExecutionFrame> frameStack)
        {
            if (ifStatement.Else != null)
            {
                // unexpected case
                throw new NotSupportedException();
            }
            Int32           usedParameter = ExtractParameterFromCondition(ifStatement.Condition);
            StatementSyntax ifBody        = ifStatement.Statement;

            frameStack.Push(new ExecutionFrame(usedParameter));
            ProcessIfImpl(ifBody, frameStack);
            ExecutionFrame frame = frameStack.Pop();

            frameStack.Peek().Merge(frame);
        }
        public void ItEvaluatesJsonObjectExpression()
        {
            frame = frame
                    .AddVariable("x", 42);

            Assert.AreEqual(
                "{'foo':42,'bar':84}".Replace("'", "\""),
                parser
                .Parse((x) => new JsonObject()
                       .Add("foo", x)
                       .Add("bar", x * 2)
                       )
                .Evaluate(executor, frame)
                .ToString()
                );
        }
Ejemplo n.º 14
0
        private ExecutionState InternalCall(ContractMethod method, ExecutionFrame frame, Stack <VMObject> stack)
        {
            var args = new object[method.parameters.Length];

            for (int i = 0; i < args.Length; i++)
            {
                var arg = stack.Pop();

                var temp = arg.Data;

                if (temp is string)
                {
                    switch (method.parameters[i])
                    {
                    // TODO this currently is casting any type of object, not just addresses!
                    // when a string is passed instead of an address we do an automatic lookup and replace
                    case VMType.Object:
                        var name    = (string)temp;
                        var runtime = (RuntimeVM)frame.VM;
                        var address = runtime.Nexus.LookUpName(name);
                        temp = address;
                        break;

                    case VMType.Number:
                        var value = (string)temp;
                        if (BigInteger.TryParse(value, out BigInteger number))
                        {
                            temp = number;
                        }
                        break;
                    }
                }

                args[i] = temp;
            }

            var result = this.Contract.CallInternalMethod(method.name, args);

            if (method.returnType != VMType.None)
            {
                var obj = VMObject.FromObject(result);
                stack.Push(obj);
            }

            return(ExecutionState.Running);
        }
        public override JsonValue Evaluate(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            JsonValue o = Operand.Evaluate(executor, frame);

            switch (ExpressionType)
            {
            case AqlExpressionType.UnaryPlus: return(AqlArithmetic.Plus(o));

            case AqlExpressionType.UnaryMinus: return(AqlArithmetic.Minus(o));

            case AqlExpressionType.Not: return(AqlArithmetic.Not(o));
            }

            throw new QueryExecutionException(
                      $"Cannot evaluate expression {ExpressionType} - not implemented"
                      );
        }
        private ExecutionState InternalCall(ContractMethod method, ExecutionFrame frame, Stack <VMObject> stack)
        {
            var args = new object[method.parameters.Length];

            for (int i = 0; i < args.Length; i++)
            {
                var arg = stack.Pop();
                args[i] = arg.Data;
            }

            var result = this.Contract.CallInternalMethod((RuntimeVM)frame.VM, method.name, args);

            if (method.returnType != VMType.None)
            {
                var obj = VMObject.FromObject(result);
                stack.Push(obj);
            }

            return(ExecutionState.Running);
        }
        public override JsonValue Evaluate(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            JsonValue l = Left.Evaluate(executor, frame);
            JsonValue r = Right.Evaluate(executor, frame);

            switch (ExpressionType)
            {
            case AqlExpressionType.Add: return(AqlArithmetic.Add(l, r));

            case AqlExpressionType.Subtract: return(AqlArithmetic.Subtract(l, r));

            case AqlExpressionType.Multiply: return(AqlArithmetic.Multiply(l, r));

            case AqlExpressionType.Divide: return(AqlArithmetic.Divide(l, r));

            case AqlExpressionType.Modulo: return(AqlArithmetic.Modulo(l, r));

            case AqlExpressionType.Equal: return(AqlArithmetic.Equal(l, r));

            case AqlExpressionType.NotEqual: return(AqlArithmetic.NotEqual(l, r));

            case AqlExpressionType.GreaterThan: return(AqlArithmetic.GreaterThan(l, r));

            case AqlExpressionType.GreaterThanOrEqual: return(AqlArithmetic.GreaterThenOrEqual(l, r));

            case AqlExpressionType.LessThan: return(AqlArithmetic.LessThan(l, r));

            case AqlExpressionType.LessThanOrEqual: return(AqlArithmetic.LessThanOrEqual(l, r));

            case AqlExpressionType.And: return(AqlArithmetic.And(l, r));

            case AqlExpressionType.Or: return(AqlArithmetic.Or(l, r));
            }

            throw new QueryExecutionException(
                      $"Cannot evaluate expression {ExpressionType} - not implemented"
                      );
        }
        public override JsonValue Evaluate(
            QueryExecutor executor,
            ExecutionFrame frame
            )
        {
            JsonValue m = Member.Evaluate(executor, frame);
            JsonValue s = Subject.Evaluate(executor, frame);

            if (s.IsJsonArray)
            {
                if (!m.IsInteger)
                {
                    return(JsonValue.Null);
                }

                int i = m.AsInteger;

                if (i < 0)
                {
                    i += s.AsJsonArray.Count;
                }

                return(s[i]);
            }

            if (s.IsJsonObject)
            {
                if (!m.IsString)
                {
                    return(JsonValue.Null);
                }

                return(s[m.AsString]);
            }

            return(JsonValue.Null);
        }
Ejemplo n.º 19
0
 public override ExecutionState Execute(ExecutionFrame frame, Stack <VMObject> stack)
 {
     return(ExecutionState.Halt);
 }
Ejemplo n.º 20
0
        public override ExecutionState Execute(ExecutionFrame frame, Stack <VMObject> stack)
        {
            if (this.Contract.ABI == null)
            {
                throw new VMException(frame.VM, $"VM nativecall failed: ABI is missing for contract '{this.Contract.Name}'");
            }

            if (stack.Count <= 0)
            {
                throw new VMException(frame.VM, $"VM nativecall failed: method name not present in the VM stack {frame.Context.Name}");
            }

            var stackObj   = stack.Pop();
            var methodName = stackObj.AsString();

            var runtime = (RuntimeVM)frame.VM;

            if (methodName.Equals(SmartContract.ConstructorName, StringComparison.OrdinalIgnoreCase) && runtime.HasGenesis)
            {
                BigInteger usedQuota;

                if (Nexus.IsNativeContract(Contract.Name))
                {
                    usedQuota = 1024; // does not matter what number, just than its greater than 0
                }
                else
                {
                    usedQuota = runtime.CallNativeContext(NativeContractKind.Storage, nameof(StorageContract.GetUsedDataQuota), this.Contract.Address).AsNumber();
                }

                if (usedQuota > 0)
                {
                    throw new VMException(frame.VM, $"VM nativecall failed: constructor can only be called once");
                }
            }

            var method = this.Contract.ABI.FindMethod(methodName);

            if (method == null)
            {
                throw new VMException(frame.VM, $"VM nativecall failed: contract '{this.Contract.Name}' does not have method '{methodName}' in its ABI");
            }

            if (stack.Count < method.parameters.Length)
            {
                throw new VMException(frame.VM, $"VM nativecall failed: calling method {methodName} with {stack.Count} arguments instead of {method.parameters.Length}");
            }

            ExecutionState result;

            BigInteger gasCost = 10;

            result = runtime.ConsumeGas(gasCost);
            if (result != ExecutionState.Running)
            {
                return(result);
            }

            var native = Contract as NativeContract;

            if (native != null)
            {
                using (var m = new ProfileMarker("InternalCall"))
                {
                    try
                    {
                        native.SetRuntime(runtime);
                        native.LoadFromStorage(runtime.Storage);

                        result = InternalCall(native, method, frame, stack);
                        native.SaveChangesToStorage();
                    }
                    catch (ArgumentException ex)
                    {
                        throw new VMException(frame.VM, $"VM nativecall failed: calling method {methodName} with arguments of wrong type, " + ex.ToString());
                    }
                }
            }
            else
            {
                var custom = Contract as CustomContract;

                if (custom != null)
                {
                    if (method.offset < 0)
                    {
                        throw new VMException(frame.VM, $"VM context call failed: abi contains invalid offset for {method.name}");
                    }

#if SUSHI_MODE
                    var debugPath = @"C:\Code\Poltergeist\Builds\Windows\debug.asm";
                    var disasm    = new VM.Disassembler(custom.Script);
                    var asm       = string.Join("\n", disasm.Instructions.Select(x => x.ToString()));
                    System.IO.File.WriteAllText(debugPath, asm);
#endif

                    var context = new ScriptContext(Contract.Name, custom.Script, (uint)method.offset);
                    result = context.Execute(frame, stack);
                }
                else
                {
                    throw new VMException(frame.VM, $"VM context call failed: unknown contract instance class {Contract.GetType().Name}");
                }
            }


            // we terminate here execution, since it will be restarted in next context
            if (result == ExecutionState.Running)
            {
                result = ExecutionState.Halt;
            }

            return(result);
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Evaluates the expression to a concrete value
 /// in a given execution context
 /// </summary>
 public abstract JsonValue Evaluate(
     QueryExecutor executor,
     ExecutionFrame frame
     );
        public override ExecutionState Execute(ExecutionFrame frame, Stack <VMObject> stack)
        {
            if (this.Contract.ABI == null)
            {
#if DEBUG
                throw new VMDebugException(frame.VM, $"VM nativecall failed: ABI is missing for contract '{this.Contract.Name}'");
#else
                return(ExecutionState.Fault);
#endif
            }

            if (stack.Count <= 0)
            {
#if DEBUG
                throw new VMDebugException(frame.VM, $"VM nativecall failed: method name not present in the VM stack");
#else
                return(ExecutionState.Fault);
#endif
            }

            var stackObj   = stack.Pop();
            var methodName = stackObj.AsString();
            var method     = this.Contract.ABI.FindMethod(methodName);

            if (method == null)
            {
#if DEBUG
                throw new VMDebugException(frame.VM, $"VM nativecall failed: contract '{this.Contract.Name}' does not have method '{methodName}' in its ABI");
#else
                return(ExecutionState.Fault);
#endif
            }

            if (stack.Count < method.parameters.Length)
            {
#if DEBUG
                throw new VMDebugException(frame.VM, $"VM nativecall failed: calling method {methodName} with {stack.Count} arguments instead of {method.parameters.Length}");
#else
                return(ExecutionState.Fault);
#endif
            }

            var runtime = (RuntimeVM)frame.VM;

            BigInteger gasCost;
            if (this.Contract.HasInternalMethod(methodName, out gasCost))
            {
                ExecutionState result;
                try
                {
                    result = runtime.ConsumeGas(gasCost);
                    if (result == ExecutionState.Running)
                    {
                        Contract.LoadRuntimeData(runtime);
                        result = InternalCall(method, frame, stack);
                        Contract.UnloadRuntimeData();
                    }
                }
                catch (ArgumentException ex)
                {
#if DEBUG
                    throw new VMDebugException(frame.VM, $"VM nativecall failed: calling method {methodName} with arguments of wrong type, " + ex.ToString());
#else
                    result = ExecutionState.Fault;
#endif
                }

                // we terminate here execution, since it will be restarted in next context
                if (result == ExecutionState.Running)
                {
                    result = ExecutionState.Halt;
                }

                return(result);
            }


            if (!(this.Contract is CustomContract customContract))
            {
#if DEBUG
                throw new VMDebugException(frame.VM, $"VM nativecall failed: contract '{this.Contract.Name}' is not a valid custom contract");
#else
                return(ExecutionState.Fault);
#endif
            }

            stack.Push(stackObj);

            var context = new ScriptContext(customContract.Name, customContract.Script, true);
            return(context.Execute(frame, stack));
        }
        public void ItEvaluatesBinaryOperators()
        {
            frame = frame
                    .AddVariable("x2", 2)
                    .AddVariable("t", true);

            Assert.AreEqual(
                "5".Replace("'", "\""),
                parser
                .Parse((x2) => x2 + 3)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "5.5".Replace("'", "\""),
                parser
                .Parse((x2) => x2 + 3.5)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "'2asd'".Replace("'", "\""),
                parser
                .Parse((x2) => x2 + "asd")
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "1".Replace("'", "\""),
                parser
                .Parse((x2) => x2 - 1)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "8".Replace("'", "\""),
                parser
                .Parse((x2) => x2 * 4)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "0.5".Replace("'", "\""),
                parser
                .Parse((x2) => x2 / 4)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "2".Replace("'", "\""),
                parser
                .Parse((x2) => x2 % 3)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "true".Replace("'", "\""),
                parser
                .Parse((x2) => x2 == 2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "false".Replace("'", "\""),
                parser
                .Parse((x2) => x2 != 2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "false".Replace("'", "\""),
                parser
                .Parse((x2) => x2 > 2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "true".Replace("'", "\""),
                parser
                .Parse((x2) => x2 >= 2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "false".Replace("'", "\""),
                parser
                .Parse((x2) => x2 < 2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "true".Replace("'", "\""),
                parser
                .Parse((x2) => x2 <= 2)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "false".Replace("'", "\""),
                parser
                .Parse((t) => t && false)
                .Evaluate(executor, frame)
                .ToString()
                );

            Assert.AreEqual(
                "true".Replace("'", "\""),
                parser
                .Parse((t) => t || true)
                .Evaluate(executor, frame)
                .ToString()
                );
        }