Skip to content

Commit 89f39c3

Browse files
committed
[js] Mangle all method names when compiling to js with a p6$ prefix
This will stop us from defining a then method that interfers with js Promises
1 parent e0e7944 commit 89f39c3

File tree

11 files changed

+86
-74
lines changed

11 files changed

+86
-74
lines changed

src/vm/js/Operations.nqp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -761,12 +761,12 @@ class QAST::OperationsJS {
761761

762762
my str $method;
763763
if $node.name {
764-
$method := '[' ~ quote_string($node.name) ~ ']';
764+
$method := '[' ~ quote_string('p6$' ~ $node.name) ~ ']';
765765
}
766766
else {
767767
my $method_name := $comp.as_js(@args.shift, :want($T_STR));
768768
@setup.push($method_name);
769-
$method := "[{$method_name.expr}]";
769+
$method := "[\"p6\$\" + {$method_name.expr}]";
770770
}
771771

772772
my $compiled_args := $comp.args(@args, :invocant($invocant.expr));
@@ -1157,7 +1157,7 @@ class QAST::OperationsJS {
11571157
my $check_cond;
11581158
if $is_withy {
11591159
my $deconted := $comp.await("{$cond.expr}.\$\$decont($*CTX)");
1160-
my $defined := $comp.await("$deconted.defined($*CTX, null, {$cond.expr})");
1160+
my $defined := $comp.await("$deconted.p6\$defined($*CTX, null, {$cond.expr})");
11611161
my $retvaled := "nqp.retval(HLL, $defined)";
11621162
$check_cond := Chunk.new($T_INT, $comp.await("$retvaled.\$\$toBool($*CTX)"), $cond);
11631163
} else {

src/vm/js/RegexCompiler.nqp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class RegexCompiler {
5252

5353
Chunk.new($T_OBJ, $!cursor, [
5454
"{$!label} = {$!initial_label};\n",
55-
"$start = ({$!compiler.await}$self['!cursor_start_all']({$*CTX}, null, $self)).array;\n",
55+
"$start = ({$!compiler.await}$self['p6\$!cursor_start_all']({$*CTX}, null, $self)).array;\n",
5656
"{$!cursor} = $start[0];\n",
5757
self.set_cursor_var(),
5858
"{$!target} = {$!compiler.await}nqp.toStr($start[1], $*CTX);\n",
@@ -85,7 +85,7 @@ class RegexCompiler {
8585
self.goto($jump),
8686

8787
self.case($!done_label),
88-
$!compiler.await ~ "{$!cursor}['!cursor_fail']({$*CTX}, null, $!cursor);\n",
88+
$!compiler.await ~ "{$!cursor}['p6\$!cursor_fail']({$*CTX}, null, $!cursor);\n",
8989
"break {$!js_loop_label}\n",
9090
"\}\n\}\n"
9191
]);
@@ -287,7 +287,7 @@ class RegexCompiler {
287287
my @setup;
288288

289289
@setup.push(
290-
$!compiler.await ~ "{$!cursor}['!cursor_pass']({$*CTX},"
290+
$!compiler.await ~ "{$!cursor}['p6\$!cursor_pass']({$*CTX},"
291291
~ "\{backtrack: new nqp.NQPInt({$node.backtrack ne 'r'})\}, $!cursor, new nqp.NQPInt({$!pos})"
292292
);
293293

@@ -331,7 +331,7 @@ class RegexCompiler {
331331
nqp::unshift(@args, $invocant);
332332
nqp::unshift(@args, 'null');
333333
nqp::unshift(@args, $*CTX);
334-
$!compiler.await($invocant ~ "[" ~ quote_string($method) ~ "](" ~ nqp::join(",", @args) ~ ")");
334+
$!compiler.await($invocant ~ "[" ~ quote_string('p6$' ~ $method) ~ "](" ~ nqp::join(",", @args) ~ ")");
335335
}
336336

337337
# We never autovifiy $!from and $!pos so we can access them directly
@@ -393,7 +393,7 @@ class RegexCompiler {
393393
my str $invocation := $compiled_args.is_args_array ?? ".apply({$!cursor}," !! '(';
394394

395395
$call := Chunk.new($T_OBJ,
396-
$!compiler.await ~ $!cursor ~ '[' ~ quote_string($method) ~ "]" ~ $invocation ~ $compiled_args.expr ~ ')',
396+
$!compiler.await ~ $!cursor ~ '[' ~ quote_string('p6$' ~ $method) ~ "]" ~ $invocation ~ $compiled_args.expr ~ ')',
397397
$compiled_args);
398398
}
399399
else {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function createKnowHOWAttribute() {
5454
typeObj.$$STable.modeFlags = constants.METHOD_CACHE_AUTHORITATIVE;
5555

5656
for (const method of Object.keys(methods)) {
57-
typeObj.$$STable.ObjConstructor.prototype[method] = methods[method];
57+
typeObj.$$STable.ObjConstructor.prototype['p6$' + method] = methods[method];
5858
typeObj.$$STable.methodCache.set(method, wrapMethod(method, methods[method]));
5959
}
6060

@@ -89,8 +89,8 @@ function wrapMethod(name, method) {
8989
function addKnowhowHowMethod(name, method) {
9090
/* TODO - think if setting the object cache would be better */
9191

92-
KnowHowHOW.$$STable.ObjConstructor.prototype[name] = method;
93-
KnowHOW.$$STable.ObjConstructor.prototype[name] = method;
92+
KnowHowHOW.$$STable.ObjConstructor.prototype['p6$' + name] = method;
93+
KnowHOW.$$STable.ObjConstructor.prototype['p6$' + name] = method;
9494

9595
const wrapped = wrapMethod(name, method);
9696
KnowHOW.$$STable.methodCache.set(name, wrapped);

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ exports.buildSourceMap = new BuildSourceMap();
862862

863863

864864
class JavaScriptCompiler extends NQPObject {
865-
/*async*/ eval(ctx, _NAMED, self, code) {
865+
/*async*/ p6$eval(ctx, _NAMED, self, code) {
866866
if (!(_NAMED !== null && _NAMED.hasOwnProperty('mapping'))) {
867867
const codeStr = nqp.arg_s(ctx, code);
868868
return fromJSToReturnValue(ctx, /*await*/ eval('(function() {' + codeStr + '})()'));
@@ -915,7 +915,7 @@ class JavaScriptCompiler extends NQPObject {
915915
return ret;
916916
}
917917

918-
compile(ctx, _NAMED, self, code) {
918+
p6$compile(ctx, _NAMED, self, code) {
919919
const codeStr = nqp.arg_s(ctx, code);
920920
const compiled = process.browser
921921
? eval('(function() {' + codeStr + '})')
@@ -932,7 +932,7 @@ class JavaScriptCompiler extends NQPObject {
932932
globalContext.initialize(context => context.compilerRegistry.set('JavaScript', new JavaScriptCompiler()));
933933

934934
class JSBackendStub extends NQPObject {
935-
name(ctx, named) {
935+
p6$name(ctx, named) {
936936
return new NQPStr('js');
937937
}
938938
};
@@ -942,7 +942,8 @@ class NQPStub extends NQPObject {
942942
super();
943943
this.$$backend = new JSBackendStub();
944944
}
945-
backend(ctx, named) {
945+
946+
p6$backend(ctx, named) {
946947
return this.$$backend;
947948
}
948949
};
@@ -961,7 +962,7 @@ class FakePerl6 extends NQPObject {
961962
}
962963
}
963964

964-
FakePerl6.prototype['cli-options'] = function() {
965+
FakePerl6.prototype['p6$cli-options'] = function() {
965966
return new Hash();
966967
};
967968

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,15 +475,15 @@ class CtxIter extends NQPObject {
475475
return this.$$idx < this.$$target;
476476
}
477477

478-
Str(ctx, _NAMED, self) {
478+
p6$Str(ctx, _NAMED, self) {
479479
return new NQPStr(this.$$iterkey_s());
480480
}
481481

482-
key(ctx, _NAMED, self) {
482+
p6$key(ctx, _NAMED, self) {
483483
return new NQPStr(this.$$iterkey_s());
484484
}
485485

486-
value(ctx, _NAMED, self) {
486+
p6$value(ctx, _NAMED, self) {
487487
return this.$$iterval();
488488
}
489489
};

src/vm/js/nqp-runtime/hash-iter.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ class HashIter extends NQPObject {
2727
return this.$$idx < this.$$target;
2828
}
2929

30-
Str(ctx, _NAMED, self) {
30+
p6$Str(ctx, _NAMED, self) {
3131
return new NQPStr(this.$$iterkey_s());
3232
}
3333

34-
key(ctx, _NAMED, self) {
34+
p6$key(ctx, _NAMED, self) {
3535
return new NQPStr(this.$$iterkey_s());
3636
}
3737

38-
value(ctx, _NAMED, self) {
38+
p6$value(ctx, _NAMED, self) {
3939
return this.$$iterval();
4040
}
4141
};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class NQPException extends Error {
66
this.$$message = message;
77
}
88

9-
Str(ctx, _NAMED, self) {
9+
p6$Str(ctx, _NAMED, self) {
1010
return new NQPStr(this.$$message);
1111
}
1212

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class NQPInt extends NQPObject {
99
this.value = value | 0;
1010
}
1111

12-
Str(ctx, _NAMED, self) {
12+
p6$Str(ctx, _NAMED, self) {
1313
return new NQPStr(this.value.toString());
1414
}
1515

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

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -87,45 +87,50 @@ class REPR {
8787
createObjConstructor(STable) {
8888
const ObjConstructor = function() {};
8989
const handler = {};
90-
handler.get = function(target, name) {
91-
if (STable.lazyMethodCache) {
92-
STable.setMethodCache(STable.methodCache);
93-
const method = STable.methodCache.get(name);
94-
if (method !== undefined) {
95-
return STable.ObjConstructor.prototype[name];
96-
}
97-
}
90+
handler.get = function(target, jsName) {
9891

99-
/* are we trying to access an internal property? */
100-
/* HACK with then, we likely need to prefix p6 methods to avoid this problem */
101-
if (name.substr(0, 2) === '$$' || name == 'then') {
92+
if (jsName.substr(0, 2) === '$$') {
10293
return undefined;
103-
}
94+
} else if (jsName.substr(0, 3) == 'p6$') {
95+
const name = jsName.substr(3);
96+
97+
if (STable.lazyMethodCache) {
98+
STable.setMethodCache(STable.methodCache);
99+
const method = STable.methodCache.get(name);
100+
if (method !== undefined) {
101+
return STable.ObjConstructor.prototype[jsName];
102+
}
103+
}
104104

105-
if (STable.modeFlags & constants.METHOD_CACHE_AUTHORITATIVE) {
106-
return function(ctx, _NAMED, obj) {
107-
return methodNotFoundError(ctx, obj, name);
108-
};
109-
}
105+
if (STable.modeFlags & constants.METHOD_CACHE_AUTHORITATIVE) {
106+
return function(ctx, _NAMED, obj) {
107+
return methodNotFoundError(ctx, obj, name);
108+
};
109+
}
110110

111111

112-
return /*async*/ function() {
113-
const how = this.$$STable.HOW;
112+
return /*async*/ function() {
113+
const how = this.$$STable.HOW;
114114

115-
const method = /*await*/ how.find_method(null, null, how, this, new NativeStrArg(name));
115+
const method = /*await*/ how.p6$find_method(null, null, how, this, new NativeStrArg(name));
116116

117-
if (method === Null) {
118-
return methodNotFoundError(arguments[0], arguments[2], name);
119-
}
117+
if (method === Null) {
118+
return methodNotFoundError(arguments[0], arguments[2], name);
119+
}
120120

121-
const args = [];
122-
for (let i = 0; i < arguments.length; i++) {
123-
args.push(arguments[i]);
124-
}
125-
return method.$$apply(args);
126-
};
121+
const args = [];
122+
for (let i = 0; i < arguments.length; i++) {
123+
args.push(arguments[i]);
124+
}
125+
return method.$$apply(args);
126+
};
127+
} else {
128+
console.log('unprefixed js method', jsName);
129+
return undefined;
130+
}
127131
};
128132

133+
129134
ObjConstructor.prototype = Object.create(new Proxy({}, handler));
130135
ObjConstructor.prototype.$$STable = STable;
131136

@@ -2483,23 +2488,29 @@ class WrappedJSObject extends REPR {
24832488
createObjConstructor(STable) {
24842489
const ObjConstructor = function() {};
24852490
const handler = {};
2486-
handler.get = function(target, name) {
2487-
if (name.substr(0, 2) === '$$') {
2491+
handler.get = function(target, mangledName) {
2492+
if (mangledName.substr(0, 2) === '$$') {
24882493
return undefined;
24892494
}
24902495

2491-
return /*async*/ function() {
2492-
const converted = [];
2493-
for (let i = 3; i < arguments.length; i++) {
2494-
converted.push(/*await*/ core.toJSWithCtx(arguments[0], arguments[i].$$decont(arguments[0])));
2495-
}
2496+
if (mangledName.substr(0, 3) === 'p6$') {
2497+
const name = mangledName.substr(3);
24962498

2497-
if (this.$$jsObject[name]) {
2498-
return core.fromJSToReturnValue(arguments[0], this.$$jsObject[name].apply(this.$$jsObject, converted));
2499-
} else {
2500-
methodNotFoundError(arguments[0], this, name);
2501-
}
2502-
};
2499+
return /*async*/ function() {
2500+
const converted = [];
2501+
for (let i = 3; i < arguments.length; i++) {
2502+
converted.push(/*await*/ core.toJSWithCtx(arguments[0], arguments[i].$$decont(arguments[0])));
2503+
}
2504+
2505+
if (this.$$jsObject[name]) {
2506+
return core.fromJSToReturnValue(arguments[0], this.$$jsObject[name].apply(this.$$jsObject, converted));
2507+
} else {
2508+
methodNotFoundError(arguments[0], this, name);
2509+
}
2510+
};
2511+
} else {
2512+
throw new NQPException(`Got raw js method: ${mangledName}`);
2513+
}
25032514
};
25042515

25052516
ObjConstructor.prototype = Object.create(new Proxy({}, handler));

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ exports.toStr = /*async*/ function(arg_, ctx) {
291291
return '';
292292
} else if (arg.$$getStr) {
293293
return arg.$$getStr();
294-
} else if (arg.Str) {
295-
const ret = /*await*/ arg.Str(ctx, null, arg); // eslint-disable-line new-cap
294+
} else if (arg.p6$Str) {
295+
const ret = /*await*/ arg.p6$Str(ctx, null, arg); // eslint-disable-line new-cap
296296
return (typeof ret === 'string' ? ret : (/*await*/ ret.$$decont(ctx)).$$getStr());
297297
} else if (arg.$$getNum) {
298298
return coercions.numToStr(arg.$$getNum());
@@ -311,7 +311,7 @@ exports.toNum = /*async*/ function(arg_, ctx) {
311311
} else if (arg instanceof NQPStr) {
312312
return coercions.strToNum(arg.value);
313313
} else if (arg.$$STable && arg.$$STable.methodCache && arg.$$STable.methodCache.get('Num')) {
314-
const result = /*await*/ arg.Num(ctx, null, arg); // eslint-disable-line new-cap
314+
const result = /*await*/ arg.p6$Num(ctx, null, arg); // eslint-disable-line new-cap
315315
if (typeof result === 'number') {
316316
return result;
317317
} else if (result.$$getNum) {
@@ -493,7 +493,7 @@ exports.dumpObj = function(obj) {
493493
if (typeof obj === 'object') {
494494
if (obj.$$STable) {
495495
console.log(obj.$$STable.REPR.name);
496-
const name = obj.$$STable.HOW.name(null, null, obj.$$STable.HOW, obj);
496+
const name = obj.$$STable.HOW.p6$name(null, null, obj.$$STable.HOW, obj);
497497
console.log(name instanceof NQPStr ? name.value : name);
498498
} else {
499499
console.log('no STable', obj.constructor.name);

0 commit comments

Comments
 (0)