Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Last active June 29, 2023 02:55
Show Gist options
  • Save MasterDuke17/1122bd705d14232cf9ec14084f14d361 to your computer and use it in GitHub Desktop.
Save MasterDuke17/1122bd705d14232cf9ec14084f14d361 to your computer and use it in GitHub Desktop.
#include "moar.h"
/* This representation's function pointer table. */
static const MVMREPROps Stat_this_repr;
/* Creates a new type object of this representation, and associates it with
* the given HOW. */
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
MVMSTable *st = MVM_gc_allocate_stable(tc, &Stat_this_repr, HOW);
MVMROOT(tc, st, {
MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
st->size = sizeof(MVMStat);
});
return st->WHAT;
}
/* Copies the body of one object to another. */
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
memcpy((MVMStatBody *)dest, (MVMStatBody *)src, sizeof(MVMStatBody));
}
/* Called by the VM in order to free memory associated with this object. */
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
/* Nothing to do for this REPR. */
}
static const MVMStorageSpec storage_spec = {
MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
0, /* bits */
0, /* align */
MVM_STORAGE_SPEC_BP_NONE, /* boxed_primitive */
0, /* can_box */
0, /* is_unsigned */
};
/* Gets the storage specification for this representation. */
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
return &storage_spec;
}
/* Compose the representation. */
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info) {
/* Nothing to do for this REPR. */
}
/* Set the size of the STable. */
static void deserialize_stable_size(MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader) {
st->size = sizeof(MVMStat);
}
/* Initializes the representation. */
const MVMREPROps * MVMStat_initialize(MVMThreadContext *tc) {
return &Stat_this_repr;
}
static const MVMREPROps Stat_this_repr = {
type_object_for,
MVM_gc_allocate_object,
NULL, /* initialize */
copy_to,
MVM_REPR_DEFAULT_ATTR_FUNCS,
{
MVM_REPR_DEFAULT_SET_INT,
MVM_REPR_DEFAULT_GET_INT,
MVM_REPR_DEFAULT_SET_NUM,
MVM_REPR_DEFAULT_GET_NUM,
MVM_REPR_DEFAULT_SET_STR,
MVM_REPR_DEFAULT_GET_STR,
MVM_REPR_DEFAULT_SET_UINT,
MVM_REPR_DEFAULT_GET_UINT,
MVM_REPR_DEFAULT_GET_BOXED_REF
}, /* box_funcs */
MVM_REPR_DEFAULT_POS_FUNCS,
MVM_REPR_DEFAULT_ASS_FUNCS,
MVM_REPR_DEFAULT_ELEMS,
get_storage_spec,
NULL, /* change_type */
NULL, /* serialize */
NULL, /* deserialize */
NULL, /* serialize_repr_data */
NULL, /* deserialize_repr_data */
deserialize_stable_size,
NULL, /* gc_mark */
gc_free,
NULL, /* gc_cleanup */
NULL, /* gc_mark_repr_data */
NULL, /* gc_free_repr_data */
compose,
NULL, /* spesh */
"Stat", /* name */
MVM_REPR_ID_MVMStat,
NULL, /* unmanaged_size */
NULL, /* describe_refs */
};
struct MVMStatBody {
uv_stat_t uv_stat;
};
struct MVMStat {
MVMObject common;
MVMStatBody body;
};
/* Function for REPR setup. */
const MVMREPROps * MVMStat_initialize(MVMThreadContext *tc);
[dan@alexandria nqp]$ gdb --args ./nqp-m -e 'my $a := nqp::dispatch("boot-syscall", "file-stat", "/home/dan/p6/nqp/VERSION", 0); say(nqp::dispatch("boot-syscall", "stat-is-reg", $a))'
GNU gdb (GDB) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./nqp-m...
(gdb) r
Starting program: /home/dan/Source/perl6/nqp/nqp-m -e my\ \$a\ :=\ nqp::dispatch\(\"boot-syscall\",\ \"file-stat\",\ \"/home/dan/p6/nqp/VERSION\",\ 0\)\;\ say\(nqp::dispatch\(\"boot-syscall\",\ \"stat-is-reg\",\ \$a\)\)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
process 2547440 is executing new program: /home/dan/Source/perl6/install/bin/moar
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7ffff72156c0 (LWP 2547443)]
Thread 1 "moar" received signal SIGSEGV, Segmentation fault.
0x00007ffff78c1773 in boot_syscall (tc=0x532dc020180, arg_info=...) at src/disp/boot.c:213
213 MVMuint32 got = REPR(MVM_capture_arg_pos_o(tc, args_capture, i))->ID;
(gdb) bt
#0 0x00007ffff78c1773 in boot_syscall (tc=0x532dc020180, arg_info=...) at src/disp/boot.c:213
#1 0x00007ffff78c5830 in run_dispatch (tc=tc@entry=0x532dc020180, record=record@entry=0x532dc481b10, disp=disp@entry=0x532dc450b60, capture=capture@entry=0x532dc1e2150) at src/disp/program.c:540
#2 0x00007ffff78ca069 in MVM_disp_program_run_dispatch (tc=0x532dc020180, disp=0x532dc450b60, arg_info=..., ic_entry_ptr=<optimized out>, ic_entry=<optimized out>, update_sf=<optimized out>) at src/disp/program.c:611
#3 0x00007ffff782f7d7 in MVM_interp_run (tc=0x532dc020180, initial_invoke=0x532dc1e2178, initial_invoke@entry=0x7ffff795ccb0 <toplevel_initial_invoke>, invoke_data=0x532dc1e2178, invoke_data@entry=0x7ffff795ccb0 <toplevel_initial_invoke>,
outer_runloop=0x1, outer_runloop@entry=0x0) at src/core/interp.c:5508
#4 0x00007ffff795dd65 in MVM_vm_run_file (instance=<optimized out>, filename=<optimized out>) at src/moar.c:505
#5 0x000055555555560b in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:307
(gdb) list
208
209 /* Add any guards. */
210 if (syscall->expected_kinds[i] == MVM_CALLSITE_ARG_OBJ) {
211 if (syscall->expected_reprs[i]) {
212 MVMuint32 expected = syscall->expected_reprs[i];
213 MVMuint32 got = REPR(MVM_capture_arg_pos_o(tc, args_capture, i))->ID;
214 if (expected == got) {
215 MVMROOT2(tc, name, args_capture, {
216 MVM_disp_program_record_guard_type(tc,
217 MVM_disp_program_record_track_arg(tc, args_capture, i));
(gdb)
diff --git build/Makefile.in build/Makefile.in
index f8221f121..fe5812409 100644
--- build/Makefile.in
+++ build/Makefile.in
@@ -187,6 +187,7 @@ OBJECTS2 = src/6model/reprs/MVMDLLSym@obj@ \
src/6model/reprs/MVMStaticFrameSpesh@obj@ \
src/6model/reprs/MVMCapture@obj@ \
src/6model/reprs/MVMTracked@obj@ \
+ src/6model/reprs/MVMStat@obj@ \
src/6model/6model@obj@ \
src/6model/bootstrap@obj@ \
src/6model/sc@obj@ \
@@ -373,6 +374,7 @@ HEADERS = src/moar.h \
src/6model/reprs/MVMStaticFrameSpesh.h \
src/6model/reprs/MVMCapture.h \
src/6model/reprs/MVMTracked.h \
+ src/6model/reprs/MVMStat.h \
src/6model/sc.h \
src/disp/boot.h \
src/disp/registry.h \
diff --git src/6model/bootstrap.c src/6model/bootstrap.c
index 597325fd0..12630729d 100644
--- src/6model/bootstrap.c
+++ src/6model/bootstrap.c
@@ -667,6 +667,7 @@ void MVM_6model_bootstrap(MVMThreadContext *tc) {
create_stub_boot_type(tc, MVM_REPR_ID_MVMSpeshCandidate, SpeshCandidate, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
create_stub_boot_type(tc, MVM_REPR_ID_MVMCapture, boot_types.BOOTCapture, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
create_stub_boot_type(tc, MVM_REPR_ID_MVMTracked, boot_types.BOOTTracked, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
+ create_stub_boot_type(tc, MVM_REPR_ID_MVMStat, boot_types.BOOTStat, 0, MVM_BOOL_MODE_NOT_TYPE_OBJECT);
/* Bootstrap the KnowHOW type, giving it a meta-object. */
bootstrap_KnowHOW(tc);
@@ -703,6 +704,7 @@ void MVM_6model_bootstrap(MVMThreadContext *tc) {
meta_objectifier(tc, SpeshCandidate, "SpeshCandidate");
meta_objectifier(tc, boot_types.BOOTCapture, "BOOTCapture");
meta_objectifier(tc, boot_types.BOOTTracked, "BOOTTracked");
+ meta_objectifier(tc, boot_types.BOOTStat, "BOOTStat");
/* Create the KnowHOWAttribute type. */
create_KnowHOWAttribute(tc);
diff --git src/6model/reprs.c src/6model/reprs.c
index 1c67cda83..225fbdf22 100644
--- src/6model/reprs.c
+++ src/6model/reprs.c
@@ -288,6 +288,7 @@ void MVM_repr_initialize_registry(MVMThreadContext *tc) {
register_core_repr(SpeshCandidate);
register_core_repr(Capture);
register_core_repr(Tracked);
+ register_core_repr(Stat);
assert(tc->instance->num_reprs == MVM_REPR_CORE_COUNT);
}
diff --git src/6model/reprs.h src/6model/reprs.h
index 71d4a1522..0d30083a1 100644
--- src/6model/reprs.h
+++ src/6model/reprs.h
@@ -45,6 +45,7 @@
#include "6model/reprs/MVMStaticFrameSpesh.h"
#include "6model/reprs/MVMSpeshCandidate.h"
#include "6model/reprs/MVMTracked.h"
+#include "6model/reprs/MVMStat.h"
/* REPR related functions. */
void MVM_repr_initialize_registry(MVMThreadContext *tc);
@@ -100,8 +101,9 @@ const MVMREPROps * MVM_repr_get_by_name(MVMThreadContext *tc, MVMString *name);
#define MVM_REPR_ID_MVMSpeshCandidate 43
#define MVM_REPR_ID_MVMCapture 44
#define MVM_REPR_ID_MVMTracked 45
+#define MVM_REPR_ID_MVMStat 46
-#define MVM_REPR_CORE_COUNT 46
+#define MVM_REPR_CORE_COUNT 47
#define MVM_REPR_MAX_COUNT 64
/* Default attribute functions for a REPR that lacks them. */
diff --git src/core/instance.h src/core/instance.h
index 9bc35d068..04543e0b1 100644
--- src/core/instance.h
+++ src/core/instance.h
@@ -24,6 +24,7 @@ struct MVMBootTypes {
MVMObject *BOOTReentrantMutex;
MVMObject *BOOTCapture;
MVMObject *BOOTTracked;
+ MVMObject *BOOTStat;
};
/* Various raw types that don't need a HOW */
diff --git src/disp/syscall.c src/disp/syscall.c
index 292834296..1fc98e7fb 100644
--- src/disp/syscall.c
+++ src/disp/syscall.c
@@ -1282,6 +1282,42 @@ static MVMDispSysCall async_unix_listen = {
.expected_concrete = { 1, 1, 1, 1, 0 },
};
+/* file-stat */
+static void file_stat_impl(MVMThreadContext *tc, MVMArgs arg_info) {
+ MVMString *filename = get_str_arg(arg_info, 0);
+ MVMint32 use_lstat = get_int_arg(arg_info, 1);
+ uv_stat_t file_stat = MVM_file_info(tc, filename, use_lstat);
+ MVMStat *stat_obj = MVM_malloc(sizeof(MVMStat));
+ stat_obj->body.uv_stat = file_stat;
+ MVM_args_set_result_obj(tc, (MVMObject *)stat_obj, MVM_RETURN_CURRENT_FRAME);
+}
+static MVMDispSysCall file_stat = {
+ .c_name = "file-stat",
+ .implementation = file_stat_impl,
+ .min_args = 2,
+ .max_args = 2,
+ .expected_kinds = { MVM_CALLSITE_ARG_STR, MVM_CALLSITE_ARG_INT },
+ .expected_reprs = { MVM_REPR_ID_MVMString, 0 },
+ .expected_concrete = { 1, 1 },
+};
+
+/* stat-is-reg */
+static void stat_is_reg_impl(MVMThreadContext *tc, MVMArgs arg_info) {
+ MVMStat *stat_obj = (MVMStat *)get_obj_arg(arg_info, 0);
+ uv_stat_t file_stat = stat_obj->body.uv_stat;
+ MVMint64 is_reg = (file_stat.st_mode & S_IFMT) == S_IFREG;
+ MVM_args_set_result_int(tc, is_reg, MVM_RETURN_CURRENT_FRAME);
+}
+static MVMDispSysCall stat_is_reg = {
+ .c_name = "stat-is-reg",
+ .implementation = stat_is_reg_impl,
+ .min_args = 1,
+ .max_args = 1,
+ .expected_kinds = { MVM_CALLSITE_ARG_OBJ },
+ .expected_reprs = { MVM_REPR_ID_MVMStat },
+ .expected_concrete = { 1 },
+};
+
void MVM_disp_syscall_setup(MVMThreadContext *tc) {
MVM_gc_allocate_gen2_default_set(tc);
MVM_fixkey_hash_build(tc, &tc->instance->syscalls, 0);
@@ -1356,6 +1392,8 @@ void MVM_disp_syscall_setup(MVMThreadContext *tc) {
add_to_hash(tc, &set_compunit_resolver);
add_to_hash(tc, &async_unix_connect);
add_to_hash(tc, &async_unix_listen);
+ add_to_hash(tc, &file_stat);
+ add_to_hash(tc, &stat_is_reg);
MVM_gc_allocate_gen2_default_clear(tc);
}
diff --git src/io/fileops.c src/io/fileops.c
index cd6b87208..052c2db12 100644
--- src/io/fileops.c
+++ src/io/fileops.c
@@ -43,6 +43,10 @@ static uv_stat_t file_info(MVMThreadContext *tc, MVMString *filename, MVMint32 u
return req.statbuf;
}
+uv_stat_t MVM_file_info(MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat) {
+ return file_info(tc, filename, use_lstat);
+}
+
MVMint64 MVM_file_stat(MVMThreadContext *tc, MVMString *filename, MVMint64 status, MVMint32 use_lstat) {
MVMint64 r = -1;
diff --git src/io/fileops.h src/io/fileops.h
index c11d27678..a479f4539 100644
--- src/io/fileops.h
+++ src/io/fileops.h
@@ -31,6 +31,7 @@ void MVM_file_rename(MVMThreadContext *tc, MVMString *src, MVMString *dest);
void MVM_file_delete(MVMThreadContext *tc, MVMString *f);
void MVM_file_chmod(MVMThreadContext *tc, MVMString *f, MVMint64 flag);
void MVM_file_chown(MVMThreadContext *tc, MVMString *f, MVMuint64 uid, MVMuint64 gid);
+uv_stat_t MVM_file_info(MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat);
MVMint64 MVM_file_exists(MVMThreadContext *tc, MVMString *f, MVMint32 use_lstat);
MVMint64 MVM_file_isreadable(MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat);
MVMint64 MVM_file_iswritable(MVMThreadContext *tc, MVMString *filename, MVMint32 use_lstat);
diff --git src/types.h src/types.h
index 3831f6ff0..e86dd810b 100644
--- src/types.h
+++ src/types.h
@@ -334,3 +334,5 @@ typedef struct MVMDispSysCall MVMDispSysCall;
typedef struct MVMDispSysCallHashEntry MVMDispSysCallHashEntry;
typedef struct MVMTracked MVMTracked;
typedef struct MVMTrackedBody MVMTrackedBody;
+typedef struct MVMStat MVMStat;
+typedef struct MVMStatBody MVMStatBody;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment