XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text.Json;
using AngleSharp.Html.Parser;
using Jint;
using XFESystem.Browser;

var root = Path.GetFullPath(args.Length > 0 ? args[0] : ".");
var assetRoot = Path.Combine(root, "assets/Browser/Monaco/0.52.2");
var run = Path.Combine(root, "build/BrowserProbe", "Run-" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
Directory.CreateDirectory(run);
var loaderPath = Path.Combine(assetRoot, "min/vs/loader.js");
var mainPath = Path.Combine(assetRoot, "min/vs/editor/editor.main.js");
var loader = File.ReadAllText(loaderPath);
var main = File.ReadAllText(mainPath);
var stages = new List<object>();

JavaScriptRuntime Create(bool expanded = false)
{
    var limits = expanded ? new BrowserLimits {
        MaximumScriptCharacters = 1_048_576, MaximumScriptMemoryBytes = 268_435_456,
        MaximumStatements = 10_000_000, MaximumRecursionDepth = 256, ScriptTimeout = TimeSpan.FromSeconds(30)
    } : new BrowserLimits();
    var runtime = new JavaScriptRuntime(limits);
    var document = new HtmlParser().ParseDocument("<!doctype html><html><head></head><body><div id='container' style='width:800px;height:600px'></div></body></html>");
    _ = new DomBridge(runtime, document, new Uri("http://xfe.test/Monaco/"), limits);
    return runtime;
}
bool Step(JavaScriptRuntime runtime, string name, string source, bool bypassCharacterLimit = false)
{
    var timer = Stopwatch.StartNew();
    bool success;
    string error;
    try
    {
        if (bypassCharacterLimit) { runtime.Engine.Execute(source); success = true; error = ""; }
        else { var result = runtime.Evaluate(source); success = result.Success; error = result.Error; }
    }
    catch (Exception ex) { success = false; error = ex.ToString(); }
    stages.Add(new { Name = name, SourceCharacters = source.Length, BypassCharacterLimit = bypassCharacterLimit,
        Success = success, Error = error, ElapsedMilliseconds = timer.Elapsed.TotalMilliseconds });
    Console.WriteLine(JsonSerializer.Serialize(new { Name = name, Success = success, Error = error.Length > 1500 ? error[..1500] : error }));
    return success;
}

var current = Create();
Step(current, "ProductionProfile.RealLoader", loader);
Step(current, "ProductionProfile.RealEditorBundle", main);
var expanded = Create(true);
Step(expanded, "ExpandedProbe.RealLoader", loader);
Step(expanded, "ExpandedProbe.RealEditorBundle", main, true);
Step(expanded, "ExpandedProbe.RequireEditor", "require(['vs/editor/editor.main'],function(){globalThis.__xfeLoaded=true;},function(e){throw e;});");
Step(expanded, "ExpandedProbe.CreateRealEditor", "globalThis.__xfeEditor=monaco.editor.create(document.getElementById('container'),{value:'const answer = 42;',language:'javascript',automaticLayout:false});");

var withNavigator = Create(true);
Step(withNavigator, "NavigatorProbe.Platform", "globalThis.navigator={userAgent:'XFESystem/MonacoProbe',platform:'XFESystem',language:'en-US',languages:['en-US'],hardwareConcurrency:1,onLine:false};globalThis.location={href:'http://xfe.test/Monaco/',protocol:'http:',hostname:'xfe.test',host:'xfe.test',origin:'http://xfe.test',pathname:'/Monaco/',search:'',hash:''};");
Step(withNavigator, "NavigatorProbe.RealLoader", loader);
Step(withNavigator, "NavigatorProbe.RealEditorBundle", main, true);
var withoutCss = Create(true);
Step(withoutCss, "NoCssProbe.Platform", "globalThis.navigator={userAgent:'XFESystem/MonacoProbe',platform:'XFESystem',language:'en-US',languages:['en-US'],hardwareConcurrency:1,onLine:false};globalThis.location={href:'http://xfe.test/Monaco/',protocol:'http:',hostname:'xfe.test',host:'xfe.test',origin:'http://xfe.test',pathname:'/Monaco/',search:'',hash:''};");
Step(withoutCss, "NoCssProbe.RealLoader", loader);
Step(withoutCss, "NoCssProbe.OfficialCssPluginDisabledForDiagnosis", "require.config({'vs/css':{disabled:true}});");
Step(withoutCss, "NoCssProbe.RealEditorBundle", main, true);
var platform = "globalThis.navigator={userAgent:'XFESystem/MonacoProbe',platform:'XFESystem',language:'en-US',languages:['en-US'],hardwareConcurrency:1,onLine:false};globalThis.location={href:'http://xfe.test/Monaco/',protocol:'http:',hostname:'xfe.test',host:'xfe.test',origin:'http://xfe.test',pathname:'/Monaco/',search:'',hash:''};document.queryCommandSupported=function(command){return false;};";
var tasks = File.ReadAllText(Path.Combine(root, "Tools/BrowserCompatibility/ProbeTasks.js"));
var events = File.ReadAllText(Path.Combine(root, "Tools/BrowserCompatibility/ProbeWindowEvents.js"));
var tokens = File.ReadAllText(Path.Combine(root, "Tools/BrowserCompatibility/ProbeDomTokens.js"));
foreach (var diagnostic in new[] { (Name:"TaskProbe", Script:tasks), (Name:"WindowEventProbe", Script:tasks + "\n" + events), (Name:"DomTokenProbe", Script:tasks + "\n" + events + "\n" + tokens) })
{
    var candidate = Create(true);
    Step(candidate, diagnostic.Name + ".Platform", platform + diagnostic.Script);
    Step(candidate, diagnostic.Name + ".RealLoader", loader);
    Step(candidate, diagnostic.Name + ".OfficialCssPluginDisabledForDiagnosis", "require.config({'vs/css':{disabled:true}});");
    if (Step(candidate, diagnostic.Name + ".RealEditorBundle", main, true))
    {
        Step(candidate, diagnostic.Name + ".RequireRealEditor", "require(['vs/editor/editor.main'],function(){globalThis.__xfeLoaded=true;},function(e){throw e;});__xfeCheckpoint();if(!globalThis.__xfeLoaded)throw new Error('Real editor.main has not completed');");
        Step(candidate, diagnostic.Name + ".CreateRealEditor", "globalThis.__xfeEditor=monaco.editor.create(document.getElementById('container'),{value:'const answer = 42;',language:'javascript',automaticLayout:false});", true);
    }
}

var resultPath = Path.Combine(run, "Result.json");
var result = new {
    Kind = "RealMonacoJintCompatibilityProbe", MonacoVersion = "0.52.2", JintVersion = "4.11.0",
    ProductionBrowserModified = false, ProbeOnly = true, NativeGuestTested = false, HostBrowserUsed = false,
    FakeMonacoObjects = false, ExpandedBudgetIsProductionSupport = false,
    LoaderSha256 = Convert.ToHexStringLower(SHA256.HashData(File.ReadAllBytes(loaderPath))),
    EditorBundleSha256 = Convert.ToHexStringLower(SHA256.HashData(File.ReadAllBytes(mainPath))),
    Baseline = Directory.GetFiles(Path.Combine(root, "build/BrowserProbe/InitialBaseline"), "*.cs")
        .Select(p => new { Name = Path.GetFileName(p), Sha256 = Convert.ToHexStringLower(SHA256.HashData(File.ReadAllBytes(p))) }).ToArray(),
    Stages = stages
};
File.WriteAllText(resultPath, JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }));
Console.WriteLine(resultPath);