• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

C# CompilationFlags类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C#中CompilationFlags的典型用法代码示例。如果您正苦于以下问题:C# CompilationFlags类的具体用法?C# CompilationFlags怎么用?C# CompilationFlags使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



CompilationFlags类属于命名空间,在下文中一共展示了CompilationFlags类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。

示例1: EmitConditionalExpression

        private void EmitConditionalExpression(Expression expr, CompilationFlags flags)
        {
            ConditionalExpression node = (ConditionalExpression)expr;
            Debug.Assert(node.Test.Type == typeof(bool));
            Label labFalse = _ilg.DefineLabel();
            EmitExpressionAndBranch(false, node.Test, labFalse);
            EmitExpressionAsType(node.IfTrue, node.Type, flags);

            if (NotEmpty(node.IfFalse))
            {
                Label labEnd = _ilg.DefineLabel();
                if ((flags & CompilationFlags.EmitAsTailCallMask) == CompilationFlags.EmitAsTail)
                {
                    // We know the conditional expression is at the end of the lambda,
                    // so it is safe to emit Ret here.
                    _ilg.Emit(OpCodes.Ret);
                }
                else
                {
                    _ilg.Emit(OpCodes.Br, labEnd);
                }
                _ilg.MarkLabel(labFalse);
                EmitExpressionAsType(node.IfFalse, node.Type, flags);
                _ilg.MarkLabel(labEnd);
            }
            else
            {
                _ilg.MarkLabel(labFalse);
            }
        }
开发者ID:noahfalk,项目名称:corefx,代码行数:30,代码来源:LambdaCompiler.Logical.cs


示例2: Emit

        private void Emit(BlockExpression node, CompilationFlags flags)
        {
            int count = node.ExpressionCount;

            if (count == 0)
            {
                return;
            }

            EnterScope(node);

            CompilationFlags emitAs = flags & CompilationFlags.EmitAsTypeMask;

            CompilationFlags tailCall = flags & CompilationFlags.EmitAsTailCallMask;
            for (int index = 0; index < count - 1; index++)
            {
                var e = node.GetExpression(index);
                var next = node.GetExpression(index + 1);

                CompilationFlags tailCallFlag;
                if (tailCall != CompilationFlags.EmitAsNoTail)
                {
                    var g = next as GotoExpression;
                    if (g != null && (g.Value == null || !Significant(g.Value)) && ReferenceLabel(g.Target).CanReturn)
                    {
                        // Since tail call flags are not passed into EmitTryExpression, CanReturn means the goto will be emitted
                        // as Ret. Therefore we can emit the current expression with tail call.
                        tailCallFlag = CompilationFlags.EmitAsTail;
                    }
                    else
                    {
                        // In the middle of the block.
                        // We may do better here by marking it as Tail if the following expressions are not going to emit any IL.
                        tailCallFlag = CompilationFlags.EmitAsMiddle;
                    }
                }
                else
                {
                    tailCallFlag = CompilationFlags.EmitAsNoTail;
                }

                flags = UpdateEmitAsTailCallFlag(flags, tailCallFlag);
                EmitExpressionAsVoid(e, flags);
            }

            // if the type of Block it means this is not a Comma
            // so we will force the last expression to emit as void.
            // We don't need EmitAsType flag anymore, should only pass
            // the EmitTailCall field in flags to emitting the last expression.
            if (emitAs == CompilationFlags.EmitAsVoidType || node.Type == typeof(void))
            {
                EmitExpressionAsVoid(node.GetExpression(count - 1), tailCall);
            }
            else
            {
                EmitExpressionAsType(node.GetExpression(count - 1), node.Type, tailCall);
            }

            ExitScope(node);
        }
开发者ID:SamuelEnglard,项目名称:corefx,代码行数:60,代码来源:LambdaCompiler.Statements.cs


