Skip to content

Commit

Permalink
Improved node port and added metacallfms.
Browse files Browse the repository at this point in the history
  • Loading branch information
viferga committed Aug 14, 2024
1 parent b31ccab commit 649a054
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 8 deletions.
112 changes: 106 additions & 6 deletions source/loaders/node_loader/source/node_loader_port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ napi_value node_loader_port_metacall(napi_env env, napi_callback_info info)
if (argc == 0)
{
napi_throw_error(env, nullptr, "Invalid number of arguments");

return nullptr;
}

Expand All @@ -65,7 +64,8 @@ napi_value node_loader_port_metacall(napi_env env, napi_callback_info info)
if (name == nullptr)
{
napi_throw_error(env, nullptr, "Invalid function name allocation");

delete[] argv;
delete[] args;
return nullptr;
}

Expand Down Expand Up @@ -114,6 +114,105 @@ napi_value node_loader_port_metacall(napi_env env, napi_callback_info info)
return result;
}

napi_value node_loader_port_metacallfms(napi_env env, napi_callback_info info)
{
size_t argc = 0;

napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);

if (argc != 2)
{
napi_throw_error(env, nullptr, "Invalid number of arguments");
return nullptr;
}

napi_value *argv = new napi_value[argc];
napi_value recv;

napi_get_cb_info(env, info, &argc, argv, &recv, nullptr);

size_t name_length;
napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &name_length);

char *name = new char[name_length + 1];

if (name == nullptr)
{
napi_throw_error(env, nullptr, "Invalid function name allocation");
delete[] argv;
return nullptr;
}

status = napi_get_value_string_utf8(env, argv[0], name, name_length + 1, &name_length);

name[name_length] = '\0';

node_loader_impl_exception(env, status);

void *func = metacall_function(name);

if (func == NULL)
{
napi_throw_error(env, nullptr, "The function does not exist");
delete[] argv;
delete[] name;
return nullptr;
}

size_t buffer_length;
status = napi_get_value_string_utf8(env, argv[1], nullptr, 0, &buffer_length);

char *buffer = new char[buffer_length + 1];

if (buffer == nullptr)
{
napi_throw_error(env, nullptr, "Invalid function buffer allocation");
delete[] argv;
delete[] name;
return nullptr;
}

status = napi_get_value_string_utf8(env, argv[1], buffer, buffer_length + 1, &buffer_length);

buffer[buffer_length] = '\0';

node_loader_impl_exception(env, status);

/* Obtain NodeJS loader implementation */
loader_impl impl = loader_get_impl(node_loader_tag);
loader_impl_node node_impl = (loader_impl_node)loader_impl_get(impl);

/* Store current reference of the environment */
node_loader_impl_env(node_impl, env);

struct metacall_allocator_std_type std_ctx = { &std::malloc, &std::realloc, &std::free };

void *allocator = metacall_allocator_create(METACALL_ALLOCATOR_STD, (void *)&std_ctx);

/* Call to the function */
void *ret = metacallfms(func, buffer, buffer_length + 1, allocator);

metacall_allocator_destroy(allocator);

napi_value result = node_loader_impl_value_to_napi(node_impl, env, ret);

if (metacall_value_id(ret) == METACALL_THROWABLE)
{
napi_throw(env, result);
}

/* Release current reference of the environment */
// node_loader_impl_env(node_impl, nullptr);

metacall_value_destroy(ret);

delete[] argv;
delete[] name;
delete[] buffer;

return result;
}

