public static void CreateFunction(ref mdr.CallFrame callFrame, int funcDefIndex, mdr.DObject context, ref Stack stack) { //Debug.WriteLine("calling Exec.CreateFunction"); var funcDef = ((JSFunctionMetadata)callFrame.Function.Metadata).SubFunctions[funcDefIndex]; var func = new mdr.DFunction(funcDef, context); stack.Items[stack.Sp++].Set(func); ; }
public static void Throw(ref Stack stack) { //Debug.WriteLine("calling Exec.Throw"); //JSRuntime.Instance.CurrentException.Set(ref stack.Items[--stack.Sp]); //throw new JSException(); throw new JSException(ref stack.Items[--stack.Sp]); }
public static void Dup(ref Stack stack) { var inputIndex = stack.Sp - 1; var resultIndex = inputIndex + 1; var items = stack.Items; items[resultIndex] = items[inputIndex]; stack.Sp = resultIndex + 1; }
public static mdr.DObject CreateContext(ref mdr.CallFrame callFrame, ref Stack stack) { mdr.DObject context; var contextMap = callFrame.Function.Metadata.ContextMap; if (contextMap != null) { context = new mdr.DObject(contextMap); } else { var outerContext = callFrame.Function.OuterContext; context = new mdr.DObject(outerContext); callFrame.Function.Metadata.ContextMap = context.Map; //This will at least prevent the lookup in the DObject } return context; }
public static void StoreVariable(mdr.DObject context, int fieldId, int ancestorDistance, bool pushBackResult, ref Stack stack) { var valueIndex = stack.Sp - 1; //TODO: If we do not create a prototype for GlobalContext, the following code would have been enough! //var pd = context.Map.GetPropertyDescriptorByFieldId(fieldId); //if (pd != null) // pd.Set(context, ref stack.Items[stack.Sp - 1]); //else // mdr.Runtime.Instance.GlobalContext.SetFieldByFieldId(fieldId, ref stack.Items[stack.Sp - 1]); //DOTO: this is very expensive! mdr.PropertyDescriptor pd = null; if (ancestorDistance < 0) {//We are dealing with unknown symbol type //while (context != mdr.Runtime.Instance.GlobalContext) //{ // pd = context.Map.GetCachedOwnPropertyDescriptorByFieldId(fieldId); // if (pd != null) // break; // context = context.Prototype; //} //if (pd != null) // pd.Set(context, ref stack.Items[stack.Sp - 1]); //else // context.SetFieldByFieldId(fieldId, ref stack.Items[stack.Sp - 1]); pd = context.Map.GetPropertyDescriptorByFieldId(fieldId); if (pd != null && !pd.IsUndefined) pd.Set(context, ref stack.Items[valueIndex]); else mdr.Runtime.Instance.GlobalContext.SetFieldByFieldId(fieldId, ref stack.Items[valueIndex]); } else {//we are dealing with known symbol type for (var i = 0; i < ancestorDistance && context != mdr.Runtime.Instance.GlobalContext; ++i) { context = context.Prototype; } pd = context.Map.GetPropertyDescriptorByFieldId(fieldId); Debug.Assert(pd != null && pd.IsDataDescriptor, "Invalid situation, variable is undeclared in current context"); pd.Set(context, ref stack.Items[valueIndex]); } if (!pushBackResult) stack.Sp = valueIndex; }
public static void LoadVariable(mdr.DObject context, int fieldId, int ancestorDistance, ref Stack stack) { mdr.PropertyDescriptor pd = null; //TODO: If we do not create a prototype for GlobalContext, the following code would have been enough! //var pd = context.GetPropertyDescriptorByLineId(fieldId); //pd.Get(context, ref stack.Items[stack.Sp++]); if (ancestorDistance < 0) {//We are dealing with unknown symbol type while (context != mdr.Runtime.Instance.GlobalContext) { pd = context.Map.GetPropertyDescriptorByFieldId(fieldId); if (pd != null) break; context = context.Prototype; } } else {//we are dealing with known symbol type for (var i = 0; i < ancestorDistance && context != mdr.Runtime.Instance.GlobalContext; ++i) { context = context.Prototype; } } if (pd == null) pd = context.GetPropertyDescriptorByFieldId(fieldId); pd.Get(context, ref stack.Items[stack.Sp++]); }
public static void DeleteVariable(ref Stack stack) { var baseIndex = stack.Sp - 2; var fieldIndex = stack.Sp - 1; var valueIndex = baseIndex; stack.Items[valueIndex].Set(Unary.DeleteVariable.Run(stack.Items[baseIndex].AsDObject(), stack.Items[fieldIndex].AsInt32())); stack.Sp = fieldIndex; }
public static void LoadDouble(double value, ref Stack stack) { stack.Items[stack.Sp++].Set(value); }
public static void LoadBoolean(bool value, ref Stack stack) { stack.Items[stack.Sp++].Set(value); }
public static void StoreField(bool pushBackResult, ref Stack stack) { //Debug.WriteLine("calling Exec.StoreField"); var baseIndex = stack.Sp - 3; var fieldIndex = stack.Sp - 2; var valueIndex = stack.Sp - 1; stack.Items[baseIndex].AsDObject().SetField(ref stack.Items[fieldIndex], ref stack.Items[valueIndex]); if (pushBackResult) { stack.Items[baseIndex] = stack.Items[valueIndex]; stack.Sp = fieldIndex; } else stack.Sp = baseIndex; }
public static void LoadNull(ref Stack stack) { stack.Items[stack.Sp++].Set(mdr.Runtime.Instance.DefaultDNull); }
public static void LoadField(int popOperandCount, ref Stack stack) { //Debug.WriteLine("calling Exec.LoadField"); var baseIndex = stack.Sp - 2; var fieldIndex = stack.Sp - 1; int valueIndex = stack.Sp - popOperandCount; stack.Items[baseIndex].AsDObject().GetField(ref stack.Items[fieldIndex], ref stack.Items[valueIndex]); //stack.Items[valueIndex] = stack.Items[baseIndex].GetFieldContainer().GetField(ref stack.Items[fieldIndex]); stack.Sp = valueIndex + 1; }
//public static void LoadContext(ref mdr.CallFrame callFrame, ref Stack stack) //{ // //Debug.WriteLine("calling Exec.LoadContext"); // stack.Items[stack.Sp++].Set(callFrame.Function.Context); //} public static void Return(ref mdr.CallFrame callFrame, ref Stack stack) { //Debug.WriteLine("calling Exec.Return"); callFrame.Return = stack.Items[--stack.Sp]; }
public static void LogicalNot(ref Stack stack) { //Debug.WriteLine("calling Exec.LogicalNot"); var inputIndex = stack.Sp - 1; var resultIndex = inputIndex; var items = stack.Items; items[resultIndex].Set(Unary.LogicalNot.Run(ref items[inputIndex])); }
public static void Negate(ref Stack stack) { //Debug.WriteLine("calling Exec.Negate"); var inputIndex = stack.Sp - 1; var resultIndex = inputIndex; var items = stack.Items; Unary.Negative.Run(ref items[inputIndex], ref items[resultIndex]); }
public static void TypeOf(ref Stack stack) { //Debug.WriteLine("calling Exec.TypeOf"); var inputIndex = stack.Sp - 1; var resultIndex = inputIndex; var items = stack.Items; items[resultIndex].Set(Operations.Unary.Typeof.Run(ref items[inputIndex])); }
public static void Delete(ref Stack stack) { //Debug.WriteLine("calling Exec.Delete"); var inputIndex = stack.Sp - 1; var resultIndex = inputIndex; var items = stack.Items; items[resultIndex].Set(Unary.Delete.Run(ref items[inputIndex])); }
public static void LoadArg(ref mdr.CallFrame callFrame, int argIndex, ref Stack stack) { //Debug.WriteLine("calling Exec.LoadArg"); if (argIndex >= callFrame.PassedArgsCount) { stack.Items[stack.Sp++].Set(mdr.Runtime.Instance.DefaultDUndefined); return; } switch (argIndex) { case 0: stack.Items[stack.Sp++].Set(ref callFrame.Arg0); break; case 1: stack.Items[stack.Sp++].Set(ref callFrame.Arg1); break; case 2: stack.Items[stack.Sp++].Set(ref callFrame.Arg2); break; case 3: stack.Items[stack.Sp++].Set(ref callFrame.Arg3); break; default: stack.Items[stack.Sp++].Set(ref callFrame.Arguments[argIndex - mdr.CallFrame.InlineArgsCount]); break; } }
public static void LoadUndefined(ref Stack stack) { stack.Items[stack.Sp++].Set(mdr.Runtime.Instance.DefaultDUndefined); }
public static void StoreArg(ref mdr.CallFrame callFrame, int argIndex, bool pushBackResult, ref Stack stack) { var valueIndex = stack.Sp - 1; Debug.WriteLine("calling Exec.StoreArg index {0} vindex {1} cf arg count {2}", argIndex, valueIndex, callFrame.PassedArgsCount); ///Since an arguments may be written and then read again in the same function ///we should make sure the value is stored properly. ///for the first 4 arguments, we have a storage in the call frame ///beyond that is tricky! We can extend the Arguments array, but we have to make sure ///no one has a pointer/reference to any of its elements ///For now, we fail, but we should fix this later switch (argIndex) { case 0: callFrame.Arg0.Set(ref stack.Items[valueIndex]); break; case 1: callFrame.Arg1.Set(ref stack.Items[valueIndex]); break; case 2: callFrame.Arg2.Set(ref stack.Items[valueIndex]); break; case 3: callFrame.Arg3.Set(ref stack.Items[valueIndex]); break; default: if (argIndex < callFrame.PassedArgsCount) { callFrame.Arguments[argIndex - mdr.CallFrame.InlineArgsCount].Set(ref stack.Items[valueIndex]); break; } else { Debug.Fail("argIndex {0} > argsCount {1}", argIndex, callFrame.PassedArgsCount); } break; } if (!pushBackResult) stack.Sp = valueIndex; }
public static void LoadString(string value, ref Stack stack) { stack.Items[stack.Sp++].Set(value); }
public static void LoadAny(object value, ref Stack stack) { stack.Items[stack.Sp++].Set(value); }
public static void LoadInt(int value, ref Stack stack) { stack.Items[stack.Sp++].Set(value); }
public static void CreateArray(int itemsCount, ref Stack stack) { //Debug.WriteLine("calling Exec.CreateArray"); var sp = stack.Sp - 1; var array = new mdr.DArray(itemsCount); for (var i = itemsCount - 1; i >= 0; --i, --sp) array.Elements[i] = stack.Items[sp]; stack.Items[sp + 1].Set(array); stack.Sp = sp + 2; }
public static void LoadDObject(mdr.DObject value, ref Stack stack) { stack.Items[stack.Sp++].Set(value); }
public static void DeleteProperty(ref Stack stack) { var baseIndex = stack.Sp - 2; var fieldIndex = stack.Sp - 1; var valueIndex = baseIndex; stack.Items[valueIndex].Set(Unary.DeleteProperty.Run(stack.Items[baseIndex].AsDObject(), ref stack.Items[fieldIndex])); stack.Sp = fieldIndex; }
public static void LoadDValue(ref mdr.DValue value, ref Stack stack) { stack.Items[stack.Sp++].Set(ref value); }
public static void LoadThis(ref mdr.CallFrame callFrame, ref Stack stack) { stack.Items[stack.Sp++].Set(callFrame.This); }
public static void CreateJson(int itemsCount, ref Stack stack) { //Debug.WriteLine("calling Exec.CreateJson"); var obj = new mdr.DObject(); var resultIndex = stack.Sp - itemsCount * 2; //TODO: here we know things are string, so just push their fieldIds and user then here! if (itemsCount > 0) { var sp = resultIndex; for (var i = itemsCount - 1; i >= 0; --i, sp += 2) obj.SetField(ref stack.Items[sp], ref stack.Items[sp + 1]); } stack.Items[resultIndex].Set(obj); stack.Sp = resultIndex + 1; ; }
public static void DeclareVariable(mdr.DObject context, string field, int fieldId, ref Stack stack) { //we may be looking at a global or this might be second time we call this function with the same context, so following assert will fail (incorrectly) //Debug.Assert(!context.HasOwnPropertyByFieldId(fieldId), "Cannot redeclare local variable {0}", field); context.AddOwnPropertyDescriptorByFieldId(fieldId, mdr.PropertyDescriptor.Attributes.Data | mdr.PropertyDescriptor.Attributes.NotConfigurable); }