public AssemblyCodeGenerator(GlobalBuilder globalBuilder) { this.globalBuilder = globalBuilder; // magic int magic = 0x72303b3e; Executable.WriteInt(magic); // version int version = 0x00000001; Executable.WriteInt(version); }
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"); } }
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"); } } }