Skip to content

Commit

Permalink
feat: directory
Browse files Browse the repository at this point in the history
  • Loading branch information
LazuliKao committed Jul 31, 2023
1 parent eb8936a commit d4bedec
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 11 deletions.
5 changes: 2 additions & 3 deletions src/Loader/SetupContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Hosihikari.VanillaScript.Loader.Modules.IO;
using Hosihikari.VanillaScript.QuickJS.Wrapper;
using Hosihikari.VanillaScript.QuickJS.Wrapper;

namespace Hosihikari.VanillaScript.Loader;

Expand All @@ -15,7 +14,7 @@ internal static void SetupContext(JsContextWrapper ctx)
OnContextCreated?.Invoke(ctx);
if (Config.Data.BuildInModules.FileIo)
{
FileModule.Setup(ctx);
Modules.IO.Main.Setup(ctx);
}
}
}
131 changes: 131 additions & 0 deletions src/Modules/IO/DirectoryModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#define JsPromise
using System.Runtime.InteropServices;
using Hosihikari.VanillaScript.QuickJS;
using Hosihikari.VanillaScript.QuickJS.Extensions.Check;
using Hosihikari.VanillaScript.QuickJS.Helper;
using Hosihikari.VanillaScript.QuickJS.Types;
using Hosihikari.VanillaScript.QuickJS.Wrapper;

namespace Hosihikari.VanillaScript.Modules.IO;

