Skip to content

Commit

Permalink
[js] Allow calling methods on a wrapped js function
Browse files Browse the repository at this point in the history
Wrap js functions in a full class when passing them to Perl 6
land
  • Loading branch information
pmurias committed Jun 20, 2019
1 parent 33ed626 commit 4c5ec49
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/vm/js/nqp-runtime/core.js
Expand Up @@ -636,9 +636,7 @@ function fromJSToObject(ctx, obj) {
}

function fromJS(HLL, obj, isReturnValue, isArgument) {
if (typeof obj === 'function') {
return new WrappedFunction(obj);
} else if (obj === undefined || obj === null) {
if (obj === undefined || obj === null) {
return HLL.get('null_value');
} else if (obj === true) {
return HLL.get('true_value');
Expand Down Expand Up @@ -672,6 +670,11 @@ function fromJS(HLL, obj, isReturnValue, isArgument) {
return obj;
} else {
const type = HLL.get('js_box');

if (!type && typeof obj === 'function') {
return new WrappedFunction(obj);
}

const wrapped = type.$$STable.REPR.allocate(type.$$STable);
wrapped.$$jsObject = obj;
return wrapped;
Expand Down
15 changes: 15 additions & 0 deletions src/vm/js/nqp-runtime/reprs.js
Expand Up @@ -2569,10 +2569,25 @@ class WrappedJSObject extends REPR {
}

setupSTable(STable) {
this.hardcodedInvokeSpec = true;

STable.addInternalMethods(class {
$$can(ctx, name) {
return typeof this.$$jsObject[name] === 'function';
}

/*async*/ $$apply(args) {
const converted = [];
for (let i = 2; i < args.length; i++) {
converted.push(/*await*/ core.toJSWithCtx(args[0], args[i]));
}
return core.fromJSToReturnValue(args[0], this.$$jsObject.apply(null, converted));
}

$$call(args) {
return this.$$apply(arguments);
}

});
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/vm/js/nqp-runtime/sixmodel.js
Expand Up @@ -198,6 +198,10 @@ class STable {
}

setinvokespec(classHandle, attrName, invocationHandler) {
if (this.REPR.hardcodedInvokeSpec) {
return;
}

if (classHandle !== Null) {
/* TODO - think if we can use direct access here */
const getter = this.REPR.getterForAttr(classHandle, attrName);
Expand Down

0 comments on commit 4c5ec49

Please sign in to comment.