示例3: EmitExpressionAsVoid

        private void EmitExpressionAsVoid(Expression node, CompilationFlags flags) {
            Debug.Assert(node != null);

            CompilationFlags startEmitted = EmitExpressionStart(node);

            switch (node.NodeType) {
                case ExpressionType.Assign:
                    EmitAssign((BinaryExpression)node, CompilationFlags.EmitAsVoidType);
                    break;
                case ExpressionType.Block:
                    Emit((BlockExpression)node, UpdateEmitAsTypeFlag(flags, CompilationFlags.EmitAsVoidType));
                    break;
                case ExpressionType.Throw:
                    EmitThrow((UnaryExpression)node, CompilationFlags.EmitAsVoidType);
                    break;
                case ExpressionType.Goto:
                    EmitGotoExpression(node, UpdateEmitAsTypeFlag(flags, CompilationFlags.EmitAsVoidType));
                    break;
                case ExpressionType.Constant:
                case ExpressionType.Default:
                case ExpressionType.Parameter:
                    // no-op
                    break;
                default:
                    if (node.Type == typeof(void)) {
                        EmitExpression(node, UpdateEmitExpressionStartFlag(flags, CompilationFlags.EmitNoExpressionStart));
                    } else {
                        EmitExpression(node, CompilationFlags.EmitAsNoTail | CompilationFlags.EmitNoExpressionStart);
                        _ilg.Emit(OpCodes.Pop);
                    }
                    break;
            }
            EmitExpressionEnd(startEmitted);
        }
开发者ID:xerxesb,项目名称:ironruby,代码行数:34,代码来源:LambdaCompiler.Expressions.cs


示例4: TryParseArgs

        private static bool TryParseArgs(string[] args, out string sourceFile, out CompilationFlags flags)
        {
            sourceFile = null;
            flags = 0;
            if (args.Length < 1)
                return false;

            foreach (string arg in args)
            {
                string normalizedArg = arg.ToUpper();
                switch (normalizedArg)
                {
                    case "/32":
                        flags |= CompilationFlags.Platform32;
                        break;
                    case "/64":
                        flags |= CompilationFlags.Platform64;
                        break;
                    case "/NODEBUG":
                        flags |= CompilationFlags.NoDebug;
                        break;
                    case "/ASM":
                        flags |= CompilationFlags.Assembly;
                        break;
                    default:
                        if (normalizedArg.StartsWith("/"))
                        {
                            Console.WriteLine("Unrecognized option {0}", normalizedArg);
                            return false;
                        }
                        if (!File.Exists(arg))
                        {
                            Console.WriteLine("Source file '{0}' not found", arg);
                            return false;
                        }
                        if (sourceFile != null)
                        {
                            Console.WriteLine("Multiple source files specified.  Only one file is supported");
                            return false;
                        }
                        sourceFile = arg;
                        break;
                }
            }

            if (flags.HasFlag(CompilationFlags.Platform32) && flags.HasFlag(CompilationFlags.Platform64))
            {
                Console.WriteLine("Both 32-bit and 64-bit platforms specified.  Only one platform is supported");
                return false;
            }

            if (!flags.HasFlag(CompilationFlags.Platform32) && !flags.HasFlag(CompilationFlags.Platform64))
                flags |= CompilationFlags.Platform32;

            if (sourceFile == null)
                return false;

            return true;
        }
开发者ID:OToL,项目名称:ConcordExtensibilitySamples,代码行数:59,代码来源:CompilerRunner.cs


示例5: PeEmitter

        /// <summary>
        /// Initializes a new instance of the PeEmitter class.
        /// Use this constructor to when saving the PE file to disk
        /// </summary>
        /// <param name="outputFile">Path to output file</param>
        /// <param name="flags">Compiler flags</param>
        public PeEmitter(string outputFile, CompilationFlags flags)
        {
            _ilFile = GetPathToTempFile("il");
            _textEmitter = new TextEmitter(_ilFile);

            _outputFile = outputFile;
            _flags = flags;
        }
开发者ID:OToL,项目名称:ConcordExtensibilitySamples,代码行数:14,代码来源:PeEmitter.cs


示例6: CompilerContext

 protected CompilerContext(string filePath, StreamReader inputReader, Importer importer, IEmitter emitter, CompilationFlags flags)
 {
     FilePath = filePath;
     Flags = flags;
     Emitter = emitter;
     CompileErrors = new ErrorList();
     Importer = importer;
     SymbolTable = new SymbolTable();
     Lexer = Lexer.Create(inputReader, CompileErrors);
 }
