Field tables can contain field arrays, and vice versa
Write message frames all at once if small enough

If the method, properties and content frames all fit in 2KB, copy them
into a single buffer and write that. The 2KB threshold is more or less
arbitrary, same as the "safely-sized" buffers allocated when encoding
-- it's based on some fairly vague reasoning around being sufficiently
smaller than the SlowBuffer allocation size.  The method and
properties for a message is on the order of 100 bytes (depending on
the strings supplied), so there's room for almost the full 2KB of
message content.

It turns out this is quite a boost for those small messages, even
though it involves more buffer allocations. Socket writes are just
expensive!

This further coalesces `sendMethodAndProperties`+`sendContent` to
`sendMessage`. Not sure why I had them separate in the first place.
Allocate buffers after the encoded size is known

Instead of checking whether every field is fixed and if not,
allocating a large buffer, calculate the size of fields that aren't
fixed-size first, then allocate the buffer to an exact size.

In the case of strings this just means getting the byte length
(assuming they are UTF8 as the AMQP specification requires). In the
case of tables, I have to encode them into a buffer first to get the
size; and once I've done that, I can keep the encoded table around to
copy into the full result.

Properties are a bit trickier because of the flags indicating
presence; this makes every field effectively variable size, since it
may or may not be present. I end up with two passes, one to calculate
the size and one to write the values.
Declare the decoding result with all fields

As I understand it, this avoids V8 switching the object's hidden class
every time a value is assigned to a field. The trade off is that V8
might allocate larger object than it needs to -- especially in the
case of properties, which may quite reasonably be empty. For that
reason, there's a shortcut when no flags are set in an encoded
properties.
Update changelog
Field values can be null