Skip to content

Commit

Permalink
support fs and v8 binding
Browse files Browse the repository at this point in the history
  • Loading branch information
joyeecheung committed Jan 15, 2021
1 parent 07c87b1 commit 75283c6
Show file tree
Hide file tree
Showing 31 changed files with 679 additions and 343 deletions.
3 changes: 3 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ process.emitWarning = emitWarning;
// Note: only after this point are the timers effective
}

require('fs');
internalBinding('v8');

function setupPrepareStackTrace() {
const {
setEnhanceStackForFatalException,
Expand Down
3 changes: 3 additions & 0 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@
'src/node_report_module.cc',
'src/node_report_utils.cc',
'src/node_serdes.cc',
'src/node_serializable.cc',
'src/node_sockaddr.cc',
'src/node_stat_watcher.cc',
'src/node_symbols.cc',
Expand Down Expand Up @@ -740,12 +741,14 @@
'src/node_report.h',
'src/node_revert.h',
'src/node_root_certs.h',
'src/node_serializable.h',
'src/node_sockaddr.h',
'src/node_sockaddr-inl.h',
'src/node_stat_watcher.h',
'src/node_union_bytes.h',
'src/node_url.h',
'src/node_version.h',
'src/node_v8.h',
'src/node_v8_platform-inl.h',
'src/node_wasi.h',
'src/node_watchdog.h',
Expand Down
4 changes: 2 additions & 2 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ that state is through the use of `Environment::AddBindingData`, which gives
binding functions access to an object for storing such state.
That object is always a [`BaseObject`][].
Its class needs to have a static `binding_data_name` field based on a
Its class needs to have a static `type_name` field based on a
constant string, in order to disambiguate it from other classes of this type,
and which could e.g. match the binding’s name (in the example above, that would
be `cares_wrap`).
Expand All @@ -433,7 +433,7 @@ class BindingData : public BaseObject {
public:
BindingData(Environment* env, Local<Object> obj) : BaseObject(env, obj) {}
static constexpr FastStringKey binding_data_name { "http_parser" };
static constexpr FastStringKey type_name { "http_parser" };
std::vector<char> parser_buffer;
bool parser_buffer_in_use = false;
Expand Down
5 changes: 5 additions & 0 deletions src/aliased_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ class AliasedBufferBase {
return js_array_.Get(isolate_);
}

void Release() {
DCHECK_NULL(info_);
js_array_.Reset();
}

/**
* Get the underlying v8::ArrayBuffer underlying the TypedArray and
* overlaying the native buffer
Expand Down
10 changes: 2 additions & 8 deletions src/base_object-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,10 @@

namespace node {

BaseObject::BaseObject(Environment* env,
v8::Local<v8::Object> object,
InternalFieldType type)
: type_(type), persistent_handle_(env->isolate(), object), env_(env) {
BaseObject::BaseObject(Environment* env, v8::Local<v8::Object> object)
: persistent_handle_(env->isolate(), object), env_(env) {
CHECK_EQ(false, object.IsEmpty());
CHECK_GT(object->InternalFieldCount(), 0);
object->SetInternalField(BaseObject::kType,
v8::Integer::NewFromUnsigned(
env->isolate(), static_cast<uint32_t>(type)));
object->SetAlignedPointerInInternalField(
BaseObject::kSlot,
static_cast<void*>(this));
Expand Down Expand Up @@ -368,7 +363,6 @@ BaseObjectPtr<T> MakeDetachedBaseObject(Args&&... args) {
target->Detach();
return target;
}

} // namespace node

#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
Expand Down
11 changes: 1 addition & 10 deletions src/base_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
#include "v8.h"

namespace node {

enum class InternalFieldType : uint8_t { kDefault = 0, kFSBindingData };

class Environment;
template <typename T, bool kIsWeak>
class BaseObjectPtrImpl;
Expand All @@ -46,9 +43,7 @@ class BaseObject : public MemoryRetainer {

// Associates this object with `object`. It uses the 0th internal field for
// that, and in particular aborts if there is no such field.
inline BaseObject(Environment* env,
v8::Local<v8::Object> object,
InternalFieldType type = InternalFieldType::kDefault);
inline BaseObject(Environment* env, v8::Local<v8::Object> object);
inline ~BaseObject() override;

BaseObject() = delete;
Expand Down Expand Up @@ -111,9 +106,6 @@ class BaseObject : public MemoryRetainer {
// a BaseObjectPtr to this object.
inline void Detach();

// We'll make sure that the type is set in the constructor
InternalFieldType type() { return type_; }

static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);

Expand Down Expand Up @@ -166,7 +158,6 @@ class BaseObject : public MemoryRetainer {
virtual inline void OnGCCollect();

private:
InternalFieldType type_ = InternalFieldType::kDefault;
v8::Local<v8::Object> WrappedObject() const override;
bool IsRootNode() const override;
static void DeleteMe(void* data);
Expand Down
21 changes: 19 additions & 2 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ inline T* Environment::GetBindingData(v8::Local<v8::Context> context) {
context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kBindingListIndex));
DCHECK_NOT_NULL(map);
auto it = map->find(T::binding_data_name);
auto it = map->find(T::type_name);
if (UNLIKELY(it == map->end())) return nullptr;
T* result = static_cast<T*>(it->second.get());
DCHECK_NOT_NULL(result);
Expand All @@ -377,7 +377,7 @@ inline T* Environment::AddBindingData(
context->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kBindingListIndex));
DCHECK_NOT_NULL(map);
auto result = map->emplace(T::binding_data_name, item);
auto result = map->emplace(T::type_name, item);
CHECK(result.second);
DCHECK_EQ(GetBindingData<T>(context), item.get());
return item.get();
Expand Down Expand Up @@ -1081,6 +1081,17 @@ void Environment::ForEachBaseObject(T&& iterator) {
}
}

template <typename T>
void Environment::ForEachBindingData(T&& iterator) {
BindingDataStore* map = static_cast<BindingDataStore*>(
context()->GetAlignedPointerFromEmbedderData(
ContextEmbedderIndex::kBindingListIndex));
DCHECK_NOT_NULL(map);
for (auto& it : *map) {
iterator(it.first, it.second);
}
}

void Environment::modify_base_object_count(int64_t delta) {
base_object_count_ += delta;
}
Expand All @@ -1102,6 +1113,7 @@ void Environment::set_process_exit_handler(
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
#define VB(PropertyName, _) V(v8::String, PropertyName##_string)
#define V(TypeName, PropertyName) \
inline \
v8::Local<TypeName> IsolateData::PropertyName() const { \
Expand All @@ -1110,22 +1122,27 @@ void Environment::set_process_exit_handler(
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_SYMBOL_PROPERTIES(VY)
PER_ISOLATE_STRING_PROPERTIES(VS)
SERIALIZABLE_OBJECT_TYPES(VB)
#undef V
#undef VB
#undef VS
#undef VY
#undef VP

#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
#define VB(PropertyName, _) V(v8::String, PropertyName##_string)
#define V(TypeName, PropertyName) \
inline v8::Local<TypeName> Environment::PropertyName() const { \
return isolate_data()->PropertyName(); \
}
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_SYMBOL_PROPERTIES(VY)
PER_ISOLATE_STRING_PROPERTIES(VS)
SERIALIZABLE_OBJECT_TYPES(VB)
#undef V
#undef VB
#undef VS
#undef VY
#undef VP
Expand Down
30 changes: 30 additions & 0 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
#include "node_buffer.h"
#include "node_context_data.h"
#include "node_errors.h"
#include "node_file.h"
#include "node_internals.h"
#include "node_options-inl.h"
#include "node_process.h"
#include "node_v8.h"
#include "node_v8_platform-inl.h"
#include "node_worker.h"
#include "req_wrap-inl.h"
Expand Down Expand Up @@ -72,12 +74,15 @@ std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) {
#define VP(PropertyName, StringValue) V(Private, PropertyName)
#define VY(PropertyName, StringValue) V(Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(String, PropertyName)
#define VB(PropertyName, _) V(v8::String, PropertyName##_string)
#define V(TypeName, PropertyName) \
indexes.push_back(creator->AddData(PropertyName##_.Get(isolate)));
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_SYMBOL_PROPERTIES(VY)
PER_ISOLATE_STRING_PROPERTIES(VS)
SERIALIZABLE_OBJECT_TYPES(VB)
#undef V
#undef VB
#undef VY
#undef VS
#undef VP
Expand All @@ -94,6 +99,7 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {
#define VP(PropertyName, StringValue) V(Private, PropertyName)
#define VY(PropertyName, StringValue) V(Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(String, PropertyName)
#define VB(PropertyName, _) V(v8::String, PropertyName##_string)
#define V(TypeName, PropertyName) \
do { \
MaybeLocal<TypeName> maybe_field = \
Expand All @@ -107,7 +113,9 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_SYMBOL_PROPERTIES(VY)
PER_ISOLATE_STRING_PROPERTIES(VS)
SERIALIZABLE_OBJECT_TYPES(VB)
#undef V
#undef VB
#undef VY
#undef VS
#undef VP
Expand Down Expand Up @@ -172,6 +180,19 @@ void IsolateData::CreateProperties() {
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V

// Add strings of names of serializable object types.
#define V(PropertyName, NativeTypeName) \
PropertyName##_string_.Set( \
isolate_, \
String::NewFromOneByte( \
isolate_, \
reinterpret_cast<const uint8_t*>(NativeTypeName::type_name.c_str()), \
v8::NewStringType::kInternalized, \
-1) \
.ToLocalChecked());
SERIALIZABLE_OBJECT_TYPES(V)
#undef V

// Create all the provider strings that will be passed to JS. Place them in
// an array so the array index matches the PROVIDER id offset. This way the
// strings can be retrieved quickly.
Expand Down Expand Up @@ -215,6 +236,11 @@ void IsolateData::MemoryInfo(MemoryTracker* tracker) const {
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V

#define V(PropertyName, _) \
tracker->TrackField(#PropertyName, PropertyName##_string());
SERIALIZABLE_OBJECT_TYPES(V)
#undef V

tracker->TrackField("async_wrap_providers", async_wrap_providers_);

if (node_allocator_ != nullptr) {
Expand Down Expand Up @@ -1235,6 +1261,7 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
EnvSerializeInfo info;
Local<Context> ctx = context();

SerializeBindingData(this, creator, &info);
// Currently all modules are compiled without cache in builtin snapshot
// builder.
info.native_modules = std::vector<std::string>(
Expand Down Expand Up @@ -1301,6 +1328,9 @@ std::ostream& operator<<(std::ostream& output,

std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
output << "{\n"
<< "// -- bindings begins --\n"
<< i.bindings << ",\n"
<< "// -- bindings ends --\n"
<< "// -- native_modules begins --\n"
<< i.native_modules << ",\n"
<< "// -- native_modules ends --\n"
Expand Down

0 comments on commit 75283c6

Please sign in to comment.