开发者ID:OToL,项目名称:ConcordExtensibilitySamples,代码行数:10,代码来源:CompilerContext.cs


示例7: EmitThrow

        private void EmitThrow(UnaryExpression expr, CompilationFlags flags) {
            if (expr.Operand == null) {
                CheckRethrow();

                _ilg.Emit(OpCodes.Rethrow);
            } else {
                EmitExpression(expr.Operand);
                _ilg.Emit(OpCodes.Throw);
            }

            EmitUnreachable(expr, flags);
        }
开发者ID:stabbylambda,项目名称:mono,代码行数:12,代码来源:LambdaCompiler.Unary.cs


示例8: TestCompilerContext

 private TestCompilerContext(
     MemoryStream input,
     StreamReader reader,
     MemoryStream output,
     IEmitter emitter,
     CompilationFlags flags)
     : base("FakeFile.iris", reader, emitter, flags)
 {
     _input = input;
     _reader = reader;
     _output = output;
 }
开发者ID:OToL,项目名称:ConcordExtensibilitySamples,代码行数:12,代码来源:TestCompilerContext.cs


示例9: CmdLineCompilerContext

 protected CmdLineCompilerContext(
     string sourcePath,
     Stream inputFile,
     StreamReader sourceReader,
     IEmitter emitter,
     CompilationFlags flags)
     : base(sourcePath, sourceReader, emitter, flags)
 {
     _inputFile = inputFile;
     _reader = sourceReader;
     _emitter = emitter;
 }
开发者ID:OToL,项目名称:ConcordExtensibilitySamples,代码行数:12,代码来源:CmdLineCompilerContext.cs


示例10: Emit

        private void Emit(BlockExpression node, CompilationFlags flags) {
            EnterScope(node);

            CompilationFlags emitAs = flags & CompilationFlags.EmitAsTypeMask;

            int count = node.ExpressionCount;
            CompilationFlags tailCall = flags & CompilationFlags.EmitAsTailCallMask;
            CompilationFlags middleTailCall = tailCall == CompilationFlags.EmitAsNoTail ? CompilationFlags.EmitAsNoTail : CompilationFlags.EmitAsMiddle;

            for (int index = 0; index < count - 1; index++) {
                var e = node.GetExpression(index);
                var next = node.GetExpression(index + 1);

                if (EmitDebugSymbols) {
                    // No need to emit a clearance if the next expression in the block is also a
                    // DebugInfoExprssion.
                    var debugInfo = e as DebugInfoExpression;
                    if (debugInfo != null && debugInfo.IsClear && next is DebugInfoExpression) {
                        continue;
                    }
                }
                // In the middle of the block.
                // We may do better here by marking it as Tail if the following expressions are not going to emit any IL.
                var tailCallFlag = middleTailCall;

                var g = next as GotoExpression;
                if (g != null && (g.Value == null || !Significant(g.Value))) {
                    var labelInfo = ReferenceLabel(g.Target);
                    if (labelInfo.CanReturn) {
                        // Since tail call flags are not passed into EmitTryExpression, CanReturn means the goto will be emitted
                        // as Ret. Therefore we can emit the current expression with tail call.
                        tailCallFlag = CompilationFlags.EmitAsTail;
                    }
                }
                flags = UpdateEmitAsTailCallFlag(flags, tailCallFlag);
                EmitExpressionAsVoid(e, flags);
            }

            // if the type of Block it means this is not a Comma
            // so we will force the last expression to emit as void.
            // We don't need EmitAsType flag anymore, should only pass
            // the EmitTailCall field in flags to emitting the last expression.
            if (emitAs == CompilationFlags.EmitAsVoidType || node.Type == typeof(void)) {
                EmitExpressionAsVoid(node.GetExpression(count - 1), tailCall);
            } else {
                EmitExpressionAsType(node.GetExpression(count - 1), node.Type, tailCall);
            }

            ExitScope(node);
        }
开发者ID:jxnmaomao,项目名称:ironruby,代码行数:50,代码来源:LambdaCompiler.Statements.cs


