BadScript 2
Loading...
Searching...
No Matches
BadRuntimeVirtualMachine.cs
Go to the documentation of this file.
21
23
28{
32 private readonly Stack<BadObject> m_ArgumentStack = new Stack<BadObject>();
33
37 private readonly Stack<BadRuntimeVirtualStackFrame> m_ContextStack = new Stack<BadRuntimeVirtualStackFrame>();
38
42 private readonly BadInstruction[] m_Instructions;
43
48
52 private readonly bool m_UseOverrides;
53
58
64 public BadRuntimeVirtualMachine(BadCompiledFunction function, BadInstruction[] instructions, bool useOverrides = true)
65 {
66 m_Function = function;
67 m_Instructions = instructions;
68 m_UseOverrides = useOverrides;
69 }
70
71 private IEnumerable<BadObject> ExecuteStep(BadExecutionContext ctx)
72 {
75 {
76 BadDebugger.Step(new BadDebuggerStep(ctx, instr.Position, instr));
77 }
79
80 switch (instr.OpCode)
81 {
82 case BadOpCode.Nop:
83
84 break;
85 case BadOpCode.Dup:
87
88 break;
89 case BadOpCode.Pop:
90 m_ArgumentStack.Pop();
91
92 break;
93 case BadOpCode.AquireLock:
94 {
95 BadObject lockObj = m_ArgumentStack.Pop().Dereference();
96
97 if (lockObj is not BadArray && lockObj is not BadTable && lockObj is BadClass)
98 {
99 throw new BadRuntimeException(
100 "Lock object must be of type Array, Object or Class",
101 instr.Position
102 );
103 }
104
105 while (!BadLockList.Instance.TryAquire(lockObj))
106 {
107 yield return BadObject.Null;
108 }
109
110 break;
111 }
112 case BadOpCode.ArrayInit:
113 {
114 int length = (int)instr.Arguments[0];
115 List<BadObject> arr = new List<BadObject>();
116
117 for (int i = 0; i < length; i++)
118 {
119 arr.Insert(0, m_ArgumentStack.Pop().Dereference());
120 }
121
122 m_ArgumentStack.Push(new BadArray(arr));
123
124 break;
125 }
126 case BadOpCode.TableInit:
127 {
128 int length = (int)instr.Arguments[0];
129 Dictionary<string, BadObject> arr = new Dictionary<string, BadObject>();
130
131 for (int i = 0; i < length; i++)
132 {
133 BadObject val = m_ArgumentStack.Pop().Dereference();
134 BadObject key = m_ArgumentStack.Pop().Dereference();
135 if (key is not IBadString s)
136 {
137 throw BadRuntimeException.Create(ctx.Scope, "Invalid Property Key", instr.Position);
138 }
139
140 arr.Add(s.Value, val);
141 }
142
143 m_ArgumentStack.Push(new BadTable(arr));
144
145 break;
146 }
147 case BadOpCode.HasProperty:
148 {
149 BadObject key = m_ArgumentStack.Pop().Dereference();
150 BadObject obj = m_ArgumentStack.Pop().Dereference();
151 BadObject? result = BadObject.Null;
152
153 if (m_UseOverrides)
154 {
155 foreach (BadObject o in BadInExpression.InWithOverride(ctx, key, obj, instr.Position))
156 {
157 result = o;
158 }
159 }
160 else
161 {
162 result = BadInExpression.In(ctx, key, obj);
163 }
164
165 m_ArgumentStack.Push(result);
166
167 break;
168 }
169 case BadOpCode.Invoke:
170 {
171 BadObject func = m_ArgumentStack.Pop().Dereference();
172 int argCount = (int)instr.Arguments[0];
173 BadObject[] args = new BadObject[argCount];
174
175 for (int i = argCount - 1; i >= 0; i--)
176 {
177 args[i] = m_ArgumentStack.Pop().Dereference();
178 }
179
181
182 if (m_Function == func) //Invoke Self
183 {
184 m_ContextStack.Push(
186 {
187 ReturnPointer = m_InstructionPointer
188 }
189 );
191 break;
192 }
193 foreach (BadObject o in BadInvocationExpression.Invoke(func, args, instr.Position, ctx))
194 {
195 r = o;
196
197 yield return o;
198 }
199
200 m_ArgumentStack.Push(r);
201
202 break;
203 }
204 case BadOpCode.New:
205 {
206 BadObject func = m_ArgumentStack.Pop().Dereference();
207
208 if (func is not BadClassPrototype ptype)
209 {
210 throw new BadRuntimeException("Cannot create object from non-class type", instr.Position);
211 }
212
213 int argCount = (int)instr.Arguments[0];
214 BadObject[] args = new BadObject[argCount];
215
216 for (int i = argCount - 1; i >= 0; i--)
217 {
218 args[i] = m_ArgumentStack.Pop().Dereference();
219 }
220
222
223 foreach (BadObject o in BadNewExpression.CreateObject(ptype, ctx, args, instr.Position))
224 {
225 r = o;
226
227 yield return o;
228 }
229
230 m_ArgumentStack.Push(r);
231
232 break;
233 }
234 case BadOpCode.Range:
235 {
236 BadObject start = m_ArgumentStack.Pop().Dereference();
237 BadObject end = m_ArgumentStack.Pop().Dereference();
238
239 if (start is not IBadNumber sn || end is not IBadNumber en)
240 {
241 throw new BadRuntimeException("Range start and end must be numbers", instr.Position);
242 }
243
244 m_ArgumentStack.Push(
245 new BadInteropEnumerator(BadRangeExpression.Range(sn.Value, en.Value).GetEnumerator())
246 );
247
248 break;
249 }
250 case BadOpCode.ReleaseLock:
251 {
252 BadObject lockObj = m_ArgumentStack.Pop().Dereference();
253
254 if (lockObj is not BadArray && lockObj is not BadTable && lockObj is BadClass)
255 {
256 throw new BadRuntimeException(
257 "Lock object must be of type Array, Object or Class",
258 instr.Position
259 );
260 }
261
262
264
265 break;
266 }
267 case BadOpCode.DefVar:
268 {
269 string name = (string)instr.Arguments[0];
270 bool isReadOnly = (bool)instr.Arguments[1];
272 m_ArgumentStack.Push(ctx.Scope.GetVariable(name));
273
274 break;
275 }
276 case BadOpCode.DefVarTyped:
277
278 {
279 string name = (string)instr.Arguments[0];
280 bool isReadOnly = (bool)instr.Arguments[1];
282 name,
284 ctx.Scope,
285 new BadPropertyInfo((BadClassPrototype)m_ArgumentStack.Pop().Dereference(), isReadOnly)
286 );
287 m_ArgumentStack.Push(ctx.Scope.GetVariable(name));
288
289 break;
290 }
291 case BadOpCode.LoadVar:
292 {
293 if (instr.Arguments.Length > 1 && instr.Arguments[1] is int genericArgCount && genericArgCount != 0)
294 {
295 BadObject item = ctx.Scope.GetVariable((string)instr.Arguments[0]).Dereference();
296 if (item is not IBadGenericObject genItem)
297 {
298 throw BadRuntimeException.Create(ctx.Scope, "Variable is not a generic object", instr.Position);
299 }
300 BadObject[] genericArgs = new BadObject[genericArgCount];
301 for (int i = genericArgCount - 1; i >= 0; i--)
302 {
303 genericArgs[i] = m_ArgumentStack.Pop().Dereference();
304 }
305 m_ArgumentStack.Push(genItem.CreateGeneric(genericArgs));
306 }
307 else
308 {
309 m_ArgumentStack.Push(ctx.Scope.GetVariable((string)instr.Arguments[0]));
310 }
311
312 break;
313 }
314 case BadOpCode.LoadMember:
315 {
316 if (instr.Arguments.Length > 1 && instr.Arguments[1] is int genericArgCount && genericArgCount != 0)
317 {
318 BadObject left =
319 m_ArgumentStack.Pop()
320 .Dereference()
321 .GetProperty((string)instr.Arguments[0], ctx.Scope)
322 .Dereference();
323 if (left is not IBadGenericObject genItem)
324 {
325 throw BadRuntimeException.Create(ctx.Scope, "Variable is not a generic object", instr.Position);
326 }
327
328 BadObject[] genericArgs = new BadObject[genericArgCount];
329 for (int i = genericArgCount - 1; i >= 0; i--)
330 {
331 genericArgs[i] = m_ArgumentStack.Pop().Dereference();
332 }
333 m_ArgumentStack.Push(genItem.CreateGeneric(genericArgs));
334 }
335 else
336 {
337 m_ArgumentStack.Push(
338 m_ArgumentStack.Pop()
339 .Dereference()
340 .GetProperty((string)instr.Arguments[0], ctx.Scope)
341 );
342 }
343
344 break;
345 }
346 case BadOpCode.LoadMemberNullChecked:
347 {
348 BadObject obj = m_ArgumentStack.Pop().Dereference();
349 string name = (string)instr.Arguments[0];
350
351 if (obj.HasProperty(name, ctx.Scope))
352 {
353 if (instr.Arguments.Length > 1 && instr.Arguments[1] is int genericArgCount && genericArgCount != 0)
354 {
355 BadObject left = obj
356 .GetProperty((string)instr.Arguments[0], ctx.Scope)
357 .Dereference();
358 if (left is not IBadGenericObject genItem)
359 {
360 throw BadRuntimeException.Create(ctx.Scope, "Variable is not a generic object", instr.Position);
361 }
362
363 BadObject[] genericArgs = new BadObject[genericArgCount];
364 for (int i = genericArgCount - 1; i >= 0; i--)
365 {
366 genericArgs[i] = m_ArgumentStack.Pop().Dereference();
367 }
368 m_ArgumentStack.Push(genItem.CreateGeneric(genericArgs));
369 }
370 else
371 {
372 m_ArgumentStack.Push(
373 obj.GetProperty(name, ctx.Scope)
374 );
375 }
376 }
377 else
378 {
380 }
381
382 break;
383 }
384 case BadOpCode.LoadArrayAccess:
385 {
386 BadObject obj = m_ArgumentStack.Pop().Dereference();
387 int argCount = (int)instr.Arguments[0];
388
389 BadObject[] args = new BadObject[argCount];
390
391 for (int i = argCount - 1; i >= 0; i--)
392 {
393 args[i] = m_ArgumentStack.Pop();
394 }
395
397
398 foreach (BadObject o in BadArrayAccessExpression.Access(ctx, obj, args, instr.Position))
399 {
400 r = o;
401
402 yield return o;
403 }
404
405 m_ArgumentStack.Push(r);
406
407 break;
408 }
409 case BadOpCode.LoadArrayAccessNullChecked:
410 {
411 BadObject obj = m_ArgumentStack.Pop().Dereference();
412 int argCount = (int)instr.Arguments[0];
413
414 if (obj == BadObject.Null)
415 {
416 for (int i = 0; i < argCount; i++)
417 {
418 m_ArgumentStack.Pop();
419 }
420
422
423 break;
424 }
425
426
427 BadObject[] args = new BadObject[argCount];
428
429 for (int i = argCount - 1; i >= 0; i--)
430 {
431 args[i] = m_ArgumentStack.Pop();
432 }
433
435
436 foreach (BadObject o in BadArrayAccessExpression.Access(ctx, obj, args, instr.Position))
437 {
438 r = o;
439
440 yield return o;
441 }
442
443 m_ArgumentStack.Push(r);
444
445 break;
446 }
447 case BadOpCode.LoadArrayAccessReverse:
448 {
449 BadObject obj = m_ArgumentStack.Pop().Dereference();
450 int argCount = (int)instr.Arguments[0];
451
452 BadObject[] args = new BadObject[argCount];
453
454 for (int i = argCount - 1; i >= 0; i--)
455 {
456 args[i] = m_ArgumentStack.Pop();
457 }
458
460
461 foreach (BadObject o in BadArrayAccessReverseExpression.Access(ctx, obj, args, instr.Position))
462 {
463 r = o;
464
465 yield return o;
466 }
467
468 m_ArgumentStack.Push(r);
469
470 break;
471 }
472 case BadOpCode.LoadArrayAccessReverseNullChecked:
473 {
474 BadObject obj = m_ArgumentStack.Pop().Dereference();
475
476 if (obj == BadObject.Null)
477 {
479
480 break;
481 }
482
483 int argCount = (int)instr.Arguments[0];
484
485 BadObject[] args = new BadObject[argCount];
486
487 for (int i = argCount - 1; i >= 0; i--)
488 {
489 args[i] = m_ArgumentStack.Pop();
490 }
491
493
494 foreach (BadObject o in BadArrayAccessReverseExpression.Access(ctx, obj, args, instr.Position))
495 {
496 r = o;
497
498 yield return o;
499 }
500
501 m_ArgumentStack.Push(r);
502
503 break;
504 }
505 case BadOpCode.Swap:
506 {
507 BadObject a = m_ArgumentStack.Pop();
508 BadObject b = m_ArgumentStack.Pop();
509
510 m_ArgumentStack.Push(a);
511 m_ArgumentStack.Push(b);
512
513 break;
514 }
515 case BadOpCode.Assign:
516 {
517 BadObject val = m_ArgumentStack.Pop().Dereference();
519 left.Set(val);
520
521 break;
522 }
523 case BadOpCode.Push:
524 m_ArgumentStack.Push((BadObject)instr.Arguments[0]);
525
526 break;
527 case BadOpCode.FormatString:
528 {
529 string format = (string)instr.Arguments[0];
530 int argCount = (int)instr.Arguments[1];
531 BadObject[] args = new BadObject[argCount];
532
533 for (int i = argCount - 1; i >= 0; i--)
534 {
535 args[i] = m_ArgumentStack.Pop().Dereference();
536 }
537
538 m_ArgumentStack.Push(string.Format(format, args.Cast<object?>().ToArray()));
539
540 break;
541 }
542 case BadOpCode.And:
543 {
544 BadObject right = m_ArgumentStack.Pop().Dereference();
545 BadObject left = m_ArgumentStack.Pop().Dereference();
546 m_ArgumentStack.Push(BadLogicAndExpression.And(left, right, instr.Position));
547
548 break;
549 }
550 case BadOpCode.Not:
551 {
552 BadObject left = m_ArgumentStack.Pop().Dereference();
554
555 if (m_UseOverrides)
556 {
557 foreach (BadObject? o in BadLogicNotExpression.NotWithOverride(ctx, left, instr.Position))
558 {
559 obj = o;
560
561 yield return o;
562 }
563 }
564 else
565 {
566 obj = BadLogicNotExpression.Not(left, instr.Position);
567 }
568
569 m_ArgumentStack.Push(obj);
570
571 break;
572 }
573 case BadOpCode.XOr:
574 {
575 BadObject right = m_ArgumentStack.Pop().Dereference();
576 BadObject left = m_ArgumentStack.Pop().Dereference();
577 m_ArgumentStack.Push(BadLogicXOrExpression.XOr(left, right, instr.Position));
578
579 break;
580 }
581 case BadOpCode.AndAssign:
582 {
583 BadObject right = m_ArgumentStack.Pop().Dereference();
585 left.Set(BadLogicAndExpression.And(left.Dereference(), right, instr.Position));
586
587 break;
588 }
589 case BadOpCode.XOrAssign:
590 {
591 BadObject right = m_ArgumentStack.Pop().Dereference();
593 left.Set(BadLogicXOrExpression.XOr(left.Dereference(), right, instr.Position));
594
595 break;
596 }
597 case BadOpCode.Add:
598 {
599 BadObject right = m_ArgumentStack.Pop().Dereference();
600 BadObject left = m_ArgumentStack.Pop().Dereference();
602
603 if (m_UseOverrides)
604 {
605 foreach (BadObject o in BadAddExpression.AddWithOverride(ctx, left, right, instr.Position))
606 {
607 obj = o;
608 }
609 }
610 else
611 {
612 obj = BadAddExpression.Add(left, right, instr.Position);
613 }
614
615 m_ArgumentStack.Push(obj);
616
617 break;
618 }
619 case BadOpCode.Sub:
620 {
621 BadObject right = m_ArgumentStack.Pop().Dereference();
622 BadObject left = m_ArgumentStack.Pop().Dereference();
624
625 if (m_UseOverrides)
626 {
627 foreach (BadObject o in BadSubtractExpression.SubWithOverride(ctx, left, right, instr.Position))
628 {
629 obj = o;
630 }
631 }
632 else
633 {
634 obj = BadSubtractExpression.Sub(left, right, instr.Position);
635 }
636
637 m_ArgumentStack.Push(obj);
638
639 break;
640 }
641 case BadOpCode.Mul:
642 {
643 BadObject right = m_ArgumentStack.Pop().Dereference();
644 BadObject left = m_ArgumentStack.Pop().Dereference();
646
647 if (m_UseOverrides)
648 {
649 foreach (BadObject o in BadMultiplyExpression.MulWithOverride(ctx, left, right, instr.Position))
650 {
651 obj = o;
652 }
653 }
654 else
655 {
656 obj = BadMultiplyExpression.Mul(left, right, instr.Position);
657 }
658
659 m_ArgumentStack.Push(obj);
660
661 break;
662 }
663 case BadOpCode.Exp:
664 {
665 BadObject right = m_ArgumentStack.Pop().Dereference();
666 BadObject left = m_ArgumentStack.Pop().Dereference();
668
669 if (m_UseOverrides)
670 {
672 ctx,
673 left,
674 right,
675 instr.Position
676 ))
677 {
678 obj = o;
679 }
680 }
681 else
682 {
683 obj = BadExponentiationExpression.Exp(left, right, instr.Position);
684 }
685
686 m_ArgumentStack.Push(obj);
687
688 break;
689 }
690 case BadOpCode.Div:
691 {
692 BadObject right = m_ArgumentStack.Pop().Dereference();
693 BadObject left = m_ArgumentStack.Pop().Dereference();
695
696 if (m_UseOverrides)
697 {
698 foreach (BadObject o in BadDivideExpression.DivWithOverride(ctx, left, right, instr.Position))
699 {
700 obj = o;
701 }
702 }
703 else
704 {
705 obj = BadDivideExpression.Div(left, right, instr.Position);
706 }
707
708 m_ArgumentStack.Push(obj);
709
710 break;
711 }
712 case BadOpCode.Mod:
713 {
714 BadObject right = m_ArgumentStack.Pop().Dereference();
715 BadObject left = m_ArgumentStack.Pop().Dereference();
717
718 if (m_UseOverrides)
719 {
720 foreach (BadObject o in BadModulusExpression.ModWithOverride(ctx, left, right, instr.Position))
721 {
722 obj = o;
723 }
724 }
725 else
726 {
727 obj = BadModulusExpression.Mod(left, right, instr.Position);
728 }
729
730 m_ArgumentStack.Push(obj);
731
732 break;
733 }
734 case BadOpCode.Neg:
735 {
736 BadObject left = m_ArgumentStack.Pop().Dereference();
737
739
740 if (m_UseOverrides)
741 {
742 foreach (BadObject o in BadNegationExpression.NegateWithOverride(ctx, left, instr.Position))
743 {
744 yield return o;
745
746 obj = o;
747 }
748 }
749 else
750 {
751 obj = BadNegationExpression.Negate(left, instr.Position);
752 }
753
754 m_ArgumentStack.Push(obj);
755
756 break;
757 }
758 case BadOpCode.JumpRelative:
759 m_InstructionPointer += (int)instr.Arguments[0];
760
761 break;
762 case BadOpCode.JumpRelativeIfFalse:
763 {
764 IBadBoolean val = (IBadBoolean)m_ArgumentStack.Pop().Dereference();
765
766 if (!val.Value)
767 {
768 m_InstructionPointer += (int)instr.Arguments[0];
769 }
770
771 break;
772 }
773 case BadOpCode.JumpRelativeIfNull:
774 {
775 BadObject val = m_ArgumentStack.Pop().Dereference();
776
777 if (val == BadObject.Null)
778 {
779 m_InstructionPointer += (int)instr.Arguments[0];
780 }
781
782 break;
783 }
784 case BadOpCode.JumpRelativeIfNotNull:
785 {
786 BadObject val = m_ArgumentStack.Pop().Dereference();
787
788 if (val != BadObject.Null)
789 {
790 m_InstructionPointer += (int)instr.Arguments[0];
791 }
792
793 break;
794 }
795 case BadOpCode.JumpRelativeIfTrue:
796 {
797 IBadBoolean val = (IBadBoolean)m_ArgumentStack.Pop().Dereference();
798
799 if (val.Value)
800 {
801 m_InstructionPointer += (int)instr.Arguments[0];
802 }
803
804 break;
805 }
806 case BadOpCode.CreateScope:
807 {
808 //0: name
809 //1: useVisibility
810 //3: flags
811 //4: relative jump to break
812 //5: relative jump to continue
813 //6: relative jump to return
814 //7: relative jump to throw
815 string name = (string)instr.Arguments[0];
816 bool? useVisibility = null;
817
818 if (instr.Arguments[1] != BadObject.Null)
819 {
820 useVisibility = (bool)instr.Arguments[1];
821 }
822
823 BadScopeFlags flags = BadScopeFlags.AllowThrow;
824
825 if (instr.Arguments.Length > 2)
826 {
827 flags = (BadScopeFlags)instr.Arguments[2];
828 }
829
832 ctx.Scope.CreateChild(
833 name,
834 ctx.Scope,
835 useVisibility,
836 flags
837 )
838 )
839 )
840 {
841 CreatePointer = m_InstructionPointer,
842 };
843 m_ContextStack.Push(sf);
844
845 break;
846 }
847 case BadOpCode.DestroyScope:
848 {
850 frame.Context.Dispose();
851
852 break;
853 }
854 case BadOpCode.AddDisposeFinalizer:
855 {
856 //Load Variable with that name and call dispose on it
857 ctx.Scope.AddFinalizer(() => BadUsingExpression.Finalize(ctx, (string)instr.Arguments[0], instr.Position));
858
859 break;
860 }
861 case BadOpCode.ClearStack:
862 m_ArgumentStack.Clear();
863
864 break;
865 case BadOpCode.TypeOf:
866 {
867 m_ArgumentStack.Push(m_ArgumentStack.Pop().Dereference().GetPrototype());
868
869 break;
870 }
871 case BadOpCode.InstanceOf:
872 {
873 BadObject right = m_ArgumentStack.Pop().Dereference();
874 BadObject left = m_ArgumentStack.Pop().Dereference();
875
876 if (right is not BadClassPrototype type)
877 {
879 ctx.Scope,
880 "Cannot check if an object is an instance of a non-class object.",
881 instr.Position
882 );
883 }
884
885 m_ArgumentStack.Push(type.IsSuperClassOf(left.GetPrototype()));
886
887 break;
888 }
889 case BadOpCode.Export:
890 {
891 if (instr.Arguments.Length == 0)
892 {
893 BadObject? obj = m_ArgumentStack.Pop().Dereference();
894 ctx.Scope.SetExports(ctx, obj);
895 }
896 else
897 {
898 string name = (string)instr.Arguments[0];
899 BadObject obj = ctx.Scope.GetVariable(name).Dereference();
900 ctx.Scope.AddExport(name, obj);
901 }
902
903 break;
904 }
905 case BadOpCode.Import:
906 {
907 string name = (string)instr.Arguments[0];
908 string path = (string)instr.Arguments[1];
909 BadImportExpression.Import(ctx, name, path);
910
911 break;
912 }
913 case BadOpCode.Delete:
914 {
915 BadObject? obj = m_ArgumentStack.Pop();
916
917 if (obj is not BadObjectReference r)
918 {
920 ctx.Scope,
921 "Cannot delete a non-reference object.",
922 instr.Position
923 );
924 }
925
926 r.Delete();
927
928 break;
929 }
930 case BadOpCode.Equals:
931 {
932 BadObject right = m_ArgumentStack.Pop().Dereference();
933 BadObject left = m_ArgumentStack.Pop().Dereference();
935
936 if (m_UseOverrides)
937 {
939 ctx,
940 left,
941 right,
942 instr.Position
943 ))
944 {
945 obj = o;
946
947 yield return o;
948 }
949 }
950 else
951 {
952 obj = BadEqualityExpression.Equal(left, right);
953 }
954
955 m_ArgumentStack.Push(obj.Dereference());
956
957 break;
958 }
959 case BadOpCode.NotEquals:
960 {
961 BadObject right = m_ArgumentStack.Pop().Dereference();
962 BadObject left = m_ArgumentStack.Pop().Dereference();
964
965 if (m_UseOverrides)
966 {
968 ctx,
969 left,
970 right,
971 instr.Position
972 ))
973 {
974 obj = o;
975
976 yield return o;
977 }
978 }
979 else
980 {
981 obj = BadInequalityExpression.NotEqual(left, right);
982 }
983
984 m_ArgumentStack.Push(obj.Dereference());
985
986 break;
987 }
988 case BadOpCode.Greater:
989 {
990 BadObject right = m_ArgumentStack.Pop().Dereference();
991 BadObject left = m_ArgumentStack.Pop().Dereference();
993
994 if (m_UseOverrides)
995 {
997 ctx,
998 left,
999 right,
1000 instr.Position
1001 ))
1002 {
1003 obj = o;
1004
1005 yield return o;
1006 }
1007 }
1008 else
1009 {
1010 obj = BadGreaterThanExpression.GreaterThan(left, right, instr.Position);
1011 }
1012
1013 m_ArgumentStack.Push(obj.Dereference());
1014
1015 break;
1016 }
1017 case BadOpCode.GreaterEquals:
1018 {
1019 BadObject right = m_ArgumentStack.Pop().Dereference();
1020 BadObject left = m_ArgumentStack.Pop().Dereference();
1021 BadObject obj = BadObject.Null;
1022
1023 if (m_UseOverrides)
1024 {
1026 ctx,
1027 left,
1028 right,
1029 instr.Position
1030 ))
1031 {
1032 obj = o;
1033
1034 yield return o;
1035 }
1036 }
1037 else
1038 {
1039 obj = BadGreaterOrEqualExpression.GreaterOrEqual(left, right, instr.Position);
1040 }
1041
1042 m_ArgumentStack.Push(obj.Dereference());
1043
1044 break;
1045 }
1046 case BadOpCode.Less:
1047 {
1048 BadObject right = m_ArgumentStack.Pop().Dereference();
1049 BadObject left = m_ArgumentStack.Pop().Dereference();
1050 BadObject obj = BadObject.Null;
1051
1052 if (m_UseOverrides)
1053 {
1055 ctx,
1056 left,
1057 right,
1058 instr.Position
1059 ))
1060 {
1061 obj = o;
1062
1063 yield return o;
1064 }
1065 }
1066 else
1067 {
1068 obj = BadLessThanExpression.LessThan(left, right, instr.Position);
1069 }
1070
1071 m_ArgumentStack.Push(obj.Dereference());
1072
1073 break;
1074 }
1075 case BadOpCode.LessEquals:
1076 {
1077 BadObject right = m_ArgumentStack.Pop().Dereference();
1078 BadObject left = m_ArgumentStack.Pop().Dereference();
1079 BadObject obj = BadObject.Null;
1080
1081 if (m_UseOverrides)
1082 {
1084 ctx,
1085 left,
1086 right,
1087 instr.Position
1088 ))
1089 {
1090 obj = o;
1091
1092 yield return o;
1093 }
1094 }
1095 else
1096 {
1097 obj = BadLessOrEqualExpression.LessOrEqual(left, right, instr.Position);
1098 }
1099
1100 m_ArgumentStack.Push(obj.Dereference());
1101
1102 break;
1103 }
1104 case BadOpCode.AddAssign:
1105 {
1106 BadObject right = m_ArgumentStack.Pop().Dereference();
1108 BadObject obj = BadObject.Null;
1109
1110 if (m_UseOverrides)
1111 {
1113 ctx,
1114 left,
1115 right,
1116 instr.Position,
1117 "+="
1118 ))
1119 {
1120 obj = o;
1121
1122 yield return o;
1123 }
1124 }
1125 else
1126 {
1127 obj = BadAddAssignExpression.Add(left, left.Dereference(), right, instr.Position, "+=");
1128 }
1129
1130 m_ArgumentStack.Push(obj.Dereference());
1131
1132 break;
1133 }
1134 case BadOpCode.SubAssign:
1135 {
1136 BadObject right = m_ArgumentStack.Pop().Dereference();
1138 BadObject obj = BadObject.Null;
1139
1140 if (m_UseOverrides)
1141 {
1143 ctx,
1144 left,
1145 right,
1146 instr.Position,
1147 "-="
1148 ))
1149 {
1150 obj = o;
1151
1152 yield return o;
1153 }
1154 }
1155 else
1156 {
1158 left,
1159 left.Dereference(),
1160 right,
1161 instr.Position,
1162 "-="
1163 );
1164 }
1165
1166 m_ArgumentStack.Push(obj.Dereference());
1167
1168 break;
1169 }
1170 case BadOpCode.MulAssign:
1171 {
1172 BadObject right = m_ArgumentStack.Pop().Dereference();
1174 BadObject obj = BadObject.Null;
1175
1176 if (m_UseOverrides)
1177 {
1179 ctx,
1180 left,
1181 right,
1182 instr.Position,
1183 "*="
1184 ))
1185 {
1186 obj = o;
1187
1188 yield return o;
1189 }
1190 }
1191 else
1192 {
1194 left,
1195 left.Dereference(),
1196 right,
1197 instr.Position,
1198 "*="
1199 );
1200 }
1201
1202 m_ArgumentStack.Push(obj.Dereference());
1203
1204 break;
1205 }
1206 case BadOpCode.DivAssign:
1207 {
1208 BadObject right = m_ArgumentStack.Pop().Dereference();
1210 BadObject obj = BadObject.Null;
1211
1212 if (m_UseOverrides)
1213 {
1215 ctx,
1216 left,
1217 right,
1218 instr.Position,
1219 "/="
1220 ))
1221 {
1222 obj = o;
1223
1224 yield return o;
1225 }
1226 }
1227 else
1228 {
1229 obj = BadDivideAssignExpression.Divide(left, left.Dereference(), right, instr.Position, "/=");
1230 }
1231
1232 m_ArgumentStack.Push(obj.Dereference());
1233
1234 break;
1235 }
1236 case BadOpCode.ModAssign:
1237 {
1238 BadObject right = m_ArgumentStack.Pop().Dereference();
1240 BadObject obj = BadObject.Null;
1241
1242 if (m_UseOverrides)
1243 {
1245 ctx,
1246 left,
1247 right,
1248 instr.Position,
1249 "%="
1250 ))
1251 {
1252 obj = o;
1253
1254 yield return o;
1255 }
1256 }
1257 else
1258 {
1259 obj = BadModulusAssignExpression.Modulus(left, left.Dereference(), right, instr.Position, "%=");
1260 }
1261
1262 m_ArgumentStack.Push(obj.Dereference());
1263
1264 break;
1265 }
1266 case BadOpCode.ExpAssign:
1267 {
1268 BadObject right = m_ArgumentStack.Pop().Dereference();
1270 BadObject obj = BadObject.Null;
1271
1272 if (m_UseOverrides)
1273 {
1275 ctx,
1276 left,
1277 right,
1278 instr.Position,
1279 "**="
1280 ))
1281 {
1282 obj = o;
1283
1284 yield return o;
1285 }
1286 }
1287 else
1288 {
1290 left,
1291 left.Dereference(),
1292 right,
1293 instr.Position,
1294 "**="
1295 );
1296 }
1297
1298 m_ArgumentStack.Push(obj.Dereference());
1299
1300 break;
1301 }
1302 case BadOpCode.PostInc:
1303 {
1305 BadObject? result = BadObject.Null;
1306
1307 if (m_UseOverrides)
1308 {
1310 ctx,
1311 obj,
1312 instr.Position
1313 ))
1314 {
1315 result = o;
1316 }
1317 }
1318 else
1319 {
1320 result = BadPostIncrementExpression.Increment(obj, instr.Position);
1321 }
1322
1323 m_ArgumentStack.Push(result);
1324
1325 break;
1326 }
1327 case BadOpCode.PostDec:
1328 {
1330 BadObject? result = BadObject.Null;
1331
1332 if (m_UseOverrides)
1333 {
1335 ctx,
1336 obj,
1337 instr.Position
1338 ))
1339 {
1340 result = o;
1341 }
1342 }
1343 else
1344 {
1345 result = BadPostDecrementExpression.Decrement(obj, instr.Position);
1346 }
1347
1348 m_ArgumentStack.Push(result);
1349
1350 break;
1351 }
1352 case BadOpCode.PreInc:
1353 {
1355 BadObject? result = BadObject.Null;
1356
1357 if (m_UseOverrides)
1358 {
1360 ctx,
1361 obj,
1362 instr.Position
1363 ))
1364 {
1365 result = o;
1366 }
1367 }
1368 else
1369 {
1370 result = BadPreIncrementExpression.Increment(obj, instr.Position);
1371 }
1372
1373 m_ArgumentStack.Push(result);
1374
1375 break;
1376 }
1377 case BadOpCode.PreDec:
1378 {
1380 BadObject? result = BadObject.Null;
1381
1382 if (m_UseOverrides)
1383 {
1385 ctx,
1386 obj,
1387 instr.Position
1388 ))
1389 {
1390 result = o;
1391 }
1392 }
1393 else
1394 {
1395 result = BadPreDecrementExpression.Decrement(obj, instr.Position);
1396 }
1397
1398 m_ArgumentStack.Push(result);
1399
1400 break;
1401 }
1402 case BadOpCode.Return:
1403 {
1404 BadObject ret = BadObject.Null;
1405
1406 if (instr.Arguments.Length != 0)
1407 {
1408 ret = m_ArgumentStack.Pop();
1409 bool isRefReturn = (bool)instr.Arguments[0];
1410
1411 if (!isRefReturn)
1412 {
1413 ret = ret.Dereference();
1414 }
1415 }
1416
1417 if (ctx.Scope.FunctionObject != null &&
1419 {
1420 if (!ctx.Scope.FunctionObject.IsSingleLine)
1421 {
1422 throw BadRuntimeException.Create(ctx.Scope, "Cannot return a value from a void function", instr.Position);
1423 }
1425 }
1426 else
1427 ctx.Scope.SetReturnValue(ret);
1428
1429 break;
1430 }
1431 case BadOpCode.Break:
1432 ctx.Scope.SetBreak();
1433
1434 break;
1435 case BadOpCode.Continue:
1436 ctx.Scope.SetContinue();
1437
1438 break;
1439 case BadOpCode.Throw:
1441
1442 case BadOpCode.SetBreakPointer:
1443 m_ContextStack.Peek().BreakPointer = (int)instr.Arguments[0];
1444
1445 break;
1446 case BadOpCode.SetContinuePointer:
1447 m_ContextStack.Peek().ContinuePointer = (int)instr.Arguments[0];
1448
1449 break;
1450 case BadOpCode.SetThrowPointer:
1451 m_ContextStack.Peek().ThrowPointer = (int)instr.Arguments[0];
1452
1453 break;
1454 case BadOpCode.BinaryUnpack:
1455 {
1456 BadObject right = m_ArgumentStack.Pop().Dereference();
1457 BadObject left = m_ArgumentStack.Pop().Dereference();
1458 m_ArgumentStack.Push(BadBinaryUnpackExpression.Unpack(left, right, instr.Position));
1459
1460 break;
1461 }
1462 case BadOpCode.UnaryUnpack:
1463 {
1464 BadObject right = m_ArgumentStack.Pop().Dereference();
1465 BadTable table = ctx.Scope.GetTable();
1466 BadUnaryUnpackExpression.Unpack(table, right, instr.Position);
1467 m_ArgumentStack.Push(table);
1468
1469 break;
1470 }
1471 case BadOpCode.Eval:
1472 {
1473 BadExpression expr = (BadExpression)instr.Arguments[0];
1474 BadObject ret = BadObject.Null;
1475
1476 foreach (BadObject o in ctx.Execute(expr))
1477 {
1478 ret = o;
1479
1480 yield return o;
1481 }
1482
1483 m_ArgumentStack.Push(ret);
1484
1485 break;
1486 }
1487 default:
1488 throw new ArgumentOutOfRangeException();
1489 }
1490 }
1497 private IEnumerable<BadObject> Execute()
1498 {
1499 while (m_InstructionPointer <= m_Instructions.Length)
1500 {
1501 BadExecutionContext ctx = m_ContextStack.Peek().Context;
1502
1503
1504 if (ctx.Scope.ReturnValue != null)
1505 {
1506 //Pop scopes until we find a scope that captures return
1507 while ((ctx.Scope.Flags & BadScopeFlags.CaptureReturn) == 0)
1508 {
1509 m_ContextStack.Pop();
1510
1511 if (m_ContextStack.Count == 0)
1512 {
1513 yield break; //We exited the virtual machine. Quit the Execute method.
1514 }
1515
1517 ctx = sf.Context;
1518
1519 //Set Return Pointer to the next instruction
1521 }
1522
1524
1525 if (m_ContextStack.Count == 0)
1526 {
1527 yield break; //We exited the virtual machine. Quit the Execute method.
1528 }
1529
1530 //We found a scope that captures return, we push the return value to the stack and continue execution
1533 continue;
1534 }
1535
1536 if (ctx.Scope.IsBreak)
1537 {
1538 //Pop scopes until we find a scope that captures break
1539 while ((ctx.Scope.Flags & BadScopeFlags.CaptureBreak) == 0)
1540 {
1541 m_ContextStack.Pop();
1542
1543 if (m_ContextStack.Count == 0)
1544 {
1545 throw BadRuntimeException.Create(ctx.Scope, "VIRTUAL MACHINE BREAK ERROR");
1546 }
1547
1548 ctx = m_ContextStack.Peek().Context;
1549 }
1550
1552
1553 //Set Return Pointer to the next instruction
1554 m_InstructionPointer = sf.CreatePointer + sf.BreakPointer;
1555
1556 continue;
1557 }
1558
1559 if (ctx.Scope.IsContinue)
1560 {
1561 //Pop scopes until we find a scope that captures continue
1562 while ((ctx.Scope.Flags & BadScopeFlags.CaptureContinue) == 0)
1563 {
1564 m_ContextStack.Pop();
1565
1566 if (m_ContextStack.Count == 0)
1567 {
1568 throw BadRuntimeException.Create(ctx.Scope, "VIRTUAL MACHINE CONTINUE ERROR");
1569 }
1570
1572 ctx = sf.Context;
1573
1574 //Set Return Pointer to the next instruction
1575 m_InstructionPointer = sf.CreatePointer + sf.ContinuePointer;
1576 }
1577
1578 m_ContextStack.Pop();
1579
1580 continue;
1581 }
1583 {
1584 break;
1585 }
1586
1587 using IEnumerator<BadObject> enumerator = ExecuteStep(ctx).GetEnumerator();
1588 while (true)
1589 {
1590 try
1591 {
1592 if (!enumerator.MoveNext())
1593 {
1594 break;
1595 }
1596 }
1597 catch (Exception e)
1598 {
1599 BadRuntimeError error;
1600 if (e is BadRuntimeErrorException err) error = err.Error;
1601 else error = BadRuntimeError.FromException(e, ctx.Scope.GetStackTrace());
1602 m_ArgumentStack.Push(error);
1603
1604 //Pop scopes until we find a scope that captures throw
1605 while ((ctx.Scope.Flags & BadScopeFlags.CaptureThrow) == 0)
1606 {
1607 m_ContextStack.Pop();
1608
1609 if (m_ContextStack.Count == 0)
1610 {
1611 yield break; //We exited the virtual machine. Quit the Execute method.
1612 }
1613 }
1614
1616 m_InstructionPointer = sframe.CreatePointer + sframe.ThrowPointer;
1617 m_ContextStack.Pop();
1618 if(m_ContextStack.Count == 0)
1619 {
1620 yield break;
1621 }
1622 break;
1623 }
1624 yield return enumerator.Current ?? BadObject.Null;
1625 }
1626 }
1627 }
1628
1634 public IEnumerable<BadObject> Execute(BadExecutionContext ctx)
1635 {
1636 m_ContextStack.Clear();
1637 m_ArgumentStack.Clear();
1640
1641 return Execute();
1642 }
1643}
Public Debugger Interface.
static void Step(BadDebuggerStep stepInfo)
Sends a step event to the debugger.
static bool IsAttached
True if a debugger is attached.
Implements the Array Access to set or get properties from an object. LEFT[RIGHT].
static IEnumerable< BadObject > Access(BadExecutionContext? context, BadObject left, IEnumerable< BadObject > args, BadSourcePosition position)
Executes the Array Access Expression.
Implements the Reverse Array Access to set or get properties from an object. LEFT[^RIGHT].
static IEnumerable< BadObject > Access(BadExecutionContext context, BadObject left, IEnumerable< BadObject > args, BadSourcePosition position)
Executes the Array Access Expression.
Base Implementation for all Expressions used inside the Script.
Implements the binary ... operator. This operator is used to unpack the right side into the left side...
static BadTable Unpack(BadObject left, BadObject right, BadSourcePosition position)
Executes the binary ... operator.
Implements the 'in' operator. The 'in' operator is used to check if a key is present in an instance o...
static IEnumerable< BadObject > InWithOverride(BadExecutionContext context, BadObject left, BadObject right, BadSourcePosition position)
Implements the logic of the 'in' operator but checks for an operator override first.
static BadObject In(BadExecutionContext ctx, BadObject left, BadObject right)
Implements the logic of the 'in' operator.
Implements the Range Expression START..END.
static IEnumerable< BadObject > Range(decimal from, decimal to)
Returns a range of numbers.
Implements the unary ... operator. This operator is used to unpack a table into the current execution...
static void Unpack(BadTable table, BadObject right, BadSourcePosition position)
Implements the logic of the unary ... operator.
static BadObject Equal(BadObject left, BadObject right)
Returns true if the left side is equal to the right side.
static IEnumerable< BadObject > EqualWithOverride(BadExecutionContext? caller, BadObject left, BadObject right, BadSourcePosition position)
Executes the operator override for the given operator name.
static IEnumerable< BadObject > GreaterOrEqualWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject GreaterOrEqual(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is greater or equal to the right side.
static BadObject GreaterThan(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is greater than the right side.
static IEnumerable< BadObject > GreaterThanWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject NotEqual(BadObject left, BadObject right)
Returns True if the two Objects are not equal.
static IEnumerable< BadObject > NotEqualWithOverride(BadExecutionContext? caller, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject LessOrEqual(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is less or equal to the right side.
static IEnumerable< BadObject > LessOrEqualWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject LessThan(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if the left side is less than the right side.
static IEnumerable< BadObject > LessThanWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the expression.
static BadObject And(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if left and right are true.
static IEnumerable< BadObject > NotWithOverride(BadExecutionContext? context, BadObject left, BadSourcePosition position)
Executes the expression.
static BadObject Not(BadObject left, BadSourcePosition pos)
Returns true if the Input is false Returns false if the Input is true.
static BadObject XOr(BadObject left, BadObject right, BadSourcePosition pos)
Returns true if left or right are true. False if both are true.
static IEnumerable< BadObject > AddWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static BadObject Add(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Add Assignment Operator.
static IEnumerable< BadObject > DivideWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static BadObject Divide(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static BadObject Exp(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Implements the logic of the Exponentiation Operator.
static IEnumerable< BadObject > ExpWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Runs the Exponentiation Operator on the given objects.
static BadObject Modulus(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static IEnumerable< BadObject > ModulusWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static IEnumerable< BadObject > MultiplyWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
static BadObject Multiply(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static BadObject Subtract(BadObjectReference leftRef, BadObject left, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator.
static IEnumerable< BadObject > SubtractWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadObject right, BadSourcePosition position, string symbol)
Executes the Operator with operator override.
Implements the Post Decrement Expression.
static BadObject Decrement(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static IEnumerable< BadObject > DecrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
Implements the Post Increment Expression.
static IEnumerable< BadObject > IncrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
static BadObject Increment(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static BadObject Decrement(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static IEnumerable< BadObject > DecrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
static BadObject Increment(BadObjectReference reference, BadSourcePosition position)
Executes the Operator.
static IEnumerable< BadObject > IncrementWithOverride(BadExecutionContext? context, BadObjectReference leftRef, BadSourcePosition position)
Executes the Operator.
static BadObject Add(BadObject left, BadObject right, BadSourcePosition pos)
Adds left and right together.
static IEnumerable< BadObject > AddWithOverride(BadExecutionContext? context, BadObject leftRef, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static IEnumerable< BadObject > DivWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static BadObject Div(BadObject left, BadObject right, BadSourcePosition pos)
Divides left by right.
static BadObject Exp(BadObject left, BadObject right, BadSourcePosition position)
Implements the logic of the Exponentiation Operator.
static IEnumerable< BadObject > ExpWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Runs the Exponentiation Operator on the given objects.
static BadObject Mod(BadObject left, BadObject right, BadSourcePosition pos)
Performs the Modulus Operation on left and right.
static IEnumerable< BadObject > ModWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static IEnumerable< BadObject > MulWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static BadObject Mul(BadObject left, BadObject right, BadSourcePosition pos)
Performs the Multiplication Operation on left and right.
static IEnumerable< BadObject > NegateWithOverride(BadExecutionContext? context, BadObject left, BadSourcePosition position)
Executes the Operator.
static BadObject Negate(BadObject obj, BadSourcePosition pos)
Executes the Operator.
static BadObject Sub(BadObject left, BadObject right, BadSourcePosition pos)
Performs the Subtraction Operation on left and right.
static IEnumerable< BadObject > SubWithOverride(BadExecutionContext? context, BadObject left, BadObject right, BadSourcePosition position)
Executes the Operator with operator overrides.
static void Finalize(BadExecutionContext usingContext, string name, BadSourcePosition position)
The Finalizer method of the Using Expression.
The Lock List that is used to store all locks.
static readonly BadLockList Instance
Instance of the Lock List.
bool TryAquire(BadObject lockObj)
Tries to aquire a lock on the given object.
void Release(BadObject lockObj)
Releases the lock on the given object.
static IEnumerable< BadObject > Invoke(BadObject left, IEnumerable< BadObject > args, BadSourcePosition position, BadExecutionContext context)
Invokes a function.
A Import Expression that is used to import a module from a specified path.
static IEnumerable< BadObject > Import(BadExecutionContext ctx, string name, string path)
Imports a module from the specified path and assigns it to the specified name.
static IEnumerable< BadObject > CreateObject(BadClassPrototype proto, BadExecutionContext context, BadObject[] args, BadSourcePosition pos)
Creates an Instance of the Specified Class prototype.
The Execution Context. Every execution of a script needs a context the script is running in....
IEnumerable< BadObject > Execute(IEnumerable< BadExpression > expressions)
Executes an enumeration of expressions.
BadScope Scope
The Root Scope of the Context.
BadScope CreateChild(string name, BadScope? caller, bool? useVisibility, BadScopeFlags flags=BadScopeFlags.RootScope)
Creates a subscope of the current scope.
Definition BadScope.cs:792
BadScopeFlags Flags
The Scope Flags.
Definition BadScope.cs:394
bool IsContinue
Is true if the Continue Keyword was set.
Definition BadScope.cs:409
BadObjectReference GetVariable(string name, BadScope caller)
Returns the variable reference of the specified variable.
Definition BadScope.cs:1018
BadTable GetTable()
Returns the Variable Table of the current scope.
Definition BadScope.cs:778
void SetContinue()
Sets the continue keyword inside this scope.
Definition BadScope.cs:698
bool IsBreak
Is true if the Break Keyword was set.
Definition BadScope.cs:404
string GetStackTrace()
Returns the Stack Trace of the Current scope.
Definition BadScope.cs:633
void SetExports(BadExecutionContext ctx, BadObject exports)
Definition BadScope.cs:722
void AddExport(string key, BadObject value)
Sets an exported key value pair in the scope.
Definition BadScope.cs:737
BadObject? ReturnValue
The Return value of the scope.
Definition BadScope.cs:414
void SetReturnValue(BadObject? value)
Sets the Return value of this scope.
Definition BadScope.cs:759
void SetBreak()
Sets the break keyword inside this scope.
Definition BadScope.cs:679
void AddFinalizer(Action finalizer)
Adds a Finalizer to the Scope.
Definition BadScope.cs:498
void DefineVariable(string name, BadObject value, BadScope? caller=null, BadPropertyInfo? info=null, BadObject[]? attributes=null)
Defines a new Variable in the current scope.
Definition BadScope.cs:929
BadFunction? FunctionObject
The Function Object of the Scope.
Definition BadScope.cs:378
Gets thrown if the runtime encounters an error.
Implements the Error Object Type.
static BadRuntimeError FromException(Exception e, string? scriptStackTrace=null)
Creates a BadRuntimeError from an Exception.
static BadRuntimeException Create(BadScope? scope, string message)
Creates a new BadScriptException.
Implements a simple wrapper for C# IEnumerators to be used in BS2.
Implements a Dynamic List/Array for the BadScript Language.
Definition BadArray.cs:17
The Base Class for all BadScript Objects.
Definition BadObject.cs:14
virtual BadObjectReference GetProperty(string propName, BadScope? caller=null)
Returns a Reference to the Property with the given Name.
Definition BadObject.cs:129
BadClassPrototype GetPrototype()
Returns the Prototype of this Object.
virtual bool HasProperty(string propName, BadScope? caller=null)
Returns true if the object contains a given property or there exists an extension for the current Ins...
Definition BadObject.cs:118
static readonly BadObject Null
The Null Value for the BadScript Language.
Definition BadObject.cs:28
Implements the base functionality for a BadScript Reference.
void Set(BadObject obj, BadPropertyInfo? info=null, bool noChangeEvent=false)
Sets the Referenced Object to a new Value.
Stores Meta Information about a Property.
Implements a Table Structure for the BadScript Language.
Definition BadTable.cs:14
The Any Prototype, Base type for all types.
static readonly BadAnyPrototype Instance
The Instance of the BadAnyPrototype.
Implements a Type Instance in the BadScript Language.
Definition BadClass.cs:11
Implements a Class Prototype for the BadScript Language.
The Void Prototype, can be assigned to nothing, can not be inherited from, can not be instantiated....
static BadVoidPrototype Instance
The Instance of the BadVoidPrototype.
BadExecutionContext CreateExecutionContext(BadExecutionContext caller, BadObject[] args)
Implements a Virtual Machine for the BadScript Language.
readonly Stack< BadObject > m_ArgumentStack
The Argument Stack.
readonly bool m_UseOverrides
Indicates if the Virtual Machine should use Operator Overrides.
readonly BadCompiledFunction m_Function
The Function that is executed by this Virtual Machine.
readonly Stack< BadRuntimeVirtualStackFrame > m_ContextStack
The Context Stack.
IEnumerable< BadObject > ExecuteStep(BadExecutionContext ctx)
IEnumerable< BadObject > Execute()
Executes the Virtual Machine.
IEnumerable< BadObject > Execute(BadExecutionContext ctx)
Executes the virtual machine with the given context.
BadRuntimeVirtualMachine(BadCompiledFunction function, BadInstruction[] instructions, bool useOverrides=true)
Creates a new BadRuntimeVirtualMachine instance.
Stores the current execution state of the Virtual Machine.
readonly BadExecutionContext Context
The current execution context.
Implements the Interface for Native Boolean.
Definition IBadBoolean.cs:7
Implements the Interface for Native Numbers.
Definition IBadNumber.cs:7
Implements the Interface for Native Strings.
Definition IBadString.cs:7
Contains the debugging abstractions for the BadScript2 Runtime.
Definition BadDebugger.cs:7
Contains the Access Expressions for the BadScript2 Language.
Contains the Comparison Expressions for the BadScript2 Language.
Contains the Logic Expressions for the BadScript2 Language.
Contains the Self-Assigning Math Expressions for the BadScript2 Language.
Contains the Atomic Math Expressions for the BadScript2 Language.
Contains the Math Expressions for the BadScript2 Language.
Contains the Binary Expressions for the BadScript2 Language.
Contains the Locking Expressions for the BadScript2 Language.
Contains the Block Expressions for the BadScript2 Language.
Contains the Function Expressions for the BadScript2 Language.
Contains the Type Expressions for the BadScript2 Language.
Contains the Expressions for the BadScript2 Language.
Contains the Error Objects for the BadScript2 Language.
Contains the Interop Abstractions and Implementations for the BadScript2 Language.
Contains the Native Runtime Objects.
Definition BadBoolean.cs:6
Contains Runtime Interface Objects.
Contains the Runtime Objects.
Definition BadArray.cs:10
Contains the Virtual Machine Implementation.
BadOpCode
Defines the Operations that the BadVirtualMachine can execute.
Definition BadOpCode.cs:7
BadScopeFlags
Defines Different Behaviours for the Current Scope.
Represents a Debugging Step.
Implements a single instruction for the BadVirtualMachine.
readonly object[] Arguments
The arguments of this Instruction.
readonly BadSourcePosition Position
The position of this Instruction in the source code.
readonly BadOpCode OpCode
The OpCode of this Instruction.