예제 #1
0
        public AssemblyCodeGenerator(GlobalBuilder globalBuilder)
        {
            this.globalBuilder = globalBuilder;

            // magic
            int magic = 0x72303b3e;

            Executable.WriteInt(magic);

            // version
            int version = 0x00000001;

            Executable.WriteInt(version);
        }
예제 #2
0
        public JsAnalyzer(AnalysisLimits limits = null)
        {
            _modules      = new ModuleTable();
            _itemCache    = new Dictionary <object, AnalysisValue>();
            _builtinEntry = new ProjectEntry(this, String.Empty, null);

            Limits = limits ?? new AnalysisLimits();

            _queue = new Deque <AnalysisUnit>();

            _nullInst  = new NullValue(this);
            _trueInst  = new BooleanValue(true, this);
            _falseInst = new BooleanValue(false, this);
            _undefined = new UndefinedValue(this);

            _emptyStringValue = GetConstant(String.Empty);
            _zeroIntValue     = GetConstant(0.0);

            var globals = GlobalBuilder.MakeGlobal(this);

            _globalObject      = globals.GlobalObject;
            _numberPrototype   = globals.NumberPrototype;
            _stringPrototype   = globals.StringPrototype;
            _booleanPrototype  = globals.BooleanPrototype;
            _functionPrototype = globals.FunctionPrototype;
            _arrayFunction     = globals.ArrayFunction;
            _objectPrototype   = globals.ObjectPrototype;
            _requireFunc       = globals.RequireFunction;
            _arrayPrototype    = globals.ArrayPrototype;
            _objectGetOwnPropertyDescriptor = globals.ObjectGetOwnPropertyDescriptor;
            _immutableObject = new ImmutableObjectValue(_builtinEntry);

            var allJson = Path.Combine(
                Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                "all.json"
                );


            if (File.Exists(allJson))
            {
                NodejsModuleBuilder.Build(allJson, this);
            }
            else
            {
                Debug.Fail("Could not find all.json");
            }
        }
