Merge branch 'next/arvo' into lf/lure

This commit is contained in:
Zach Alberico 2022-12-02 11:21:48 -08:00 committed by GitHub
commit c84fc5d5d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 2201 additions and 838 deletions

70
doc/spec/nock/10.txt Normal file
View File

@ -0,0 +1,70 @@
Author: Mencius Moldbug [moldbug@gmail.com]
Date: 9/15/2008
Version: 10K
1. Introduction
This file defines one function, "nock."
nock is in the public domain.
2. Data
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
integer of any size. A "cell" is an ordered pair of any two nouns,
the "head" and "tail."
3. Semantics
nock maps one noun to another. It doesn't always terminate.
4. Pseudocode
nock is defined in a pattern-matching pseudocode, below.
Brackets enclose cells. [a b c] is [a [b c]].
5. Definition
5.1 Transformations
*[a [b c] d] => [*[a b c] *[a d]]
*[a 0 b] => /[b a]
*[a 1 b] => [b]
*[a 2 b c d] => *[a 3 [0 1] 3 [1 c d] [1 0] 3 [1 2 3] [1 0] 5 5 b]
*[a 3 b] => **[a b]
*[a 4 b] => &*[a b]
*[a 5 b] => ^*[a b]
*[a 6 b] => =*[a b]
*[a] => *[a]
5.2 Operators
5.2.1 Goto [*]
*[a] -> nock[a]
5.2.2 Deep [&]
&[a b] -> 0
&[a] -> 1
5.2.4 Bump [^]
^[a b] -> ^[a b]
^[a] -> (a + 1)
5.2.5 Like [=]
=[a a] -> 0
=[a b] -> 1
=[a] -> =[a]
5.2.6 Snip [/]
/[1 a] -> a
/[2 a b] -> a
/[3 a b] -> b
/[(a + a) b] -> /[2 /[a b]]
/[(a + a + 1) b] -> /[3 /[a b]]
/[a] -> /[a]

74
doc/spec/nock/11.txt Normal file
View File

@ -0,0 +1,74 @@
Author: Mencius Moldbug (moldbug@gmail.com)
Date: 5/25/2008
Version: 11K
1. Introduction
This file defines one function, "nock."
nock is in the public domain.
2. Data
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
integer of any size. A "cell" is an ordered pair of any two nouns,
the "head" and "tail."
3. Semantics
nock maps one noun to another. It doesn't always terminate.
4. Pseudocode
nock is defined in a pattern-matching pseudocode, below.
Parentheses enclose cells. (a b c) is (a (b c)).
5. Definition
5.1 Transformations
*(a (b c) d) => (*(a b c) *(a d))
*(a 0 b) => /(b a)
*(a 1 b) => (b)
*(a 2 b c d) => *(a 3 (0 1) 3 (1 c d) (1 0) 3 (1 2 3) (1 0) 5 5 b)
*(a 3 b) => **(a b)
*(a 4 b) => &*(a b)
*(a 5 b) => ^*(a b)
*(a 6 b) => =*(a b)
*(a 7 b c) => *(a 3 (((1 0) b) c) 1 0 3)
*(a 8 b c) => *(a c)
*(a) => *(a)
5.2 Operators
5.2.1 Goto (*)
*(a) -> nock(a)
5.2.2 Deep (&)
&(a b) -> 0
&(a) -> 1
5.2.4 Bump (^)
^(a b) -> ^(a b)
^(a) -> a + 1
5.2.5 Same (=)
=(a a) -> 0
=(a b) -> 1
=(a) -> =(a)
5.2.6 Snip (/)
/(1 a) -> a
/(2 a b) -> a
/(3 a b) -> b
/((a + a) b) -> /(2 /(a b))
/((a + a + 1) b) -> /(3 /(a b))
/(a) -> /(a)

75
doc/spec/nock/12.txt Normal file
View File

@ -0,0 +1,75 @@
Author: Curtis Yarvin (curtis.yarvin@gmail.com)
Date: 3/28/2008
Version: 0.12
1. Introduction
This file defines one function, "nock."
nock is in the public domain.
2. Data
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
integer of any size. A "cell" is an ordered pair of any two nouns,
the "head" and "tail."
3. Semantics
nock maps one noun to another. It doesn't always terminate.
4. Pseudocode
nock is defined in a pattern-matching pseudocode, below.
Parentheses enclose cells. (a b c) is (a (b c)).
5. Definition
5.1 Transformations
*(a (b c) d) => (*(a b c) *(a d))
*(a 0 b) => /(b a)
*(a 1 b) => (b)
*(a 2 b c) => *(*(a b) c)
*(a 3 b) => **(a b)
*(a 4 b) => &*(a b)
*(a 5 b) => ^*(a b)
*(a 6 b) => =*(a b)
*(a 7 b c d) => *(a 3 (0 1) 3 (1 c d) (1 0) 3 (1 2 3) (1 0) 5 5 b)
*(a 8 b c) => *(a 2 (((1 0) b) c) 0 3)
*(a 9 b c) => *(a c)
*(a) => *(a)
5.2 Operators
5.2.1 Goto (*)
*(a) -> nock(a)
5.2.2 Deep (&)
&(a b) -> 0
&(a) -> 1
5.2.4 Bump (^)
^(a b) -> ^(a b)
^(a) -> a + 1
5.2.5 Same (=)
=(a a) -> 0
=(a b) -> 1
=(a) -> =(a)
5.2.6 Snip (/)
/(1 a) -> a
/(2 a b) -> a
/(3 a b) -> b
/((a + a) b) -> /(2 /(a b))
/((a + a + 1) b) -> /(3 /(a b))
/(a) -> /(a)

71
doc/spec/nock/13.txt Normal file
View File

@ -0,0 +1,71 @@
Author: Curtis Yarvin (curtis.yarvin@gmail.com)
Date: 3/8/2008
Version: 0.13
1. Manifest
This file defines one Turing-complete function, "nock."
nock is in the public domain. So far as I know, it is
neither patentable nor patented. Use it at your own risk.
2. Data
Both the domain and range of nock are "nouns."
A "noun" is either an "atom" or a "cell." An "atom" is an unsigned
integer of any size. A "cell" is an ordered pair of any two nouns,
the "head" and "tail."
3. Pseudocode
nock is defined in a pattern-matching pseudocode.
Match precedence is top-down. Operators are prefix. Parens
denote cells, and group right: (a b c) is (a (b c)).
4. Definition
4.1 Transformations
*(a 0 b c) => *(*(a b) c)
*(a 0 b) => /(b a)
*(a 1 b) => (b)
*(a 2 b) => **(a b)
*(a 3 b) => &*(a b)
*(a 4 b) => ^*(a b)
*(a 5 b) => =*(a b)
*(a 6 b c d) => *(a 2 (0 1) 2 (1 c d) (1 0) 2 (1 2 3) (1 0) 4 4 b)
*(a b c) => (*(a b) *(a c))
*(a) => *(a)
4.2 Operators
4.2.1 Goto (*)
*(a) -> nock(a)
4.2.2 Deep (&)
&(a b) -> 0
&(a) -> 1
4.2.3 Bump (^)
^(a b) -> ^(a b)
^(a) -> a + 1
4.2.4 Same (=)
=(a a) -> 0
=(a b) -> 1
=(a) -> =(a)
4.2.5 Snip (/)
/(1 a) -> a
/(2 a b) -> a
/(3 a b) -> b
/((a + a) b) -> /(2 /(a b))
/((a + a + 1) b) -> /(3 /(a b))
/(a) -> /(a)

42
doc/spec/nock/6.txt Normal file
View File

@ -0,0 +1,42 @@
1 Structures
A noun is an atom or a cell. An atom is any natural number.
A cell is an ordered pair of nouns.
2 Reductions
nock(a) *a
[a b c] [a [b c]]
?[a b] 0
?a 1
+a 1 + a
=[a a] 0
=[a b] 1
/[1 a] a
/[2 a b] a
/[3 a b] b
/[(a + a) b] /[2 /[a b]]
/[(a + a + 1) b] /[3 /[a b]]
*[a [b c] d] [*[a b c] *[a d]]
*[a 0 b] /[b a]
*[a 1 b] b
*[a 2 b c] *[*[a b] *[a c]]
*[a 3 b] ?*[a b]
*[a 4 b] +*[a b]
*[a 5 b] =*[a b]
*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
*[a 7 b c] *[a 2 b 1 c]
*[a 8 b c] *[a 7 [[0 1] b] c]
*[a 9 b c] *[a 7 c 0 b]
*[a 10 b c] *[a c]
*[a 10 [b c] d] *[a 8 c 7 [0 2] d]
+[a b] +[a b]
=a =a
/a /a
*a *a

42
doc/spec/nock/7.txt Normal file
View File

@ -0,0 +1,42 @@
1 Structures
A noun is an atom or a cell. An atom is any natural number.
A cell is any ordered pair of nouns.
2 Pseudocode
[a b c] [a [b c]]
nock(a) *a
?[a b] 0
?a 1
^a 1 + a
=[a a] 0
=[a b] 1
/[1 a] a
/[2 a b] a
/[3 a b] b
/[(a + a) b] /[2 /[a b]]
/[(a + a + 1) b] /[3 /[a b]]
*[a [b c] d] [*[a b c] *[a d]]
*[a 0 b] /[b a]
*[a 1 b] b
*[a 2 b c] *[*[a b] *[a c]]
*[a 3 b] ?*[a b]
*[a 4 b] ^*[a b]
*[a 5 b] =*[a b]
*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
*[a 7 b c] *[a 2 b 1 c]
*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
*[a 9 b c] *[a 7 c 0 b]
*[a 10 b c] *[a c]
*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
^[a b] ^[a b]
=a =a
/a /a
*a *a

45
doc/spec/nock/8.txt Normal file
View File

@ -0,0 +1,45 @@
1 Structures
A noun is an atom or a cell. An atom is any unsigned integer.
A cell is an ordered pair of nouns.
2 Pseudocode
[a b c] is [a [b c]]; *a is nock(a). Reductions match top-down.
3 Reductions
?[a b] 0
?a 1
^a (a + 1)
=[a a] 0
=[a b] 1
/[1 a] a
/[2 a b] a
/[3 a b] b
/[(a + a) b] /[2 /[a b]]
/[(a + a + 1) b] /[3 /[a b]]
*[a [b c] d] [*[a b c] *[a d]]
*[a 0 b] /[b a]
*[a 1 b] b
*[a 2 b c] *[*[a b] *[a c]]
*[a 3 b] ?*[a b]
*[a 4 b] ^*[a b]
*[a 5 b] =*[a b]
*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
*[a 7 b c] *[a 2 b 1 c]
*[a 8 b c] *[a 7 [7 b [0 1]] c]
*[a 9 b c] *[a 8 b 2 [[7 [0 3] d] [0 5]] 0 5]
*[a 10 b c] *[a 8 b 8 [7 [0 3] c] 0 2]
*[a 11 b c] *[a 8 b 7 [0 3] c]
*[a 12 b c] *[a [1 0] 1 c]
^[a b] ^[a b]
=a =a
/a /a
*a *a

43
doc/spec/nock/9.txt Normal file
View File

@ -0,0 +1,43 @@
1 Context
This spec defines one function, Nock.
2 Structures
A noun is an atom or a cell. An atom is any unsigned integer.
A cell is an ordered pair of any two nouns.
3 Pseudocode
Brackets enclose cells. [a b c] is [a [b c]].
*a is Nock(a). Reductions match top-down.
4 Reductions
?[a b] => 0
?a => 1
^[a b] => ^[a b]
^a => (a + 1)
=[a a] => 0
=[a b] => 1
=a => =a
/[1 a] => a
/[2 a b] => a
/[3 a b] => b
/[(a + a) b] => /[2 /[a b]]
/[(a + a + 1) b] => /[3 /[a b]]
/a => /a
*[a 0 b] => /[b a]
*[a 1 b] => b
*[a 2 b c d] => *[a 3 [0 1] 3 [1 c d] [1 0] 3 [1 2 3] [1 0] 5 5 b]
*[a 3 b] => **[a b]
*[a 4 b] => ?*[a b]
*[a 5 b] => ^*[a b]
*[a 6 b] => =*[a b]
*[a [b c] d] => [*[a b c] *[a d]]
*a => *a

View File

@ -415,7 +415,7 @@
==
--
::
:: |de: axal engine
:: |of: axal engine
::
++ of
=| fat=(axal)

View File

@ -1,21 +1,33 @@
:: Test that these hints do not crash the runtime
:: there is no need to include the hints for dynamic %bout
:: there is no need to include a test for dynamic %bout
:: since all hoon tests exersize dynamic %bout
|%
:: these test that the hilt-trace hints
:: test that these trace hints
:: are safe to run or ignore
++ test-hela-hilt
++ test-hilt-hela
~> %hela
~
++ test-nara-hilt
++ test-hint-hela
~> %hela.[1 leaf+"test-hint-hela ~"]
~
++ test-hilt-nara
~> %nara
~
:: these test that the hint-trace hints
:: are safe to run or ignore
++ test-hela-hint
~> %hela.[1 leaf+"test-hela-trace-hint"]
++ test-hint-nara
~> %nara.[1 leaf+"test-hint-nara ~"]
~
++ test-nara-hint
~> %nara.[1 leaf+"test-nara-trace-hint"]
:: test that theses bytecode-report hints
:: are safe to run or ignore
++ test-hilt-xray
~> %xray
~
++ test-hint-xray
~> %xray.[1 leaf+"test-hint-xray ~"]
~
:: test that the hilt bout hint
:: is safe to run or ignore
++ test-hilt-bout
~> %bout
~
--

View File

