Skip to content

Commit 649a054

Browse files
committed
Improved node port and added metacallfms.
1 parent b31ccab commit 649a054

File tree

5 files changed

+131
-8
lines changed

5 files changed

+131
-8
lines changed

source/loaders/node_loader/source/node_loader_port.cpp

Lines changed: 106 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ napi_value node_loader_port_metacall(napi_env env, napi_callback_info info)
4747
if (argc == 0)
4848
{
4949
napi_throw_error(env, nullptr, "Invalid number of arguments");
50-
5150
return nullptr;
5251
}
5352

@@ -65,7 +64,8 @@ napi_value node_loader_port_metacall(napi_env env, napi_callback_info info)
6564
if (name == nullptr)
6665
{
6766
napi_throw_error(env, nullptr, "Invalid function name allocation");
68-
67+
delete[] argv;
68+
delete[] args;
6969
return nullptr;
7070
}
7171

@@ -114,6 +114,105 @@ napi_value node_loader_port_metacall(napi_env env, napi_callback_info info)
114114
return result;
115115
}
116116

117+
napi_value node_loader_port_metacallfms(napi_env env, napi_callback_info info)
118+
{
119+
size_t argc = 0;
120+
121+
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
122+
123+
if (argc != 2)
124+
{
125+
napi_throw_error(env, nullptr, "Invalid number of arguments");
126+
return nullptr;
127+
}
128+
129+
napi_value *argv = new napi_value[argc];
130+
napi_value recv;
131+
132+
napi_get_cb_info(env, info, &argc, argv, &recv, nullptr);
133+
134+
size_t name_length;
135+
napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &name_length);
136+
137+
char *name = new char[name_length + 1];
138+
139+
if (name == nullptr)
140+
{
141+
napi_throw_error(env, nullptr, "Invalid function name allocation");
142+
delete[] argv;
143+
return nullptr;
144+
}
145+
146+
status = napi_get_value_string_utf8(env, argv[0], name, name_length + 1, &name_length);
147+
148+
name[name_length] = '\0';
149+
150+
node_loader_impl_exception(env, status);
151+
152+
void *func = metacall_function(name);
153+
154+
if (func == NULL)
155+
{
156+
napi_throw_error(env, nullptr, "The function does not exist");
157+
delete[] argv;
158+
delete[] name;
159+
return nullptr;
160+
}
161+
162+
size_t buffer_length;
163+
status = napi_get_value_string_utf8(env, argv[1], nullptr, 0, &buffer_length);
164+
165+
char *buffer = new char[buffer_length + 1];
166+
167+
if (buffer == nullptr)
168+
{
169+
napi_throw_error(env, nullptr, "Invalid function buffer allocation");
170+
delete[] argv;
171+
delete[] name;
172+
return nullptr;
173+
}
174+
175+
status = napi_get_value_string_utf8(env, argv[1], buffer, buffer_length + 1, &buffer_length);
176+
177+
buffer[buffer_length] = '\0';
178+
179+
node_loader_impl_exception(env, status);
180+
181+
/* Obtain NodeJS loader implementation */
182+
loader_impl impl = loader_get_impl(node_loader_tag);
183+
loader_impl_node node_impl = (loader_impl_node)loader_impl_get(impl);
184+
185+
/* Store current reference of the environment */
186+
node_loader_impl_env(node_impl, env);
187+
188+
struct metacall_allocator_std_type std_ctx = { &std::malloc, &std::realloc, &std::free };
189+
190+
void *allocator = metacall_allocator_create(METACALL_ALLOCATOR_STD, (void *)&std_ctx);
191+
192+
/* Call to the function */
193+
void *ret = metacallfms(func, buffer, buffer_length + 1, allocator);
194+
195+
metacall_allocator_destroy(allocator);
196+
197+
napi_value result = node_loader_impl_value_to_napi(node_impl, env, ret);
198+
199+
if (metacall_value_id(ret) == METACALL_THROWABLE)
200+
{
201+
napi_throw(env, result);
202+
}
203+
204+
/* Release current reference of the environment */
205+
// node_loader_impl_env(node_impl, nullptr);
206+
207+
metacall_value_destroy(ret);
208+
209+
delete[] argv;
210+
delete[] name;
211+
delete[] buffer;
212+
213+
return result;
214+
}
215+
117216
napi_value node_loader_port_metacall_await(napi_env env, napi_callback_info info)
118217
{
119218
size_t argc = 0;
@@ -123,7 +222,6 @@ napi_value node_loader_port_metacall_await(napi_env env, napi_callback_info info
123222
if (argc == 0)
124223
{
125224
napi_throw_error(env, nullptr, "Invalid number of arguments");
126-
127225
return nullptr;
128226
}
129227

@@ -142,7 +240,8 @@ napi_value node_loader_port_metacall_await(napi_env env, napi_callback_info info
142240
if (name == nullptr)
143241
{
144242
napi_throw_error(env, nullptr, "Invalid function name allocation");
145-
243+
delete[] argv;
244+
delete[] args;
146245
return nullptr;
147246
}
148247

@@ -414,8 +513,8 @@ napi_value node_loader_port_metacall_load_from_memory(napi_env env, napi_callbac
414513

415514
if (script == nullptr)
416515
{
417-
delete[] tag;
418516
napi_throw_error(env, nullptr, "MetaCall could not load from memory, script allocation failed");
517+
delete[] tag;
419518
return nullptr;
420519
}
421520

@@ -489,8 +588,8 @@ napi_value node_loader_port_metacall_load_from_memory_export(napi_env env, napi_
489588

490589
if (script == nullptr)
491590
{
492-
delete[] tag;
493591
napi_throw_error(env, nullptr, "MetaCall could not load from memory, script allocation failed");
592+
delete[] tag;
494593
return nullptr;
495594
}
496595

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

716815
#define NODE_LOADER_PORT_DECL_X_MACRO(x) \
717816
x(metacall); \
817+
x(metacallfms); \
718818
x(metacall_await); \
719819
x(metacall_load_from_file); \
720820
x(metacall_load_from_file_export); \

source/ports/node_port/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
declare module 'metacall' {
22
export function metacall(name: string, ...args: any): any;
3+
export function metacallfms(name: string, buffer: string): any;
34
export function metacall_load_from_file(tag: string, paths: string[]): number;
45
export function metacall_load_from_file_export(tag: string, paths: string[]): any;
56
export function metacall_load_from_memory(tag: string, code: string): number;

source/ports/node_port/index.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ const metacall = (name, ...args) => {
8282
return addon.metacall(name, ...args);
8383
};
8484

85+
const metacallfms = (name, buffer) => {
86+
if (Object.prototype.toString.call(name) !== '[object String]') {
87+
throw Error('Function name should be of string type.');
88+
}
89+
90+
if (Object.prototype.toString.call(buffer) !== '[object String]') {
91+
throw Error('Buffer should be of string type.');
92+
}
93+
94+
return addon.metacallfms(name, buffer);
95+
};
96+
8597
const metacall_await = (name, ...args) => {
8698
if (Object.prototype.toString.call(name) !== '[object String]') {
8799
throw Error('Function name should be of string type.');
@@ -172,7 +184,7 @@ const metacall_handle = (tag, name) => {
172184
// TODO: This can be implemented with metacall_handle C API, meanwhile we use this trick
173185
const inspect = metacall_inspect();
174186

175-
if (inspect === {} || inspect === undefined) {
187+
if (inspect === undefined) {
176188
return null;
177189
}
178190

@@ -192,6 +204,7 @@ const metacall_require = (tag, name) => {
192204
/* Module exports */
193205
const module_exports = {
194206
metacall,
207+
metacallfms,
195208
metacall_await,
196209
metacall_inspect,
197210
metacall_load_from_file,

source/ports/node_port/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const mocha = new Mocha();
2626
const testDir = path.resolve(__dirname, 'test');
2727

2828
fs.readdirSync(testDir).filter((file) => {
29-
return file.substr(-3) === '.js';
29+
return path.extname(file) === '.js';
3030
}).forEach((file) => {
3131
mocha.addFile(
3232
path.join(testDir, file)

source/ports/node_port/test/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const assert = require('assert');
2424

2525
const {
2626
metacall,
27+
metacallfms,
2728
metacall_load_from_file,
2829
metacall_load_from_file_export,
2930
metacall_load_from_memory,
@@ -37,6 +38,7 @@ describe('metacall', () => {
3738
describe('defined', () => {
3839
it('functions metacall and metacall_load_from_file must be defined', () => {
3940
assert.notStrictEqual(metacall, undefined);
41+
assert.notStrictEqual(metacallfms, undefined);
4042
assert.notStrictEqual(metacall_load_from_memory, undefined);
4143
assert.notStrictEqual(metacall_load_from_file, undefined);
4244
assert.notStrictEqual(metacall_load_from_memory_export, undefined);
@@ -280,6 +282,13 @@ describe('metacall', () => {
280282
}
281283
});
282284

285+
describe('call by map', () => {
286+
it('metacallfms (py)', () => {
287+
assert.strictEqual(metacallfms('s_sum', '{"left":2,"right":2}'), 4);
288+
assert.strictEqual(metacallfms('s_sum', '{"right":2,"left":2}'), 4);
289+
});
290+
});
291+
283292
describe('callback', () => {
284293
it('callback (py)', () => {
285294
const py_f = require('function.py');

0 commit comments

Comments
 (0)