Perl 6 - the future is here, just unevenly distributed

IRC log for #moarvm, 2014-03-15

| Channels | #moarvm index | Today | | Search | Google Search | Plain-Text | summary

All times shown according to UTC.

Time Nick Message
00:02 ilbot3 joined #moarvm
00:02 Topic for #moarvm is now https://github.com/moarvm/moarvm | IRC logs at  http://irclog.perlgeek.de/moarvm/today
00:06 jnthn timotimo: OK, go for it. :)
00:07 dalek joined #moarvm
00:07 tokuhirom joined #moarvm
00:07 rurban joined #moarvm
00:08 jnthn Guess the commit message for the callback return values got lost :/
00:08 timotimo i was wondering
00:09 jnthn Was https://github.com/MoarVM/MoarVM/commit/e6fa9af516be95196b579a89f28e40a6554ddf64 anyways
00:10 _sri joined #moarvm
00:10 FROGGS_ joined #moarvm
00:11 hoelzro joined #moarvm
00:13 timotimo how exactly do i build zavolaj for moar? with uf?
00:13 timotimo ufo?
00:13 tadzik joined #moarvm
00:14 jnthn You could, though I've just been doing
00:14 jnthn prove --exec="perl6-m -Ilib" t
00:14 jnthn Rather than building it.
00:14 dalek joined #moarvm
00:16 timotimo ah, right
00:16 jnthn Some of the C REPRs may be missing their repr data serialize functions yet too
00:16 timotimo getting the PREFIX command not found output
00:17 timotimo but all tests successfull
00:19 jnthn \o/
00:20 timotimo but each of the tests outputs the warning about PREFIX :)
00:20 jnthn No idea what the PREFIX thingy is. Must be non-Windows-y :)
00:20 jnthn Since I don't se it at all here
00:22 tokuhirom joined #moarvm
00:22 timotimo wait what.
00:22 timotimo stracing perl6-m gives me pages and pages and pages and pages and pages and pages and pages and pages of:
00:22 timotimo stat("/home/timo/perl6/rakudo/../install/languages/perl6/runtime/dynext/libperl6_ops_moar.so", {st_mode=S_IFREG|0644, st_size=305778, ...}) = 0
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/nqp/lib/dynext/libperl6_ops_moar.so", 0x7fff42b580e0) = -1 ENOENT (No such file or directory)
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/perl6/lib/dynext/libperl6_ops_moar.so", 0x7fff42b580e0) = -1 ENOENT (No such file or directory)
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/perl6/runtime/dynext/libperl6_ops_moar.so", {st_mode=S_IFREG|0644, st_size=305778, ...}) = 0
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/nqp/lib/dynext/libperl6_ops_moar.so", 0x7fff42b580e0) = -1 ENOENT (No such file or directory)
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/perl6/lib/dynext/libperl6_ops_moar.so", 0x7fff42b580e0) = -1 ENOENT (No such file or directory)
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/perl6/runtime/dynext/libperl6_ops_moar.so", {st_mode=S_IFREG|0644, st_size=305778, ...}) = 0
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/nqp/lib/dynext/libperl6_ops_moar.so", 0x7fff42b580e0) = -1 ENOENT (No such file or directory)
00:23 timotimo stat("/home/timo/perl6/rakudo/../install/languages/perl6/lib/dynext/libperl6_ops_moar.so", 0x7fff42b580e0) = -1 ENOENT (No such file or directory)
00:24 jnthn Wonder where those all come from o.O
00:24 jnthn Well, I need some rest. Will leave that little mystery (and probable speedup) for your hunting :)
00:25 jnthn 'night
00:25 timotimo good night!
00:26 tokuhirom_ joined #moarvm
00:30 rurban joined #moarvm
00:37 _sri joined #moarvm
00:44 timotimo "c_line" => "gcc -c -fPIC -o 01-argless.o  -O1 -DNDEBUG -g3  -D_REENTRANT -D_FILE_OFFSET_BITS=64 -fPIC t/01-argless.c"
00:44 timotimo "l_line" => "gcc -shared -fPIC  -O1 -DNDEBUG -g3 -Wl,-rpath,\$(PREFIX)/lib -lm -lpthread -lrt -ldl -o 01-arglesslib.so 01-argless.o"
01:12 MadHatter1987 joined #moarvm
01:45 hoelzro joined #moarvm
01:52 _sri joined #moarvm
03:00 colomon joined #moarvm
04:29 ggoebel11114 joined #moarvm
04:41 ggoebel11115 joined #moarvm
04:56 dalek MoarVM: fe23b59 | jimmy++ | / (2 files):
04:56 dalek MoarVM: Restore using linenoise
04:56 dalek MoarVM: review: https://github.com/MoarVM/MoarVM/commit/fe23b59937
05:08 TimToady I get millions of > now :/
05:09 JimmyZ you didn't update linenoise
05:10 TimToady it said "Fetching submodule 3rdparty/linenoise
05:13 JimmyZ try 'git clean -xdf'?
05:15 JimmyZ I reproduced the bug and fixed it by set STDIN to block mode
05:20 TimToady still fails after recompiling moarvm and nom; does nqp have to be recompiled?
05:21 JimmyZ hmm, Could you `cd 3rdparty/linenoise && git log` to make sure it's the newest version?
05:23 JimmyZ only needs to recompile moarvm
05:23 JimmyZ and make install
05:25 TimToady has your patch
05:26 TimToady have completely cleaned/recompiled all of moarvm/nqp/nom, still fails
05:28 TimToady is it supposed to install any kind of library?  it only installs a .h
05:29 TimToady or is it already linked into moarvm
05:29 JimmyZ it linked into moarvm
05:30 TimToady ok, I see the liblinenoise.a compiled
05:31 TimToady so I think it's just not working here
05:31 JimmyZ Could you help me gdb nqp? set breakpoint to : b 3rdparty\linenoise\linenoise.c:422
05:34 TimToady doesn't break, just spews >
05:36 JimmyZ yeah, I want to know what's there in line 422
05:36 TimToady it says I don't know what that is, do you want to set breakpoint on shared library
05:36 TimToady so it's probably not finding it
05:37 JimmyZ that's not a share lib
05:37 TimToady well, it's not finding it
05:37 JimmyZ hmm
05:38 TimToady that's: gdb /home/larry/nom/install/bin/moar
05:38 TimToady then run nqp.moarvm
05:38 TimToady and that's presumably the moar that was installed, lemme double check
05:39 TimToady I may have lost my prefix somewhere
05:40 TimToady \o/
05:40 TimToady that was it
05:41 TimToady was installing it into nqp's install dir instead of nom's
05:41 TimToady works now, JimmyZ++
05:41 JimmyZ great
05:41 TimToady thanks!
05:44 JimmyZ You can input things and press ctrl+r to search it, after ctrl+r, you can press tab to continue searching
05:44 JimmyZ something different from lib-readline :P
05:44 JimmyZ and works on widnows also
05:44 JimmyZ windows
06:22 vincent22 joined #moarvm
07:43 nwc10 jnthn: "nearly" works on "my" machine - valgrind and ASAN spot a use-after free in the callback test: http://paste.scsys.co.uk/325393
07:43 nwc10 ooh, and an optimised build on (at least one) x86 system didn't like 05
07:44 nwc10 oh, the non-optimised build on the other x86 system was unhappy too
07:44 nwc10 same 'long' problem as yesterday
07:59 FROGGS joined #moarvm
08:05 nwc10 jnthn: the problem is the second free() here:
08:05 nwc10 /* Clean up. */
08:05 nwc10 free(args);
08:05 nwc10 free(cs);
08:05 nwc10 is subsequently read by this:
08:05 nwc10 if (ctx->callsite->has_flattening) {
08:05 nwc10 er, memory freed by that is read later by the other
08:22 nwc10 I can't figure out how to fix it
08:47 colors joined #moarvm
08:55 woolfy joined #moarvm
08:55 nwc10 OK, only works on "my" machine if it's little endian
08:55 nwc10 Unhandled exception: Bytecode validation error at offset 0, instruction 0:
08:55 nwc10 invalid extension opcode 40704 - should be less than 1024
08:56 nwc10 that's on a power7 machine running Fedora
08:56 nwc10 this is probably not today's problem
09:17 woolfy joined #moarvm
10:22 lizmat joined #moarvm
10:27 lizmat joined #moarvm
10:36 lizmat joined #moarvm
10:51 jnthn nwc10: Probably I shoulda thought to hang the callsite off the callback cache. That'd also mean we can compute it once and re-use it...
10:51 jnthn Wil look at it in a little bit.
10:52 jnthn And yes, BE will be broken until we write a smallish patch to endian convert the bytecode on first invocatin.
10:53 FROGGS does that mean I can't compile to a CD-R? :P
10:55 jnthn You can compile to anything if you write the porting patches :P
10:57 JimmyZ jnthn: I restored linenoise...
10:58 jnthn yes, noticed...
10:58 * FROGGS .oO( don't talk like that about Perl! )
10:59 jnthn :D
10:59 jnthn heh, I'd never considered the amusement of a VM for a Perl depending on linenoise :)
11:00 * jnthn trying the update here
11:00 FROGGS :o)
11:01 JimmyZ well, there is a lua version for linenoise, we can write a Perl6 one too by using nativecall ...
11:09 JimmyZ https://github.com/fperrad/ljlinenoise/blob/master/src/linenoise.lua FYI :P
11:14 jnthn JimmyZ: Seems to work for me.
11:14 JimmyZ \o
11:30 timotimo o/
11:31 jnthn hi timotimo
11:31 JimmyZ Hello, moarer
11:32 timotimo "moarons"?
11:32 JimmyZ moarning
11:42 lizmat joined #moarvm
11:42 woolfy joined #moarvm
11:42 dalek joined #moarvm
11:48 timotimo it seems like the pages and pages of stats for the perl6_ops_moar were caused by something in nativecall
11:48 timotimo maybe some result of some temporary hack
11:48 timotimo so no easy wins to be had there
12:39 vincent22 joined #moarvm
13:07 dalek MoarVM: f55b8ed | jnthn++ | src/core/nativecall. (2 files):
13:07 dalek MoarVM: Build and cache callsite once per callback.
13:07 dalek MoarVM:
13:07 dalek MoarVM: Saves per-callback overhead, but also means lifetime of it is righter,
13:07 dalek MoarVM: hopefully avoiding referencing unused memory.
13:07 dalek MoarVM: review: https://github.com/MoarVM/MoarVM/commit/f55b8edf24
13:08 jnthn nwc10: That should fix your SEGV
13:08 jnthn uh, or my SEGV
13:08 jnthn Or valgrind's complaint
13:08 jnthn Or whatever :)
13:39 JimmyZ jnthn: line CArray.c:88, Did it miss else if (repr_data->elem_kind == MVM_CARRAY_ELEM_KIND_STRING) ?
13:47 JimmyZ hmm, looks like the comments is wrong-ish
13:58 tgt joined #moarvm
14:09 * nwc10 tests
14:18 nwc10 jnthn: valgrind happy for that test. ASAN build not yet there
14:18 jnthn ok
14:23 nwc10 jnthn: ASAN hapy with all 8 tests
14:24 nwc10 jnthn: "righter" ?? - where was you drug up? :-)
14:25 jnthn nwc10: We never reclaim the callback cache entries at present.
14:26 nwc10 so the "cache" grows without limits until process exit?
14:26 nwc10 and gotcha - it's better, but not "best" yet.
14:26 jnthn nwc10: So in the (unlikely) event you are eval'ing lots of callback routines...
14:26 jnthn ...then yeah, you leak.
14:26 jnthn That's a pretty odd thing to be doing though :)
14:30 nwc10 valgrind still grumps about this:
14:30 nwc10 t/05-arrays.t .......... 1/26 ==14553== Conditional jump or move depends on uninitialised value(s)
14:30 nwc10 ==14553==    at 0x4F7CD4F: MVM_nativecall_make_cpointer (nativecall.c:171)
14:30 nwc10 ==14553==    by 0x4FBBC43: make_wrapper (CArray.c:209)
14:31 nwc10 I think that it's the test for an uninitialised pointer
14:36 jnthn Yeah, I think so
14:36 zakharyas joined #moarvm
14:39 nwc10 valgrind happy with all 8
14:44 jnthn hehe...with pre-comp and --jobs=6 I can run the NativeCall tests in 2s on Moar :)
14:45 JimmyZ nmake compile is a pain when you edit a .h file
14:45 dalek MoarVM: ff01095 | jnthn++ | src/6model/reprs/C (4 files):
14:45 dalek MoarVM: Implement missing deserialize_stable_size funcs.
14:45 dalek MoarVM:
14:45 dalek MoarVM: With this, pre-compiling NativeCall now works.
14:45 dalek MoarVM: review: https://github.com/MoarVM/MoarVM/commit/ff01095d58
14:46 jnthn JimmyZ: Yes, nmake is too stupid to support parallel builds :/
14:46 * JimmyZ hopes someone will split moar.h file
14:47 woolfy joined #moarvm
14:48 jnthn Very much doubt that will happen.
14:48 jnthn It's not like a non-parallel build takes long.
14:48 JimmyZ gerdr said about it...
14:48 jnthn Especially as we're using link time code generation.
14:49 jnthn So much of the cost is there.
15:07 woolfy joined #moarvm
15:10 brrt joined #moarvm
15:10 brrt hi #moarvm
15:10 JimmyZ hello
15:11 lizmat joined #moarvm
15:12 brrt 88 commits in what, 3 days? moarvm goes fast
15:13 jnthn It's due to our use of nuclear power.
15:13 timotimo it does, aye
15:15 jnthn .oO( That's what they meant by "atomic commits", right? )
15:17 hoelzro ba-dum tssssh
15:20 brrt joined #moarvm
15:28 brrt unrelated aside - actors are basically what objects could've been if people had taken 'message passing' seriously from the start
15:37 JimmyZ brrt: you know akka?
16:11 woolfy joined #moarvm
16:16 brrt joined #moarvm
16:27 * TimToady has never bothered to parallelize any of his makes because he has only two cores on his ancient laptop, and wants to save one core for doing other things while he's compiling :)
16:29 TimToady and does http://irclog.perlgeek.de/moarvm/2014-03-15#i_8440520 mean we're planning to always include lua now? :)
16:30 jnthn TimToady: No, it was just pointing out lua had a binding to liblinenoise and we could potentially get at it the same way (through native calling) rather than making Moar itself aware of it.
16:32 TimToady oic  <-- channeling diakopter++
16:37 TimToady it's obviously still too early in the morning, since I'm considering whether we should always embed lue++ as our resident AI
16:37 TimToady which would explain the reticence to reveal his True Name :)
16:38 TimToady because then we could unplug him
16:41 * lizmat wonders how dangerous it is to channel diakopter++ this early in the morning
16:49 japhb__ lizmat: Safer than at midnight?
16:50 lizmat ah, probably, yes  :-)
16:52 * brrt wonders if moarvm doesn't have an unwieldily-sized opcode library for JITTING
16:53 brrt in other words
16:53 brrt maybe we should generate bytecode from a different IR than from moarvm opcodes
16:54 jnthn brrt: No, you just JIT things that contain ops you know how to JIT.
16:54 jnthn brrt: JIT should be frame level anyway.
16:54 brrt how large is a frame level?
16:55 TimToady about the same size as a frame, so maybe about as big as a house?
16:55 jnthn Method/sub/non-inlined block.
16:56 brrt right
16:56 * brrt is thinking a bit
16:57 brrt i don't think i agree entirely
16:58 brrt that is to say, i think the biggest gains of JIT-ing in a very-high-level language such as p6 will be due to making routine calls faster
16:58 brrt i.e. p6 has rather complex parameter binding semantics iirc
16:59 japhb__ brrt: Many opcodes for same-size functionality space is just another way of providing information to the JIT. It's when you have many opcodes that sprawl over a much larger functionality space that it gets to be painfully more work, I should think.
16:59 jnthn Yeah, though the pre-JIT specializer work will help a lot on those too. And JIT can take it a step further...
16:59 brrt but for routines that have simple parameters or that are allways called in the same manner (from a certain site) you'd want to optimise that to as simple as possible
16:59 brrt good point japhb__ :-)
16:59 jnthn Ah, I was unclear in what I wrote, and now see what you meant.
17:00 jnthn I wasn't saying we shouldn't do inter-procedural opts, inlining, etc.
17:00 jnthn Just that we shouldn't have to be able to JIT every single op used in an entire compilation unit in order to JIT at all.
17:00 brrt i agree
17:01 brrt but i'm not sure the bytecode format is a good 'starting point' for a JIT compiler :-)
17:01 TimToady .oO(All ops are equal, but some are more equal than others.)
17:01 brrt i believe - totally unsure - the hotspot compiler does a form of 'decompiling' before JIT-ing
17:01 jnthn Right, nor is it for any kind of optimization, which is why the stuff I've been working on locally builds a CFG...
17:02 jnthn With instruction nodes, etc.
17:02 brrt and v8 is said to use the original source
17:03 brrt ok i see
17:03 jnthn Which should be in SSA form also, which should help further.
17:03 brrt uhuh
17:03 * brrt is only now reading the 'dragon book'
17:05 jnthn The bytecode specializer will produce bytecode with some non-userspace-accessible instruction codes based on "proofs" it can do with runtime info. I suspect a similar approach can be used in order to take things apart or re-structure them for JITting.
17:05 jnthn (At the tree level.)
17:06 brrt what bytecode specializer do you refer too? the one for moarvm-bytecode or for jit-opcode? can i read the source? :-)
17:07 jnthn brrt: The thing that's still mostly in my head, that I promise to turn into code as soon as we've got the Moar star out of the door :)
17:09 jnthn brrt: But basically, it will 1) take hot bytecode, 2) build an SSA data structure, 3) in conjunction with runtime-known stuff, produce specialized bytecode from it, and 4) turn it back into improve bytecode, registering what we assumed so we can undo it if things change.
17:10 jnthn *improved
17:10 brrt ok understood
17:10 brrt thats still mvm-level bytecode isn't it?
17:11 brrt again, learning from v8, it is said to use the original source + runtime information for creating specialised (native) bytecode
17:12 jnthn yes, mvm-level
17:12 brrt which is possible because memory is cheap and javascript programs are small
17:12 brrt ok, so in that case the JIT could use some / many of the same mechanisms but not the ultimate bytecode generation
17:12 jnthn Yes, that was my design idea. :)
17:12 brrt then i understand it :-)
17:13 brrt interesting
17:13 jnthn One reason we have a bunch of ops is to try and keep the semantic information to let us do a good job of optimizing without having source-level knowledge.
17:13 brrt ok, why don't you want source-level knowledge?
17:13 jnthn It leads to a rather tight compiler/runtime coupling.
17:14 jnthn Which if you've v8 and your language is very stable is fine.
17:14 brrt that is true, i guess
17:14 jnthn *you're
17:14 jnthn Also, JavaScript is rather smaller than Perl 6 :)
17:14 brrt also true
17:15 * brrt is, by the way, a bit of angry about the 'wat' video that keeps coming up
17:15 brrt yeah javascript is a bit over-dwimmy wrt comparisons
17:15 brrt many languages do the same
17:16 brrt nobody / too few people gives java a hard time about == meaning identity comparison for objects
17:16 brrt which is just as unintuitive
17:17 jnthn I think the issue there is that you can either have static types and overload operators with different semantics, or give operators one semantic and have them coerce types freely, but the multiple semantics and automatic coercion mix tends to lead to more surprises.
17:18 jnthn The == thing in Java is a mess.
17:18 jnthn "foo" == someString // that's a reference comp, wtf. :/
17:18 brrt precisely :-)
17:18 TimToady you must surprise Some of the people All of the Things!
17:19 jnthn Every single Java program I write ends up with that bug at some point. Thankfully I don't write many of them :)
17:19 brrt equality is a difficult problem - ask frege
17:19 brrt :-)
17:19 TimToady or orwell
17:19 brrt don't know what orwell has written about it
17:20 TimToady some of the things he writes about it are more equal than others
17:20 brrt oh i see :-) animal farm
17:26 brrt what confuses me most is that there are so many different semantics
17:27 brrt :-)
17:44 woolfy left #moarvm
17:53 * brrt dining
17:54 masak oh, I know Frege had conceptual problems in his works, but I didn't know they related somehow to equality.
17:54 masak I know category theory has three different notions of it, though, on different levels.
18:17 FROGGS joined #moarvm
18:29 lue TimToady: not like I've never put my name anywhere, I just don't like websites asking for it when it seems unnecessary :P
19:25 TimToady lue: but does that indicate Natural Intelligence or Artificial Intelligence? :)
19:26 lue :)
19:27 zakharyas joined #moarvm
19:27 TimToady if I were an AI, I'd put out a fake real name as bait, to see who was coming after me :)
19:29 TimToady as they say, they absence of smoke proves the fire is carefully hidden :)
19:29 TimToady *the
19:32 TimToady TimToady's Inequality: For every secret, there are many unequal and not-quite-opposite conspiracy theories.
19:32 lue .oO(The teapot is actually a government espresso machine!)
19:54 timotimo jnthn: did you look at the output from $l_line?
19:57 timotimo "l_line" => "gcc -shared -fPIC  -O1 -DNDEBUG -g3 -Wl,-rpath,\$(PREFIX)/lib -lm -lpthread -lrt -ldl -o 01-arglesslib.so 01-argless.o"
19:58 timotimo the \$(PREFIX) arguably should have been expanded when writing this string to wherever it is
20:00 timotimo well, they ought to be expanded by *something* at *some* point
20:01 timotimo in parrot's $*VM these variables seem to be expanded
20:02 timotimo build systems *shudder*
20:09 timotimo now i'm wondering by what heuristic to put self.intern calls into the actions
20:12 jnthn timotimo: I think we could just s/// it out
20:16 timotimo mhh
20:20 timotimo hm. in NQP, will ~$foo give the identical object back if it's already a string?
20:40 jnthn It'll probably unbox it
20:40 timotimo unbox and rebox?
20:41 timotimo so same MVMString, but different P6str?
20:41 jnthn If you manage to ~ in a context that needs to, yeah
20:41 jnthn ~ in NQP is "give me a str"
20:41 timotimo yeah
20:42 timotimo i still segfault :\
20:42 jnthn What backend are you on? Try it on one that is less explodey over null...
20:42 jnthn (if you're using Moar)
20:43 timotimo moar, yeah
20:43 timotimo even worse, when i stash my changes and try to rebuild, it doesn't fail any more
20:48 jnthn well, then your changes are to blame, no? :)
20:48 timotimo yes
21:21 cognominal joined #moarvm
21:23 cognominal joined #moarvm
22:20 dalek Heuristic branch merge: pushed 84 commits to MoarVM/moar-conc by jnthn
22:21 dalek joined #moarvm
22:30 timotimo ooooh
22:30 jnthn Just updating the branch. :)
22:31 TimToady we wants it, my precioussss
22:31 jnthn Turns out I'd rather face a parallel GC bug than a Makefile split job :P
23:08 timotimo :D
23:31 dalek MoarVM/moar-conc: 6ec25c5 | jnthn++ | src/ (4 files):
23:31 dalek MoarVM/moar-conc: Eliminate the new_child mechanism.
23:31 dalek MoarVM/moar-conc:
23:31 dalek MoarVM/moar-conc: Causes a deadlock, couldn't figure out what it was trying to deal
23:31 dalek MoarVM/moar-conc: with, didn't actually work like it said anyway, and spawning a thread
23:31 dalek MoarVM/moar-conc: triggering an immediate GC run seems less than ideal.
23:31 dalek MoarVM/moar-conc: review: https://github.com/MoarVM/MoarVM/commit/6ec25c5da7
23:31 dalek MoarVM/moar-conc: f9ac15d | jnthn++ | src/gc/collect.c:
23:31 dalek MoarVM/moar-conc: Move corruption check to after work pass.
23:31 dalek MoarVM/moar-conc:
23:31 dalek MoarVM/moar-conc: If the work belongs to another thread, it makes no sense to check.
23:31 dalek MoarVM/moar-conc: review: https://github.com/MoarVM/MoarVM/commit/f9ac15d12d
23:31 dalek MoarVM/moar-conc: ce2ee48 | jnthn++ | src/gc/collect.c:
23:32 jnthn The real, nasty bug I'm currently hunting is that some of the workload just gets dropped.
23:37 jnthn Don't think I'll find it tonight, but I know where to look now, at least.

| Channels | #moarvm index | Today | | Search | Google Search | Plain-Text | summary