Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/os.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,6 @@ if (binding.isBigEndian)
exports.endianness = function() { return 'BE'; };
else
exports.endianness = function() { return 'LE'; };

exports.sizeof = process.binding('sizeof');
exports.alignof = process.binding('alignof');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to cache a return result here? (Or is that already what the c++ does?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C++ layer already caches process.binding() results.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok cool, so long as this doesn't have to go through c++ each time it is accessed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lib/os.js also is only executed once (and the exports are cached), so yes, the values should basically be cached indefinitely.

2 changes: 2 additions & 0 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@
'src/node_i18n.cc',
'src/pipe_wrap.cc',
'src/signal_wrap.cc',
'src/sizeof.cc',
'src/alignof.cc',
'src/smalloc.cc',
'src/spawn_sync.cc',
'src/string_bytes.cc',
Expand Down
68 changes: 68 additions & 0 deletions src/alignof.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason why this is in a new file rather than src/node_os.cc?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No particularly good reason, but I was planning on using process.binding('sizeof').pointer within buffer.js in order to add correct offset validation to the read/writePointer() functions. We could easily just require('os').sizeof.pointer instead though. I'm open either way.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay! I don't have much experience with the C++ anyways, but perhaps someone else may have an opinion on it.

#include "env.h"
#include "env-inl.h"
#include "node.h"
#include "node_internals.h"
#include "v8-profiler.h"
#include "v8.h"

namespace node {
namespace _alignof {

using v8::Context;
using v8::Handle;
using v8::Object;
using v8::Persistent;
using v8::Uint32;
using v8::Value;


void Initialize(Handle<Object> exports,
Handle<Value> unused,
Handle<Context> context) {
Environment* env = Environment::GetCurrent(context);

#define SET_ALIGNOF(name, type) \
struct s_##name { type a; }; \
exports->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #name ), \
Uint32::NewFromUnsigned(env->isolate(), static_cast<uint32_t>(__alignof__(struct s_##name))));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you use alignof(type) here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget we're in C++ land sometimes :) Does that mean I can ditch the struct thing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, long line.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, no need for the struct.


// fixed alignments
SET_ALIGNOF(int8, int8_t);
SET_ALIGNOF(uint8, uint8_t);
SET_ALIGNOF(int16, int16_t);
SET_ALIGNOF(uint16, uint16_t);
SET_ALIGNOF(int32, int32_t);
SET_ALIGNOF(uint32, uint32_t);
SET_ALIGNOF(int64, int64_t);
SET_ALIGNOF(uint64, uint64_t);
SET_ALIGNOF(float, float);
SET_ALIGNOF(double, double);
SET_ALIGNOF(longdouble, long double);

// (potentially) variable alignments
SET_ALIGNOF(bool, bool);
SET_ALIGNOF(char, char);
SET_ALIGNOF(uchar, unsigned char);
SET_ALIGNOF(short, short);
SET_ALIGNOF(ushort, unsigned short);
SET_ALIGNOF(int, int);
SET_ALIGNOF(uint, unsigned int);
SET_ALIGNOF(long, long);
SET_ALIGNOF(ulong, unsigned long);
SET_ALIGNOF(longlong, long long);
SET_ALIGNOF(ulonglong, unsigned long long);
SET_ALIGNOF(pointer, char *);
SET_ALIGNOF(size_t, size_t);

// alignment of a Persistent handle to a JS object
SET_ALIGNOF(Object, Persistent<Object>);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the need for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove it (copy and paste oversight).

But as an explanation, in ref I have readObject() and writeObject(), which allow you to create and write the memory address of a Persistent<Object> handle to a Buffer instance, for later retrieval. It was more black magic / experimental though, and probably unsafe for use in core. At least for now. It's not necessary for the main "FFI in core" mission anyways, so we could revisit the idea once all this big stuff is landed.


#undef SET_ALIGNOF
}


} // namespace _alignof
} // namespace node

NODE_MODULE_CONTEXT_AWARE_BUILTIN(alignof, node::_alignof::Initialize)
69 changes: 69 additions & 0 deletions src/sizeof.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

#include "env.h"
#include "env-inl.h"
#include "node.h"
#include "node_internals.h"
#include "v8-profiler.h"
#include "v8.h"

namespace node {
namespace _sizeof {

using v8::Context;
using v8::Handle;
using v8::Isolate;
using v8::Object;
using v8::Persistent;
using v8::Uint32;
using v8::Value;


void Initialize(Handle<Object> exports,
Handle<Value> unused,
Handle<Context> context) {
Environment* env = Environment::GetCurrent(context);

// fixed sizes
#define SET_SIZEOF(name, type) \
exports->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #name ), \
Uint32::NewFromUnsigned(env->isolate(), static_cast<uint32_t>(sizeof( type ))));

SET_SIZEOF(int8, int8_t);
SET_SIZEOF(uint8, uint8_t);
SET_SIZEOF(int16, int16_t);
SET_SIZEOF(uint16, uint16_t);
SET_SIZEOF(int32, int32_t);
SET_SIZEOF(uint32, uint32_t);
SET_SIZEOF(int64, int64_t);
SET_SIZEOF(uint64, uint64_t);
SET_SIZEOF(float, float);
SET_SIZEOF(double, double);
SET_SIZEOF(longdouble, long double);

// (potentially) variable sizes
SET_SIZEOF(bool, bool);
SET_SIZEOF(byte, unsigned char);
SET_SIZEOF(char, char);
SET_SIZEOF(uchar, unsigned char);
SET_SIZEOF(short, short);
SET_SIZEOF(ushort, unsigned short);
SET_SIZEOF(int, int);
SET_SIZEOF(uint, unsigned int);
SET_SIZEOF(long, long);
SET_SIZEOF(ulong, unsigned long);
SET_SIZEOF(longlong, long long);
SET_SIZEOF(ulonglong, unsigned long long);
SET_SIZEOF(pointer, char *);
SET_SIZEOF(size_t, size_t);

// size of a Persistent handle to a JS object
SET_SIZEOF(Object, Persistent<Object>);

#undef SET_SIZEOF
}


} // namespace _sizeof
} // namespace node

NODE_MODULE_CONTEXT_AWARE_BUILTIN(sizeof, node::_sizeof::Initialize)