internal class DirectoryModule
{
public static void Setup(JsContextWrapper ctx, JsModuleDefWrapper module)
{
unsafe
{
module.AddExport(
"directory",
_ =>
{
using var obj = ctx.NewObject();
#region FileExists
obj.DefineFunction(ctx, "exists", 1, &DirectoryExists);
[UnmanagedCallersOnly]
static JsValue DirectoryExists(
JsContext* ctx,
JsValue thisObj,
int argCount,
JsValue* argvIn
)
{
try
{
var argv = new ReadOnlySpan<JsValue>(argvIn, argCount);
argv.InsureArgumentCount(1);
argv[0].InsureTypeString(ctx, out var directory);
return JsValueCreateHelper.NewBool(Directory.Exists(directory));
}
catch (Exception ex)
{
return Native.JS_ThrowInternalError(ctx, ex);
}
}
#endregion
#region GetFiles
obj.DefineFunction(ctx, "getFiles", 1, &GetFiles);
[UnmanagedCallersOnly]
static JsValue GetFiles(
JsContext* ctx,
JsValue thisObj,
int argCount,
JsValue* argvIn
)
{
try
{
var argv = new ReadOnlySpan<JsValue>(argvIn, argCount);
argv.InsureArgumentCount(1);
argv[0].InsureTypeString(ctx, out var directory);
#if JsPromise
var (promise, resolve, reject) = JsValueCreateHelper.NewPromise(ctx);
JsPromiseHelper.AwaitTask(
(nint)ctx,
thisObj,
(resolve, reject),
Task.Run(() => Directory.GetFiles(directory)),
result => JsValueCreateHelper.NewArray(ctx, result).Steal()
);
return promise.Steal();
//Native.JS_Call(ctx, resolve, safeThis.Instance,)
#else
return JsValueCreateHelper
.NewArray(ctx, Directory.GetFiles(directory))
.Steal();
#endif
}
catch (Exception ex)
{
return Native.JS_ThrowInternalError(ctx, ex);
}
}
#endregion
#region GetDirectories
obj.DefineFunction(ctx, "getDirectories", 1, &GetDirectories);
[UnmanagedCallersOnly]
static JsValue GetDirectories(
JsContext* ctx,
JsValue thisObj,
int argCount,
JsValue* argvIn
)
{
try
{
var argv = new ReadOnlySpan<JsValue>(argvIn, argCount);
argv.InsureArgumentCount(1);
argv[0].InsureTypeString(ctx, out var directory);
#if JsPromise
var (promise, resolve, reject) = JsValueCreateHelper.NewPromise(ctx);
JsPromiseHelper.AwaitTask(
(nint)ctx,
thisObj,
(resolve, reject),
Task.Run(() => Directory.GetDirectories(directory)),
result => JsValueCreateHelper.NewArray(ctx, result).Steal()
);
return promise.Steal();
//Native.JS_Call(ctx, resolve, safeThis.Instance,)
#else
return JsValueCreateHelper
.NewArray(ctx, Directory.GetDirectories(directory))
.Steal();
#endif
}
catch (Exception ex)
{
return Native.JS_ThrowInternalError(ctx, ex);
}
}
#endregion
return obj.Steal();
}
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
using System.Runtime.InteropServices;
using Hosihikari.VanillaScript.QuickJS.Extensions.Check;

namespace Hosihikari.VanillaScript.Loader.Modules.IO;
namespace Hosihikari.VanillaScript.Modules.IO;

internal static class FileModule
{
public static void Setup(JsContextWrapper ctx)
public static void Setup(JsContextWrapper ctx, JsModuleDefWrapper module)
{
unsafe
{
var module = ctx.NewModule(Config.ConfigModules.FileIoModuleName);
module.AddExport(
"file",
_ =>
Expand Down
14 changes: 14 additions & 0 deletions src/Modules/IO/Main.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Hosihikari.VanillaScript.QuickJS.Wrapper;

namespace Hosihikari.VanillaScript.Modules.IO;

internal class Main
{
public static void Setup(JsContextWrapper ctx)
{
var module = ctx.NewModule(Config.ConfigModules.FileIoModuleName);
FileModule.Setup(ctx, module);
DirectoryModule.Setup(ctx, module);
PathModule.Setup(ctx, module);
}
}
11 changes: 11 additions & 0 deletions src/Modules/IO/PathModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Hosihikari.VanillaScript.QuickJS.Wrapper;

namespace Hosihikari.VanillaScript.Modules.IO;

internal class PathModule
{
public static void Setup(JsContextWrapper ctx, JsModuleDefWrapper module)
{
module.AddExportValue("currentDirectory", _ => ctx.NewString(Environment.CurrentDirectory));
}
}
111 changes: 110 additions & 1 deletion src/QuickJS/Helper/JsValueCreateHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Hosihikari.VanillaScript.QuickJS.Types;
using Hosihikari.VanillaScript.QuickJS.Wrapper;
Expand All @@ -15,6 +17,74 @@ private static JsValue MkVal(JsTag tag, int val)
return item;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool NewUnmanagedInternal<T>(T val, [NotNullWhen(true)] out JsValue? jsValue)
{
//match all unmanaged types
jsValue = val switch
{
bool b => NewBool(b),
char c => NewCatchOffset(c),
byte b => NewInt32(b),
sbyte sb => NewInt32(sb),
short s => NewInt32(s),
ushort us => NewInt32(us),
int i => NewInt32(i),
uint ui => NewUint32(ui),
long l => NewInt64(l),
ulong ul => NewFloat64(ul),
float f => NewFloat64(f),
double d => NewFloat64(d),
decimal dec => NewFloat64((double)dec),
_ => null
};
return jsValue is not null;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool NewUnmanaged<T>(T val, [NotNullWhen(true)] out JsValue? jsValue)
where T : unmanaged
{
return NewUnmanagedInternal(val, out jsValue);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static JsValue NewUnmanaged<T>(T val)
where T : unmanaged
{
//match all unmanaged types
if (NewUnmanaged(val, out var jsValue))
{
return jsValue.Value;
}
throw new NotImplementedException($"new {typeof(T)} is not support");
}

public static unsafe AutoDropJsValue New<T>(T val, JsContext* ctx)
{
if (NewUnmanagedInternal(val, out var jsValue))
{
return new AutoDropJsValue(jsValue.Value, ctx);
}
return val switch
{
string s => NewString(ctx, s),
string[] ss => NewArray(ctx, ss),
byte[] cc => NewArray(ctx, cc),
sbyte[] sb => NewArray(ctx, sb),
short[] ss => NewArray(ctx, ss),
ushort[] us => NewArray(ctx, us),
int[] ii => NewArray(ctx, ii),
uint[] ui => NewArray(ctx, ui),
long[] ll => NewArray(ctx, ll),
ulong[] ul => NewArray(ctx, ul),
float[] ff => NewArray(ctx, ff),
double[] dd => NewArray(ctx, dd),
decimal[] dec => NewArray(ctx, dec),
_ => throw new NotImplementedException($"new {typeof(T)} is not support")
};
}

// /* special values */
//#define JS_NULL JS_MKVAL(JS_TAG_NULL, 0)
public static JsValue Null => MkVal(JsTag.Null, 0);
Expand Down Expand Up @@ -221,6 +291,45 @@ public static unsafe AutoDropJsValue NewObject(JsContext* ctx)
return Native.JS_NewObject(ctx);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe AutoDropJsValue NewArray(JsContext* ctx)
{
return Native.JS_NewArray(ctx);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe AutoDropJsValue NewArray(JsContext* ctx, string[] strings)
{
var array = Native.JS_NewArray(ctx);
for (uint i = 0; i < strings.Length; i++)
{
using var str = NewString(ctx, strings[i]);
Native.JS_SetPropertyUint32(ctx, array.Value, i, str.Steal());
}
return array;
}

public static unsafe AutoDropJsValue NewArray(JsContext* ctx, AutoDropJsValue[] values)
{
var array = Native.JS_NewArray(ctx);
for (uint i = 0; i < values.Length; i++)
{
Native.JS_SetPropertyUint32(ctx, array.Value, i, values[i].Steal());
}
return array;
}

public static unsafe AutoDropJsValue NewArray<T>(JsContext* ctx, T[] values)
where T : unmanaged
{
var array = Native.JS_NewArray(ctx);
for (uint i = 0; i < values.Length; i++)
{
Native.JS_SetPropertyUint32(ctx, array.Value, i, New(values[i], ctx).Steal());
}
return array;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe AutoDropJsValue NewError(JsContext* ctx)
{
Expand Down
Loading

0 comments on commit d4bedec

Please sign in to comment.