@ -7,8 +7,9 @@
static void
_setup(void)
{
u3m_init();
u3m_init(1 << 24);
u3m_pave(c3y);
u3e_init();
}
/* _ames_writ_ex(): |hi packet from fake ~zod to fake ~nec

View File

@ -4,6 +4,8 @@
#define U3_GLOBAL
#define C3_GLOBAL
#include "all.h"
#include "vere/ivory.h"
#include "ur/ur.h"
#include "rsignal.h"
#include <vere/serf.h>
#include "vere/vere.h"
@ -164,6 +166,9 @@ _main_init(void)
u3_Host.ops_u.puf_c = "jam";
u3_Host.ops_u.hap_w = 50000;
u3_Host.ops_u.kno_w = DefaultKernel;
u3_Host.ops_u.lut_y = u3a_bits + 1;
u3_Host.ops_u.lom_y = u3a_bits + 1;
}
/* _main_pier_run(): get pier from binary path (argv[0]), if appropriate
@ -216,6 +221,7 @@ _main_getopt(c3_i argc, c3_c** argv)
{ "json-trace", no_argument, NULL, 'j' },
{ "kernel-stage", required_argument, NULL, 'K' },
{ "key-file", required_argument, NULL, 'k' },
{ "loom", required_argument, NULL, c3__loom },
{ "local", no_argument, NULL, 'L' },
{ "lite-boot", no_argument, NULL, 'l' },
{ "replay-to", required_argument, NULL, 'n' },
@ -238,6 +244,9 @@ _main_getopt(c3_i argc, c3_c** argv)
{ "exit", no_argument, NULL, 'x' },
{ "scry-into", required_argument, NULL, 'Y' },
{ "scry-format", required_argument, NULL, 'Z' },
//
{ "urth-loom", required_argument, NULL, 5 },
//
{ NULL, 0, NULL, 0 },
};
@ -246,6 +255,17 @@ _main_getopt(c3_i argc, c3_c** argv)
lop_u, &lid_i)) )
{
switch ( ch_i ) {
case 5: { // urth-loom
c3_w lut_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lut_w);
if ( (c3n == res_o) || (lut_w < 20) ) {
fprintf(stderr, "error: --urth-loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
return c3n;
}
u3_Host.ops_u.lut_y = lut_w;
break;
}
case 'X': {
u3_Host.ops_u.pek_c = strdup(optarg);
break;
@ -346,6 +366,16 @@ _main_getopt(c3_i argc, c3_c** argv)
} else u3_Host.ops_u.pes_s = arg_w;
break;
}
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
return c3n;
}
u3_Host.ops_u.lom_y = lom_w;
break;
}
case c3__noco: {
u3_Host.ops_u.con = c3n;
break;
@ -660,6 +690,7 @@ u3_ve_usage(c3_i argc, c3_c** argv)
"-K, --kernel-stage STAGE Start at Hoon kernel version stage\n",
"-k, --key-file KEYS Private key file (see also -G)\n",
"-L, --local Local networking only\n",
" --loom Set loom to binary exponent (31 == 2GB)\n"
"-l, --lite-boot Most-minimal startup\n",
"-n, --replay-to NUMBER Replay up to event\n",
"-P, --profile Profiling\n",
@ -997,9 +1028,9 @@ static void
_cw_serf_commence(c3_i argc, c3_c* argv[])
{
#ifdef U3_OS_mingw
if ( 8 > argc ) {
if ( 9 > argc ) {
#else
if ( 7 > argc ) {
if ( 8 > argc ) {
#endif
fprintf(stderr, "serf: missing args\n");
exit(1);
@ -1011,9 +1042,11 @@ _cw_serf_commence(c3_i argc, c3_c* argv[])
c3_c* key_c = argv[3]; // XX use passkey
c3_c* wag_c = argv[4];
c3_c* hap_c = argv[5];
c3_c* eve_c = argv[6];
c3_c* lom_c = argv[6];
c3_w lom_w;
c3_c* eve_c = argv[7];
#ifdef U3_OS_mingw
c3_c* han_c = argv[7];
c3_c* han_c = argv[8];
_cw_intr_win(han_c);
#endif
@ -1039,6 +1072,7 @@ _cw_serf_commence(c3_i argc, c3_c* argv[])
{
sscanf(wag_c, "%" SCNu32, &u3C.wag_w);
sscanf(hap_c, "%" SCNu32, &u3_Host.ops_u.hap_w);
sscanf(lom_c, "%" SCNu32, &lom_w);
if ( 1 != sscanf(eve_c, "%" PRIu64, &eve_d) ) {
fprintf(stderr, "serf: rock: invalid number '%s'\r\n", argv[4]);
@ -1062,7 +1096,7 @@ _cw_serf_commence(c3_i argc, c3_c* argv[])
//
{
u3V.dir_c = strdup(dir_c);
u3V.sen_d = u3V.dun_d = u3m_boot(dir_c);
u3V.sen_d = u3V.dun_d = u3m_boot(dir_c, (size_t)1 << lom_w);
if ( eve_d ) {
// XX need not be fatal, need a u3m_reboot equivalent
@ -1152,6 +1186,117 @@ _cw_dock(c3_i argc, c3_c* argv[])
u3_king_dock(U3_VERE_PACE);
}
/* _cw_eval_get_input(): read file til EOF and return a malloc'd string
*/
c3_c*
_cw_eval_get_input(FILE* fil_u, size_t siz_i)
{
c3_i car_i;
size_t len_i = 0;
c3_c* str_c = c3_realloc(NULL, siz_i);//size is start size
while( EOF != (car_i = fgetc(fil_u)) ){
str_c[len_i++] = car_i;
if( len_i == siz_i ){
siz_i += 16;
str_c = c3_realloc(str_c, siz_i);
}
}
str_c[len_i++]='\0';
return c3_realloc(str_c, len_i);
}
/* _cw_eval(): initialize and run the hoon evaluator
*/
static void
_cw_eval(c3_i argc, c3_c* argv[])
{
c3_i ch_i, lid_i;
c3_w arg_w;
static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}
// argv[optind] is always "eval"
//
if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}
c3_c* evl_c = _cw_eval_get_input(stdin, 10);
// initialize the Loom and load the Ivory Pill
//
{
c3_d len_d = u3_Ivory_pill_len;
c3_y* byt_y = u3_Ivory_pill;
u3_cue_xeno* sil_u;
u3_weak pil;
u3C.wag_w |= u3o_hashless;
u3m_boot_lite((size_t)1 << u3_Host.ops_u.lom_y);
sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28);
if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) {
printf("lite: unable to cue ivory pill\r\n");
exit(1);
}
u3s_cue_xeno_done(sil_u);
if ( c3n == u3v_boot_lite(pil) ) {
u3l_log("lite: boot failed\r\n");
exit(1);
}
}
printf("eval:\n");
// +wish for an eval gate (virtualized twice for pretty-printing)
//
u3_noun gat = u3v_wish("|=(a=@t (sell (slap !>(+>.$) (rain /eval a))))");
u3_noun res;
{
u3_noun sam = u3i_string(evl_c);
u3_noun cor = u3nc(u3k(u3h(gat)), u3nc(sam, u3k(u3t(u3t(gat)))));
res = u3m_soft(0, u3n_kick_on, cor);
}
if ( 0 == u3h(res) ) { // successful execution, print output
u3_pier_tank(0, 0, u3k(u3t(res)));
}
else { // error, print stack trace
u3_pier_punt_goof("eval", u3k(res));
}
u3z(res);
u3z(gat);
free(evl_c);
}
/* _cw_info(): print pier info
*/
static void
@ -1175,7 +1320,7 @@ _cw_info(c3_i argc, c3_c* argv[])
} break;
}
c3_d eve_d = u3m_boot(u3_Host.dir_c);
c3_d eve_d = u3m_boot(u3_Host.dir_c, u3a_bytes);
u3_disk* log_u = _cw_disk_init(u3_Host.dir_c);
fprintf(stderr, "\r\nurbit: %s at event %" PRIu64 "\r\n",
@ -1212,7 +1357,7 @@ _cw_grab(c3_i argc, c3_c* argv[])
} break;
}
u3m_boot(u3_Host.dir_c);
u3m_boot(u3_Host.dir_c, u3a_bytes);
u3C.wag_w |= u3o_hashless;
u3_serf_grab();
u3m_stop();
@ -1223,25 +1368,56 @@ _cw_grab(c3_i argc, c3_c* argv[])
static void
_cw_cram(c3_i argc, c3_c* argv[])
{
switch ( argc ) {
case 2: {
if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) {
fprintf(stderr, "unable to find pier\r\n");
exit (1);
}
} break;
c3_i ch_i, lid_i;
c3_w arg_w;
case 3: {
u3_Host.dir_c = argv[2];
} break;
static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
default: {
fprintf(stderr, "invalid command\r\n");
exit(1);
} break;
u3_Host.dir_c = _main_pier_run(argv[0]);
while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}
c3_d eve_d = u3m_boot(u3_Host.dir_c);
// argv[optind] is always "cram"
//
if ( !u3_Host.dir_c ) {
if ( optind + 1 < argc ) {
u3_Host.dir_c = argv[optind + 1];
}
else {
fprintf(stderr, "invalid command, pier required\r\n");
exit(1);
}
optind++;
}
if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}
c3_d eve_d = u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y);
u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock
c3_o ret_o;
@ -1271,29 +1447,58 @@ _cw_cram(c3_i argc, c3_c* argv[])
static void
_cw_queu(c3_i argc, c3_c* argv[])
{
c3_i ch_i, lid_i;
c3_w arg_w;
static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
u3_Host.dir_c = _main_pier_run(argv[0]);
while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}
// argv[optind] is always "queu"
//
if ( !u3_Host.dir_c ) {
if ( optind + 1 < argc ) {
u3_Host.dir_c = argv[optind + 1];
}
else {
fprintf(stderr, "invalid command, pier required\r\n");
exit(1);
}
optind++;
}
if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}
c3_c* eve_c;
c3_d eve_d;
switch ( argc ) {
case 3: {
if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) {
fprintf(stderr, "unable to find pier\r\n");
exit (1);
}
eve_c = argv[2];
} break;
case 4: {
u3_Host.dir_c = argv[2];
eve_c = argv[3];
} break;
default: {
fprintf(stderr, "invalid command\r\n");
exit(1);
} break;
}
if ( 1 != sscanf(eve_c, "%" PRIu64 "", &eve_d) ) {
fprintf(stderr, "urbit: queu: invalid number '%s'\r\n", eve_c);
exit(1);
@ -1303,7 +1508,7 @@ _cw_queu(c3_i argc, c3_c* argv[])
fprintf(stderr, "urbit: queu: preparing\r\n");
u3m_boot(u3_Host.dir_c);
u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y);
// XX can spuriously fail do to corrupt memory-image checkpoint,
// need a u3m_half_boot equivalent
@ -1327,29 +1532,60 @@ _cw_queu(c3_i argc, c3_c* argv[])
static void
_cw_meld(c3_i argc, c3_c* argv[])
{
switch ( argc ) {
case 2: {
if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) {
fprintf(stderr, "unable to find pier\r\n");
exit (1);
}
} break;
c3_i ch_i, lid_i;
c3_w arg_w;
case 3: {
u3_Host.dir_c = argv[2];
} break;
static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
default: {
fprintf(stderr, "invalid command\r\n");
u3_Host.dir_c = _main_pier_run(argv[0]);
while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}
// argv[optind] is always "meld"
//
if ( !u3_Host.dir_c ) {
if ( optind + 1 < argc ) {
u3_Host.dir_c = argv[optind + 1];
}
else {
fprintf(stderr, "invalid command, pier required\r\n");
exit(1);
} break;
}
optind++;
}
if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}
u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock
c3_w pre_w;
u3C.wag_w |= u3o_hashless;
u3m_boot(u3_Host.dir_c);
u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y);
pre_w = u3a_open(u3R);
u3u_meld();
@ -1369,7 +1605,8 @@ _cw_next(c3_i argc, c3_c* argv[])
c3_w arg_w;
static struct option lop_u[] = {
{ "arch", required_argument, NULL, 'a' },
{ "arch", required_argument, NULL, 'a' },
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
@ -1381,7 +1618,18 @@ _cw_next(c3_i argc, c3_c* argv[])
u3_Host.arc_c = strdup(optarg);
} break;
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
@ -1409,6 +1657,7 @@ _cw_next(c3_i argc, c3_c* argv[])
u3_Host.pep_o = c3y;
u3_Host.nex_o = c3y;
u3_Host.ops_u.tem = c3y;
}
/* _cw_pack(): compact memory, save, and exit.
@ -1416,27 +1665,58 @@ _cw_next(c3_i argc, c3_c* argv[])
static void
_cw_pack(c3_i argc, c3_c* argv[])
{
switch ( argc ) {
case 2: {
if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) {
fprintf(stderr, "unable to find pier\r\n");
exit (1);
}
} break;
c3_i ch_i, lid_i;
c3_w arg_w;
case 3: {
u3_Host.dir_c = argv[2];
} break;
static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
default: {
fprintf(stderr, "invalid command\r\n");
u3_Host.dir_c = _main_pier_run(argv[0]);
while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}
// argv[optind] is always "pack"
//
if ( !u3_Host.dir_c ) {
if ( optind + 1 < argc ) {
u3_Host.dir_c = argv[optind + 1];
}
else {
fprintf(stderr, "invalid command, pier required\r\n");
exit(1);
} break;
}
optind++;
}
if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}
u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock
u3m_boot(u3_Host.dir_c);
u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y);
u3a_print_memory(stderr, "urbit: pack: gained", u3m_pack());
u3e_save();
@ -1449,25 +1729,57 @@ _cw_pack(c3_i argc, c3_c* argv[])
static void
_cw_prep(c3_i argc, c3_c* argv[])
{
switch ( argc ) {
case 2: {
if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) {
fprintf(stderr, "unable to find pier\r\n");
exit (1);
}
} break;
c3_i ch_i, lid_i;
c3_w arg_w;
case 3: {
u3_Host.dir_c = argv[2];
} break;
static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
default: {
fprintf(stderr, "invalid command\r\n");
u3_Host.dir_c = _main_pier_run(argv[0]);
while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}
// argv[optind] is always "prep"
//
if ( !u3_Host.dir_c ) {
if ( optind + 1 < argc ) {
u3_Host.dir_c = argv[optind + 1];
}
else {
fprintf(stderr, "invalid command, pier required\r\n");
exit(1);
} break;
}
optind++;
}
if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}
u3_Host.pep_o = c3y;
u3_Host.ops_u.tem = c3y;
}
/* _cw_vere(): download vere
@ -1484,9 +1796,9 @@ _cw_vere(c3_i argc, c3_c* argv[])
c3_w arg_w;
static struct option lop_u[] = {
{ "arch", required_argument, NULL, 'a' },
{ "pace", required_argument, NULL, 'p' },
{ "version", required_argument, NULL, 'v' },
{ "arch", required_argument, NULL, 'a' },
{ "pace", required_argument, NULL, 'p' },
{ "version", required_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
};
@ -1583,6 +1895,100 @@ _cw_vere(c3_i argc, c3_c* argv[])
u3l_log("vere: download succeeded\r\n");
}
/* _cw_vile(): generatoe/print keyfile
*/
static void
_cw_vile(c3_i argc, c3_c* argv[])
{
c3_i ch_i, lid_i;
c3_w arg_w;
static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ NULL, 0, NULL, 0 }
};
u3_Host.dir_c = _main_pier_run(argv[0]);
while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
c3_w lom_w;
c3_o res_o = _main_readw(optarg, u3a_bits + 3, &lom_w);
if ( (c3n == res_o) || (lom_w < 20) ) {
fprintf(stderr, "error: --loom must be >= 20 and <= %u\r\n", u3a_bits + 2);
exit(1);
}
u3_Host.ops_u.lom_y = lom_w;
} break;
case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}
// argv[optind] is always "vile"
//
if ( !u3_Host.dir_c ) {
if ( optind + 1 < argc ) {
u3_Host.dir_c = argv[optind + 1];
}
else {
fprintf(stderr, "invalid command, pier required\r\n");
exit(1);
}
optind++;
}
if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}
// XX check if snapshot is stale?
//
c3_d eve_d = u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y);
u3_noun sam = u3nc(u3nc(u3_nul, u3_nul),
u3nc(c3n, u3nq(c3__once, 'j', c3__vile, u3_nul)));
u3_noun res = u3v_soft_peek(0, sam);
switch ( u3h(res) ) {
default: c3_assert(0);
case c3n: {
fprintf(stderr, "vile: unable to retrieve key file\r\n");
u3_pier_punt_goof("foo", u3k(u3t(res)));
}
case c3y: {
u3_noun dat, vil, out;
c3_c* out_c;
if ( (u3_nul != u3h(u3t(res)))
|| (c3n == u3r_pq(u3t(u3t(res)), c3__omen, 0, &dat))
|| (c3n == u3r_p(dat, c3__atom, &vil))
|| (c3n == u3a_is_atom(vil)) )
{
fprintf(stderr, "vile: unable to extract key file\r\n");
u3m_p("vil", res);
}
else {
out = u3dc("scot", c3__uw, u3k(vil));
out_c = u3r_string(out);
puts(out_c);
c3_free(out_c);
u3z(out);
}
}
}
u3z(res);
}
/* _cw_utils(): "worker" utilities and "serf" entrypoint
*/
static c3_i
@ -1601,9 +2007,12 @@ _cw_utils(c3_i argc, c3_c* argv[])
// [%prep dir=@t] :: prep upgrade
// [%queu dir=@t eve=@ud] :: cue state
// [?(%vere %fetch-vere) dir=@t] :: download vere
// [%vile dir=@t] :: extract keys
// :: :: ipc:
// [%serf dir=@t key=@t wag=@t hap=@ud eve=@ud] :: compute
// ==
// $: %serf :: compute
// dir=@t key=@t wag=@t hap=@ud ::
// lom=@ud eve=@ud ::
// == == ::
//
// NB: don't print to anything other than stderr;
// other streams may be used for ipc.
@ -1626,6 +2035,7 @@ _cw_utils(c3_i argc, c3_c* argv[])
switch ( mot_m ) {
case c3__cram: _cw_cram(argc, argv); return 1;
case c3__dock: _cw_dock(argc, argv); return 1;
case c3__eval: _cw_eval(argc, argv); return 1;
case c3__mass:
case c3__grab: _cw_grab(argc, argv); return 1;
@ -1637,6 +2047,7 @@ _cw_utils(c3_i argc, c3_c* argv[])
case c3__prep: _cw_prep(argc, argv); return 2; // continue on
case c3__queu: _cw_queu(argc, argv); return 1;
case c3__vere: _cw_vere(argc, argv); return 1;
case c3__vile: _cw_vile(argc, argv); return 1;
case c3__serf: _cw_serf_commence(argc, argv); return 1;
}
@ -1828,7 +2239,7 @@ main(c3_i argc,
// starting u3m configures OpenSSL memory functions, so we must do it
// before any OpenSSL allocations
//
u3m_boot_lite();
u3m_boot_lite((size_t)1 << u3_Host.ops_u.lut_y);
// Initialize OpenSSL for client and server
//

View File

@ -387,6 +387,7 @@
# define c3__ergo c3_s4('e','r','g','o')
# define c3__esh c3_s3('e','s','h')
# define c3__etch c3_s4('e','t','c','h')
# define c3__eval c3_s4('e','v','a','l')
# define c3__evil c3_s4('e','v','i','l')
# define c3__ex c3_s2('e','x')
# define c3__exit c3_s4('e','x','i','t')
@ -698,6 +699,7 @@
# define c3__lond c3_s4('l','o','n','d')
# define c3__lonk c3_s4('l','o','n','k')
# define c3__look c3_s4('l','o','o','k')
# define c3__loom c3_s4('l','o','o','m')
# define c3__loop c3_s4('l','o','o','p')
# define c3__lorb c3_s4('l','o','r','b')
# define c3__lord c3_s4('l','o','r','d')
@ -1239,6 +1241,7 @@
# define c3__vern c3_s4('v','e','r','n')
# define c3__very c3_s4('v','e','r','y')
# define c3__view c3_s4('v','i','e','w')
# define c3__vile c3_s4('v','i','l', 'e')
# define c3__vint c3_s4('v','i','n','t')
# define c3__void c3_s4('v','o','i','d')
# define c3__vorp c3_s4('v','o','r','p')
@ -1296,6 +1299,7 @@
# define c3__wtts c3_s4('w','t','t','s')
# define c3__wtzp c3_s4('w','t','z','p')
# define c3__wyrd c3_s4('w','y','r','d')
# define c3__xray c3_s4('x','r','a','y')
# define c3__yell c3_s4('y','e','l','l')
# define c3__yelp c3_s4('y','e','l','p')
# define c3__z c3_s1('z')

View File

@ -157,24 +157,24 @@
# else
# define U3_OS_LoomBase 0x36000000
# endif
# define U3_OS_LoomBits 29
# define U3_OS_LoomBits 30
# elif defined(U3_OS_mingw)
# define U3_OS_LoomBase 0x28000000000
# define U3_OS_LoomBits 29
# define U3_OS_LoomBits 30
# elif defined(U3_OS_osx)
# ifdef __LP64__
# define U3_OS_LoomBase 0x28000000000
# else
# define U3_OS_LoomBase 0x4000000
# endif
# define U3_OS_LoomBits 29
# define U3_OS_LoomBits 30
# elif defined(U3_OS_bsd)
# ifdef __LP64__
# define U3_OS_LoomBase 0x200000000
# else
# define U3_OS_LoomBase 0x4000000
# endif
# define U3_OS_LoomBits 29
# define U3_OS_LoomBits 30
# else
# error "port: LoomBase"
# endif

View File

@ -1,8 +1,6 @@
#ifndef U3_ALLOCATE_H
#define U3_ALLOCATE_H
#include <openssl/opensslv.h>
#include "manage.h"
/** Constants.
@ -15,15 +13,15 @@
*/
# define u3a_page 12
/* u3a_pages: number of pages in memory.
/* u3a_pages: maximum number of pages in memory.
*/
# define u3a_pages (1 << (u3a_bits - u3a_page))
/* u3a_words: number of words in memory.
/* u3a_words: maximum number of words in memory.
*/
# define u3a_words (1 << u3a_bits)
/* u3a_bytes: number of bytes in memory.
/* u3a_bytes: maximum number of bytes in memory.
*/
# define u3a_bytes (sizeof(c3_w) * u3a_words)
@ -477,15 +475,6 @@
void*
u3a_malloc(size_t len_i);
/* u3a_malloc_ssl(): openssl-shaped malloc
*/
void*
u3a_malloc_ssl(size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
);
/* u3a_calloc(): aligned storage measured in bytes.
*/
void*
@ -496,39 +485,11 @@
void*
u3a_realloc(void* lag_v, size_t len_i);
/* u3a_realloc2(): gmp-shaped realloc.
*/
void*
u3a_realloc2(void* lag_v, size_t old_i, size_t new_i);
/* u3a_realloc_ssl(): openssl-shaped realloc.
*/
void*
u3a_realloc_ssl(void* lag_v, size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
);
/* u3a_free(): free for aligned malloc.
*/
void
u3a_free(void* tox_v);
/* u3a_free2(): gmp-shaped free.
*/
void
u3a_free2(void* tox_v, size_t siz_i);
/* u3a_free_ssl(): openssl-shaped free.
*/
void
u3a_free_ssl(void* tox_v
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
);
/* Reference and arena control.
*/
/* u3a_gain(): gain a reference count in normal space.

View File

@ -41,6 +41,7 @@
typedef struct _u3e_pool {
c3_c* dir_c; // path to
c3_w dit_w[u3a_pages >> 5]; // touched since last save
c3_w pag_w; // number of pages (<= u3a_pages)
u3e_image nor_u; // north segment
u3e_image sou_u; // south segment
} u3e_pool;

View File

@ -6,12 +6,12 @@
/* u3m_boot(): start the u3 system. return next event, starting from 1.
*/
c3_d
u3m_boot(c3_c* dir_c);
u3m_boot(c3_c* dir_c, size_t len_i);
/* u3m_boot_lite(): start without checkpointing.
*/
c3_d
u3m_boot_lite(void);
u3m_boot_lite(size_t len_i);
/* u3m_stop(): graceful shutdown cleanup. */
void
@ -37,7 +37,7 @@
/* u3m_init(): start the environment.
*/
void
u3m_init();
u3m_init(size_t len_i);
/* u3m_pave(): instantiate or activate image.
*/

View File

@ -9,6 +9,7 @@
u3_noun who; // single identity
c3_c* dir_c; // execution directory (pier)
c3_w wag_w; // flags (both ways)
size_t wor_i; // loom word-length (<= u3a_words)
void (*stderr_log_f)(c3_c*); // errors from c code
void (*slog_f)(u3_noun); // function pointer for slog
void (*sign_hold_f)(void); // suspend system signal regime

View File

@ -304,6 +304,7 @@
** (1 << a_y).
**
** For example, (a_y == 3) returns the size in bytes.
** NB: (a_y) must be < 37.
*/
c3_w
u3r_met(c3_y a_y,
@ -362,18 +363,50 @@
u3r_bytes_all(c3_w* len_w,
u3_atom a);
/* u3r_chop_bits():
**
** XOR `wid_d` bits from`src_w` at `bif_g` to `dst_w` at `bif_g`
**
** NB: [dst_w] must have space for [bit_g + wid_d] bits
*/
void
u3r_chop_bits(c3_g bif_g,
c3_d wid_d,
c3_g bit_g,
c3_w* dst_w,
const c3_w* src_w);
/* u3r_chop_words():
**
** Into the bloq space of `met`, from position `fum` for a
** span of `wid`, to position `tou`, XOR from `src_w`
** into `dst_w`.
**
** NB: [dst_w] must have space for [tou_w + wid_w] bloqs
*/
void
u3r_chop_words(c3_g met_g,
c3_w fum_w,
c3_w wid_w,
c3_w tou_w,
c3_w* dst_w,
c3_w len_w,
const c3_w* src_w);
/* u3r_chop():
**
** Into the bloq space of `met`, from position `fum` for a
** span of `wid`, to position `tou`, XOR from atom `src`
** into ray `dst`.
** into `dst_w`.
**
** NB: [dst_w] must have space for [tou_w + wid_w] bloqs
*/
void
u3r_chop(c3_g met_g,
c3_w fum_w,
c3_w wid_w,
c3_w tou_w,
c3_w* dst_w,
u3r_chop(c3_g met_g,
c3_w fum_w,
c3_w wid_w,
c3_w tou_w,
c3_w* dst_w,
u3_atom src);
/* u3r_mp():

View File

@ -77,6 +77,11 @@
u3_noun
u3v_peek(u3_noun hap);
/* u3v_soft_peek(): softly query the reck namespace.
*/
u3_noun
u3v_soft_peek(c3_w mil_w, u3_noun sam);
/* u3v_poke(): insert and apply an input ovum (protected).
*/
u3_noun

View File

@ -291,6 +291,8 @@
c3_c* key_c; // -k, private key file
c3_o net; // -L, local-only networking
c3_o lit; // -l, lite mode
c3_y lom_y; // loom bex
c3_y lut_y; // urth-loom bex
c3_c* til_c; // -n, play till eve_d
c3_o pro; // -P, profile
c3_s per_s; // http port

View File

@ -692,18 +692,6 @@ u3a_malloc(size_t len_i)
return out_w;
}
/* u3a_malloc_ssl(): openssl-shaped malloc
*/
void*
u3a_malloc_ssl(size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_malloc(len_i);
}
/* u3a_cellblock(): allocate a block of cells on the hat.
*/
static c3_o
@ -885,26 +873,6 @@ u3a_realloc(void* lag_v, size_t len_i)
return u3a_wealloc(lag_v, (len_w + 3) >> 2);
}
/* u3a_realloc2(): gmp-shaped realloc.
*/
void*
u3a_realloc2(void* lag_v, size_t old_i, size_t new_i)
{
return u3a_realloc(lag_v, new_i);
}
/* u3a_realloc_ssl(): openssl-shaped realloc.
*/
void*
u3a_realloc_ssl(void* lag_v, size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_realloc(lag_v, len_i);
}
/* u3a_free(): free for aligned malloc.
*/
void
@ -921,26 +889,6 @@ u3a_free(void* tox_v)
u3a_wfree(org_w);
}
/* u3a_free2(): gmp-shaped free.
*/
void
u3a_free2(void* tox_v, size_t siz_i)
{
return u3a_free(tox_v);
}
/* u3a_free_ssl(): openssl-shaped free.
*/
void
u3a_free_ssl(void* tox_v
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_free(tox_v);
}
/* _me_wash_north(): clean up mug slots after copy.
*/
static void _me_wash_north(u3_noun dog);

