mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 05:22:27 +03:00
Merge pull request #3979 from urbit/jb/dynamic-hints
u3: adds bytecode ops and protocol for dynamic hints
This commit is contained in:
commit
8de7af85fb
@ -475,22 +475,32 @@ _n_nock_on(u3_noun bus, u3_noun fol)
|
||||
#define SLIB 70
|
||||
#define SLIS 71
|
||||
#define SAVE 72
|
||||
// before formula
|
||||
#define HILB 73 // atomic, byte
|
||||
#define HILS 74 // atomic, short
|
||||
#define HINB 75 // arbitrary, byte
|
||||
#define HINS 76 // arbitrary, short
|
||||
// after formula
|
||||
#define HILK 77 // atomic, keep
|
||||
#define HILL 78 // atomic, lose
|
||||
#define HINK 79 // arbitrary, keep
|
||||
#define HINL 80 // arbitrary, lose
|
||||
// nock 10
|
||||
#define MUTH 73
|
||||
#define KUTH 74
|
||||
#define MUTT 75
|
||||
#define KUTT 76
|
||||
#define MUSM 77
|
||||
#define KUSM 78
|
||||
#define MUTB 79
|
||||
#define MUTS 80
|
||||
#define MITB 81
|
||||
#define MITS 82
|
||||
#define KUTB 83
|
||||
#define KUTS 84
|
||||
#define KITB 85
|
||||
#define KITS 86
|
||||
#define LAST 87
|
||||
#define MUTH 81
|
||||
#define KUTH 82
|
||||
#define MUTT 83
|
||||
#define KUTT 84
|
||||
#define MUSM 85
|
||||
#define KUSM 86
|
||||
#define MUTB 87
|
||||
#define MUTS 88
|
||||
#define MITB 89
|
||||
#define MITS 90
|
||||
#define KUTB 91
|
||||
#define KUTS 92
|
||||
#define KITB 93
|
||||
#define KITS 94
|
||||
#define LAST 95
|
||||
|
||||
/* _n_arg(): return the size (in bytes) of an opcode's argument
|
||||
*/
|
||||
@ -605,6 +615,7 @@ _n_melt(u3_noun ops, c3_w* byc_w, c3_w* cal_w,
|
||||
case SAST: case SALT: case KICS: case TICS:
|
||||
case FISK: case FISL: case SUSH: case SANS:
|
||||
case LISL: case LISK: case SKIS: case SLIS:
|
||||
case HILS: case HINS:
|
||||
c3_assert(0); //overflows
|
||||
break;
|
||||
|
||||
@ -625,6 +636,7 @@ _n_melt(u3_noun ops, c3_w* byc_w, c3_w* cal_w,
|
||||
case BUSH: case FIBK: case FIBL:
|
||||
case SANB: case LIBL: case LIBK:
|
||||
case KITB: case MITB:
|
||||
case HILB: case HINB:
|
||||
a_w = (*lit_w)++;
|
||||
if ( a_w <= 0xFF ) {
|
||||
siz_y[i_w] = 2;
|
||||
@ -856,6 +868,7 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip)
|
||||
case LIBK: case LIBL:
|
||||
case BUSH: case SANB:
|
||||
case KITB: case MITB:
|
||||
case HILB: case HINB:
|
||||
_n_prog_asm_inx(buf_y, &i_w, lit_s, cod);
|
||||
pog_u->lit_u.non[lit_s++] = u3k(u3t(op));
|
||||
break;
|
||||
@ -963,6 +976,8 @@ static char* opcode_names[] = {
|
||||
"balt", "salt",
|
||||
"skib", "skis", "slib", "slis",
|
||||
"save",
|
||||
"hilb", "hils", "hinb", "hins"
|
||||
"hilk", "hill", "hink", "hinl"
|
||||
"muth", "kuth", "mutt", "kutt",
|
||||
"musm", "kusm",
|
||||
"mutb", "muts", "mitb", "mits",
|
||||
@ -995,21 +1010,64 @@ static c3_w _n_comp(u3_noun*, u3_noun, c3_o, c3_o);
|
||||
static c3_w
|
||||
_n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
|
||||
{
|
||||
c3_w tot_w = 0;
|
||||
|
||||
if ( c3n == u3du(hif) ) {
|
||||
// no currently recognized static hints
|
||||
return _n_comp(ops, nef, los_o, tel_o);
|
||||
// compile whitelisted atomic hints to dispatch protocol;
|
||||
// compute and drop all others;
|
||||
//
|
||||
switch ( hif ) {
|
||||
default: {
|
||||
return _n_comp(ops, nef, los_o, tel_o);
|
||||
}
|
||||
|
||||
// no currently recognized static hints
|
||||
//
|
||||
case u3_none: {
|
||||
u3_noun fen = u3_nul;
|
||||
c3_w nef_w = _n_comp(&fen, nef, los_o, tel_o);
|
||||
|
||||
// HILB overflows to HILS
|
||||
//
|
||||
++tot_w; _n_emit(ops, u3nc(HILB, u3nc(u3k(hif), u3k(nef))));
|
||||
++tot_w; _n_emit(ops, u3nc(SBIN, nef_w + 1));
|
||||
tot_w += nef_w; _n_apen(ops, fen);
|
||||
++tot_w; _n_emit(ops, ( c3y == los_o ) ? HILL : HILK);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
c3_w tot_w = 0;
|
||||
u3_noun zep, hod;
|
||||
u3x_cell(hif, &zep, &hod);
|
||||
|
||||
switch ( zep ) {
|
||||
default:
|
||||
tot_w += _n_comp(ops, hod, c3n, c3n);
|
||||
++tot_w; _n_emit(ops, TOSS);
|
||||
tot_w += _n_comp(ops, nef, los_o, tel_o);
|
||||
break;
|
||||
default: {
|
||||
// compile whitelisted dynamic hints to dispatch protocol;
|
||||
// compute and drop all others;
|
||||
//
|
||||
switch ( zep ) {
|
||||
default: {
|
||||
tot_w += _n_comp(ops, hod, c3n, c3n);
|
||||
++tot_w; _n_emit(ops, TOSS);
|
||||
tot_w += _n_comp(ops, nef, los_o, tel_o);
|
||||
} break;
|
||||
|
||||
// no currently recognized dynamic hints
|
||||
//
|
||||
case u3_none: {
|
||||
u3_noun fen = u3_nul;
|
||||
c3_w nef_w = _n_comp(&fen, nef, los_o, tel_o);
|
||||
|
||||
tot_w += _n_comp(ops, hod, c3n, c3n);
|
||||
// HINB overflows to HINS
|
||||
//
|
||||
++tot_w; _n_emit(ops, u3nc(HINB, u3nc(u3k(zep), u3k(nef))));
|
||||
++tot_w; _n_emit(ops, u3nc(SBIN, nef_w + 1));
|
||||
tot_w += nef_w; _n_apen(ops, fen);
|
||||
++tot_w; _n_emit(ops, ( c3y == los_o ) ? HINL : HINK);
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case c3__hunk:
|
||||
case c3__lose:
|
||||
@ -1062,8 +1120,9 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return tot_w;
|
||||
}
|
||||
|
||||
return tot_w;
|
||||
}
|
||||
|
||||
static c3_t
|
||||
@ -1485,6 +1544,19 @@ _n_rewo(c3_y* buf, c3_w* ip_w)
|
||||
return one | (two << 8) | (tre << 16) | (qua << 24);
|
||||
}
|
||||
|
||||
/* _n_swap(): swap two items on the top of the stack, return pointer to top
|
||||
*/
|
||||
static inline u3_noun*
|
||||
_n_swap(c3_ys mov, c3_ys off)
|
||||
{
|
||||
u3_noun* top = _n_peek(off);
|
||||
u3_noun* up = _n_peet(mov, off);
|
||||
u3_noun tmp = *up;
|
||||
*up = *top;
|
||||
*top = tmp;
|
||||
return top;
|
||||
}
|
||||
|
||||
#ifdef VERBOSE_BYTECODE
|
||||
/* _n_print_byc(): print bytecode. used for debugging.
|
||||
*/
|
||||
@ -1604,17 +1676,59 @@ u3n_find(u3_noun key, u3_noun fol)
|
||||
return pog_p;
|
||||
}
|
||||
|
||||
/* _n_swap(): swap two items on the top of the stack, return pointer to top
|
||||
*/
|
||||
static inline u3_noun*
|
||||
_n_swap(c3_ys mov, c3_ys off)
|
||||
/* _n_hilt_fore(): literal (atomic) dynamic hint, before formula evaluation.
|
||||
** lit: hint atom. TRANSFER
|
||||
** bus: subject. RETAIN
|
||||
** out: token for _n_hilt_hind();
|
||||
** conventionally, [lit] or [lit data]. ~ if unused.
|
||||
**
|
||||
** any hints herein must be whitelisted in _n_burn().
|
||||
*/
|
||||
static c3_o
|
||||
_n_hilt_fore(u3_atom lit, u3_noun bus, u3_noun* out) // transfer, retain, n/a
|
||||
{
|
||||
u3_noun* top = _n_peek(off);
|
||||
u3_noun* up = _n_peet(mov, off);
|
||||
u3_noun tmp = *up;
|
||||
*up = *top;
|
||||
*top = tmp;
|
||||
return top;
|
||||
u3z(lit);
|
||||
*out = u3_nul;
|
||||
return c3y;
|
||||
}
|
||||
|
||||
/* _n_hilt_hind(): literal (atomic) dynamic hint, after formula evaluation.
|
||||
** tok: token from _n_hilt_fore(). TRANSFER
|
||||
** pro: product of formula evaluation. RETAIN
|
||||
*/
|
||||
static void
|
||||
_n_hilt_hind(u3_noun tok, u3_noun pro) // transfer, retain
|
||||
{
|
||||
c3_assert( u3_nul == tok );
|
||||
u3z(tok);
|
||||
}
|
||||
|
||||
/* _n_hint_fore(): arbitrary dynamic hint, before formula evaluation
|
||||
** hin: [hint-atom, formula]. TRANSFER
|
||||
** bus: subject. RETAIN
|
||||
** clu: product of the hint-formula. TRANSFER
|
||||
** also, token for _n_hint_hind();
|
||||
** conventionally, [hint-atom] or [hint-atom data]. ~ if unused.
|
||||
**
|
||||
** any hints herein must be whitelisted in _n_burn().
|
||||
*/
|
||||
static c3_o
|
||||
_n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu)
|
||||
{
|
||||
u3z(hin); u3z(*clu);
|
||||
*clu = u3_nul;
|
||||
return c3y;
|
||||
}
|
||||
|
||||
/* _n_hint_hind(): arbitrary dynamic hint, after formula evaluation.
|
||||
** tok: token from _n_hint_fore(). TRANSFER
|
||||
** pro: product of formula evaluation. RETAIN
|
||||
*/
|
||||
static void
|
||||
_n_hint_hind(u3_noun tok, u3_noun pro)
|
||||
{
|
||||
c3_assert( u3_nul == tok );
|
||||
u3z(tok);
|
||||
}
|
||||
|
||||
/* _n_kick(): stop tracing noc and kick a u3j_site.
|
||||
@ -1680,6 +1794,8 @@ _n_burn(u3n_prog* pog_u, u3_noun bus, c3_ys mov, c3_ys off)
|
||||
&&do_balt, &&do_salt,
|
||||
&&do_skib, &&do_skis, &&do_slib, &&do_slis,
|
||||
&&do_save,
|
||||
&&do_hilb, &&do_hils, &&do_hinb, &&do_hins,
|
||||
&&do_hilk, &&do_hill, &&do_hink, &&do_hinl,
|
||||
&&do_muth, &&do_kuth, &&do_mutt, &&do_kutt,
|
||||
&&do_musm, &&do_kusm,
|
||||
&&do_mutb, &&do_muts, &&do_mitb, &&do_mits,
|
||||
@ -2270,6 +2386,67 @@ _n_burn(u3n_prog* pog_u, u3_noun bus, c3_ys mov, c3_ys off)
|
||||
u3z(o);
|
||||
BURN();
|
||||
|
||||
do_hilb:
|
||||
x = pog[ip_w++];
|
||||
goto hilt_fore_in;
|
||||
|
||||
do_hils:
|
||||
x = _n_resh(pog, &ip_w);
|
||||
hilt_fore_in:
|
||||
x = u3k(pog_u->lit_u.non[x]);
|
||||
top = _n_peek(off); // bus
|
||||
x = _n_hilt_fore(x, *top, &o);
|
||||
_n_push(mov, off, o);
|
||||
_n_swap(mov, off); // bus
|
||||
_n_push(mov, off, x); // shortcircuit if c3n
|
||||
BURN();
|
||||
|
||||
do_hinb:
|
||||
x = pog[ip_w++];
|
||||
goto hint_fore_in;
|
||||
|
||||
do_hins:
|
||||
x = _n_resh(pog, &ip_w);
|
||||
hint_fore_in: // [clu bus]
|
||||
x = u3k(pog_u->lit_u.non[x]);
|
||||
o = _n_pep(mov, off); // [bus]
|
||||
top = _n_peek(off);
|
||||
x = _n_hint_fore(x, *top, &o);
|
||||
_n_push(mov, off, o); // [tok bus]
|
||||
_n_swap(mov, off); // [bus tok]
|
||||
_n_push(mov, off, x); // [kip bus tok]
|
||||
BURN();
|
||||
|
||||
do_hilk: // [pro bus tok]
|
||||
x = _n_pep(mov, off); // [bus tok]
|
||||
_n_swap(mov, off); // [tok bus]
|
||||
o = _n_pep(mov, off); // [bus]
|
||||
_n_push(mov, off, x); // [pro bus]
|
||||
_n_hilt_hind(o, x);
|
||||
BURN();
|
||||
|
||||
do_hill: // [pro tok]
|
||||
top = _n_swap(mov, off); // [tok pro]
|
||||
o = _n_pep(mov, off); // [pro]
|
||||
top = _n_peek(off);
|
||||
_n_hilt_hind(o, *top);
|
||||
BURN();
|
||||
|
||||
do_hink: // [pro bus tok]
|
||||
x = _n_pep(mov, off); // [bus tok]
|
||||
_n_swap(mov, off); // [tok bus]
|
||||
o = _n_pep(mov, off); // [bus]
|
||||
_n_push(mov, off, x); // [pro bus]
|
||||
_n_hint_hind(o, x);
|
||||
BURN();
|
||||
|
||||
do_hinl: // [pro tok]
|
||||
top = _n_swap(mov, off); // [tok pro]
|
||||
o = _n_pep(mov, off); // [pro]
|
||||
top = _n_peek(off);
|
||||
_n_hint_hind(o, *top);
|
||||
BURN();
|
||||
|
||||
do_kuth:
|
||||
x = _n_pep(mov, off);
|
||||
top = _n_swap(mov, off);
|
||||
|
Loading…
Reference in New Issue
Block a user