Exemple #1
0
 internal void CompileEqualityBy(FunctionCompiler compiler, OpCode strictOp, OpCode convOp, bool isLastOperator)
 {
     if (!LeftOperand.CanBeObject && !RightOperand.CanBeObject)
     {
         LeftOperand.CompileBy(compiler, false);
         RightOperand.CompileBy(compiler, false);
         compiler.Emitter.Emit(strictOp);
     }
     else
     {
         var endLabel   = compiler.Emitter.DefineLabel();
         var falseLabel = compiler.Emitter.DefineLabel();
         LeftOperand.CompileBy(compiler, false);
         RightOperand.CompileBy(compiler, false);
         compiler.Emitter.Emit(OpCode.Dup2);
         compiler.Emitter.Emit(strictOp);
         compiler.Emitter.Emit(OpCode.GotoIfFalse, falseLabel);
         compiler.Emitter.Emit(OpCode.Pop2);
         compiler.Emitter.Emit(OpCode.LdBoolean, true);
         compiler.Emitter.Emit(OpCode.Goto, endLabel);
         compiler.Emitter.MarkLabel(falseLabel);
         // В вершине стека лежит правый операнд
         if (RightOperand.CanBeObject)
         {
             compiler.Emitter.Emit(OpCode.CastToPrimitive);
         }
         compiler.Emitter.Emit(OpCode.Swap);
         if (LeftOperand.CanBeObject)
         {
             compiler.Emitter.Emit(OpCode.CastToPrimitive);
         }
         compiler.Emitter.Emit(convOp);
         compiler.Emitter.MarkLabel(endLabel);
     }
     if (isLastOperator)
     {
         compiler.Emitter.Emit(OpCode.Pop);
     }
 }
Exemple #2
0
 internal void CompileBy(
     FunctionCompiler compiler,
     OpCode op,
     bool isLeftAssociative,
     bool needCastToPrimitive,
     bool isLastOperator)
 {
     if (isLeftAssociative)
     {
         LeftOperand.CompileBy(compiler, false);
         if (needCastToPrimitive && LeftOperand.CanBeObject)
         {
             compiler.Emitter.Emit(OpCode.CastToPrimitive);
         }
         RightOperand.CompileBy(compiler, false);
         if (needCastToPrimitive && RightOperand.CanBeObject)
         {
             compiler.Emitter.Emit(OpCode.CastToPrimitive);
         }
     }
     else
     {
         RightOperand.CompileBy(compiler, false);
         if (needCastToPrimitive && RightOperand.CanBeObject)
         {
             compiler.Emitter.Emit(OpCode.CastToPrimitive);
         }
         LeftOperand.CompileBy(compiler, false);
         if (needCastToPrimitive && LeftOperand.CanBeObject)
         {
             compiler.Emitter.Emit(OpCode.CastToPrimitive);
         }
     }
     compiler.Emitter.Emit(op);
     if (isLastOperator)
     {
         compiler.Emitter.Emit(OpCode.Pop);
     }
 }