mirror of
https://github.com/janet-lang/janet
synced 2025-01-25 22:56:52 +00:00
Add second argument to disasm.
This commit is contained in:
parent
28439d822a
commit
5dda83dc73
@ -2,6 +2,7 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## Unreleased - ???
|
## Unreleased - ???
|
||||||
|
- Allow passing a second argument to `disasm`.
|
||||||
- Add `cancel`. Resumes a fiber but makes it immediately error at the yield point.
|
- Add `cancel`. Resumes a fiber but makes it immediately error at the yield point.
|
||||||
- Allow multi-line paste into built in repl.
|
- Allow multi-line paste into built in repl.
|
||||||
- Add `(curenv)`.
|
- Add `(curenv)`.
|
||||||
|
190
src/core/asm.c
190
src/core/asm.c
@ -841,85 +841,110 @@ Janet janet_asm_decode_instruction(uint32_t instr) {
|
|||||||
return janet_wrap_nil();
|
return janet_wrap_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
Janet janet_disasm(JanetFuncDef *def) {
|
/*
|
||||||
int32_t i;
|
* Disasm sections
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Janet janet_disasm_arity(JanetFuncDef *def) {
|
||||||
|
return janet_wrap_integer(def->arity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Janet janet_disasm_min_arity(JanetFuncDef *def) {
|
||||||
|
return janet_wrap_integer(def->min_arity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Janet janet_disasm_max_arity(JanetFuncDef *def) {
|
||||||
|
return janet_wrap_integer(def->max_arity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Janet janet_disasm_slotcount(JanetFuncDef *def) {
|
||||||
|
return janet_wrap_integer(def->slotcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Janet janet_disasm_bytecode(JanetFuncDef *def) {
|
||||||
JanetArray *bcode = janet_array(def->bytecode_length);
|
JanetArray *bcode = janet_array(def->bytecode_length);
|
||||||
JanetArray *constants;
|
for (int32_t i = 0; i < def->bytecode_length; i++) {
|
||||||
JanetTable *ret = janet_table(10);
|
|
||||||
janet_table_put(ret, janet_ckeywordv("arity"), janet_wrap_integer(def->arity));
|
|
||||||
janet_table_put(ret, janet_ckeywordv("min-arity"), janet_wrap_integer(def->min_arity));
|
|
||||||
janet_table_put(ret, janet_ckeywordv("max-arity"), janet_wrap_integer(def->max_arity));
|
|
||||||
janet_table_put(ret, janet_ckeywordv("bytecode"), janet_wrap_array(bcode));
|
|
||||||
if (NULL != def->source) {
|
|
||||||
janet_table_put(ret, janet_ckeywordv("source"), janet_wrap_string(def->source));
|
|
||||||
}
|
|
||||||
if (def->flags & JANET_FUNCDEF_FLAG_VARARG) {
|
|
||||||
janet_table_put(ret, janet_ckeywordv("vararg"), janet_wrap_true());
|
|
||||||
}
|
|
||||||
if (NULL != def->name) {
|
|
||||||
janet_table_put(ret, janet_ckeywordv("name"), janet_wrap_string(def->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add constants */
|
|
||||||
if (def->constants_length > 0) {
|
|
||||||
constants = janet_array(def->constants_length);
|
|
||||||
janet_table_put(ret, janet_ckeywordv("constants"), janet_wrap_array(constants));
|
|
||||||
for (i = 0; i < def->constants_length; i++) {
|
|
||||||
constants->data[i] = def->constants[i];
|
|
||||||
}
|
|
||||||
constants->count = def->constants_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add bytecode */
|
|
||||||
for (i = 0; i < def->bytecode_length; i++) {
|
|
||||||
bcode->data[i] = janet_asm_decode_instruction(def->bytecode[i]);
|
bcode->data[i] = janet_asm_decode_instruction(def->bytecode[i]);
|
||||||
}
|
}
|
||||||
bcode->count = def->bytecode_length;
|
bcode->count = def->bytecode_length;
|
||||||
|
return janet_wrap_array(bcode);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add source map */
|
static Janet janet_disasm_source(JanetFuncDef *def) {
|
||||||
if (NULL != def->sourcemap) {
|
if (def->source != NULL) return janet_wrap_string(def->source);
|
||||||
JanetArray *sourcemap = janet_array(def->bytecode_length);
|
return janet_wrap_nil();
|
||||||
for (i = 0; i < def->bytecode_length; i++) {
|
}
|
||||||
Janet *t = janet_tuple_begin(2);
|
|
||||||
JanetSourceMapping mapping = def->sourcemap[i];
|
static Janet janet_disasm_name(JanetFuncDef *def) {
|
||||||
t[0] = janet_wrap_integer(mapping.line);
|
if (def->name != NULL) return janet_wrap_string(def->name);
|
||||||
t[1] = janet_wrap_integer(mapping.column);
|
return janet_wrap_nil();
|
||||||
sourcemap->data[i] = janet_wrap_tuple(janet_tuple_end(t));
|
}
|
||||||
}
|
|
||||||
sourcemap->count = def->bytecode_length;
|
static Janet janet_disasm_vararg(JanetFuncDef *def) {
|
||||||
janet_table_put(ret, janet_ckeywordv("sourcemap"), janet_wrap_array(sourcemap));
|
return janet_wrap_boolean(def->flags & JANET_FUNCDEF_FLAG_VARARG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Janet janet_disasm_constants(JanetFuncDef *def) {
|
||||||
|
JanetArray *constants = janet_array(def->constants_length);
|
||||||
|
for (int32_t i = 0; i < def->constants_length; i++) {
|
||||||
|
constants->data[i] = def->constants[i];
|
||||||
}
|
}
|
||||||
|
constants->count = def->constants_length;
|
||||||
|
return janet_wrap_array(constants);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add environments */
|
static Janet janet_disasm_sourcemap(JanetFuncDef *def) {
|
||||||
if (NULL != def->environments) {
|
if (NULL == def->sourcemap) return janet_wrap_nil();
|
||||||
JanetArray *envs = janet_array(def->environments_length);
|
JanetArray *sourcemap = janet_array(def->bytecode_length);
|
||||||
for (i = 0; i < def->environments_length; i++) {
|
for (int32_t i = 0; i < def->bytecode_length; i++) {
|
||||||
envs->data[i] = janet_wrap_integer(def->environments[i]);
|
Janet *t = janet_tuple_begin(2);
|
||||||
}
|
JanetSourceMapping mapping = def->sourcemap[i];
|
||||||
envs->count = def->environments_length;
|
t[0] = janet_wrap_integer(mapping.line);
|
||||||
janet_table_put(ret, janet_ckeywordv("environments"), janet_wrap_array(envs));
|
t[1] = janet_wrap_integer(mapping.column);
|
||||||
|
sourcemap->data[i] = janet_wrap_tuple(janet_tuple_end(t));
|
||||||
}
|
}
|
||||||
|
sourcemap->count = def->bytecode_length;
|
||||||
|
return janet_wrap_array(sourcemap);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add closures */
|
static Janet janet_disasm_environments(JanetFuncDef *def) {
|
||||||
/* Funcdefs cannot be recursive */
|
JanetArray *envs = janet_array(def->environments_length);
|
||||||
if (NULL != def->defs) {
|
for (int32_t i = 0; i < def->environments_length; i++) {
|
||||||
JanetArray *defs = janet_array(def->defs_length);
|
envs->data[i] = janet_wrap_integer(def->environments[i]);
|
||||||
for (i = 0; i < def->defs_length; i++) {
|
|
||||||
defs->data[i] = janet_disasm(def->defs[i]);
|
|
||||||
}
|
|
||||||
defs->count = def->defs_length;
|
|
||||||
janet_table_put(ret, janet_ckeywordv("defs"), janet_wrap_array(defs));
|
|
||||||
}
|
}
|
||||||
|
envs->count = def->environments_length;
|
||||||
|
return janet_wrap_array(envs);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add slotcount */
|
static Janet janet_disasm_defs(JanetFuncDef *def) {
|
||||||
janet_table_put(ret, janet_ckeywordv("slotcount"), janet_wrap_integer(def->slotcount));
|
JanetArray *defs = janet_array(def->defs_length);
|
||||||
|
for (int32_t i = 0; i < def->defs_length; i++) {
|
||||||
|
defs->data[i] = janet_disasm(def->defs[i]);
|
||||||
|
}
|
||||||
|
defs->count = def->defs_length;
|
||||||
|
return janet_wrap_array(defs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Janet janet_disasm(JanetFuncDef *def) {
|
||||||
|
JanetTable *ret = janet_table(10);
|
||||||
|
janet_table_put(ret, janet_ckeywordv("arity"), janet_disasm_arity(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("min-arity"), janet_disasm_min_arity(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("max-arity"), janet_disasm_max_arity(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("bytecode"), janet_disasm_bytecode(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("source"), janet_disasm_source(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("vararg"), janet_disasm_vararg(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("name"), janet_disasm_name(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("slotcount"), janet_disasm_slotcount(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("constants"), janet_disasm_constants(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("sourcemap"), janet_disasm_sourcemap(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("environments"), janet_disasm_environments(def));
|
||||||
|
janet_table_put(ret, janet_ckeywordv("defs"), janet_disasm_defs(def));
|
||||||
return janet_wrap_struct(janet_table_to_struct(ret));
|
return janet_wrap_struct(janet_table_to_struct(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C Function for assembly */
|
/* C Function for assembly */
|
||||||
static Janet cfun_asm(int32_t argc, Janet *argv) {
|
static Janet cfun_asm(int32_t argc, Janet *argv) {
|
||||||
janet_arity(argc, 1, 1);
|
janet_fixarity(argc, 1);
|
||||||
JanetAssembleResult res;
|
JanetAssembleResult res;
|
||||||
res = janet_asm(argv[0], 0);
|
res = janet_asm(argv[0], 0);
|
||||||
if (res.status != JANET_ASSEMBLE_OK) {
|
if (res.status != JANET_ASSEMBLE_OK) {
|
||||||
@ -929,9 +954,26 @@ static Janet cfun_asm(int32_t argc, Janet *argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Janet cfun_disasm(int32_t argc, Janet *argv) {
|
static Janet cfun_disasm(int32_t argc, Janet *argv) {
|
||||||
janet_arity(argc, 1, 1);
|
janet_arity(argc, 1, 2);
|
||||||
JanetFunction *f = janet_getfunction(argv, 0);
|
JanetFunction *f = janet_getfunction(argv, 0);
|
||||||
return janet_disasm(f->def);
|
if (argc == 2) {
|
||||||
|
JanetKeyword kw = janet_getkeyword(argv, 1);
|
||||||
|
if (!janet_cstrcmp(kw, "arity")) return janet_disasm_arity(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "min-arity")) return janet_disasm_min_arity(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "max-arity")) return janet_disasm_max_arity(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "bytecode")) return janet_disasm_bytecode(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "source")) return janet_disasm_source(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "name")) return janet_disasm_name(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "vararg")) return janet_disasm_vararg(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "slotcount")) return janet_disasm_slotcount(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "constants")) return janet_disasm_constants(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "sourcemap")) return janet_disasm_sourcemap(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "environments")) return janet_disasm_environments(f->def);
|
||||||
|
if (!janet_cstrcmp(kw, "defs")) return janet_disasm_defs(f->def);
|
||||||
|
janet_panicf("unknown disasm key %v", argv[1]);
|
||||||
|
} else {
|
||||||
|
return janet_disasm(f->def);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg asm_cfuns[] = {
|
static const JanetReg asm_cfuns[] = {
|
||||||
@ -939,15 +981,29 @@ static const JanetReg asm_cfuns[] = {
|
|||||||
"asm", cfun_asm,
|
"asm", cfun_asm,
|
||||||
JDOC("(asm assembly)\n\n"
|
JDOC("(asm assembly)\n\n"
|
||||||
"Returns a new function that is the compiled result of the assembly.\n"
|
"Returns a new function that is the compiled result of the assembly.\n"
|
||||||
"The syntax for the assembly can be found on the Janet website. Will throw an\n"
|
"The syntax for the assembly can be found on the Janet website, and should correspond\n"
|
||||||
|
"to the return value of disasm. Will throw an\n"
|
||||||
"error on invalid assembly.")
|
"error on invalid assembly.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"disasm", cfun_disasm,
|
"disasm", cfun_disasm,
|
||||||
JDOC("(disasm func)\n\n"
|
JDOC("(disasm func &opt field)\n\n"
|
||||||
"Returns assembly that could be used be compile the given function.\n"
|
"Returns assembly that could be used be compile the given function.\n"
|
||||||
"func must be a function, not a c function. Will throw on error on a badly\n"
|
"func must be a function, not a c function. Will throw on error on a badly\n"
|
||||||
"typed argument.")
|
"typed argument. If given a field name, will only return that part of the function assembly.\n"
|
||||||
|
"Possible fields are:\n\n"
|
||||||
|
"\t:arity - number of required and optional arguments.\n"
|
||||||
|
"\t:min-arity - minimum number of arguments function can be called with.\n"
|
||||||
|
"\t:max-arity - maximum number of arguments function can be called with.\n"
|
||||||
|
"\t:vararg - true if function can take a variable number of arguments.\n"
|
||||||
|
"\t:bytecode - array of parsed bytecode instructions. Each instruction is a tuple.\n"
|
||||||
|
"\t:source - name of source file that this function was compiled from.\n"
|
||||||
|
"\t:name - name of function.\n"
|
||||||
|
"\t:slotcount - how many virtual registers, or slots, this function uses. Corresponds to stack space used by function.\n"
|
||||||
|
"\t:constants - an array of constants referenced by this function.\n"
|
||||||
|
"\t:sourcemap - a mapping of each bytecode instruction to a line and column in the source file.\n"
|
||||||
|
"\t:environments - an internal mapping of which enclosing functions are referenced for bindings.\n"
|
||||||
|
"\t:defs - other function definitions that this function may instantiate.\n")
|
||||||
},
|
},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user