示例11: EmitBinaryExpression

        private void EmitBinaryExpression(Expression expr, CompilationFlags flags)
        {
            BinaryExpression b = (BinaryExpression)expr;

            Debug.Assert(b.NodeType != ExpressionType.AndAlso && b.NodeType != ExpressionType.OrElse && b.NodeType != ExpressionType.Coalesce);

            if (b.Method != null)
            {
                EmitBinaryMethod(b, flags);
                return;
            }

            // For EQ and NE, if there is a user-specified method, use it.
            // Otherwise implement the C# semantics that allow equality
            // comparisons on non-primitive nullable structs that don't
            // overload "=="
            if ((b.NodeType == ExpressionType.Equal || b.NodeType == ExpressionType.NotEqual) &&
                (b.Type == typeof(bool) || b.Type == typeof(bool?)))
            {
                // If we have x==null, x!=null, null==x or null!=x where x is
                // nullable but not null, then generate a call to x.HasValue.
                Debug.Assert(!b.IsLiftedToNull || b.Type == typeof(bool?));
                if (ConstantCheck.IsNull(b.Left) && !ConstantCheck.IsNull(b.Right) && TypeHelper.IsNullableType(b.Right.Type))
                {
                    EmitNullEquality(b.NodeType, b.Right, b.IsLiftedToNull);
                    return;
                }
                if (ConstantCheck.IsNull(b.Right) && !ConstantCheck.IsNull(b.Left) && TypeHelper.IsNullableType(b.Left.Type))
                {
                    EmitNullEquality(b.NodeType, b.Left, b.IsLiftedToNull);
                    return;
                }

                // For EQ and NE, we can avoid some conversions if we're
                // ultimately just comparing two managed pointers.
                EmitExpression(GetEqualityOperand(b.Left));
                EmitExpression(GetEqualityOperand(b.Right));
            }
            else
            {
                // Otherwise generate it normally
                EmitExpression(b.Left);
                EmitExpression(b.Right);
            }

            EmitBinaryOperator(b.NodeType, b.Left.Type, b.Right.Type, b.Type, b.IsLiftedToNull);
        }
开发者ID:mesheets,项目名称:Theraot-CF,代码行数:47,代码来源:LambdaCompiler.Binary.net30.cs


示例12: EmitUnary

 private void EmitUnary(UnaryExpression node, CompilationFlags flags) {
     if (node.Method != null) {
         EmitUnaryMethod(node, flags);
     } else if (node.NodeType == ExpressionType.NegateChecked && TypeUtils.IsInteger(node.Operand.Type)) {
         EmitExpression(node.Operand);
         LocalBuilder loc = GetLocal(node.Operand.Type);
         _ilg.Emit(OpCodes.Stloc, loc);
         _ilg.EmitInt(0);
         _ilg.EmitConvertToType(typeof(int), node.Operand.Type, false);
         _ilg.Emit(OpCodes.Ldloc, loc);
         FreeLocal(loc);
         EmitBinaryOperator(ExpressionType.SubtractChecked, node.Operand.Type, node.Operand.Type, node.Type, false);
     } else {
         EmitExpression(node.Operand);
         EmitUnaryOperator(node.NodeType, node.Operand.Type, node.Type);
     }
 }
开发者ID:stabbylambda,项目名称:mono,代码行数:17,代码来源:LambdaCompiler.Unary.cs


示例13: Create

        public static TestCompilerContext Create(string compiland, GlobalSymbolList globals, CompilationFlags flags)
        {
            byte[] buffer = Encoding.Default.GetBytes(compiland);
            MemoryStream input = new MemoryStream(buffer);
            StreamReader reader = new StreamReader(input);
            MemoryStream output = new MemoryStream();
            TextEmitter emitter = new TextEmitter(output);

            TestCompilerContext testContext = new TestCompilerContext(input, reader, output, emitter, flags);
            if (globals != null)
            {
                foreach (var symbol in globals.Items)
                    testContext.SymbolTable.Add(symbol.Item1, symbol.Item2, StorageClass.Global, null);
            }

            return testContext;
        }
开发者ID:OToL,项目名称:ConcordExtensibilitySamples,代码行数:17,代码来源:TestCompilerContext.cs


