示例#1
0
        public object Invoke(ScriptMethodBase scriptMethod, object target, params object[] args)
        {
            var callArgs = args;

            if (scriptMethod.MethodDefinition.HasThis)
            {
                callArgs    = new object[args.Length + 1];
                callArgs[0] = target;
                Array.Copy(args, 0, callArgs, 1, args.Length);
            }

            _runtimeContext.PushCallStack(scriptMethod, callArgs);

            var instruction = scriptMethod.MethodDefinition.Body.Instructions[0];

            while (true)
            {
                try
                {
                    Execute(ref instruction);
                    break;
                }
                catch (ScriptException ex)
                {
                    if (HandleException(scriptMethod, ex.InnerException, ref instruction))
                    {
                        _runtimeContext.PushToStack(ex.InnerException);
                        continue;
                    }

                    _runtimeContext.PopCallStack();

                    throw;
                }
                catch (Exception ex)
                {
                    if (HandleException(scriptMethod, ex, ref instruction))
                    {
                        _runtimeContext.PushToStack(ex);
                        continue;
                    }

                    _runtimeContext.PopCallStack();
                    throw;
                }
            }

            return(_runtimeContext.PopCallStack().Return());
        }
        private bool HandleException(ScriptMethodBase method, Exception ex, ref Instruction instruction)
        {
            if (method.MethodDefinition.Body.HasExceptionHandlers)
            {
                var inst = instruction;

                var handlers = method.MethodDefinition.Body.ExceptionHandlers
                               .Where(_ =>
                {
                    if (_.HandlerType != ExceptionHandlerType.Catch)
                    {
                        return(false);
                    }

                    if (_.TryStart.Offset > inst.Offset)
                    {
                        return(false);
                    }

                    if (_.TryEnd.Offset < inst.Offset)
                    {
                        return(false);
                    }

                    return(true);
                })
                               .OrderBy(_ => _.TryEnd.Offset - _.TryStart.Offset);

                var handlerList = handlers.ToList();
                var bestMatch   = FindBestExceptionMatch(ex, handlerList);

                if (bestMatch == null)
                {
                    return(false);
                }

                instruction = bestMatch.HandlerStart;
                return(true);
            }

            return(false);
        }
示例#3
0
        private StackFrame Init(ScriptMethodBase scriptMethod, params object[] param)
        {
            // init local vars
            _locals = scriptMethod.MethodDefinition.Body.Variables.Select(_ =>
            {
                var type = _.VariableType;
                if (!type.IsValueType)
                {
                    return(null);
                }

                var scriptType = ScriptContext.GetType(type);
                return(scriptType.IsHost ? Activator.CreateInstance(scriptType.HostType) : scriptType.CreateInstance());
            }).ToArray();

            // init arguments
            _arguments = param;

            ScriptMethod = scriptMethod;

            return(this);
        }
示例#4
0
 internal static StackFrame Alloc(ScriptMethodBase scriptMethod, params object[] param)
 {
     return(FreeList.Count == 0 ? new StackFrame().Init(scriptMethod, param) : FreeList.Pop().Init(scriptMethod, param));
 }
示例#5
0
 internal void PushCallStack(ScriptMethodBase scriptMethod, params object[] param)
 {
     _stackFrames.Push(StackFrame.Alloc(scriptMethod, param));
 }