napi_value node_loader_port_metacall_await(napi_env env, napi_callback_info info)
{
size_t argc = 0;
Expand All @@ -123,7 +222,6 @@ napi_value node_loader_port_metacall_await(napi_env env, napi_callback_info info
if (argc == 0)
{
napi_throw_error(env, nullptr, "Invalid number of arguments");

return nullptr;
}

Expand All @@ -142,7 +240,8 @@ napi_value node_loader_port_metacall_await(napi_env env, napi_callback_info info
if (name == nullptr)
{
napi_throw_error(env, nullptr, "Invalid function name allocation");

delete[] argv;
delete[] args;
return nullptr;
}

Expand Down Expand Up @@ -414,8 +513,8 @@ napi_value node_loader_port_metacall_load_from_memory(napi_env env, napi_callbac

if (script == nullptr)
{
delete[] tag;
napi_throw_error(env, nullptr, "MetaCall could not load from memory, script allocation failed");
delete[] tag;
return nullptr;
}

Expand Down Expand Up @@ -489,8 +588,8 @@ napi_value node_loader_port_metacall_load_from_memory_export(napi_env env, napi_

if (script == nullptr)
{
delete[] tag;
napi_throw_error(env, nullptr, "MetaCall could not load from memory, script allocation failed");
delete[] tag;
return nullptr;
}

Expand Down Expand Up @@ -715,6 +814,7 @@ void node_loader_port_exports(napi_env env, napi_value exports)

#define NODE_LOADER_PORT_DECL_X_MACRO(x) \
x(metacall); \
x(metacallfms); \
x(metacall_await); \
x(metacall_load_from_file); \
x(metacall_load_from_file_export); \
Expand Down
1 change: 1 addition & 0 deletions source/ports/node_port/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
declare module 'metacall' {
export function metacall(name: string, ...args: any): any;
export function metacallfms(name: string, buffer: string): any;
export function metacall_load_from_file(tag: string, paths: string[]): number;
export function metacall_load_from_file_export(tag: string, paths: string[]): any;
export function metacall_load_from_memory(tag: string, code: string): number;
Expand Down
15 changes: 14 additions & 1 deletion source/ports/node_port/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ const metacall = (name, ...args) => {
return addon.metacall(name, ...args);
};

const metacallfms = (name, buffer) => {
if (Object.prototype.toString.call(name) !== '[object String]') {
throw Error('Function name should be of string type.');
}

if (Object.prototype.toString.call(buffer) !== '[object String]') {
throw Error('Buffer should be of string type.');
}

return addon.metacallfms(name, buffer);
};

const metacall_await = (name, ...args) => {
if (Object.prototype.toString.call(name) !== '[object String]') {
throw Error('Function name should be of string type.');
Expand Down Expand Up @@ -172,7 +184,7 @@ const metacall_handle = (tag, name) => {
// TODO: This can be implemented with metacall_handle C API, meanwhile we use this trick
const inspect = metacall_inspect();

if (inspect === {} || inspect === undefined) {
if (inspect === undefined) {
return null;
}

Expand All @@ -192,6 +204,7 @@ const metacall_require = (tag, name) => {
/* Module exports */
const module_exports = {
metacall,
metacallfms,
metacall_await,
metacall_inspect,
metacall_load_from_file,
Expand Down
2 changes: 1 addition & 1 deletion source/ports/node_port/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const mocha = new Mocha();
const testDir = path.resolve(__dirname, 'test');

fs.readdirSync(testDir).filter((file) => {
return file.substr(-3) === '.js';
return path.extname(file) === '.js';
}).forEach((file) => {
mocha.addFile(
path.join(testDir, file)
Expand Down
9 changes: 9 additions & 0 deletions source/ports/node_port/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const assert = require('assert');

const {
metacall,
metacallfms,
metacall_load_from_file,
metacall_load_from_file_export,
metacall_load_from_memory,
Expand All @@ -37,6 +38,7 @@ describe('metacall', () => {
describe('defined', () => {
it('functions metacall and metacall_load_from_file must be defined', () => {
assert.notStrictEqual(metacall, undefined);
assert.notStrictEqual(metacallfms, undefined);
assert.notStrictEqual(metacall_load_from_memory, undefined);
assert.notStrictEqual(metacall_load_from_file, undefined);
assert.notStrictEqual(metacall_load_from_memory_export, undefined);
Expand Down Expand Up @@ -280,6 +282,13 @@ describe('metacall', () => {
}
});

describe('call by map', () => {
it('metacallfms (py)', () => {
assert.strictEqual(metacallfms('s_sum', '{"left":2,"right":2}'), 4);
assert.strictEqual(metacallfms('s_sum', '{"right":2,"left":2}'), 4);
});
});

describe('callback', () => {
it('callback (py)', () => {
const py_f = require('function.py');
Expand Down

0 comments on commit 649a054

Please sign in to comment.