Skip to content

Commit

Permalink
feat: add JS_Eval & script loader
Browse files Browse the repository at this point in the history
  • Loading branch information
LazuliKao committed Jul 28, 2023
1 parent 2e48e0e commit 31cb539
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 9 deletions.
12 changes: 6 additions & 6 deletions src/Hook/QuickJS/Eval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ namespace Hosihikari.VanillaScript.Hook.QuickJS;
//ref https://github.com/bellard/quickjs/blob/master/quickjs.c#L33730
internal class Eval : HookBase<Eval.HookDelegate>
{
internal unsafe delegate JsValue* HookDelegate(
internal unsafe delegate JsValue HookDelegate(
JsContext* ctx,
byte* input,
long inputLen,
nint filename,
JsEvalFlag evalFlags,
JsValue* a1,
byte unknown
JsValue thisObj
);

//__int64 ctx,
Expand All @@ -31,7 +30,7 @@ public Eval()
: base("JS_Eval") { }

public override unsafe HookDelegate HookedFunc =>
(ctx, contentBytes, size, file, evalFlags, jsValue, unknown) =>
(ctx, contentBytes, size, file, evalFlags, thisObj) =>
{
try
{
Expand All @@ -49,7 +48,7 @@ out var len
)
)
{
var ret = Original(ctx, p, len, file, evalFlags, jsValue, unknown);
var ret = Original(ctx, p, len, file, evalFlags, thisObj);
return ret;
}
}
Expand All @@ -59,6 +58,7 @@ out var len
{
Log.Logger.Error(nameof(Eval), e);
}
return Original(ctx, contentBytes, size, file, evalFlags, jsValue, unknown);
return Original(ctx, contentBytes, size, file, evalFlags, thisObj);
};
internal HookDelegate OriginalFunc => Original;
}
26 changes: 26 additions & 0 deletions src/Loader/CustomScriptLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Hosihikari.VanillaScript.QuickJS;
using Hosihikari.VanillaScript.QuickJS.Types;

namespace Hosihikari.VanillaScript.Loader;

internal static partial class Manager
{
internal static unsafe void LoadAllScripts(JsContext* ctx)
{
var pluginsDir = Path.GetFullPath("plugins");
foreach (
var js in Directory.EnumerateFiles(pluginsDir, "*.js", SearchOption.AllDirectories)
)
{
try
{
var bytes = File.ReadAllText(js);
_ = Native.JS_Eval(ctx, js, bytes);
}
catch (Exception ex)
{
Log.Logger.Error(nameof(LoadAllScripts), ex);
}
}
}
}
1 change: 1 addition & 0 deletions src/Loader/Manager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ internal static unsafe void AddContext(JsContext* ctx)
{
_loadedScriptsContext.Add((nint)ctx);
SetupContext(ctx);
LoadAllScripts(ctx);
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/Loader/Modules/TestModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Hosihikari.VanillaScript.QuickJS.Extensions;
using Hosihikari.VanillaScript.QuickJS.Types;
using System.Runtime.InteropServices;

namespace Hosihikari.VanillaScript.Loader.Modules;

internal static unsafe class TestModule
{
public static void Bind(JsContext* ctx, JsValue instance)
{
instance.DefineFunction(ctx, "test", &test, 1);
}

[UnmanagedCallersOnly]
private static unsafe JsValue test(JsContext* ctx, JsValue val, int argCount, JsValue* argvIn)
{
var argv = new ReadOnlySpan<JsValue>(argvIn, argCount);
var arg = argv[0];
Log.Logger.Debug("测试", arg.ToString(ctx));
return JsValueCreateExtension.True;
}
}
4 changes: 3 additions & 1 deletion src/Loader/SetupContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Runtime.InteropServices;
using Hosihikari.Logging;

Check failure on line 2 in src/Loader/SetupContext.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'Logging' does not exist in the namespace 'Hosihikari' (are you missing an assembly reference?)
using Hosihikari.VanillaScript.QuickJS;
using Hosihikari.VanillaScript.QuickJS.Extensions;
using Hosihikari.VanillaScript.QuickJS.Types;

namespace Hosihikari.VanillaScript.Loader;
Expand Down Expand Up @@ -31,7 +33,7 @@ public static unsafe int JsModuleInitFunc(JsContext* ctx, JsModuleDef* module)
try
{
var instance = Native.JS_NewObject(ctx);
//instance.DefineFunction(ctx,"")
Modules.TestModule.Bind(ctx, instance);
Native.JS_SetModuleExport(ctx, module, apiModuleName, instance);
}
catch (Exception e)
Expand Down
5 changes: 4 additions & 1 deletion src/Main.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Hosihikari.PluginManager;
using Hosihikari.VanillaScript;
using Hosihikari.VanillaScript.Hook;
using Hosihikari.VanillaScript.QuickJS;

[assembly: EntryPoint<Main>]

Expand All @@ -11,7 +12,9 @@ public class Main : IEntryPoint
public void Initialize(AssemblyPlugin plugin)
{
new EnableScriptingHook().Install();
new Hook.QuickJS.Eval().Install();
var evalHook = new Hook.QuickJS.Eval();
evalHook.Install();
Native.JsEvalFunc = evalHook.OriginalFunc;
Assets.Prepare.Init();
}
}
2 changes: 1 addition & 1 deletion src/QuickJS/Extensions/JsValueExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public static unsafe bool DefineFunction(
string funcName,
delegate* unmanaged<JsContext*, JsValue, int, JsValue*, JsValue> func,
int argumentLength,
JscFunctionEnum cproto,
JscFunctionEnum cproto = JscFunctionEnum.Generic,
int magic = 0,
JsPropertyFlags flags = JsPropertyFlags.CWE
)
Expand Down
26 changes: 26 additions & 0 deletions src/QuickJS/Native.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Runtime.CompilerServices;
using Hosihikari.NativeInterop;

Check failure on line 2 in src/QuickJS/Native.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'NativeInterop' does not exist in the namespace 'Hosihikari' (are you missing an assembly reference?)
using Hosihikari.NativeInterop.Utils;

Check failure on line 3 in src/QuickJS/Native.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'NativeInterop' does not exist in the namespace 'Hosihikari' (are you missing an assembly reference?)
using Hosihikari.VanillaScript.Hook.QuickJS;
using Hosihikari.VanillaScript.QuickJS.Exceptions;
using Hosihikari.VanillaScript.QuickJS.Extensions;
using Hosihikari.VanillaScript.QuickJS.Types;
Expand Down Expand Up @@ -338,5 +339,30 @@ JsPropertyFlags flags
private static readonly Lazy<nint> _ptrJsDefinePropertyValueStr = GetPointerLazy(
"JS_DefinePropertyValueStr"
);

#endregion
#region JS_Eval
internal static Eval.HookDelegate JsEvalFunc = null!;

internal static SafeJsValue JS_Eval(
JsContext* ctx,
string file,
string content,
JsEvalFlag flags = JsEvalFlag.TypeModule
)
{
fixed (byte* input = StringUtils.StringToManagedUtf8(content, out var len))
fixed (byte* ptrFile = StringUtils.StringToManagedUtf8(file))
{
var globalObj = JS_GetGlobalObject(ctx);
var result = JsEvalFunc(ctx, input, len, (nint)ptrFile, flags, globalObj.Value);
if (result.IsException())
{
throw new QuickJsException(JS_GetException(ctx));
}

return new SafeJsValue(result, ctx);
}
}
#endregion
}

0 comments on commit 31cb539

Please sign in to comment.