We have one of these per thread that we are running.
Ejemplo n.º 1
0
 /// <summary>
 /// Binds a value at a given positional index from a low level list
 /// (something that uses the P6list representation).
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="LLList"></param>
 /// <param name="Index"></param>
 /// <returns></returns>
 public static RakudoObject lllist_bind_at_pos(ThreadContext TC, RakudoObject LLList, RakudoObject IndexObj, RakudoObject Value)
 {
     if (LLList is P6list.Instance)
     {
         var Storage = ((P6list.Instance)LLList).Storage;
         var Index = Ops.unbox_int(TC, IndexObj);
         if (Index < Storage.Count)
         {
             Storage[Index] = Value;
         }
         else
         {
             // XXX Need some more efficient resizable array approach...
             // Also this is no way thread safe.
             while (Index > Storage.Count)
                 Storage.Add(null);
             Storage.Add(Value);
         }
         return Value;
     }
     else
     {
         throw new Exception("Cannot use lllist_bind_at_pos if representation is not P6list");
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Object"></param>
        /// <param name="ClassHandle"></param>
        /// <param name="Name"></param>
        /// <param name="Value"></param>
        public override void bind_attribute(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, RakudoObject Value)
        {
            var I = (Instance)Object;

            // Try the slot allocation first.
            Dictionary<string, int> ClassAllocation;
            int Position;
            if (SlotAllocation != null && SlotAllocation.TryGetValue(ClassHandle, out ClassAllocation))
                if (ClassAllocation.TryGetValue(Name, out Position))
                {
                    I.SlotStorage[Position] = Value;
                    return;
                }

            // Fall back to the spill storage.
            if (I.SpillStorage == null)
                I.SpillStorage = new Dictionary<RakudoObject, Dictionary<string, RakudoObject>>();
            if (!I.SpillStorage.ContainsKey(ClassHandle))
                I.SpillStorage.Add(ClassHandle, new Dictionary<string, RakudoObject>());
            var ClassStore = I.SpillStorage[ClassHandle];
            if (ClassStore.ContainsKey(Name))
                ClassStore[Name] = Value;
            else
                ClassStore.Add(Name, Value);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates an instantiation of the dispatch routine (or proto, which may
        /// serve as one) supplied and augments it with the provided candidates.
        /// It relies on being passed the instantiation of the dispatcher from the
        /// last outer scope that had an instantiation, and we thus take its
        /// candidates. This may or may not hold up in the long run; it works out
        /// in the Perl 6-y "you can make a new instance from any object" sense
        /// though, and seems more likely to get the closure semantics right than
        /// any of the other approaches I've considered so far.
        /// </summary>
        /// <param name="TC"></param>
        /// <param name="ToInstantiate"></param>
        /// <param name="ExtraDispatchees"></param>
        /// <returns></returns>
        public static RakudoObject create_dispatch_and_add_candidates(ThreadContext TC, RakudoObject ToInstantiate, RakudoObject ExtraDispatchees)
        {
            // Make sure we got the right things.
            var Source = ToInstantiate as RakudoCodeRef.Instance;
            var AdditionalDispatchList = ExtraDispatchees as P6list.Instance;
            if (Source == null || AdditionalDispatchList == null)
                throw new Exception("create_dispatch_and_add_candidates expects a RakudoCodeRef and a P6list");

            // Clone all but SC (since it's a new object and doesn't live in any
            // SC yet) and dispatchees (which we want to munge).
            var NewDispatch = new RakudoCodeRef.Instance(Source.STable);
            NewDispatch.Body = Source.Body;
            NewDispatch.CurrentContext = Source.CurrentContext;
            NewDispatch.Handlers = Source.Handlers;
            NewDispatch.OuterBlock = Source.OuterBlock;
            NewDispatch.OuterForNextInvocation = Source.OuterForNextInvocation;
            NewDispatch.Sig = Source.Sig;
            NewDispatch.StaticLexPad = Source.StaticLexPad;

            // Take existing candidates and add new ones.
            NewDispatch.Dispatchees = new RakudoObject[Source.Dispatchees.Length + AdditionalDispatchList.Storage.Count];
            var i = 0;
            for (int j = 0; j < Source.Dispatchees.Length; j++)
                NewDispatch.Dispatchees[i++] = Source.Dispatchees[j];
            for (int j = 0; j < AdditionalDispatchList.Storage.Count; j++)
                NewDispatch.Dispatchees[i++] = AdditionalDispatchList.Storage[j];

            return NewDispatch;
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Boxes a native string into its matching value type.
 /// </summary>
 /// <param name="Value"></param>
 /// <returns></returns>
 public static RakudoObject box_str(ThreadContext TC, string Value, RakudoObject To)
 {
     var REPR = To.STable.REPR;
     var Result = REPR.instance_of(TC, To);
     REPR.set_str(TC, Result, Value);
     return Result;
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Create an instance of the given object.
 /// </summary>
 /// <param name="WHAT"></param>
 /// <returns></returns>
 public override RakudoObject instance_of(ThreadContext TC, RakudoObject WHAT)
 {
     var Object = new KnowHOWInstance(WHAT.STable);
     Object.Methods = new Dictionary<string, RakudoObject>();
     Object.Attributes = new List<RakudoObject>();
     return Object;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Checks if a routine is considered a dispatcher (that is, if it has a
 /// candidate list).
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="Check"></param>
 /// <returns></returns>
 public static RakudoObject is_dispatcher(ThreadContext TC, RakudoObject Check)
 {
     var Checkee = Check as RakudoCodeRef.Instance;
     if (Checkee != null && Checkee.Dispatchees != null)
         return Ops.box_int(TC, 1, TC.DefaultBoolBoxType);
     else
         return Ops.box_int(TC, 0, TC.DefaultBoolBoxType);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Gets the attribute with the given value.
 /// </summary>
 /// <param name="ClassHandle"></param>
 /// <param name="Name"></param>
 /// <returns></returns>
 public override RakudoObject get_attribute(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name)
 {
     // If no storage ever allocated, trivially no value. Otherwise,
     // return what we find.
     var I = (Instance)Object;
     if (I.Storage == null || !I.Storage.ContainsKey(ClassHandle))
         return null;
     var ClassStore = I.Storage[ClassHandle];
     return ClassStore.ContainsKey(Name) ? ClassStore[Name] : null;
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Gets a value at a given positional index from a low level list
 /// (something that uses the P6list representation).
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="LLList"></param>
 /// <param name="Index"></param>
 /// <returns></returns>
 public static RakudoObject lllist_get_at_pos(ThreadContext TC, RakudoObject LLList, RakudoObject Index)
 {
     if (LLList is P6list.Instance)
     {
         return ((P6list.Instance)LLList).Storage[Ops.unbox_int(TC, Index)];
     }
     else
     {
         throw new Exception("Cannot use lllist_get_at_pos if representation is not P6list");
     }
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Gets the number of elements in a low level list (something that
 /// uses the P6list representation).
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="LLList"></param>
 /// <returns></returns>
 public static RakudoObject lllist_elems(ThreadContext TC, RakudoObject LLList)
 {
     if (LLList is P6list.Instance)
     {
         return Ops.box_int(TC, ((P6list.Instance)LLList).Storage.Count, TC.DefaultIntBoxType);
     }
     else
     {
         throw new Exception("Cannot use lllist_elems if representation is not P6list");
     }
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Loads a module (that is, some pre-compiled compilation unit that
        /// was compiled using NQP). Expects the path minus an extension
        /// (that is, the .dll will be added). Returns what the body of the
        /// compilation unit evaluated to.
        /// </summary>
        /// <param name="TC"></param>
        /// <param name="Path"></param>
        /// <returns></returns>
        public static RakudoObject load_module(ThreadContext TC, RakudoObject Path)
        {
            // Load the assembly and grab the first type in it.
            var Assembly = AppDomain.CurrentDomain.Load(Ops.unbox_str(TC, Path));
            var Class = Assembly.GetTypes()[0];

            // Call the Load method, passing along the current thread context
            // and the setting to use with it. What's returned is what the main
            // body of the compilation unit evaluates to.
            var Method = Class.GetMethod("Load", BindingFlags.NonPublic | BindingFlags.Static);
            return (RakudoObject)Method.Invoke(null, new object[] { TC, TC.Domain.Setting });
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Looks up a variable in the dynamic scope.
 /// </summary>
 /// <param name="C"></param>
 /// <param name="Name"></param>
 /// <returns></returns>
 public static RakudoObject get_dynamic(ThreadContext TC, string Name)
 {
     var CurContext = TC.CurrentContext;
     while (CurContext != null)
     {
         int Index;
         if (CurContext.LexPad.SlotMapping.TryGetValue(Name, out Index))
             return CurContext.LexPad.Storage[Index];
         CurContext = CurContext.Caller;
     }
     throw new InvalidOperationException("No variable " + Name + " found in the dynamic scope");
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Binds the given value to a lexical variable of the given name.
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="name"></param>
 /// <returns></returns>
 public static RakudoObject bind_lex(ThreadContext TC, string Name, RakudoObject Value)
 {
     var CurContext = TC.CurrentContext;
     while (CurContext != null)
     {
         int Index;
         if (CurContext.LexPad.SlotMapping.TryGetValue(Name, out Index))
         {
             CurContext.LexPad.Storage[Index] = Value;
             return Value;
         }
         CurContext = CurContext.Outer;
     }
     throw new InvalidOperationException("No variable " + Name + " found in the lexical scope");
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Entry point to multi-dispatch over the current dispatchee list.
 /// </summary>
 /// <param name="TC"></param>
 /// <returns></returns>
 public static RakudoObject multi_dispatch_over_lexical_candidates(ThreadContext TC)
 {
     var CurOuter = TC.CurrentContext;
     while (CurOuter != null)
     {
         var CodeObj = CurOuter.StaticCodeObject;
         if (CodeObj.Dispatchees != null)
         {
             var Candidate = MultiDispatch.MultiDispatcher.FindBestCandidate(TC,
                 CodeObj, CurOuter.Capture);
             return Candidate.STable.Invoke(TC, Candidate, CurOuter.Capture);
         }
         CurOuter = CurOuter.Outer;
     }
     throw new Exception("Could not find dispatchee list!");
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Gets a value at a given key from a low level mapping (something that
 /// uses the P6mapping representation).
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="LLMapping"></param>
 /// <param name="Key"></param>
 /// <returns></returns>
 public static RakudoObject llmapping_get_at_key(ThreadContext TC, RakudoObject LLMapping, RakudoObject Key)
 {
     if (LLMapping is P6mapping.Instance)
     {
         var Storage = ((P6mapping.Instance)LLMapping).Storage;
         var StrKey = Ops.unbox_str(TC, Key);
         if (Storage.ContainsKey(StrKey))
             return Storage[StrKey];
         else
             return null;
     }
     else
     {
         throw new Exception("Cannot use llmapping_get_at_key if representation is not P6mapping");
     }
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Binds a value at a given key from a low level mapping (something that
 /// uses the P6mapping representation).
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="LLMapping"></param>
 /// <param name="Key"></param>
 /// <param name="Value"></param>
 /// <returns></returns>
 public static RakudoObject llmapping_bind_at_key(ThreadContext TC, RakudoObject LLMapping, RakudoObject Key, RakudoObject Value)
 {
     if (LLMapping is P6mapping.Instance)
     {
         var Storage = ((P6mapping.Instance)LLMapping).Storage;
         var StrKey = Ops.unbox_str(TC, Key);
         if (Storage.ContainsKey(StrKey))
             Storage[StrKey] = Value;
         else
             Storage.Add(StrKey, Value);
         return Value;
     }
     else
     {
         throw new Exception("Cannot use llmapping_bind_at_key if representation is not P6mapping");
     }
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Creates a clone of the given code object, and makes its outer context
        /// be set to the current context.
        /// </summary>
        /// <param name="TC"></param>
        /// <param name="Block"></param>
        /// <returns></returns>
        public static RakudoObject new_closure(ThreadContext TC, RakudoCodeRef.Instance Block)
        {
            // Clone all but OuterForNextInvocation and SC (since it's a new
            // object and doesn't live in any SC yet).
            var NewBlock = new RakudoCodeRef.Instance(Block.STable);
            NewBlock.Body = Block.Body;
            NewBlock.CurrentContext = Block.CurrentContext;
            NewBlock.Dispatchees = Block.Dispatchees;
            NewBlock.Handlers = Block.Handlers;
            NewBlock.OuterBlock = Block.OuterBlock;
            NewBlock.Sig = Block.Sig;
            NewBlock.StaticLexPad = Block.StaticLexPad;

            // Set the outer for next invocation and return the cloned block.
            NewBlock.OuterForNextInvocation = TC.CurrentContext;
            return NewBlock;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Binds an attribute to the given value.
        /// </summary>
        /// <param name="Object"></param>
        /// <param name="ClassHandle"></param>
        /// <param name="Name"></param>
        /// <param name="Value"></param>
        public override void bind_attribute(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, RakudoObject Value)
        {
            // If no storage at all, allocate some.
            var I = (Instance)Object;
            if (I.Storage == null)
                I.Storage = new Dictionary<RakudoObject, Dictionary<string, RakudoObject>>();
            if (!I.Storage.ContainsKey(ClassHandle))
                I.Storage.Add(ClassHandle, new Dictionary<string, RakudoObject>());

            // Now stick in the name slot for the class storage, creating if it
            // needed.
            var ClassStore = I.Storage[ClassHandle];
            if (ClassStore.ContainsKey(Name))
                ClassStore[Name] = Value;
            else
                ClassStore.Add(Name, Value);
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Throws the specified exception, looking for an exception handler in the
 /// dynamic scope.
 /// </summary>
 /// <param name="TC"></param>
 /// <param name="ExceptionObject"></param>
 /// <param name="ExceptionType"></param>
 /// <returns></returns>
 public static RakudoObject throw_dynamic(ThreadContext TC, RakudoObject ExceptionObject, RakudoObject ExceptionType)
 {
     int WantType = Ops.unbox_int(TC, ExceptionType);
     var CurContext = TC.CurrentContext;
     while (CurContext != null)
     {
         if (CurContext.StaticCodeObject != null)
         {
             var Handlers = CurContext.StaticCodeObject.Handlers;
             if (Handlers != null)
                 for (int i = 0; i < Handlers.Length; i++)
                     if (Handlers[i].Type == WantType)
                         return Exceptions.ExceptionDispatcher.CallHandler(TC,
                             Handlers[i].HandleBlock, ExceptionObject);
         }
         CurContext = CurContext.Caller;
     }
     Exceptions.ExceptionDispatcher.DieFromUnhandledException(TC, ExceptionObject);
     return null; // Unreachable; above call exits always.
 }
Ejemplo n.º 19
0
Archivo: Init.cs Proyecto: Util/6model
        /// <summary>
        /// Handles the various bits of initialization that are needed.
        /// Probably needs some don't-dupe-this work.
        /// </summary>
        public static ThreadContext Initialize(string SettingName)
        {
            // Bootstrap the meta-model.
            RegisterRepresentations();
            var KnowHOW = KnowHOWBootstrapper.Bootstrap();
            var KnowHOWAttribute = KnowHOWBootstrapper.SetupKnowHOWAttribute(KnowHOW);

            // See if we're to load a setting or use the fake bootstrapping one.
            Context SettingContext;
            if (SettingName == null)
            {
                SettingContext = BootstrapSetting(KnowHOW, KnowHOWAttribute);
            }
            else
            {
                SettingContext = LoadSetting(SettingName, KnowHOW, KnowHOWAttribute);
            }

            // Cache native capture and LLCode type object.
            CaptureHelper.CaptureTypeObject = SettingContext.LexPad.GetByName("capture");
            CodeObjectUtility.LLCodeTypeObject = (RakudoCodeRef.Instance)SettingContext.LexPad.GetByName("NQPCode");

            // Create an execution domain and a thread context for it.
            var ExecDom = new ExecutionDomain();
            ExecDom.Setting = SettingContext;
            var Thread = new ThreadContext();
            Thread.Domain = ExecDom;
            Thread.CurrentContext = SettingContext;
            Thread.DefaultBoolBoxType = SettingContext.LexPad.GetByName("NQPInt");
            Thread.DefaultIntBoxType = SettingContext.LexPad.GetByName("NQPInt");
            Thread.DefaultNumBoxType = SettingContext.LexPad.GetByName("NQPNum");
            Thread.DefaultStrBoxType = SettingContext.LexPad.GetByName("NQPStr");
            Thread.DefaultListType = SettingContext.LexPad.GetByName("NQPList");
            Thread.DefaultArrayType = SettingContext.LexPad.GetByName("NQPArray");
            Thread.DefaultHashType = SettingContext.LexPad.GetByName("NQPHash");

            return Thread;
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Bind the attribute, using the hint if possible.
 /// </summary>
 /// <param name="Object"></param>
 /// <param name="ClassHandle"></param>
 /// <param name="Name"></param>
 /// <param name="Hint"></param>
 /// <param name="Value"></param>
 public override void bind_attribute_with_hint(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, int Hint, RakudoObject Value)
 {
     var I = (Instance)Object;
     if (Hint < I.SlotStorage.Length)
     {
         I.SlotStorage[Hint] = Value;
     }
     else if ((Hint = hint_for(TC, ClassHandle, Name)) != Hints.NO_HINT && Hint < I.SlotStorage.Length)
     {
         I.SlotStorage[Hint] = Value;
     }
     else
     {
         if (I.SpillStorage == null)
             I.SpillStorage = new Dictionary<RakudoObject, Dictionary<string, RakudoObject>>();
         if (!I.SpillStorage.ContainsKey(ClassHandle))
             I.SpillStorage.Add(ClassHandle, new Dictionary<string, RakudoObject>());
         var ClassStore = I.SpillStorage[ClassHandle];
         if (ClassStore.ContainsKey(Name))
             ClassStore[Name] = Value;
         else
             ClassStore.Add(Name, Value);
     }
 }
Ejemplo n.º 21
0
 public override int get_int(ThreadContext TC, RakudoObject Object)
 {
     throw new InvalidOperationException("This type of representation cannot unbox to a native int");
 }
Ejemplo n.º 22
0
 /// <summary>
 /// This representation doesn't use hints, so this just delegates
 /// straight off to the hint-less version.
 /// </summary>
 /// <param name="ClassHandle"></param>
 /// <param name="Name"></param>
 /// <param name="Hint"></param>
 /// <returns></returns>
 public override RakudoObject get_attribute_with_hint(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, int Hint)
 {
     return get_attribute(TC, Object, ClassHandle, Name);
 }
Ejemplo n.º 23
0
 /// <summary>
 /// Checks if the object is defined, which boils down to "is
 /// this a type object", which in trun means "did we allocate
 /// any storage".
 /// </summary>
 /// <param name="Object"></param>
 /// <returns></returns>
 public override bool defined(ThreadContext TC, RakudoObject Object)
 {
     return ((Instance)Object).Storage != null;
 }
Ejemplo n.º 24
0
 /// <summary>
 /// This representation doesn't do hints, so this delegates straight
 /// off to the hint-less version.
 /// </summary>
 /// <param name="ClassHandle"></param>
 /// <param name="Name"></param>
 /// <param name="Hint"></param>
 /// <param name="Value"></param>
 public override void bind_attribute_with_hint(ThreadContext TC, RakudoObject Object, RakudoObject ClassHandle, string Name, int Hint, RakudoObject Value)
 {
     bind_attribute(TC, Object, ClassHandle, Name, Value);
 }
Ejemplo n.º 25
0
 /// <summary>
 /// Creates a type object that references the given HOW and
 /// this REPR; note we just use the singleton instance for
 /// all of them, since the REPR stores nothing distinct.
 /// </summary>
 /// <param name="HOW"></param>
 /// <returns></returns>
 public override RakudoObject type_object_for(ThreadContext TC, RakudoObject MetaPackage)
 {
     var STable = new SharedTable();
     STable.HOW = MetaPackage;
     STable.REPR = this;
     STable.WHAT = new Instance(STable);
     return STable.WHAT;
 }
Ejemplo n.º 26
0
 public override void set_str(ThreadContext TC, RakudoObject Object, string Value)
 {
     throw new InvalidOperationException("This type of representation cannot box a native string");
 }
Ejemplo n.º 27
0
 public override void set_num(ThreadContext TC, RakudoObject Object, double Value)
 {
     throw new InvalidOperationException("This type of representation cannot box a native num");
 }
Ejemplo n.º 28
0
 /// <summary>
 /// Allocates and returns a new object based upon the type object
 /// supplied.
 /// </summary>
 /// <param name="HOW"></param>
 /// <returns></returns>
 public override RakudoObject instance_of(ThreadContext TC, RakudoObject WHAT)
 {
     var Object = new Instance(WHAT.STable);
     Object.Storage = new Dictionary<RakudoObject, Dictionary<string, RakudoObject>>();
     return Object;
 }
Ejemplo n.º 29
0
 /// <summary>
 /// No hints for P6Hash.
 /// </summary>
 /// <param name="ClassHandle"></param>
 /// <param name="Name"></param>
 /// <returns></returns>
 public override int hint_for(ThreadContext TC, RakudoObject ClassHandle, string Name)
 {
     return Hints.NO_HINT;
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Compares two floating point numbers for greater-than inequality.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="ResultType"></param>
 /// <returns></returns>
 public static RakudoObject greater_than_nums(ThreadContext TC, RakudoObject x, RakudoObject y)
 {
     return Ops.box_int(TC,
         (Ops.unbox_num(TC, x) > Ops.unbox_num(TC, y) ? 1 : 0),
         TC.DefaultBoolBoxType);
 }