示例14: EmitLabelExpression

        private void EmitLabelExpression(Expression expr, CompilationFlags flags)
        {
            var node = (LabelExpression)expr;
            Debug.Assert(node.Target != null);

            // If we're an immediate child of a block, our label will already
            // be defined. If not, we need to define our own block so this
            // label isn't exposed except to its own child expression.
            LabelInfo label = null;

            if (_labelBlock.Kind == LabelScopeKind.Block)
            {
                _labelBlock.TryGetLabelInfo(node.Target, out label);

                // We're in a block but didn't find our label, try switch
                if (label == null && _labelBlock.Parent.Kind == LabelScopeKind.Switch)
                {
                    _labelBlock.Parent.TryGetLabelInfo(node.Target, out label);
                }

                // if we're in a switch or block, we should've found the label
                Debug.Assert(label != null);
            }

            if (label == null)
            {
                label = DefineLabel(node.Target);
            }

            if (node.DefaultValue != null)
            {
                if (node.Target.Type == typeof(void))
                {
                    EmitExpressionAsVoid(node.DefaultValue, flags);
                }
                else
                {
                    flags = UpdateEmitExpressionStartFlag(flags, CompilationFlags.EmitExpressionStart);
                    EmitExpression(node.DefaultValue, flags);
                }
            }

            label.Mark();
        }
开发者ID:ChuangYang,项目名称:corefx,代码行数:44,代码来源:LambdaCompiler.ControlFlow.cs


示例15: EmitAddress

        // We don't want "ref" parameters to modify values of expressions
        // except where it would in IL: locals, args, fields, and array elements
        // (Unbox is an exception, it's intended to emit a ref to the original
        // boxed value)
        private void EmitAddress(Expression node, Type type, CompilationFlags flags)
        {
            Debug.Assert(node != null);
            bool emitStart = (flags & CompilationFlags.EmitExpressionStartMask) == CompilationFlags.EmitExpressionStart;
            CompilationFlags startEmitted = emitStart ? EmitExpressionStart(node) : CompilationFlags.EmitNoExpressionStart;

            switch (node.NodeType)
            {
                default:
                    EmitExpressionAddress(node, type);
                    break;

                case ExpressionType.ArrayIndex:
                    AddressOf((BinaryExpression)node, type);
                    break;

                case ExpressionType.Parameter:
                    AddressOf((ParameterExpression)node, type);
                    break;

                case ExpressionType.MemberAccess:
                    AddressOf((MemberExpression)node, type);
                    break;

                case ExpressionType.Unbox:
                    AddressOf((UnaryExpression)node, type);
                    break;

                case ExpressionType.Call:
                    AddressOf((MethodCallExpression)node, type);
                    break;

                case ExpressionType.Index:
                    AddressOf((IndexExpression)node, type);
                    break;
            }

            if (emitStart)
            {
                EmitExpressionEnd(startEmitted);
            }
        }
开发者ID:alessandromontividiu03,项目名称:corefx,代码行数:46,代码来源:LambdaCompiler.Address.cs


示例16: Create

        public static CmdLineCompilerContext Create(string sourcePath, CompilationFlags flags)
        {
            string outputFile;
            IEmitter emitter;

            if (flags.HasFlag(CompilationFlags.Assembly))
            {
                outputFile = Path.ChangeExtension(sourcePath, "il");
                emitter = new TextEmitter(outputFile);
            }
            else
            {
                outputFile = Path.ChangeExtension(sourcePath, "exe");
                emitter = new PeEmitter(outputFile, flags);
            }

            Stream inputFile = File.Open(sourcePath, FileMode.Open, FileAccess.Read);
            StreamReader reader = new StreamReader(inputFile);

            return new CmdLineCompilerContext(sourcePath, inputFile, reader, emitter, flags);
        }
开发者ID:OToL,项目名称:ConcordExtensibilitySamples,代码行数:21,代码来源:CmdLineCompilerContext.cs


