Skip to content

Commit

Permalink
fs, refactor: support FileHandle promisify in fs.promises.open.
Browse files Browse the repository at this point in the history
  • Loading branch information
xicilion committed Aug 30, 2023
1 parent a2eb1b5 commit 50c0e6f
Show file tree
Hide file tree
Showing 155 changed files with 1,045 additions and 282 deletions.
109 changes: 95 additions & 14 deletions fibjs/include/ClassInfo.h
Expand Up @@ -70,24 +70,30 @@ struct ClassData {
const ClassIndexed* cis;
const ClassNamed* cns;
ClassInfo* base;
bool has_async;
};

result_t promisify(Isolate* isolate, v8::Local<v8::Function> func, v8::Local<v8::Function>& retVal);
result_t promisify(Isolate* isolate, v8::Local<v8::Function> func, v8::Local<v8::FunctionTemplate>& retVal);

class ClassInfo {
public:
class cache {
public:
cache()
: m_init_isolate(false)
: m_init_isolate(0)
{
}

public:
int32_t m_init_isolate;

v8::Global<v8::FunctionTemplate> m_class;
v8::Global<v8::Function> m_function;
v8::Global<v8::Object> m_cache;
bool m_init_isolate;
v8::Global<v8::Function> m_function;

v8::Global<v8::FunctionTemplate> m_pclass;
v8::Global<v8::Object> m_pcache;
};

public:
Expand Down Expand Up @@ -125,6 +131,17 @@ class ClassInfo {
return _init(isolate)->m_cache.Get(isolate->m_isolate)->Clone();
}

v8::Local<v8::Value> GetAsyncPrototype(Isolate* isolate)
{
assert(!m_cd.module);
return _init(isolate)->m_pcache.Get(isolate->m_isolate)->GetPrototype();
}

bool hasAsync()
{
return m_cd.has_async;
}

bool isInstance(ClassInfo& ci)
{
ClassInfo* _ci = &ci;
Expand All @@ -140,10 +157,11 @@ class ClassInfo {
bool init_isolate(Isolate* isolate)
{
cache* _cache = _init(isolate);
if (_cache->m_init_isolate)

if (_cache->m_init_isolate > (m_cd.has_async ? 1 : 0))
return false;

_cache->m_init_isolate = true;
_cache->m_init_isolate++;
return true;
}

Expand Down Expand Up @@ -338,49 +356,93 @@ class ClassInfo {
v8::Local<v8::Context> context = isolate->context();

if (!m_cd.module) {
v8::Local<v8::FunctionTemplate> _pclass;
v8::Local<v8::FunctionTemplate> _class = v8::FunctionTemplate::New(
isolate->m_isolate, m_cd.cor);
_class->SetClassName(isolate->NewString(m_cd.name));

_cache->m_class.Reset(isolate->m_isolate, _class);

_class->SetClassName(isolate->NewString(m_cd.name));
if (m_cd.has_async) {
_pclass = v8::FunctionTemplate::New(isolate->m_isolate, m_cd.cor);
_pclass->SetClassName(isolate->NewString(m_cd.name));

_cache->m_pclass.Reset(isolate->m_isolate, _pclass);
} else
_cache->m_pclass.Reset(isolate->m_isolate, _class);

if (m_cd.base) {
cache* _cache1 = m_cd.base->_init(isolate);
_class->Inherit(_cache1->m_class.Get(isolate->m_isolate));
if (m_cd.has_async)
_pclass->Inherit(_cache1->m_pclass.Get(isolate->m_isolate));
}

v8::Local<v8::ObjectTemplate> pt = _class->PrototypeTemplate();
int32_t i;

pt->Set(get_prop_name(isolate, "@toStringTag"), isolate->NewString(m_cd.name));

v8::Local<v8::ObjectTemplate> ppt;
if (m_cd.has_async) {
ppt = _pclass->PrototypeTemplate();
ppt->Set(get_prop_name(isolate, "@toStringTag"), isolate->NewString(m_cd.name));
}

int32_t i;
for (i = 0; i < m_cd.mc; i++)
if (!m_cd.cms[i].is_static)
pt->Set(get_prop_name(isolate, m_cd.cms[i].name),
v8::FunctionTemplate::New(isolate->m_isolate, m_cd.cms[i].invoker));
if (!m_cd.cms[i].is_static) {
v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(isolate->m_isolate, m_cd.cms[i].invoker);

pt->Set(get_prop_name(isolate, m_cd.cms[i].name), ft);
if (m_cd.has_async) {
if (!m_cd.cms[i].is_async)
ppt->Set(get_prop_name(isolate, m_cd.cms[i].name), ft);
else {
v8::Local<v8::FunctionTemplate> pft;
promisify(isolate, ft->GetFunction(context).FromMaybe(v8::Local<v8::Function>()), pft);
ppt->Set(get_prop_name(isolate, m_cd.cms[i].name), pft);
}
}
}

for (i = 0; i < m_cd.pc; i++)
if (!m_cd.cps[i].is_static)
if (!m_cd.cps[i].is_static) {
pt->SetAccessor(get_prop_name(isolate, m_cd.cps[i].name),
m_cd.cps[i].getter, m_cd.cps[i].setter,
v8::Local<v8::Value>(), v8::DEFAULT, v8::DontDelete);
if (m_cd.has_async)
ppt->SetAccessor(get_prop_name(isolate, m_cd.cps[i].name),
m_cd.cps[i].getter, m_cd.cps[i].setter,
v8::Local<v8::Value>(), v8::DEFAULT, v8::DontDelete);
}

for (i = 0; i < m_cd.cc; i++) {
pt->Set(isolate->NewString(m_cd.ccs[i].name),
v8::Integer::New(isolate->m_isolate, m_cd.ccs[i].value));
if (m_cd.has_async)
ppt->Set(isolate->NewString(m_cd.ccs[i].name),
v8::Integer::New(isolate->m_isolate, m_cd.ccs[i].value));
}

v8::Local<v8::ObjectTemplate> ot = _class->InstanceTemplate();
ot->SetInternalFieldCount(1);

v8::Local<v8::ObjectTemplate> pot;
if (m_cd.has_async) {
pot = _pclass->InstanceTemplate();
pot->SetInternalFieldCount(1);
}

ClassData* pcd;

pcd = &m_cd;
while (pcd && !pcd->cis)
pcd = pcd->base ? &pcd->base->m_cd : NULL;

if (pcd)
if (pcd) {
ot->SetIndexedPropertyHandler(pcd->cis->getter, pcd->cis->setter);
if (m_cd.has_async)
pot->SetIndexedPropertyHandler(pcd->cis->getter, pcd->cis->setter);
}

pcd = &m_cd;
while (pcd && !pcd->cns)
Expand All @@ -390,9 +452,17 @@ class ClassInfo {
ot->SetHandler(v8::NamedPropertyHandlerConfiguration(
pcd->cns->getter, pcd->cns->setter, nullptr, pcd->cns->remover, pcd->cns->enumerator, v8::Local<v8::Value>(),
v8::PropertyHandlerFlags::kOnlyInterceptStrings));

if (m_cd.has_async)
pot->SetHandler(v8::NamedPropertyHandlerConfiguration(
pcd->cns->getter, pcd->cns->setter, nullptr, pcd->cns->remover, pcd->cns->enumerator, v8::Local<v8::Value>(),
v8::PropertyHandlerFlags::kOnlyInterceptStrings));
}
if (m_cd.caf)
if (m_cd.caf) {
ot->SetCallAsFunctionHandler(m_cd.caf);
if (m_cd.has_async)
pot->SetCallAsFunctionHandler(m_cd.caf);
}

v8::Local<v8::Function> _function = _class->GetFunction(context).FromMaybe(v8::Local<v8::Function>());
_cache->m_function.Reset(isolate->m_isolate, _function);
Expand All @@ -403,6 +473,17 @@ class ClassInfo {
_cache->m_cache.Reset(isolate->m_isolate, o);

Attach(isolate, _function);

if (m_cd.has_async) {
v8::Local<v8::Function> _pfunction = _pclass->GetFunction(context).FromMaybe(v8::Local<v8::Function>());

v8::Local<v8::Object> po = _pfunction->NewInstance(isolate->context()).FromMaybe(v8::Local<v8::Object>());

po->SetAlignedPointerInInternalField(0, 0);
_cache->m_pcache.Reset(isolate->m_isolate, po);
} else
_cache->m_pcache.Reset(isolate->m_isolate, o);

} else {
v8::Local<v8::Object> o;

Expand Down
25 changes: 24 additions & 1 deletion fibjs/include/File.h
@@ -1,6 +1,7 @@
#pragma once

#include "ifs/File.h"
#include "ifs/FileHandle.h"
#include "Stat.h"
#include "utf8.h"
#include "Buffer.h"
Expand Down Expand Up @@ -135,4 +136,26 @@ inline result_t file_open(exlib::string fname, exlib::string flags, int32_t mode
#endif
return 0;
}
}

class FileHandle : public FileHandle_base {
public:
FileHandle(int32_t fd)
: m_fd(fd)
{
}

public:
// FileHandle_base
virtual result_t get_fd(int32_t& retVal);
virtual result_t chmod(int32_t mode, AsyncEvent* ac);
virtual result_t stat(obj_ptr<Stat_base>& retVal, AsyncEvent* ac);
virtual result_t read(Buffer_base* buffer, int32_t offset, int32_t length, int32_t position, int32_t& retVal, AsyncEvent* ac);
virtual result_t write(Buffer_base* buffer, int32_t offset, int32_t length, int32_t position, int32_t& retVal, AsyncEvent* ac);
virtual result_t write(exlib::string string, int32_t position, exlib::string encoding, int32_t& retVal, AsyncEvent* ac);
virtual result_t close(AsyncEvent* ac);

private:
int32_t m_fd;
};

} // namespace fibjs
3 changes: 2 additions & 1 deletion fibjs/include/ifs/BlsKey.h
Expand Up @@ -82,7 +82,8 @@ inline ClassInfo& BlsKey_base::class_info()
static ClassData s_cd = {
"BlsKey", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&ECKey_base::class_info()
&ECKey_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/Buffer.h
Expand Up @@ -263,7 +263,8 @@ inline ClassInfo& Buffer_base::class_info()
static ClassData s_cd = {
"Buffer", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, ARRAYSIZE(s_object), s_object, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&object_base::class_info()
&object_base::class_info(),
false
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/BufferedStream.h
Expand Up @@ -89,7 +89,8 @@ inline ClassInfo& BufferedStream_base::class_info()
static ClassData s_cd = {
"BufferedStream", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&Stream_base::class_info()
&Stream_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/Chain.h
Expand Up @@ -47,7 +47,8 @@ inline ClassInfo& Chain_base::class_info()
static ClassData s_cd = {
"Chain", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, 0, NULL, 0, NULL, NULL, NULL,
&Handler_base::class_info()
&Handler_base::class_info(),
false
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/ChildProcess.h
Expand Up @@ -100,7 +100,8 @@ inline ClassInfo& ChildProcess_base::class_info()
static ClassData s_cd = {
"ChildProcess", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&EventEmitter_base::class_info()
&EventEmitter_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/Cipher.h
Expand Up @@ -76,7 +76,8 @@ inline ClassInfo& Cipher_base::class_info()
static ClassData s_cd = {
"Cipher", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&object_base::class_info()
&object_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/Condition.h
Expand Up @@ -53,7 +53,8 @@ inline ClassInfo& Condition_base::class_info()
static ClassData s_cd = {
"Condition", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, 0, NULL, 0, NULL, NULL, NULL,
&Lock_base::class_info()
&Lock_base::class_info(),
false
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/DbConnection.h
Expand Up @@ -136,7 +136,8 @@ inline ClassInfo& DbConnection_base::class_info()
static ClassData s_cd = {
"DbConnection", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&object_base::class_info()
&object_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/DgramSocket.h
Expand Up @@ -93,7 +93,8 @@ inline ClassInfo& DgramSocket_base::class_info()
static ClassData s_cd = {
"DgramSocket", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, 0, NULL, 0, NULL, NULL, NULL,
&EventEmitter_base::class_info()
&EventEmitter_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/Digest.h
Expand Up @@ -73,7 +73,8 @@ inline ClassInfo& Digest_base::class_info()
static ClassData s_cd = {
"Digest", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&object_base::class_info()
&object_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/ECKey.h
Expand Up @@ -66,7 +66,8 @@ inline ClassInfo& ECKey_base::class_info()
static ClassData s_cd = {
"ECKey", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&PKey_base::class_info()
&PKey_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/Ed25519Key.h
Expand Up @@ -53,7 +53,8 @@ inline ClassInfo& Ed25519Key_base::class_info()
static ClassData s_cd = {
"Ed25519Key", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, 0, NULL, 0, NULL, NULL, NULL,
&ECKey_base::class_info()
&ECKey_base::class_info(),
true
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/Event.h
Expand Up @@ -58,7 +58,8 @@ inline ClassInfo& Event_base::class_info()
static ClassData s_cd = {
"Event", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, 0, NULL, 0, NULL, NULL, NULL,
&Lock_base::class_info()
&Lock_base::class_info(),
false
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/EventEmitter.h
Expand Up @@ -105,7 +105,8 @@ inline ClassInfo& EventEmitter_base::class_info()
static ClassData s_cd = {
"EventEmitter", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, ARRAYSIZE(s_object), s_object, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&object_base::class_info()
&object_base::class_info(),
false
};

static ClassInfo s_ci(s_cd);
Expand Down
3 changes: 2 additions & 1 deletion fibjs/include/ifs/FSWatcher.h
Expand Up @@ -67,7 +67,8 @@ inline ClassInfo& FSWatcher_base::class_info()
static ClassData s_cd = {
"FSWatcher", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&EventEmitter_base::class_info()
&EventEmitter_base::class_info(),
false
};

static ClassInfo s_ci(s_cd);
Expand Down

0 comments on commit 50c0e6f

Please sign in to comment.