View File

@ -136,9 +136,9 @@ u3e_check(c3_c* cap_c)
sum_w += mug_w;
}
for ( i_w = 0; i_w < sou_w; i_w++ ) {
mug_w = _ce_check_page((u3a_pages - (i_w + 1)));
mug_w = _ce_check_page((u3P.pag_w - (i_w + 1)));
if ( strcmp(cap_c, "boot") ) {
c3_assert(mug_w == u3K.mug_w[(u3a_pages - (i_w + 1))]);
c3_assert(mug_w == u3K.mug_w[(u3P.pag_w - (i_w + 1))]);
}
sum_w += mug_w;
}
@ -195,7 +195,7 @@ _ce_center_guard_page(void)
{
u3p(c3_w) bot_p, top_p;
if ( !u3R ) {
top_p = u3a_outa(u3_Loom + u3a_words);
top_p = u3a_outa(u3_Loom + u3C.wor_i);
bot_p = u3a_outa(u3_Loom);
}
else if ( c3y == u3a_is_north(u3R) ) {
@ -256,9 +256,9 @@ u3e_fault(void* adr_v, c3_i ser_i)
c3_w* adr_w = (c3_w*) adr_v;
if ( (adr_w < u3_Loom) || (adr_w >= (u3_Loom + u3a_words)) ) {
if ( (adr_w < u3_Loom) || (adr_w >= (u3_Loom + u3C.wor_i)) ) {
fprintf(stderr, "address %p out of loom!\r\n", adr_w);
fprintf(stderr, "loom: [%p : %p)\r\n", u3_Loom, u3_Loom + u3a_words);
fprintf(stderr, "loom: [%p : %p)\r\n", u3_Loom, u3_Loom + u3C.wor_i);
c3_assert(0);
return 0;
}
@ -668,7 +668,7 @@ _ce_patch_compose(void)
pgs_w = _ce_patch_count_page(i_w, pgs_w);
}
for ( i_w = 0; i_w < sou_w; i_w++ ) {
pgs_w = _ce_patch_count_page((u3a_pages - (i_w + 1)), pgs_w);
pgs_w = _ce_patch_count_page((u3P.pag_w - (i_w + 1)), pgs_w);
}
}
@ -688,7 +688,7 @@ _ce_patch_compose(void)
pgc_w = _ce_patch_save_page(pat_u, i_w, pgc_w);
}
for ( i_w = 0; i_w < sou_w; i_w++ ) {
pgc_w = _ce_patch_save_page(pat_u, (u3a_pages - (i_w + 1)), pgc_w);
pgc_w = _ce_patch_save_page(pat_u, (u3P.pag_w - (i_w + 1)), pgc_w);
}
pat_u->con_u->nor_w = nor_w;
@ -738,7 +738,7 @@ _ce_image_resize(u3e_image* img_u, c3_w pgs_w)
{
if ( img_u->pgs_w > pgs_w ) {
if ( ftruncate(img_u->fid_i, pgs_w << (u3a_page + 2)) ) {
fprintf(stderr, "loom: image truncate %s: %s\r\n",
fprintf(stderr, "loom: image (%s) truncate: %s\r\n",
img_u->nam_c,
strerror(errno));
c3_assert(0);
@ -785,7 +785,7 @@ _ce_patch_apply(u3_ce_patch* pat_u)
}
else {
fid_i = u3P.sou_u.fid_i;
off_w = (u3a_pages - (pag_w + 1));
off_w = (u3P.pag_w - (pag_w + 1));
}
if ( pag_siz_i != (ret_i = read(pat_u->mem_i, mem_w, pag_siz_i)) ) {
@ -836,18 +836,20 @@ _ce_image_blit(u3e_image* img_u,
c3_w siz_w = pag_siz_i;
if ( -1 == lseek(img_u->fid_i, 0, SEEK_SET) ) {
fprintf(stderr, "loom: image blit seek 0: %s\r\n", strerror(errno));
fprintf(stderr, "loom: image (%s) blit seek 0: %s\r\n",
img_u->nam_c, strerror(errno));
c3_assert(0);
}
for ( i_w = 0; i_w < img_u->pgs_w; i_w++ ) {
if ( siz_w != (ret_i = read(img_u->fid_i, ptr_w, siz_w)) ) {
if ( 0 < ret_i ) {
fprintf(stderr, "loom: image blit partial read: %zu\r\n",
(size_t)ret_i);
fprintf(stderr, "loom: image (%s) blit partial read: %zu\r\n",
img_u->nam_c, (size_t)ret_i);
}
else {
fprintf(stderr, "loom: image blit read: %s\r\n", strerror(errno));
fprintf(stderr, "loom: image (%s) blit read: %s\r\n",
img_u->nam_c, strerror(errno));
}
c3_assert(0);
}
@ -888,10 +890,12 @@ _ce_image_fine(u3e_image* img_u,
if ( pag_siz_i != (ret_i = read(img_u->fid_i, buf_w, pag_siz_i)) ) {
if ( 0 < ret_i ) {
fprintf(stderr, "loom: image fine partial read: %zu\r\n", (size_t)ret_i);
fprintf(stderr, "loom: image (%s) fine partial read: %zu\r\n",
img_u->nam_c, (size_t)ret_i);
}
else {
fprintf(stderr, "loom: image fine read: %s\r\n", strerror(errno));
fprintf(stderr, "loom: image (%s) fine read: %s\r\n",
img_u->nam_c, strerror(errno));
}
c3_assert(0);
}
@ -901,11 +905,13 @@ _ce_image_fine(u3e_image* img_u,
if ( mem_w != fil_w ) {
c3_w pag_w = (ptr_w - u3_Loom) >> u3a_page;
fprintf(stderr, "mismatch: page %d, mem_w %x, fil_w %x, K %x\r\n",
pag_w,
mem_w,
fil_w,
u3K.mug_w[pag_w]);
fprintf(stderr, "loom: image (%s) mismatch: "
"page %d, mem_w %x, fil_w %x, K %x\r\n",
img_u->nam_c,
pag_w,
mem_w,
fil_w,
u3K.mug_w[pag_w]);
abort();
}
ptr_w += stp_ws;
@ -930,7 +936,9 @@ _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u)
if ( (-1 == lseek(fom_u->fid_i, 0, SEEK_SET))
|| (-1 == lseek(tou_u->fid_i, 0, SEEK_SET)) )
{
fprintf(stderr, "loom: image copy seek 0: %s\r\n", strerror(errno));
fprintf(stderr, "loom: image (%s) copy seek: %s\r\n",
fom_u->nam_c,
strerror(errno));
return c3n;
}
@ -942,26 +950,29 @@ _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u)
if ( pag_siz_i != (ret_i = read(fom_u->fid_i, mem_w, pag_siz_i)) ) {
if ( 0 < ret_i ) {
fprintf(stderr, "loom: image copy partial read: %zu\r\n",
(size_t)ret_i);
fprintf(stderr, "loom: image (%s) copy partial read: %zu\r\n",
fom_u->nam_c, (size_t)ret_i);
}
else {
fprintf(stderr, "loom: image copy read: %s\r\n", strerror(errno));
fprintf(stderr, "loom: image (%s) copy read: %s\r\n",
fom_u->nam_c, strerror(errno));
}
return c3n;
}
else {
if ( -1 == lseek(tou_u->fid_i, (off_w << (u3a_page + 2)), SEEK_SET) ) {
fprintf(stderr, "loom: image copy seek: %s\r\n", strerror(errno));
fprintf(stderr, "loom: image (%s) copy seek: %s\r\n",
tou_u->nam_c, strerror(errno));
return c3n;
}
if ( pag_siz_i != (ret_i = write(tou_u->fid_i, mem_w, pag_siz_i)) ) {
if ( 0 < ret_i ) {
fprintf(stderr, "loom: image copy partial write: %zu\r\n",
(size_t)ret_i);
fprintf(stderr, "loom: image (%s) copy partial write: %zu\r\n",
tou_u->nam_c, (size_t)ret_i);
}
else {
fprintf(stderr, "loom: image copy write: %s\r\n", strerror(errno));
fprintf(stderr, "loom: image (%s) copy write: %s\r\n",
tou_u->nam_c, strerror(errno));
}
return c3n;
}
@ -1069,7 +1080,7 @@ u3e_save(void)
pag_wiz_i);
_ce_image_fine(&u3P.sou_u,
(u3_Loom + (1 << u3a_bits) - pag_wiz_i),
(u3_Loom + u3C.wor_i) - pag_wiz_i,
-(ssize_t)pag_wiz_i);
c3_assert(u3P.nor_u.pgs_w == u3K.nor_w);
@ -1105,6 +1116,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
u3P.dir_c = dir_c;
u3P.nor_u.nam_c = "north";
u3P.sou_u.nam_c = "south";
u3P.pag_w = u3C.wor_i >> u3a_page;
// XX review dryrun requirements, enable or remove
//
@ -1154,7 +1166,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
pag_wiz_i);
_ce_image_blit(&u3P.sou_u,
(u3_Loom + (1 << u3a_bits) - pag_wiz_i),
(u3_Loom + u3C.wor_i) - pag_wiz_i,
-(ssize_t)pag_wiz_i);
u3l_log("boot: protected loom\r\n");
@ -1181,9 +1193,12 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
c3_o
u3e_yolo(void)
{
// NB: u3e_save() will reinstate protection flags
// NB: u3e_save() will reinstate protection flags
//
if ( 0 != mprotect((void *)u3_Loom, u3a_bytes, (PROT_READ | PROT_WRITE)) ) {
if ( 0 != mprotect((void *)u3_Loom,
u3C.wor_i << 2,
(PROT_READ | PROT_WRITE)) )
{
// XX confirm recoverable errors
//
fprintf(stderr, "loom: yolo: %s\r\n", strerror(errno));
@ -1212,6 +1227,8 @@ u3e_foul(void)
void
u3e_init(void)
{
u3P.pag_w = u3C.wor_i >> u3a_page;
#ifdef U3_GUARD_PAGE
_ce_center_guard_page();
#endif

View File

@ -553,7 +553,7 @@ _pave_home(void)
{
c3_w* mem_w = u3_Loom + 1;
c3_w siz_w = c3_wiseof(u3v_home);
c3_w len_w = u3a_words - 1;
c3_w len_w = u3C.wor_i - 1;
u3H = (void *)_pave_north(mem_w, siz_w, len_w);
u3H->ver_w = u3v_version;
@ -574,7 +574,7 @@ _find_home(void)
//
c3_w* mem_w = u3_Loom + 1;
c3_w siz_w = c3_wiseof(u3v_home);
c3_w len_w = u3a_words - 1;
c3_w len_w = u3C.wor_i - 1;
{
c3_w ver_w = *((mem_w + len_w) - 1);
@ -594,7 +594,7 @@ _find_home(void)
// this looks risky, but there are no legitimate scenarios
// where it's wrong
//
u3R->cap_p = u3R->mat_p = u3a_words - c3_wiseof(*u3H);
u3R->cap_p = u3R->mat_p = u3C.wor_i - c3_wiseof(*u3H);
}
/* u3m_pave(): instantiate or activate image.
@ -695,22 +695,27 @@ u3m_bail(u3_noun how)
abort();
}
/* Printf some metadata.
*/
if ( c3__exit != how && (_(u3ud(how)) || 1 != u3h(how)) ) {
if ( _(u3ud(how)) ) {
c3_c str_c[5];
// printf some metadata
//
switch ( how ) {
case c3__evil:
case c3__exit: break;
str_c[0] = ((how >> 0) & 0xff);
str_c[1] = ((how >> 8) & 0xff);
str_c[2] = ((how >> 16) & 0xff);
str_c[3] = ((how >> 24) & 0xff);
str_c[4] = 0;
fprintf(stderr, "\r\nbail: %s\r\n", str_c);
}
else {
c3_assert(_(u3ud(u3h(how))));
fprintf(stderr, "\r\nbail: %d\r\n", u3h(how));
default: {
if ( _(u3ud(how)) ) {
c3_c str_c[5];
str_c[0] = ((how >> 0) & 0xff);
str_c[1] = ((how >> 8) & 0xff);
str_c[2] = ((how >> 16) & 0xff);
str_c[3] = ((how >> 24) & 0xff);
str_c[4] = 0;
fprintf(stderr, "\r\nbail: %s\r\n", str_c);
}
else if ( 1 != u3h(how) ) {
c3_assert(_(u3ud(u3h(how))));
fprintf(stderr, "\r\nbail: %d\r\n", u3h(how));
}
}
}
@ -1720,16 +1725,53 @@ _cm_signals(void)
# endif
}
extern void u3je_secp_init(void);
extern void u3je_secp_stop(void);
/* _cm_malloc_ssl(): openssl-shaped malloc
*/
static void*
_cm_malloc_ssl(size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_malloc(len_i);
}
/* _cm_realloc_ssl(): openssl-shaped realloc.
*/
static void*
_cm_realloc_ssl(void* lag_v, size_t len_i
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_realloc(lag_v, len_i);
}
/* _cm_free_ssl(): openssl-shaped free.
*/
static void
_cm_free_ssl(void* tox_v
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
, const char* file, int line
#endif
)
{
return u3a_free(tox_v);
}
extern void u3je_secp_init(void);
/* _cm_crypto(): initialize openssl and crypto jets.
*/
static void
_cm_crypto()
{
/* Initialize OpenSSL with loom allocation functions. */
if ( 0 == CRYPTO_set_mem_functions(&u3a_malloc_ssl,
&u3a_realloc_ssl,
&u3a_free_ssl) ) {
if ( 0 == CRYPTO_set_mem_functions(&_cm_malloc_ssl,
&_cm_realloc_ssl,
&_cm_free_ssl) ) {
u3l_log("%s\r\n", "openssl initialization failed");
abort();
}
@ -1737,53 +1779,81 @@ _cm_crypto()
u3je_secp_init();
}
/* _cm_realloc2(): gmp-shaped realloc.
*/
static void*
_cm_realloc2(void* lag_v, size_t old_i, size_t new_i)
{
return u3a_realloc(lag_v, new_i);
}
/* _cm_free2(): gmp-shaped free.
*/
static void
_cm_free2(void* tox_v, size_t siz_i)
{
return u3a_free(tox_v);
}
/* u3m_init(): start the environment.
*/
void
u3m_init(void)
u3m_init(size_t len_i)
{
_cm_limits();
_cm_signals();
_cm_crypto();
/* Make sure GMP uses our malloc.
*/
mp_set_memory_functions(u3a_malloc, u3a_realloc2, u3a_free2);
// make sure GMP uses our malloc.
//
mp_set_memory_functions(u3a_malloc, _cm_realloc2, _cm_free2);
/* Map at fixed address.
*/
// make sure that [len_i] is a fully-addressible non-zero power of two.
//
if ( !len_i
|| (len_i & (len_i - 1))
|| (len_i < (1 << (u3a_page + 2)))
|| (len_i > u3a_bytes) )
{
c3_w len_w = u3a_bytes;
void* map_v;
u3l_log("loom: bad size: %zu\r\n", len_i);
exit(1);
}
map_v = mmap((void *)u3_Loom,
len_w,
(PROT_READ | PROT_WRITE),
(MAP_ANON | MAP_FIXED | MAP_PRIVATE),
-1, 0);
// map at fixed address.
//
{
void* map_v = mmap((void *)u3_Loom,
len_i,
(PROT_READ | PROT_WRITE),
(MAP_ANON | MAP_FIXED | MAP_PRIVATE),
-1, 0);
if ( -1 == (c3_ps)map_v ) {
void* dyn_v = mmap((void *)0,
len_w,
PROT_READ,
MAP_ANON | MAP_PRIVATE,
-1, 0);
map_v = mmap((void *)0,
len_i,
(PROT_READ | PROT_WRITE),
(MAP_ANON | MAP_PRIVATE),
-1, 0);
u3l_log("boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
u3l_log("boot: mapping %zuMB failed\r\n", len_i >> 20);
u3l_log("see urbit.org/using/install/#about-swap-space"
" for adding swap space\r\n");
if ( -1 != (c3_ps)dyn_v ) {
if ( -1 != (c3_ps)map_v ) {
u3l_log("if porting to a new platform, try U3_OS_LoomBase %p\r\n",
dyn_v);
map_v);
}
exit(1);
}
u3l_log("loom: mapped %dMB\r\n", len_w >> 20);
u3C.wor_i = len_i >> 2;
u3l_log("loom: mapped %zuMB\r\n", len_i >> 20);
}
}
/* u3m_stop(): graceful shutdown cleanup. */
extern void u3je_secp_stop(void);
/* u3m_stop(): graceful shutdown cleanup.
*/
void
u3m_stop()
{
@ -1793,13 +1863,13 @@ u3m_stop()
/* u3m_boot(): start the u3 system. return next event, starting from 1.
*/
c3_d
u3m_boot(c3_c* dir_c)
u3m_boot(c3_c* dir_c, size_t len_i)
{
c3_o nuu_o;
/* Activate the loom.
*/
u3m_init();
u3m_init(len_i);
/* Activate the storage system.
*/
@ -1832,7 +1902,6 @@ u3m_boot(c3_c* dir_c)
if ( c3n == nuu_o ) {
u3j_ream();
u3n_ream();
return u3A->eve_d;
}
else {
@ -1846,11 +1915,11 @@ u3m_boot(c3_c* dir_c)
/* u3m_boot_lite(): start without checkpointing.
*/
c3_d
u3m_boot_lite(void)
u3m_boot_lite(size_t len_i)
{
/* Activate the loom.
*/
u3m_init();
u3m_init(len_i);
/* Activate tracing.
*/

View File

@ -388,102 +388,107 @@ _n_nock_on(u3_noun bus, u3_noun fol)
// the opcode's enum name, string representation, and computed goto into a
// single structure.
#define OPCODES \
/* general purpose */ \
X(HALT, "halt", &&do_halt), /* 0 */ \
X(BAIL, "bail", &&do_bail), /* 1 */ \
/* non-nock bytecodes */ \
X(HALT, "halt", &&do_halt), /* 0: terminator, end of bytcode program */ \
X(BAIL, "bail", &&do_bail), /* 1: deterministic crash */ \
/* stack manipulation */ \
X(COPY, "copy", &&do_copy), /* 2 */ \
X(SWAP, "swap", &&do_swap), /* 3 */ \
X(TOSS, "toss", &&do_toss), /* 4 */ \
X(AUTO, "auto", &&do_auto), /* 5 */ \
X(AULT, "ault", &&do_ault), /* 6 */ \
X(SNOC, "snoc", &&do_snoc), /* 7 */ \
X(SNOL, "snol", &&do_snol), /* 8 */ \
X(HEAD, "head", &&do_head), /* 9 */ \
X(HELD, "held", &&do_held), /* 10 */ \
X(TAIL, "tail", &&do_tail), /* 11 */ \
X(TALL, "tall", &&do_tall), /* 12 */ \
/* fragment (keep) */ \
X(FABK, "fabk", &&do_fabk), /* 13 */ \
X(FASK, "fask", &&do_fask), /* 14 */ \
X(FIBK, "fibk", &&do_fibk), /* 15 */ \
X(FISK, "fisk", &&do_fisk), /* 16 */ \
/* fragment (lose) */ \
X(FABL, "fabl", &&do_fabl), /* 17 */ \
X(FASL, "fasl", &&do_fasl), /* 18 */ \
X(FIBL, "fibl", &&do_fibl), /* 19 */ \
X(FISL, "fisl", &&do_fisl), /* 20 */ \
/* literal (keep) */ \
X(LIT0, "lit0", &&do_lit0), /* 21 */ \
X(LIT1, "lit1", &&do_lit1), /* 22 */ \
X(LITB, "litb", &&do_litb), /* 23 */ \
X(LITS, "lits", &&do_lits), /* 24 */ \
X(LIBK, "libk", &&do_libk), /* 25 */ \
X(LISK, "lisk", &&do_lisk), /* 26 */ \
/* literal (lose) */ \
X(LIL0, "lil0", &&do_lil0), /* 27 */ \
X(LIL1, "lil1", &&do_lil1), /* 28 */ \
X(LILB, "lilb", &&do_lilb), /* 29 */ \
X(LILS, "lils", &&do_lils), /* 30 */ \
X(LIBL, "libl", &&do_libl), /* 31 */ \
X(LISL, "lisl", &&do_lisl), /* 32 */ \
/* nock */ \
/* auto-cons */ \
X(AUTO, "auto", &&do_auto), /* 5: keep */ \
X(AULT, "ault", &&do_ault), /* 6: lose */ \
/* general purposes */ \
X(SNOC, "snoc", &&do_snoc), /* 7: keep */ \
X(SNOL, "snol", &&do_snol), /* 8: lose */ \
/* nock 0: head */ \
X(HEAD, "head", &&do_head), /* 9: keep */ \
X(HELD, "held", &&do_held), /* 10: lose */ \
/* nock 0: tail */ \
X(TAIL, "tail", &&do_tail), /* 11: keep */ \
X(TALL, "tall", &&do_tall), /* 12: lose */ \
/* nock 0: fragment (keep) */ \
X(FABK, "fabk", &&do_fabk), /* 13: c3_y */ \
X(FASK, "fask", &&do_fask), /* 14: c3_s */ \
X(FIBK, "fibk", &&do_fibk), /* 15: c3_y */ \
X(FISK, "fisk", &&do_fisk), /* 16: c3_s */ \
/* nock 0: fragment (lose) */ \
X(FABL, "fabl", &&do_fabl), /* 17: c3_y */ \
X(FASL, "fasl", &&do_fasl), /* 18: c3_s */ \
X(FIBL, "fibl", &&do_fibl), /* 19: c3_y */ \
X(FISL, "fisl", &&do_fisl), /* 20: c3_s */ \
/* nock 1: literal (keep) */ \
X(LIT0, "lit0", &&do_lit0), /* 21: a literal 0 */ \
X(LIT1, "lit1", &&do_lit1), /* 22: a literal 1 */ \
X(LITB, "litb", &&do_litb), /* 23: c3_y */ \
X(LITS, "lits", &&do_lits), /* 24: c3_s */ \
X(LIBK, "libk", &&do_libk), /* 25: c3_y */ \
X(LISK, "lisk", &&do_lisk), /* 26: c3_s */ \
/* nock 1: literal (lose) */ \
X(LIL0, "lil0", &&do_lil0), /* 27: a literal 0 */ \
X(LIL1, "lil1", &&do_lil1), /* 28: a literal 1 */ \
X(LILB, "lilb", &&do_lilb), /* 29: c3_y */ \
X(LILS, "lils", &&do_lils), /* 30: c3_s */ \
X(LIBL, "libl", &&do_libl), /* 31: c3_y */ \
X(LISL, "lisl", &&do_lisl), /* 32: c3_s */ \
/* nock 2: nock (lose) */ \
X(NOLK, "nolk", &&do_nolk), /* 33 */ \
X(NOCT, "noct", &&do_noct), /* 34 */ \
X(NOCK, "nock", &&do_nock), /* 35 */ \
/* 3 & 4 */ \
/* nock 3 & 4 */ \
X(DEEP, "deep", &&do_deep), /* 36 */ \
X(BUMP, "bump", &&do_bump), /* 37 */ \
/* equality */ \
X(SAM0, "sam0", &&do_sam0), /* 38 */ \
X(SAM1, "sam1", &&do_sam1), /* 39 */ \
X(SAMB, "samb", &&do_samb), /* 40 */ \
X(SAMS, "sams", &&do_sams), /* 41 */ \
X(SANB, "sanb", &&do_sanb), /* 42 */ \
X(SANS, "sans", &&do_sans), /* 43 */ \
/* nock 5: equality */ \
X(SAM0, "sam0", &&do_sam0), /* 38: test that it is equal to 0 */ \
X(SAM1, "sam1", &&do_sam1), /* 39: test that it is equal to 1 */ \
X(SAMB, "samb", &&do_samb), /* 40: test equality for vars size c3_b */ \
X(SAMS, "sams", &&do_sams), /* 41: test equality for vars size c3_s */ \
X(SANB, "sanb", &&do_sanb), /* 42: test equality for vars size c3_b */ \
X(SANS, "sans", &&do_sans), /* 43: test equality for vars size c3_s */ \
X(SAME, "same", &&do_same), /* 44 */ \
X(SALM, "salm", &&do_salm), /* 45 */ \
X(SAMC, "samc", &&do_samc), /* 46 */ \
/* unconditional skips */ \
X(SBIP, "sbip", &&do_sbip), /* 47 */ \
X(SIPS, "sips", &&do_sips), /* 48 */ \
X(SWIP, "swip", &&do_swip), /* 49 */ \
/* conditional skips */ \
X(SBIN, "sbin", &&do_sbin), /* 50 */ \
X(SINS, "sins", &&do_sins), /* 51 */ \
X(SWIN, "swin", &&do_swin), /* 52 */ \
/* related to nock 6: unconditional skips */ \
X(SBIP, "sbip", &&do_sbip), /* 47: c3_b */ \
X(SIPS, "sips", &&do_sips), /* 48: c3_s */ \
X(SWIP, "swip", &&do_swip), /* 49: c3_l */ \
/* related to nock 6: conditional skips */ \
X(SBIN, "sbin", &&do_sbin), /* 50: c3_b */ \
X(SINS, "sins", &&do_sins), /* 51: c3_s */ \
X(SWIN, "swin", &&do_swin), /* 52: c3_l */ \
/* nock 9 */ \
X(KICB, "kicb", &&do_kicb), /* 53 */ \
X(KICS, "kics", &&do_kics), /* 54 */ \
X(TICB, "ticb", &&do_ticb), /* 55 */ \
X(TICS, "tics", &&do_tics), /* 56 */ \
/* nock 12 */ \
X(KICB, "kicb", &&do_kicb), /* 53: c3_b */ \
X(KICS, "kics", &&do_kics), /* 54: c3_s */ \
X(TICB, "ticb", &&do_ticb), /* 55: c3_b */ \
X(TICS, "tics", &&do_tics), /* 56: c3_s */ \
/* nock 12: scry (only defined in arvo, not in base nock spec) */ \
X(WILS, "wils", &&do_wils), /* 57 */ \
X(WISH, "wish", &&do_wish), /* 58 */ \
/* hint processing */ \
X(BUSH, "bush", &&do_bush), /* 59 */ \
X(SUSH, "sush", &&do_sush), /* 60 */ \
/* nock 11: hint processing */ \
X(BUSH, "bush", &&do_bush), /* 59: c3_b */ \
X(SUSH, "sush", &&do_sush), /* 60: c3_s */ \
X(DROP, "drop", &&do_drop), /* 61 */ \
X(HECK, "heck", &&do_heck), /* 62 */ \
X(SLOG, "slog", &&do_slog), /* 63 */ \
/* fast (keep) */ \
X(BAST, "bast", &&do_bast), /* 64 */ \
X(SAST, "sast", &&do_sast), /* 65 */ \
/* fast (lose) */ \
X(BALT, "balt", &&do_balt), /* 66 */ \
X(SALT, "salt", &&do_salt), /* 67 */ \
/* memo (keep) */ \
X(SKIB, "skib", &&do_skib), /* 68 */ \
X(SKIS, "skis", &&do_skis), /* 69 */ \
/* memo (lose) */ \
X(SLIB, "slib", &&do_slib), /* 70 */ \
X(SLIS, "slis", &&do_slis), /* 71 */ \
/* nock 11: fast (keep) */ \
X(BAST, "bast", &&do_bast), /* 64: c3_b */ \
X(SAST, "sast", &&do_sast), /* 65: c3_s */ \
/* nock 11: fast (lose) */ \
X(BALT, "balt", &&do_balt), /* 66: c3_b */ \
X(SALT, "salt", &&do_salt), /* 67: c3_s */ \
/* nock 11: memo (keep) */ \
X(SKIB, "skib", &&do_skib), /* 68: c3_b */ \
X(SKIS, "skis", &&do_skis), /* 69: c3_s */ \
/* nock 11: memo (lose) */ \
X(SLIB, "slib", &&do_slib), /* 70: c3_b */ \
X(SLIS, "slis", &&do_slis), /* 71: c3_s */ \
X(SAVE, "save", &&do_save), /* 72 */ \
/* before formula */ \
/* nock 11: before formula */ \
X(HILB, "hilb", &&do_hilb), /* 73: atomic, byte */ \
X(HILS, "hils", &&do_hils), /* 74: atomic, short */ \
X(HINB, "hinb", &&do_hinb), /* 75: arbitrary, byte */ \
X(HINS, "hins", &&do_hins), /* 76: arbitrary, short */ \
/* after formula */ \
/* nock 11: after formula */ \
X(HILK, "hilk", &&do_hilk), /* 77: atomic, keep */ \
X(HILL, "hill", &&do_hill), /* 78: atomic, lose */ \
X(HINK, "hink", &&do_hink), /* 79: arbitrary, keep */ \
@ -495,14 +500,14 @@ _n_nock_on(u3_noun bus, u3_noun fol)
X(KUTT, "kutt", &&do_kutt), /* 84 */ \
X(MUSM, "musm", &&do_musm), /* 85 */ \
X(KUSM, "kusm", &&do_kusm), /* 86 */ \
X(MUTB, "mutb", &&do_mutb), /* 87 */ \
X(MUTS, "muts", &&do_muts), /* 88 */ \
X(MITB, "mitb", &&do_mitb), /* 89 */ \
X(MITS, "mits", &&do_mits), /* 90 */ \
X(KUTB, "kutb", &&do_kutb), /* 91 */ \
X(KUTS, "kuts", &&do_kuts), /* 92 */ \
X(KITB, "kitb", &&do_kitb), /* 93 */ \
X(KITS, "kits", &&do_kits), /* 94 */ \
X(MUTB, "mutb", &&do_mutb), /* 87: c3_b */ \
X(MUTS, "muts", &&do_muts), /* 88: c3_s */ \
X(MITB, "mitb", &&do_mitb), /* 89: c3_b */ \
X(MITS, "mits", &&do_mits), /* 90: c3_s */ \
X(KUTB, "kutb", &&do_kutb), /* 91: c3_b */ \
X(KUTS, "kuts", &&do_kuts), /* 92: c3_s */ \
X(KITB, "kitb", &&do_kitb), /* 93: c3_b */ \
X(KITS, "kits", &&do_kits), /* 94: c3_s */ \
X(LAST, NULL, NULL), /* 95 */
// Opcodes. Define X to select the enum name from OPCODES.
@ -522,6 +527,7 @@ _n_arg(c3_y cod_y)
case SLIB: case SKIB: case KICB: case TICB:
case BUSH: case BAST: case BALT:
case MUTB: case KUTB: case MITB: case KITB:
case HILB: case HINB:
return sizeof(c3_y);
case FASK: case FASL: case FISL: case FISK:
@ -530,6 +536,7 @@ _n_arg(c3_y cod_y)
case SLIS: case SKIS: case KICS: case TICS:
case SUSH: case SAST: case SALT:
case MUTS: case KUTS: case MITS: case KITS:
case HILS: case HINS:
return sizeof(c3_s);
case SWIP: case SWIN:
@ -779,7 +786,7 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip)
if ( c3y == u3ud(op) ) {
switch ( op ) {
default:
buf_y[i_w] = (c3_y) u3h(ops);
buf_y[i_w] = (c3_y) op;
break;
/* registration site index args */
@ -956,12 +963,10 @@ static void _n_print_stack(u3p(u3_noun) empty) {
}
#endif
#ifdef VERBOSE_BYTECODE
// Define X to select the opcode string representation from OPCODES.
# define X(opcode, name, indirect_jump) name
static c3_c* opcode_names[] = { OPCODES };
# undef X
#endif
/* _n_apen(): emit the instructions contained in src to dst
*/
@ -998,6 +1003,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
default: {
return _n_comp(ops, nef, los_o, tel_o);
}
case c3__xray:
case c3__nara:
case c3__hela:
case c3__bout: {
@ -1034,6 +1040,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
++tot_w; _n_emit(ops, TOSS);
tot_w += _n_comp(ops, nef, los_o, tel_o);
} break;
case c3__xray:
case c3__nara:
case c3__hela:
case c3__bout: {
@ -1665,6 +1672,144 @@ u3n_find(u3_noun key, u3_noun fol)
return pog_p;
}
/* _cn_prog_free(): free memory retained by program pog_u
*/
static void
_cn_prog_free(u3n_prog* pog_u)
{
c3_w dex_w;
for (dex_w = 0; dex_w < pog_u->lit_u.len_w; ++dex_w) {
u3z(pog_u->lit_u.non[dex_w]);
}
for (dex_w = 0; dex_w < pog_u->mem_u.len_w; ++dex_w) {
u3z(pog_u->mem_u.sot_u[dex_w].key);
}
for (dex_w = 0; dex_w < pog_u->cal_u.len_w; ++dex_w) {
u3j_site_lose(&(pog_u->cal_u.sit_u[dex_w]));
}
for (dex_w = 0; dex_w < pog_u->reg_u.len_w; ++dex_w) {
u3j_rite_lose(&(pog_u->reg_u.rit_u[dex_w]));
}
u3a_free(pog_u);
}
/* _cn_intlen(): find the number of characters num_w would take to print.
** num_w: an int we want to later serialize to a string
*/
c3_w
_cn_intlen(c3_w num_w)
{
c3_w len_w=0;
while(num_w){
num_w/=10;
len_w++;
}
return len_w;
}
/* _cn_is_indexed(): return true if bop_w is an opcodes that uses pog_u->lit_u.non
** bop_w: opcode (assumed 0-94)
*/
c3_b
_cn_is_indexed(c3_w bop_w)
{
switch (bop_w) {
case FIBK: case FISK:
case FIBL: case FISL:
case LIBK: case LISK:
case LIBL: case LISL:
case BUSH: case SUSH:
case SANB: case SANS:
case KITB: case KITS:
case MITB: case MITS:
case HILB: case HILS:
case HINB: case HINS:
return 1;
default:
return 0;
}
}
/* _cn_pog_to_num(): read a bytecode from the steam and advance the index
** par_w: c3_w: can be 0, 2, 4
** pog_y: c3_y*: a bytecode stream
** ip_w: c3_w: an index into pog
*/
#define _cn_pog_to_num(par_w, pog_y, ip_w) (\
par_w == 4 ? _n_rewo(pog_y, &ip_w): \
par_w == 2 ? _n_resh(pog_y, &ip_w): \
pog_y[ip_w++])
/* _cn_etch_bytecode(): render a nock program as string of bytecodes
** fol: a nock formula to compile and render
** returns: a u3i_string noun of the rendered bytecode
*/
u3_noun
_cn_etch_bytecode(u3_noun fol) {
u3n_prog* pog_u = _n_bite(fol);
c3_y* pog_y = pog_u->byc_u.ops_y;
c3_w len_w = pog_u->byc_u.len_w;
c3_w ip_w=0, num_w=0, bop_w=0, dex_w=0;
c3_w len_c = 1; // opening "{"
// set par_w (parameter flag) to an invalid value,
// so we can break imeadately if needed
c3_w par_w = 5;
// lets count the chars in this string
while ( ip_w < len_w ) {
par_w = _n_arg(pog_y[ip_w]);
bop_w = pog_y[ip_w++]; // move ip_w for reading a opcode name
dex_w = _cn_is_indexed(bop_w); // is this an indexed bytecode argument
len_c += 5; // a leading space, and opcode name
if (par_w > 0) { // if pair: "[bytecode arg]" else "bytecode"
len_c += 3; // "[", space between opcode & arg, "]"
if ( dex_w ) len_c += 2; // 'i:'
len_c += _cn_intlen( // length of the bytecode argument
_cn_pog_to_num(par_w, pog_y, ip_w)
);
}
}
// reset so we can loop again
ip_w=0, num_w=0, bop_w=0, dex_w=0, par_w=5;
// init our string, and give it a trailing null
c3_c str_c[len_c];
str_c[0] = 0;
// lets print this string
while ( ip_w < len_w ) {
par_w = _n_arg(pog_y[ip_w]);
bop_w = pog_y[ip_w++]; // move ip_w for reading a opcode name
dex_w = _cn_is_indexed(bop_w); // is this an indexed bytecode argument
strcat(str_c, " "); // leading space
if (par_w > 0) strcat(str_c, "["); // add "[" if the opcode pairs
strncat(str_c, opcode_names[bop_w], 4); // add the opcode name
if (par_w > 0) { // finish the pair
strcat(str_c, " "); // add the space between byt and arg
if ( dex_w ) strcat(str_c, "i:"); // indexed args are labeled as "index of arg"
num_w = _cn_pog_to_num(par_w, pog_y, ip_w); // the bytecode argument
if (num_w == 0) { //
strcat(str_c, "0"); // handle a literal zero
} //
else { //
c3_w x = 0; //
for (x = _cn_intlen(num_w); x > 0; x--) { //
strcat(str_c, "_"); // prefill the buffer
} //
c3_w f = strlen(str_c)-1; // get the index of the last prefill
while (num_w > 0) { // stringify number in LSB order
str_c[f--] = (num_w%10)+'0'; // .. stringify the tail of num into tail of buf
num_w /= 10; // .. turncate num by one digit
} //
} //
strcat(str_c, "]"); // add the closing brace
}
}
// replace the first leading space and append the last char to the string
str_c[0] = '{';
strcat(str_c, "}");
_cn_prog_free(pog_u);
return u3i_string(str_c);
}
/* _n_hilt_fore(): literal (atomic) dynamic hint, before formula evaluation.
** hin: [hint-atom, formula]. TRANSFER
** bus: subject. RETAIN
@ -1695,6 +1840,11 @@ _n_hilt_fore(u3_noun hin, u3_noun bus, u3_noun* out)
*out = u3_nul;
} break;
case c3__xray : {
u3t_slog(u3nc(0, _cn_etch_bytecode(fol)));
*out = u3_nul;
} break;
default: {
*out = u3_nul;
} break;
@ -1769,6 +1919,16 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu)
*clu = u3_nul;
} break;
case c3__xray : {
u3_noun pri, tan;
if ( c3y == u3r_cell(*clu, &pri, &tan) ) {
c3_l pri_l = c3y == u3a_is_cat(pri) ? pri : 0;
u3t_slog_cap(pri_l, u3k(tan), _cn_etch_bytecode(fol));
}
u3z(*clu);
*clu = u3_nul;
} break;
default: {
u3z(*clu);
*clu = u3_nul;
@ -2646,32 +2806,6 @@ u3n_nock_on(u3_noun bus, u3_noun fol)
return pro;
}
/* _n_prog_free(): free memory retained by program
*/
static void
_n_prog_free(u3n_prog* pog_u)
{
c3_w i_w;
for ( i_w = 0; i_w < pog_u->lit_u.len_w; ++i_w ) {
u3z(pog_u->lit_u.non[i_w]);
}
for ( i_w = 0; i_w < pog_u->mem_u.len_w; ++i_w ) {
u3z(pog_u->mem_u.sot_u[i_w].key);
}
for ( i_w = 0; i_w < pog_u->cal_u.len_w; ++i_w ) {
u3j_site_lose(&(pog_u->cal_u.sit_u[i_w]));
}
for ( i_w = 0; i_w < pog_u->reg_u.len_w; ++i_w ) {
u3j_rite_lose(&(pog_u->reg_u.rit_u[i_w]));
}
u3a_free(pog_u);
}
/* _cn_take_prog_dat(): take references from junior u3n_prog.
*/
static void
@ -2920,7 +3054,7 @@ u3n_rewrite_compact()
static void
_n_feb(u3_noun kev)
{
_n_prog_free(u3to(u3n_prog, u3t(kev)));
_cn_prog_free(u3to(u3n_prog, u3t(kev)));
}
/* u3n_free(): free bytecode cache

View File

@ -1023,10 +1023,11 @@ u3r_hext(u3_noun a,
** (1 << a_y).
**
** For example, (a_y == 3) returns the size in bytes.
** NB: (a_y) must be < 37.
*/
c3_w
u3r_met(c3_y a_y,
u3_atom b)
u3r_met(c3_y a_y,
u3_atom b)
{
c3_assert(u3_none != b);
c3_assert(_(u3a_is_atom(b)));
@ -1061,19 +1062,23 @@ u3r_met(c3_y a_y,
*/
c3_w bif_w, col_w;
if ( gal_w > ((UINT32_MAX - 35) >> 5) ) {
return u3m_bail(c3__fail);
}
col_w = c3_bits_word(daz_w);
bif_w = col_w + (gal_w << 5);
return (bif_w + ((1 << a_y) - 1)) >> a_y;
}
case 3: {
return (gal_w << 2)
+ ((daz_w >> 24) ? 4 : (daz_w >> 16) ? 3 : (daz_w >> 8) ? 2 : 1);
}
case 4: {
return (gal_w << 1)
+ ((daz_w >> 16) ? 2 : 1);
}
STATIC_ASSERT((UINT32_MAX > ((c3_d)u3a_maximum << 2)),
"met overflow");
case 3: return (gal_w << 2) + ((c3_bits_word(daz_w) + 7) >> 3);
case 4: return (gal_w << 1) + ((c3_bits_word(daz_w) + 15) >> 4);
default: {
c3_y gow_y = (a_y - 5);
@ -1448,79 +1453,201 @@ u3r_safe_chub(u3_noun dat, c3_d* out_d)
return c3y;
}
/* u3r_chop_bits():
**
** XOR `wid_d` bits from`src_w` at `bif_g` to `dst_w` at `bif_g`
**
** NB: [dst_w] must have space for [bit_g + wid_d] bits
*/
void
u3r_chop_bits(c3_g bif_g,
c3_d wid_d,
c3_g bit_g,
c3_w* dst_w,
const c3_w* src_w)
{
c3_y fib_y = 32 - bif_g;
c3_y tib_y = 32 - bit_g;
// we need to chop words
//
if ( wid_d >= tib_y ) {
// align *dst_w
//
if ( bit_g ) {
c3_w low_w = src_w[0] >> bif_g;
if ( bif_g > bit_g ) {
low_w ^= src_w[1] << fib_y;
}
*dst_w++ ^= low_w << bit_g;
wid_d -= tib_y;
bif_g += tib_y;
src_w += !!(bif_g >> 5);
bif_g &= 31;
fib_y = 32 - bif_g;
}
{
size_t i_i, byt_i = wid_d >> 5;
if ( !bif_g ) {
for ( i_i = 0; i_i < byt_i; i_i++ ) {
dst_w[i_i] ^= src_w[i_i];
}
}
else {
for ( i_i = 0; i_i < byt_i; i_i++ ) {
dst_w[i_i] ^= (src_w[i_i] >> bif_g) ^ (src_w[i_i + 1] << fib_y);
}
}
src_w += byt_i;
dst_w += byt_i;
wid_d &= 31;
bit_g = 0;
}
}
// we need to chop (more) bits
//
if ( wid_d ) {
c3_w hig_w = src_w[0] >> bif_g;
if ( wid_d > fib_y ) {
hig_w ^= src_w[1] << fib_y;
}
*dst_w ^= (hig_w & ((1 << wid_d) - 1)) << bit_g;
}
}
/* u3r_chop_words():
**
** Into the bloq space of `met`, from position `fum` for a
** span of `wid`, to position `tou`, XOR from `src_w`
** into `dst_w`.
**
** NB: [dst_w] must have space for [tou_w + wid_w] bloqs
*/
void
u3r_chop_words(c3_g met_g,
c3_w fum_w,
c3_w wid_w,
c3_w tou_w,
c3_w* dst_w,
c3_w len_w,
const c3_w* src_w)
{
// operate on words
//
if ( met_g >= 5 ) {
size_t i_i, wid_i;
{
c3_g hut_g = met_g - 5;
size_t fum_i = (size_t)fum_w << hut_g;
size_t tou_i = (size_t)tou_w << hut_g;
size_t tot_i;
wid_i = (size_t)wid_w << hut_g;
tot_i = fum_i + wid_i;
// since [dst_w] must have space for (tou_w + wid_w) bloqs,
// neither conversion can overflow
//
if ( (fum_i >> hut_g != fum_w) || (tot_i - wid_i != fum_i) ) {
u3m_bail(c3__fail);
return;
}
else if ( fum_i >= len_w ) {
return;
}
if ( tot_i > len_w ) {
wid_i -= tot_i - len_w;
}
src_w += fum_i;
dst_w += tou_i;
}
for ( i_i = 0; i_i < wid_i; i_i++ ) {
dst_w[i_i] ^= src_w[i_i];
}
}
// operate on bits
//
else {
c3_d wid_d = (c3_d)wid_w << met_g;
c3_g bif_g, bit_g;
{
c3_d len_d = (c3_d)len_w << 5;
c3_d fum_d = (c3_d)fum_w << met_g;
c3_d tou_d = (c3_d)tou_w << met_g;
c3_d tot_d = fum_d + wid_d;
// see above
//
if ( (fum_d >> met_g != fum_w) || (tot_d - wid_d != fum_d) ) {
u3m_bail(c3__fail);
return;
}
else if ( fum_d > len_d ) {
return;
}
if ( tot_d > len_d ) {
wid_d -= tot_d - len_d;
}
src_w += fum_d >> 5;
dst_w += tou_d >> 5;
bif_g = fum_d & 31;
bit_g = tou_d & 31;
}
u3r_chop_bits(bif_g, wid_d, bit_g, dst_w, src_w);
}
}
/* u3r_chop():
**
** Into the bloq space of `met`, from position `fum` for a
** span of `wid`, to position `tou`, XOR from atom `src`
** into `dst_w`.
**
** NB: [dst_w] must have space for [tou_w + wid_w] bloqs
*/
void
u3r_chop(c3_g met_g,
c3_w fum_w,
c3_w wid_w,
c3_w tou_w,
c3_w* dst_w,
u3_atom src)
u3r_chop(c3_g met_g,
c3_w fum_w,
c3_w wid_w,
c3_w tou_w,
c3_w* dst_w,
u3_atom src)
{
c3_w i_w;
c3_w* src_w;
c3_w len_w;
c3_w* buf_w;
c3_assert(u3_none != src);
c3_assert(_(u3a_is_atom(src)));
if ( _(u3a_is_cat(src)) ) {
len_w = src ? 1 : 0;
buf_w = &src;
src_w = &src;
}
else {
u3a_atom* src_u = u3a_to_ptr(src);
c3_assert(u3_none != src);
c3_assert(_(u3a_is_atom(src)));
len_w = src_u->len_w;
buf_w = src_u->buf_w;
src_w = src_u->buf_w;
}
if ( met_g < 5 ) {
c3_w san_w = (1 << met_g);
c3_w mek_w = ((1 << san_w) - 1);
c3_w baf_w = (fum_w << met_g);
c3_w bat_w = (tou_w << met_g);
// XX: efficiency: poor. Iterate by words.
//
for ( i_w = 0; i_w < wid_w; i_w++ ) {
c3_w waf_w = (baf_w >> 5);
c3_g raf_g = (baf_w & 31);
c3_w wat_w = (bat_w >> 5);
c3_g rat_g = (bat_w & 31);
c3_w hop_w;
hop_w = (waf_w >= len_w) ? 0 : buf_w[waf_w];
hop_w = (hop_w >> raf_g) & mek_w;
dst_w[wat_w] ^= (hop_w << rat_g);
baf_w += san_w;
bat_w += san_w;
}
}
else {
c3_g hut_g = (met_g - 5);
c3_w san_w = (1 << hut_g);
c3_w j_w;
for ( i_w = 0; i_w < wid_w; i_w++ ) {
c3_w wuf_w = (fum_w + i_w) << hut_g;
c3_w wut_w = (tou_w + i_w) << hut_g;
for ( j_w = 0; j_w < san_w; j_w++ ) {
dst_w[wut_w + j_w] ^=
((wuf_w + j_w) >= len_w)
? 0
: buf_w[wuf_w + j_w];
}
}
}
u3r_chop_words(met_g, fum_w, wid_w, tou_w, dst_w, len_w, src_w);
}
/* u3r_string(): `a` as malloced C string.
@ -1676,9 +1803,7 @@ u3r_mug_words(const c3_w* key_w, c3_w len_w)
c3_w gal_w = len_w - 1;
c3_w daz_w = key_w[gal_w];
byt_w = (gal_w << 2)
+ ((daz_w >> 24) ? 4 : (daz_w >> 16) ? 3 : (daz_w >> 8) ? 2 : 1);
byt_w = (gal_w << 2) + ((c3_bits_word(daz_w) + 7) >> 3);
}
// XX: assumes little-endian

View File

@ -216,6 +216,32 @@ u3v_peek(u3_noun sam)
return u3n_slam_on(fun, sam);
}
/* u3v_soft_peek(): softly query the reck namespace.
*/
u3_noun
u3v_soft_peek(c3_w mil_w, u3_noun sam)
{
u3_noun gon = u3m_soft(mil_w, u3v_peek, sam);
u3_noun tag, dat;
u3x_cell(gon, &tag, &dat);
// read failed, produce trace
//
// NB, reads *should not* fail deterministically
//
if ( u3_blip != tag ) {
return u3nc(c3n, gon);
}
// read succeeded, produce result
//
{
u3_noun pro = u3nc(c3y, u3k(dat));
u3z(gon);
return pro;
}
}
/* u3v_poke(): insert and apply an input ovum (protected).
*/
u3_noun

View File

@ -6,7 +6,7 @@
static void
_setup(void)
{
u3m_init();
u3m_init(1 << 22);
u3m_pave(c3y);
}

View File

@ -0,0 +1,68 @@
#include "all.h"
#include "ur/ur.h"
#include "vere/ivory.h"
#include "vere/vere.h"
/* _setup(): prepare for tests.
*/
static void
_setup(void)
{
c3_d len_d = u3_Ivory_pill_len;
c3_y* byt_y = u3_Ivory_pill;
u3_cue_xeno* sil_u;
u3_weak pil;
u3C.wag_w |= u3o_hashless;
u3m_boot_lite(1 << 26);
sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28);
if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) {
printf("*** fail _setup 1\n");
exit(1);
}
u3s_cue_xeno_done(sil_u);
if ( c3n == u3v_boot_lite(pil) ) {
printf("*** fail _setup 2\n");
exit(1);
}
}
/* _test_lily(): test small noun parsing.
*/
static void
_test_lily()
{
c3_l lit_l;
c3_w big_w[] = {0, 0, 1};
u3_noun big = u3i_words(3, big_w);
u3_noun cod = u3dc("scot", c3__uv, big);
if ( c3y == u3v_lily(c3__uv, cod, &lit_l) ) {
printf("*** fail _test_lily-1\n");
exit(1);
}
cod = u3dc("scot", c3__ud, 0x7fffffff);
if ( (c3n == u3v_lily(c3__ud, cod, &lit_l)) ||
(0x7fffffff != lit_l) ) {
printf("*** fail _test_lily-2a\n");
exit(1);
}
cod = u3dc("scot", c3__ux, u3i_word(0x80000000));
if ( c3y == u3v_lily(c3__ux, cod, &lit_l) ) {
printf("*** fail _test_lily-2b\n");
exit(1);
}
}
/* main(): run all test cases.
*/
int
main(int argc, char* argv[])
{
_setup();
_test_lily();
fprintf(stderr, "test boot: ok\n");
return 0;
}

View File

@ -9,7 +9,7 @@ c3_w _ch_skip_slot(c3_w mug_w, c3_w lef_w);
static void
_setup(void)
{
u3m_init();
u3m_init(1 << 26);
u3m_pave(c3y);
}

View File

@ -6,7 +6,7 @@
static void
_setup(void)
{
u3m_init();
u3m_init(1 << 24);
u3m_pave(c3y);
u3e_init();
}

View File

@ -5,7 +5,7 @@
static void
_setup(void)
{
u3m_init();
u3m_init(1 << 20);
u3m_pave(c3y);
}

View File

@ -5,7 +5,7 @@
static void
_setup(void)
{
u3m_init();
u3m_init(1 << 20);
u3m_pave(c3y);
}

View File

@ -6,7 +6,7 @@
static void
_setup(void)
{
u3m_init();
u3m_init(1 << 20);
u3m_pave(c3y);
}

View File

@ -5,7 +5,10 @@
static void
_setup(void)
{
u3m_init();
// XX at 1<<24, this succeeds on mac, but bail:exit's on linux.
// investigate possible u3n_prog corruption
//
u3m_init(1 << 25);
u3m_pave(c3y);
u3e_init();
}

View File

@ -1,7 +1,4 @@
#include "all.h"
#include "ur/ur.h"
#include "vere/ivory.h"
#include "vere/vere.h"
#define TRUE 1
#define FALSE 0
@ -11,23 +8,358 @@
static void
_setup(void)
{
c3_d len_d = u3_Ivory_pill_len;
c3_y* byt_y = u3_Ivory_pill;
u3_cue_xeno* sil_u;
u3_weak pil;
u3m_init(1 << 20);
u3m_pave(c3y);
}
u3C.wag_w |= u3o_hashless;
u3m_boot_lite();
sil_u = u3s_cue_xeno_init_with(ur_fib27, ur_fib28);
if ( u3_none == (pil = u3s_cue_xeno_with(sil_u, len_d, byt_y)) ) {
printf("*** fail _setup 1\n");
exit(1);
/* _test_u3r_chop: "extract bit slices from atom"
*/
static c3_i
_test_u3r_chop()
{
c3_i ret_i = 1;
c3_w dst_w = 0;
u3_atom src = 0b11011;
// bloq 0
//
{
// read 1 bit from pos=0 (far right)
//
dst_w = 0;
u3r_chop(0, 0, 1, 0, &dst_w, src);
if ( 0x1 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 0, 0\r\n");
ret_i = 0;
}
// read 1 bit from pos=1
//
dst_w = 0;
u3r_chop(0, 1, 1, 0, &dst_w, src);
if ( 0x1 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 0, 1\r\n");
ret_i = 0;
}
// read 1 bit from pos=2
//
dst_w = 0;
u3r_chop(0, 2, 1, 0, &dst_w, src);
if ( 0x0 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 0, 2\r\n");
ret_i = 0;
}
// read 4 x 1 bit bloq from pos=0
//
dst_w = 0;
u3r_chop(0, 0, 4, 0, &dst_w, src);
if ( 0b1011 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 0, 3\r\n");
ret_i = 0;
}
// read 4 x 1 bit bloq from pos=0 into offset 1
//
dst_w = 0;
u3r_chop(0, 0, 4, 1, &dst_w, src);
if ( 0b10110 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 0, 4\r\n");
ret_i = 0;
}
}
u3s_cue_xeno_done(sil_u);
if ( c3n == u3v_boot_lite(pil) ) {
printf("*** fail _setup 2\n");
exit(1);
// bloq 1
//
{
// read 2 bit from pos=0 (far right)
//
dst_w = 0;
u3r_chop(1, 0, 1, 0, &dst_w, src);
if ( 0b11 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 1, 0\r\n");
ret_i = 0;
}
// read 2 bit from pos=1
//
dst_w = 0;
u3r_chop(1, 1, 1, 0, &dst_w, src);
if ( 0b10 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 1, 1\r\n");
ret_i = 0;
}
// read 2 bit from pos=2 (2 bloq over)
dst_w = 0;
u3r_chop(1, 2, 1, 0, &dst_w, src);
if ( 0b01 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 1, 2\r\n");
ret_i = 0;
}
}
// bloq 3
{
dst_w = 0;
u3r_chop(3, 0, 1, 0, &dst_w, src);
if ( 0b11011 != dst_w ) {
fprintf(stderr, "test: u3r_chop: bloq 3, 0\r\n");
ret_i = 0;
}
}
// read 1,8,16 bit bloqs from an indirect atom
//
{
src = u3i_string("abcdefghij");
// 1 bit pos=0 (far right)
//
dst_w = 0;
u3r_chop(0, 0, 1, 0, &dst_w, src);
if ( 0b1 != dst_w ) {
fprintf(stderr, "test: u3r_chop: indirect 0\r\n");
ret_i = 0;
}
// 8 bits pos=0
//
dst_w = 0;
u3r_chop(0, 0, 8, 0, &dst_w, src);
if ( 0b1100001 != dst_w ) {
fprintf(stderr, "test: u3r_chop: indirect 1\r\n");
ret_i = 0;
}
// 1 byte pos=0
//
dst_w = 0;
u3r_chop(3, 0, 1, 0, &dst_w, src);
if ( 0b1100001 != dst_w ) {
fprintf(stderr, "test: u3r_chop: indirect 2\r\n");
ret_i = 0;
}
// 1 short pos=0
//
dst_w = 0;
u3r_chop(4, 0, 1, 0, &dst_w, src);
if ( 0b0110001001100001 != dst_w ) {
fprintf(stderr, "test: u3r_chop: indirect 3\r\n");
ret_i = 0;
}
u3z(src);
}
// read lots of bits from a direct noun which holds 64 bits of data
// makes sure that we handle top 32 / bottom 32 correctly
{
c3_y inp_y[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };
src = u3i_bytes(8, inp_y);
c3_w dst_w[2] = {0};
u3r_chop(0, 0, 63, 0, dst_w, src);
if ( (0x3020100 != dst_w[0]) || (0x7060504 != dst_w[1]) ) {
fprintf(stderr, "test: u3r_chop: indirect 4\r\n");
ret_i = 0;
}
u3z(src);
}
// as above (read lots of bits from a direct noun which holds 64 bits of data
// makes sure that we handle top 32 / bottom 32 correctly)
// but with a bit more nuance
{
c3_y inp_y[8] = { 0x0, 0x0, 0x0, 0xaa, 0xff, 0x0, 0x0, 0x0 };
src = u3i_bytes(8, (c3_y*)inp_y);
dst_w = 0;
u3r_chop(0, 24, 16, 0, &dst_w, src);
if ( 0b1111111110101010 != dst_w ) {
fprintf(stderr, "test: u3r_chop: indirect 5\r\n");
ret_i = 0;
}
u3z(src);
}
return ret_i;
}
/* _test_chop_slow(): "golden master" for chop tests (formerly u3r_chop())
*/
void
_test_chop_slow(c3_g met_g,
c3_w fum_w,
c3_w wid_w,
c3_w tou_w,
c3_w* dst_w,
c3_w len_w,
c3_w* buf_w)
{
c3_w i_w;
if ( met_g < 5 ) {
c3_w san_w = (1 << met_g);
c3_w mek_w = ((1 << san_w) - 1);
c3_w baf_w = (fum_w << met_g);
c3_w bat_w = (tou_w << met_g);
// XX: efficiency: poor. Iterate by words.
//
for ( i_w = 0; i_w < wid_w; i_w++ ) {
c3_w waf_w = (baf_w >> 5);
c3_g raf_g = (baf_w & 31);
c3_w wat_w = (bat_w >> 5);
c3_g rat_g = (bat_w & 31);
c3_w hop_w;
hop_w = (waf_w >= len_w) ? 0 : buf_w[waf_w];
hop_w = (hop_w >> raf_g) & mek_w;
dst_w[wat_w] ^= (hop_w << rat_g);
baf_w += san_w;
bat_w += san_w;
}
}
else {
c3_g hut_g = (met_g - 5);
c3_w san_w = (1 << hut_g);
c3_w j_w;
for ( i_w = 0; i_w < wid_w; i_w++ ) {
c3_w wuf_w = (fum_w + i_w) << hut_g;
c3_w wut_w = (tou_w + i_w) << hut_g;
for ( j_w = 0; j_w < san_w; j_w++ ) {
dst_w[wut_w + j_w] ^=
((wuf_w + j_w) >= len_w)
? 0
: buf_w[wuf_w + j_w];
}
}
}
}
/* _test_chop_smol(): test permuations of chop from bloq 0-4
*/
static c3_i
_test_chop_smol(c3_c* cap_c, c3_y val_y)
{
c3_i ret_i = 1;
c3_g met_g;
c3_w fum_w, wid_w, tou_w;
c3_w len_w = 34; // (rsh [0 5] (mul 2 (mul 34 (bex 4))))
c3_w src_w[len_w];
c3_w a_w[len_w];
c3_w b_w[len_w];
memset(src_w, val_y, len_w << 2);
for ( met_g = 0; met_g < 5; met_g++ ) {
for ( fum_w = 0; fum_w <= len_w; fum_w++ ) {
for ( wid_w = 0; wid_w <= len_w; wid_w++ ) {
for ( tou_w = 0; tou_w <= len_w; tou_w++ ) {
memset(a_w, 0, len_w << 2);
memset(b_w, 0, len_w << 2);
u3r_chop_words(met_g, fum_w, wid_w, tou_w, a_w, len_w, src_w);
_test_chop_slow(met_g, fum_w, wid_w, tou_w, b_w, len_w, src_w);
if ( 0 != memcmp(a_w, b_w, len_w << 2) ) {
c3_g sif_g = 5 - met_g;
c3_w mas_w = (1 << met_g) - 1;
c3_w out_w = tou_w >> sif_g;
c3_w max_w = out_w + !!(fum_w & mas_w)
+ (wid_w >> sif_g) + !!(wid_w & mas_w);
fprintf(stderr, "%s (0x%x): met_g=%u fum_w=%u wid_w=%u tou_w=%u\r\n",
cap_c, val_y,
met_g, fum_w, wid_w, tou_w);
fprintf(stderr, "%u-%u: ", out_w, max_w - 1);
for ( ; out_w < max_w; out_w++ ) {
fprintf(stderr, "[0x%x 0x%x] ", a_w[out_w], b_w[out_w]);
}
fprintf(stderr, "\r\n");
}
}
}
}
}
return ret_i;
}
/* _test_chop_huge(): test permuations of chop from bloq 5+
*/
static c3_i
_test_chop_huge(c3_c* cap_c, c3_y val_y)
{
c3_i ret_i = 1;
c3_g met_g;
c3_w fum_w, wid_w, tou_w;
c3_w len_w = 192; // (rsh [0 5] (mul 2 (mul 3 (bex 10))))
c3_w src_w[len_w];
c3_w a_w[len_w];
c3_w b_w[len_w];
memset(src_w, val_y, len_w << 2);
for ( met_g = 5; met_g <= 10; met_g++ ) {
for ( fum_w = 0; fum_w <= 3; fum_w++ ) {
for ( wid_w = 0; wid_w <= 2; wid_w++ ) {
for ( tou_w = 0; tou_w <= 1; tou_w++ ) {
memset(a_w, 0, len_w << 2);
memset(b_w, 0, len_w << 2);
u3r_chop_words(met_g, fum_w, wid_w, tou_w, a_w, len_w, src_w);
_test_chop_slow(met_g, fum_w, wid_w, tou_w, b_w, len_w, src_w);
if ( 0 != memcmp(a_w, b_w, len_w << 2) ) {
c3_g sif_g = met_g - 5;
c3_w mas_w = (1 << met_g) - 1;
c3_w out_w = tou_w << sif_g;
c3_w max_w = out_w + !!(fum_w & mas_w)
+ (wid_w << sif_g) + !!(wid_w & mas_w);
fprintf(stderr, "%s (0x%x): met_g=%u fum_w=%u wid_w=%u tou_w=%u\r\n",
cap_c, val_y,
met_g, fum_w, wid_w, tou_w);
fprintf(stderr, "%u-%u: ", out_w, max_w - 1);
for ( ; out_w < max_w; out_w++ ) {
fprintf(stderr, "[0x%x 0x%x] ", a_w[out_w], b_w[out_w]);
}
fprintf(stderr, "\r\n");
}
}
}
}
}
return ret_i;
}
/* _test_u3r_chop(): bit slice XOR
*/
static c3_i
_test_chop()
{
return _test_u3r_chop()
& _test_chop_smol("chop smol zeros", 0x0)
& _test_chop_smol("chop smol ones", 0xff)
& _test_chop_smol("chop smol alt 1", 0xaa)
& _test_chop_smol("chop smol alt 2", 0x55)
& _test_chop_huge("chop huge zeros", 0x0)
& _test_chop_huge("chop huge ones", 0xff)
& _test_chop_huge("chop huge alt 1", 0xaa)
& _test_chop_huge("chop huge alt 2", 0x55);
}
/* _util_rand_string(): dynamically allocated len_w random string
@ -1265,256 +1597,6 @@ _test_u3r_at()
if (bignum != ret) { printf("*** u3r_at \n"); }
}
/* _test_u3r_chop: "extract bit slices from atom"
*/
static void
_test_u3r_chop()
{
c3_w dst_w = 0;
// read 1 bit bloq
{
// read 1 bit from pos=0 (far right)
u3_atom src = 0b11011;
c3_g bloqsize_g = 0;
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0x1 != dst_w) { printf("*** test_u3r_chop \n"); }
// read 1 bit from pos=1
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
1, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0x1 != dst_w) { printf("*** test_u3r_chop 2\n"); }
// read 1 bit from pos=2
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
2, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0x0 != dst_w) { printf("*** test_u3r_chop 3\n"); }
// read 4 x 1 bit bloq from pos=0
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
4, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b1011 != dst_w) { printf("*** test_u3r_chop 4\n"); }
// read 1 x 1 bit bloq from pos=0 into offset 1
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
4, // count of bloqs
1, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b10110 != dst_w) { printf("*** test_u3r_chop 5\n"); }
}
// read 2 bit bloq
{
u3_atom src = 0b11011;
c3_g bloqsize_g = 1;
// read 2 bit from pos=0 (far right)
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b11 != dst_w) { printf("*** test_u3r_chop 2.1\n"); }
// read 2 bit from pos=1 (1 bloq over )
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
1, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b10 != dst_w) { printf("*** test_u3r_chop 2.2\n"); }
// read 2 bit from pos=2 (2 bloq over)
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
2, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b01 != dst_w) { printf("*** test_u3r_chop 2.3\n"); }
}
// read 8 bit bloq
{
u3_atom src = 0b11011;
c3_g bloqsize_g = 3; // 2^3 = 8 bits
// pos=0 (far right)
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b11011 != dst_w) { printf("*** test_u3r_chop 8.1\n"); }
}
// read 1,8,16 bit bloqs from an indirect atom
{
// build an indirect noun 'src'
c3_c* input_c = "abcdefghij";
u3_noun src = u3i_bytes(10, (c3_y*)input_c);
c3_g bloqsize_g = 0; // 2^0 = 1 bit
// 1 x 1 bit pos=0 (far right)
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b1 != dst_w) {
printf("*** test_u3r_chop indirect.1\n");
}
// 8 x 1 bit pos=0 (far right)
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
8, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b1100001 != dst_w) {
printf("*** test_u3r_chop indirect.2\n");
}
// 1 x 1 byte = 8 bit, pos=0 (far right)
bloqsize_g = 3; // 2^3 = 1 byte
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b1100001 != dst_w) {
printf("*** test_u3r_chop indirect.3\n");
}
// 1 x 16 bit bloq, pos = 0
bloqsize_g = 4; // 2^4 = 2 bytes
dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
0, // start index
1, // count of bloqs
0, // end index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b0110001001100001 != dst_w) {
printf("*** test_u3r_chop indirect.4\n");
}
}
// read lots of bits from a direct noun which holds 64 bits of data
// makes sure that we handle top 32 / bottom 32 correctly
{
// build an indirect noun 'src'
c3_c input_c[8] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };
u3_noun src = u3i_bytes(8, (c3_y*)input_c);
c3_g bloqsize_g = 0; // 2^0 = 1 bit
c3_w dst_w[2];
memset(dst_w, 0, 2 * sizeof(c3_w));
u3r_chop(bloqsize_g, /// bloq size
0, // start index
63, // count of bloqs
0, // offset on out index
dst_w, // where bytes go to
src); // where bytes come from
}
// as above (read lots of bits from a direct noun which holds 64 bits of data
// makes sure that we handle top 32 / bottom 32 correctly)
// but with a bit more nuance
{
// least significant most
c3_c input_c[8] = { 0x0, 0x0, 0x0, 0xaa, 0xff, 0x0, 0x0, 0x0 };
u3_noun src = u3i_bytes(8, (c3_y*)input_c);
c3_g bloqsize_g = 0; // 2^0 = 1 bit
c3_w dst_w = 0;
u3r_chop(bloqsize_g, /// bloq size
24, // start index
16, // count of bloqs
0, // offset on out index
& dst_w, // where bytes go to
src); // where bytes come from
if (0b1111111110101010 != dst_w) {
printf("*** test_u3r_chop indirect. 6\n");
}
}
}
// XX disabled, static functions
//
#if 0
@ -1652,31 +1734,17 @@ _test_nvm_stack()
#endif
}
/* _test_lily(): test small noun parsing.
*/
static void
_test_lily()
static c3_i
_test_noun(void)
{
c3_l lit_l;
c3_w big_w[] = {0, 0, 1};
u3_noun big = u3i_words(3, big_w);
u3_noun cod = u3dc("scot", c3__uv, big);
c3_i ret_i = 1;
if ( c3y == u3v_lily(c3__uv, cod, &lit_l) ) {
printf("*** fail _test_lily-1\n");
exit(1);
}
cod = u3dc("scot", c3__ud, 0x7fffffff);
if ( (c3n == u3v_lily(c3__ud, cod, &lit_l)) ||
(0x7fffffff != lit_l) ) {
printf("*** fail _test_lily-2a\n");
exit(1);
}
cod = u3dc("scot", c3__ux, u3i_word(0x80000000));
if ( c3y == u3v_lily(c3__ux, cod, &lit_l) ) {
printf("*** fail _test_lily-2b\n");
exit(1);
if ( !_test_chop() ) {
fprintf(stderr, "test noun: chop failed\r\n");
ret_i = 0;
}
return ret_i;
}
/* main(): run all test cases.
@ -1686,9 +1754,20 @@ main(int argc, char* argv[])
{
_setup();
if ( !_test_noun() ) {
fprintf(stderr, "test noun: failed\r\n");
exit(1);
}
// GC
//
u3m_grab(u3_none);
// XX the following tests leak memory
// fix and move to _test_noun()
//
_test_noun_bits_set();
_test_noun_bits_read();
_test_u3r_chop();
_test_imprison();
_test_imprison_complex();
_test_sing();
@ -1698,7 +1777,6 @@ main(int argc, char* argv[])
_test_cells_complex();
_test_u3r_at();
_test_nvm_stack();
_test_lily();
fprintf(stderr, "test_noun: ok\n");

View File

@ -411,25 +411,21 @@ ur_bsr_bytes_any(ur_bsr_t *bsr, uint64_t len, uint8_t *out)
//
else {
uint8_t rest = 8 - off;
uint8_t mask = (1 << off) - 1;
uint8_t byt, l, m = *b >> off;
uint64_t last = left - 1;
uint64_t max = ur_min(last, len_byt);
uint8_t m, l;
// loop over all the bytes we need (or all that remain)
//
// [l] holds [off] bits
// [m] holds [rest] bits
//
{
uint64_t max = ur_min(last, len_byt);
uint64_t i;
for ( i = 0; i < max; i++ ) {
byt = *++b;
l = byt & mask;
out[i] = m ^ (l << rest);
m = byt >> off;
out[i] = (b[i] >> off) ^ (b[i + 1] << rest);
}
b += max;
m = *b >> off;
}
// we're reading into or beyond the last byte [bsr]
@ -441,13 +437,13 @@ ur_bsr_bytes_any(ur_bsr_t *bsr, uint64_t len, uint8_t *out)
uint8_t bits = len - (last << 3);
if ( bits < rest ) {
out[last] = m & ((1 << bits) - 1);
out[max] = m & ((1 << len_bit) - 1);
bsr->bytes = b;
left = 1;
off += len_bit;
}
else {
out[last] = m;
out[max] = m;
bsr->bytes = 0;
left = 0;
off = 0;
@ -465,11 +461,11 @@ ur_bsr_bytes_any(ur_bsr_t *bsr, uint64_t len, uint8_t *out)
if ( len_bit ) {
if ( len_bit <= rest ) {
out[len_byt] = m & ((1 << len_bit) - 1);
out[max] = m & ((1 << len_bit) - 1);
}
else {
l = *++b & ((1 << off) - 1);
out[len_byt] = m ^ (l << rest);
out[max] = (m ^ (l << rest)) & ((1 << len_bit) - 1);
}
}
}
@ -1035,67 +1031,60 @@ ur_bsw64(ur_bsw_t *bsw, uint8_t len, uint64_t val)
}
static inline void
_bsw_bytes_unsafe(ur_bsw_t *bsw, uint64_t len, uint8_t *byt)
_bsw_bytes_unsafe(ur_bsw_t *bsw, const uint64_t len, const uint8_t* src)
{
uint64_t len_byt = len >> 3;
uint8_t len_bit = ur_mask_3(len);
uint64_t fill = bsw->fill;
uint8_t off = bsw->off;
uint64_t fill = bsw->fill;
uint8_t off = bsw->off;
uint8_t *dst = bsw->bytes + fill;
if ( !off ) {
memcpy(bsw->bytes + fill, byt, len_byt);
fill += len_byt;
off = len_bit;
const uint64_t len_byt = len >> 3;
const uint8_t len_bit = ur_mask_3(len);
if ( off ) {
bsw->bytes[fill] = byt[len_byt] & ((1 << off) - 1);
memcpy(dst, src, len_byt);
bsw->fill = fill + len_byt;
if ( len_bit ) {
dst[len_byt] = src[len_byt] & ((1 << len_bit) - 1);
bsw->off = len_bit;
}
}
// the least-significant bits of the input become the
// most-significant bits of a byte in the output stream, and vice-versa
//
else {
uint8_t rest = 8 - off;
uint8_t mask = (1 << rest) - 1;
uint8_t l, m = bsw->bytes[fill];
uint64_t i;
else {
const uint8_t rest = 8 - off;
for ( i = 0; i < len_byt; i++ ) {
l = byt[i] & mask;
bsw->bytes[fill++] = m ^ (l << off);
m = byt[i] >> rest;
}
if ( rest >= len ) {
uint16_t ful = off + len;
// no trailing bits; we need only write the rest of the last byte.
//
// NB: while semantically equivalent to the subsequent block,
// this case must be separate to avoid reading off the end of [byt]
//
if ( !len_bit ) {
bsw->bytes[fill] = m;
*dst ^= (*src & ((1 << len) - 1)) << off;
if ( ful >> 3 ) {
bsw->fill = fill + 1;
}
bsw->off = ur_mask_3(ful);
}
// trailing bits fit into the current output byte.
//
else if ( len_bit < rest ) {
l = byt[len_byt] & ((1 << len_bit) - 1);
bsw->bytes[fill] = m ^ (l << off);
off += len_bit;
}
// trailing bits extend into the next output byte.
//
else {
l = byt[len_byt] & mask;
bsw->bytes[fill++] = m ^ (l << off);
const uint64_t nel = len - rest;
const uint64_t len_byt = nel >> 3;
const uint8_t len_bit = ur_mask_3(nel);
m = byt[len_byt] >> rest;
*dst++ ^= *src << off;
off = len_bit - rest;
bsw->bytes[fill] = m & ((1 << off) - 1);
for ( uint64_t i = 0; i < len_byt; i++ ) {
dst[i] = (src[i] >> rest) ^ (src[i + 1] << off);
}
{
uint8_t tal = (src[len_byt] >> rest)
^ (( off > len_bit ) ? 0 : (src[len_byt + 1] << off));
dst[len_byt] = tal & ((1 << len_bit) - 1);
}
bsw->fill = fill + len_byt + 1;
bsw->off = len_bit;
}
}
bsw->off = off;
bsw->fill = fill;
bsw->bits += len;
}

View File

@ -617,7 +617,15 @@ u3_disk_acquire(c3_c* pax_c)
else if (pid_w != getpid()) {
c3_w i_w;
if ( -1 != kill(pid_w, SIGTERM) ) {
int ret = kill(pid_w, SIGTERM);
if ( -1 == ret && errno == EPERM ) {
u3l_log("disk: permission denied when trying to kill process %d!\n", pid_w);
kill(getpid(), SIGTERM);
sleep(1); c3_assert(0);
}
if ( -1 != ret ) {
u3l_log("disk: stopping process %d, live in %s...\n",
pid_w, pax_c);

View File

@ -1157,11 +1157,12 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
// spawn new process and connect to it
//
{
c3_c* arg_c[8];
c3_c* arg_c[10];
c3_c key_c[256];
c3_c wag_c[11];
c3_c hap_c[11];
c3_c cev_c[11];
c3_c lom_c[11];
c3_i err_i;
sprintf(key_c, "%" PRIx64 ":%" PRIx64 ":%" PRIx64 ":%" PRIx64 "",
@ -1174,30 +1175,34 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
sprintf(hap_c, "%u", u3_Host.ops_u.hap_w);
sprintf(lom_c, "%u", u3_Host.ops_u.lom_y);
arg_c[0] = god_u->bin_c; // executable
arg_c[1] = "serf"; // protocol
arg_c[2] = god_u->pax_c; // path to checkpoint directory
arg_c[3] = key_c; // disk key
arg_c[4] = wag_c; // runtime config
arg_c[5] = hap_c; // hash table size
arg_c[6] = lom_c; // loom bex
if ( u3_Host.ops_u.roc_c ) {
// XX validate
//
arg_c[6] = u3_Host.ops_u.roc_c;
arg_c[7] = u3_Host.ops_u.roc_c;
}
else {
arg_c[6] = "0";
arg_c[7] = "0";
}
#ifdef U3_OS_mingw
sprintf(cev_c, "%" PRIu64, u3_Host.cev_u);
arg_c[7] = cev_c;
arg_c[8] = 0;
arg_c[8] = cev_c;
#else
arg_c[7] = 0;
arg_c[8] = 0;
#endif
arg_c[9] = 0;
uv_pipe_init(u3L, &god_u->inn_u.pyp_u, 0);
uv_timer_init(u3L, &god_u->out_u.tim_u);
uv_pipe_init(u3L, &god_u->out_u.pyp_u, 0);

View File

@ -1 +1 @@
1.12
1.13