示例17: EmitMemberAssignment

        private void EmitMemberAssignment(BinaryExpression node, CompilationFlags flags)
        {
            MemberExpression lvalue = (MemberExpression)node.Left;
            MemberInfo member = lvalue.Member;

            // emit "this", if any
            Type objectType = null;
            if (lvalue.Expression != null)
            {
                EmitInstance(lvalue.Expression, objectType = lvalue.Expression.Type);
            }

            // emit value
            EmitExpression(node.Right);

            LocalBuilder temp = null;
            var emitAs = flags & CompilationFlags.EmitAsTypeMask;
            if (emitAs != CompilationFlags.EmitAsVoidType)
            {
                // save the value so we can return it
                _ilg.Emit(OpCodes.Dup);
                _ilg.Emit(OpCodes.Stloc, temp = GetLocal(node.Type));
            }

            var fld = member as FieldInfo;
            if ((object)fld != null)
            {
                _ilg.EmitFieldSet((FieldInfo)member);
            }
            else
            {
                var prop = member as PropertyInfo;
                if ((object)prop != null)
                {
                    EmitCall(objectType, prop.GetSetMethod(true));
                }
                else
                {
                    throw Error.InvalidMemberType(member);
                }
            }

            if (emitAs != CompilationFlags.EmitAsVoidType)
            {
                _ilg.Emit(OpCodes.Ldloc, temp);
                FreeLocal(temp);
            }
        }
开发者ID:SGuyGe,项目名称:corefx,代码行数:48,代码来源:LambdaCompiler.Expressions.cs


示例18: EmitAssign

 private void EmitAssign(BinaryExpression node, CompilationFlags emitAs)
 {
     switch (node.Left.NodeType)
     {
         case ExpressionType.Index:
             EmitIndexAssignment(node, emitAs);
             return;
         case ExpressionType.MemberAccess:
             EmitMemberAssignment(node, emitAs);
             return;
         case ExpressionType.Parameter:
             EmitVariableAssignment(node, emitAs);
             return;
         default:
             throw Error.InvalidLvalue(node.Left.NodeType);
     }
 }
开发者ID:SGuyGe,项目名称:corefx,代码行数:17,代码来源:LambdaCompiler.Expressions.cs


示例19: EmitVariableAssignment

        private void EmitVariableAssignment(BinaryExpression node, CompilationFlags flags)
        {
            var variable = (ParameterExpression)node.Left;
            var emitAs = flags & CompilationFlags.EmitAsTypeMask;

            EmitExpression(node.Right);
            if (emitAs != CompilationFlags.EmitAsVoidType)
            {
                _ilg.Emit(OpCodes.Dup);
            }

            if (variable.IsByRef)
            {
                // Note: the stloc/ldloc pattern is a bit suboptimal, but it
                // saves us from having to spill stack when assigning to a
                // byref parameter. We already make this same trade-off for
                // hoisted variables, see ElementStorage.EmitStore

                LocalBuilder value = GetLocal(variable.Type);
                _ilg.Emit(OpCodes.Stloc, value);
                _scope.EmitGet(variable);
                _ilg.Emit(OpCodes.Ldloc, value);
                FreeLocal(value);
                _ilg.EmitStoreValueIndirect(variable.Type);
            }
            else
            {
                _scope.EmitSet(variable);
            }
        }
开发者ID:SGuyGe,项目名称:corefx,代码行数:30,代码来源:LambdaCompiler.Expressions.cs


示例20: UpdateEmitAsTypeFlag

 /// <summary>
 /// Update the flag with a new EmitAsType flag
 /// </summary>
 private static CompilationFlags UpdateEmitAsTypeFlag(CompilationFlags flags, CompilationFlags newValue)
 {
     Debug.Assert(newValue == CompilationFlags.EmitAsDefaultType || newValue == CompilationFlags.EmitAsVoidType);
     var oldValue = flags & CompilationFlags.EmitAsTypeMask;
     return flags ^ oldValue | newValue;
 }
开发者ID:SGuyGe,项目名称:corefx,代码行数:9,代码来源:LambdaCompiler.Expressions.cs



注:本文中的CompilationFlags类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C# CompilationOptions类代码示例发布时间:2022-05-24
下一篇:
C# CompilationContext类代码示例发布时间:2022-05-24
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap