Skip to content

Commit b9ab65b

Browse files
committed
[js] Implemente simple conversion/wrapping of some basic things between NQP/native js.
1 parent b31afba commit b9ab65b

File tree

3 files changed

+67
-21
lines changed

3 files changed

+67
-21
lines changed

examples/webpacked/example.nqp

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
sub js($code) {
22
nqp::getcomp("JavaScript").eval($code);
33
}
4-
js('window.wrap = function(func) {return {"$call": func}}');
5-
js('window.unwrap = function(code_ref) {return function() {code_ref.$call(null, {})}}');
64

7-
my &set-draw := js('wrap(function($CTX, $NAMED, cb) {window.draw = unwrap(cb)})');
8-
my &set-setup := js('wrap(function($CTX, $NAMED, cb) {window.setup = unwrap(cb)})');
9-
my &fill := js('wrap(function($CTX, $NAMED, color) {fill(color.value)})');
10-
my &ellipse := js('wrap(function($CTX, $NAMED, a, b, c, d) {ellipse(a, b, c.value, d.value)})');
11-
my &createCanvas := js('wrap(function($CTX, $NAMED, width, height) {createCanvas(width.value, height.value)})');
12-
my &mouseX := js('wrap(function($CTX, $NAMED) {return mouseX})');
13-
my &mouseY := js('wrap(function($CTX, $NAMED) {return mouseY})');
14-
my &mouseIsPressed := js('wrap(function($CTX, $NAMED) {return mouseIsPressed ? 1 : 0})');
5+
my &set-draw := js('(function(cb) {window.draw = cb})');
6+
my &set-setup := js('(function(cb) {window.setup = cb})');
7+
my &mouseX := js('(function() {return mouseX})');
8+
my &mouseY := js('(function() {return mouseY})');
9+
my &mouseIsPressed := js('(function() {return mouseIsPressed ? 1 : 0})');
1510

1611
sub setup() {
12+
my &fill := js('fill');
13+
my &ellipse := js('ellipse');
14+
my &createCanvas := js('createCanvas');
15+
1716
createCanvas(640, 480);
18-
}
19-
sub draw() {
20-
if mouseIsPressed() {
21-
fill(0);
22-
} else {
23-
fill(255);
24-
}
25-
ellipse(mouseX(), mouseY(), 80, 80);
17+
set-draw(-> {
18+
if mouseIsPressed() {
19+
fill(0);
20+
} else {
21+
fill(255);
22+
}
23+
ellipse(mouseX(), mouseY(), 80, 80);
24+
});
2625
}
2726

2827
set-setup(&setup);
29-
set-draw(&draw);
3028

3129
nqp::say("Hello Fancy Browser World");

src/vm/js/nqp-runtime/core.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,49 @@ op.bindcomp = function(language, compiler) {
532532
return (compilerRegistry[language] = compiler);
533533
};
534534

535+
function WrappedFunction(func) {
536+
this.func = func;
537+
}
538+
539+
WrappedFunction.prototype.$apply = function(args) {
540+
var converted = [];
541+
for (var i = 2; i < args.length; i++) {
542+
converted.push(toJS(args[i]));
543+
}
544+
return fromJS(this.func.apply(null, converted));
545+
}
546+
547+
WrappedFunction.prototype.$call = function(args) {
548+
return this.$apply(arguments);
549+
}
550+
551+
function fromJS(obj) {
552+
if (typeof obj === 'function') {
553+
return new WrappedFunction(obj);
554+
} else {
555+
return obj;
556+
}
557+
}
558+
559+
function toJS(obj) {
560+
if (obj instanceof NQPInt) {
561+
return obj.value;
562+
} else if (obj instanceof CodeRef) {
563+
return function() {
564+
var converted = [null, {}];
565+
for (var i = 0; i < arguments.length; i++) {
566+
converted.push(fromJS(arguments[i]));
567+
}
568+
return toJS(obj.$apply(converted));
569+
};
570+
} else {
571+
return obj;
572+
}
573+
}
574+
535575
compilerRegistry['JavaScript'] = {
536576
eval: function(ctx, named, code) {
537-
return eval(code);
577+
return fromJS(eval(code));
538578
}
539579
};
540580

t/js/getcomp-js.t

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
plan(1);
1+
plan(3);
22
my $comp := nqp::getcomp('JavaScript');
33
my $helloworld := $comp.eval('"Hello " + "World"');
44
ok($helloworld eq 'Hello World',"getting a simple string from JavaScript");
5+
6+
my $square := $comp.eval('(function(num) {return num*num})');
7+
ok($square(4) == 16, "passing integers to a js func");
8+
9+
my $twice := $comp.eval('(function(func) {return function(x) {return func(func(x))}})');
10+
my $twiced := $twice(sub ($x) {"[$x]"})("abc");
11+
ok($twiced eq '[[abc]]', 'passing an calling a NQP function on the JavaScript side');
12+

0 commit comments

Comments
 (0)