예제 #3
0
        public void Test_GlobalBuilder_Basic()
        {
            using (Tester())
            {
                bool isValidSynchronizationContext = (_SynchronizationContext != null) && (_SynchronizationContext.GetType() != typeof(SynchronizationContext));
                isValidSynchronizationContext.Should().BeTrue();


                var res0 = GetSafe(() => _WebView.CreateGlobalJavascriptObject("teste"));

                GlobalBuilder gb  = new GlobalBuilder(_WebView, "Test");
                var           res = gb.CreateJSO();
                res.Should().NotBeNull();
                string name = GetSafe(() => res.GlobalObjectName);
                name.Should().Be("Test_1");
                var type = GetSafe(() => res.Type);
                type.Should().Be(JSObjectType.RemoteGlobal);
            }
        }
        public virtual DataType ProcessLiteralExpression(LiteralExpressionAst literalExpression)
        {
            if (literalExpression.Literal is UInt64LiteralToken intLiteral)
            {
                if (CodeGenerationEnabled)
                {
                    ExpressionBucket.Add(new object[] { "push", (long)intLiteral.Value });
                }
                return(DataType.Long);
            }
            if (literalExpression.Literal is DoubleLiteralToken doubleLiteral)
            {
                if (CodeGenerationEnabled)
                {
                    ExpressionBucket.Add(new object[] { "push", doubleLiteral.Value });
                }
                return(DataType.Double);
            }
            if (literalExpression.Literal is StringLiteralToken stringLiteral)
            {
                // 字符串应该存全局变量,并把地址(划掉)应该把全局变量号放在栈上
                if (CodeGenerationEnabled)
                {
                    var id = GlobalBuilder.RegisterStringConstant(stringLiteral.Value);

                    ExpressionBucket.Add(Instruction.Pack("push", (long)id));
                }

                return(DataType.String);
            }
            if (literalExpression.Literal is CharLiteralToken charLiteral)
            {
                if (CodeGenerationEnabled)
                {
                    ExpressionBucket.Add(new object[] { "push", (long)charLiteral.Value });
                }

                return(DataType.Long);
            }
            throw new ArgumentException($"Unknown literal token type: {literalExpression.GetType()}");
        }
        public void ProcessFunction(FunctionAst functionAst)
        {
            Guard.Against.Null(functionAst, nameof(functionAst));

            if (SymbolScope.FindSymbolDeep(functionAst.Name.Value, out Symbol symbol))
            {
                throw new SemanticException($"Symbol already exist: {symbol.Name}, {symbol.GetType()}");
            }

            if (!new[] { "int", "double", "void" }.Contains(functionAst.ReturnType.Value))
            {
                throw new SemanticException($"Bad returning type: {functionAst.ReturnType.Value}");
            }

            var returnType = DataTypeHelper.ParseIntDoubleVoid(functionAst.ReturnType.Value);

            // Add function to scope
            var paramTypeList = new List <DataType>();

            if (functionAst.HasParams)
            {
                foreach (var parameter in functionAst.FunctionParamList.FunctionParams)
                {
                    var paramType = parameter.Type.Value switch
                    {
                        "int" => DataType.Long,
                        "double" => DataType.Double,
                        _ => throw new SemanticException($"Bad param type: {parameter.Type.Value}")
                    };
                    paramTypeList.Add(paramType);
                }
            }
            var functionSymbol = new FunctionSymbol(functionAst.Name.Value, returnType, paramTypeList);

            SymbolScope.AddSymbol(functionSymbol);

            // register function
            if (CodeGenerationEnabled)
            {
                GlobalBuilder.RegisterFunction(functionSymbol);
            }

            // Create scope
            SymbolScope = SymbolScope.CreateChildScope();

            // for testing
            functionSymbol.BodyBlockScope = SymbolScope;

            EnterFunctionDefination(functionSymbol);
            {
                // register params

                if (functionAst.HasParams)
                {
                    foreach (var parameter in functionAst.FunctionParamList.FunctionParams)
                    {
                        var paramType = parameter.Type.Value switch
                        {
                            "int" => DataType.Long,
                            "double" => DataType.Double,
                            _ => throw new SemanticException($"Bad param type: {parameter.Type.Value}")
                        };

                        var name = parameter.Name.Value;
                        if (SymbolScope.FindSymbolShallow(name, out Symbol _))
                        {
                            throw new SemanticException($"Exist symbol: {name}");
                        }

                        // Add to scope
                        var argSymbol = new VariableSymbol(name, false, parameter.IsConstant, paramType);
                        SymbolScope.AddSymbol(argSymbol);

                        if (CodeGenerationEnabled)
                        {
                            CurrentFunction.Builder.RegisterArgument(argSymbol);
                        }
                    }
                }

                var canReturn = ProcessBlockStatement(functionAst.BodyBlock, suppressNewScopeCreation: true);

                if (!canReturn && ReturnCheckEnabled && returnType != DataType.Void)
                {
                    throw new SemanticException($"Cannot leave function {functionAst.Name.Value}");
                }

                // implecit void returning
                if (CodeGenerationEnabled && returnType == DataType.Void)
                {
                    CurrentFunction.Builder.Bucket.Add(new Instructions.Instruction("ret"));
                }
            }
            LeaveFunctionDefination();
            SymbolScope = SymbolScope.ParentScope;
        }
        public virtual void ProcessConstDeclarationStatement(ConstDeclarationStatementAst constDeclaration)
        {
            var name = constDeclaration.Name.Value;

            if (SymbolScope.FindSymbolShallow(name, out Symbol existingSymbol))
            {
                throw new SemanticException(
                          $"Cannot const declare because of duplicated name. " +
                          $"Existing symbol type: {existingSymbol.GetType()}");
            }

            if (!new[] { "int", "double" }.Contains(constDeclaration.Type.Value))
            {
                throw new SemanticException($"Type {constDeclaration.Type.Value} should be int or double");
            }

            var declaringType = constDeclaration.Type.Value switch
            {
                "int" => DataType.Long,
                "double" => DataType.Double,
                _ => throw new Exception("Not Reached")
            };


            var initialExpressionType = ProcessExpression(constDeclaration.ValueExpression);

            if (declaringType != initialExpressionType)
            {
                throw new SemanticException(
                          $"DeclaringType: {declaringType}, InitialExpressionType: {initialExpressionType}");
            }

            // All check ok
            var symbol = new VariableSymbol(name, !IsInFunction, true, declaringType);

            SymbolScope.AddSymbol(symbol);

            if (CodeGenerationEnabled)
            {
                if (symbol.IsGlobal)
                {
                    GlobalBuilder.RegisterGlobalVariable(symbol);

                    symbol.GlobalVariableBuilder.LoadValueInstructions = ExpressionBucket.Pop();
                    Debug.Assert(symbol.GlobalVariableBuilder.LoadValueInstructions.Count > 0);
                }
                else
                {
                    CurrentFunction.Builder.RegisterLocalVariable(symbol);

                    // load address
                    CurrentFunction.Builder.Bucket.Add(new object[] { "loca", symbol.LocalLocation.Id });

                    // load init expr
                    CurrentFunction.Builder.Bucket.AddRange(ExpressionBucket.Pop());

                    // set memory value
                    CurrentFunction.Builder.Bucket.AddSingle("store.64");
                }
            }
        }