Skip to content

Commit

Permalink
Rework native code function toString.
Browse files Browse the repository at this point in the history
Summary:
Tools such as Babel rely on the format of function toString.
In particular, they check for the substring `[native code]`,
as opposed to the future standard `[ native code ]` which Hermes supports.

We want to avoid pretending every single function is a native function,
so we switch bytecode functions to say `[bytecode]` instead.

Reviewed By: ridiculousfish

Differential Revision: D17102765

fbshipit-source-id: e81f63a066b1ddcae9c8e26cfd48221a86dd2b75
  • Loading branch information
avp authored and facebook-github-bot committed Sep 5, 2019
1 parent a29c955 commit d5ad9be
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 21 deletions.
12 changes: 10 additions & 2 deletions lib/VM/JSLib/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,16 @@ functionPrototypeToString(void *, Runtime *runtime, NativeArgs args) {
}

// The rest of the body.
// http://tc39.github.io/Function-prototype-toString-revision
strBuf.append(") { [ native code ] }");
if (vmisa<NativeFunction>(*func)) {
// Use [native code] here because we want to work with tools like
// Babel which detect the string [native code] and use it to alter
// behavior during the class transform.
strBuf.append(") { [native code] }");
} else {
// Avoid using the [native code] string to prevent extra wrapping overhead
// in, e.g., Babel's class extension mechanism.
strBuf.append(") { [bytecode] }");
}

// Finally allocate a StringPrimitive.
return StringPrimitive::create(runtime, strBuf);
Expand Down
8 changes: 4 additions & 4 deletions test/debugger/vars-for.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ func1();
// CHECK-NEXT: 0: elem = a
// CHECK-NEXT: 1: var1_0 = 10
// CHECK-NEXT: 1: var1_1 = 11
// CHECK-NEXT: 1: func2 = function func2(a0) { [ native code ] }
// CHECK-NEXT: 1: func2 = function func2(a0) { [bytecode] }
// CHECK-NEXT: Selected frame 1
// CHECK-NEXT: this = a,b
// CHECK-NEXT: Selected frame 2
// CHECK-NEXT: this = undefined
// CHECK-NEXT: 0: var1_0 = 10
// CHECK-NEXT: 0: var1_1 = 11
// CHECK-NEXT: 0: func2 = function func2(a0) { [ native code ] }
// CHECK-NEXT: 0: func2 = function func2(a0) { [bytecode] }
// CHECK-NEXT: Continuing execution
// CHECK-NEXT: Break on 'debugger' statement in func2: {{.*}}
// CHECK-NEXT: Selected frame 0
Expand All @@ -45,12 +45,12 @@ func1();
// CHECK-NEXT: 0: elem = b
// CHECK-NEXT: 1: var1_0 = 10
// CHECK-NEXT: 1: var1_1 = 11
// CHECK-NEXT: 1: func2 = function func2(a0) { [ native code ] }
// CHECK-NEXT: 1: func2 = function func2(a0) { [bytecode] }
// CHECK-NEXT: Selected frame 1
// CHECK-NEXT: this = a,b
// CHECK-NEXT: Selected frame 2
// CHECK-NEXT: this = undefined
// CHECK-NEXT: 0: var1_0 = 10
// CHECK-NEXT: 0: var1_1 = 11
// CHECK-NEXT: 0: func2 = function func2(a0) { [ native code ] }
// CHECK-NEXT: 0: func2 = function func2(a0) { [bytecode] }
// CHECK-NEXT: Continuing execution
4 changes: 2 additions & 2 deletions test/debugger/vars-this.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ foo.f1();
// CHECK-NEXT: Break on 'debugger' statement in f3: {{.*}}
// CHECK-NEXT: Selected frame 0
// CHECK-NEXT: this = 412
// CHECK-NEXT: 1: f3 = function f3() { [ native code ] }
// CHECK-NEXT: 1: f3 = function f3() { [bytecode] }
// CHECK-NEXT: Selected frame 2
// CHECK-NEXT: this = [object Object]
// CHECK-NEXT: 0: f3 = function f3() { [ native code ] }
// CHECK-NEXT: 0: f3 = function f3() { [bytecode] }
// CHECK-NEXT: Selected frame 3
// CHECK-NEXT: this = [object Object]
// CHECK-NEXT: Selected frame 4
Expand Down
8 changes: 4 additions & 4 deletions test/debugger/vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ func1();
// CHECK-NEXT: 0: var333 = c
// CHECK-NEXT: 1: var1 = 5
// CHECK-NEXT: 1: var22 = 17
// CHECK-NEXT: 1: func2 = function func2() { [ native code ] }
// CHECK-NEXT: 1: func2 = function func2() { [bytecode] }
// CHECK-NEXT: Selected frame 1
// CHECK-NEXT: this = undefined
// CHECK-NEXT: 0: var1 = 5
// CHECK-NEXT: 0: var22 = 17
// CHECK-NEXT: 0: func2 = function func2() { [ native code ] }
// CHECK-NEXT: 0: func2 = function func2() { [bytecode] }
// CHECK-NEXT: Selected frame 2
// CHECK-NEXT: this = [object global]
// CHECK-NEXT: Stepped to func2: {{.*}}
Expand All @@ -48,13 +48,13 @@ func1();
// CHECK-NEXT: this = undefined
// CHECK-NEXT: 0: var1 = 5
// CHECK-NEXT: 0: var22 = 17
// CHECK-NEXT: 0: func2 = function func2() { [ native code ] }
// CHECK-NEXT: 0: func2 = function func2() { [bytecode] }
// CHECK-NEXT: Selected frame 1
// CHECK-NEXT: this = undefined
// CHECK-NEXT: 0: var333 = c
// CHECK-NEXT: 1: var1 = 5
// CHECK-NEXT: 1: var22 = 17
// CHECK-NEXT: 1: func2 = function func2() { [ native code ] }
// CHECK-NEXT: 1: func2 = function func2() { [bytecode] }
// CHECK-NEXT: Selected frame 0
// CHECK-NEXT: this = undefined
// CHECK-NEXT: 0: var0 = undefined
Expand Down
12 changes: 7 additions & 5 deletions test/hermes/function-constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,21 @@ print(f.__proto__ === F.prototype, f.constructor === F, f.prop1);
print('toString');
// CHECK-LABEL: toString
print(function (){});
// CHECK-NEXT: function () { [ native code ] }
// CHECK-NEXT: function () { [bytecode] }
print(function foo(){});
// CHECK-NEXT: function foo() { [ native code ] }
// CHECK-NEXT: function foo() { [bytecode] }
print(function(a,b,c){});
// CHECK-NEXT: function (a0, a1, a2) { [ native code ] }
// CHECK-NEXT: function (a0, a1, a2) { [bytecode] }
print(function(a,b,c,d,e,f,g,h,i,j,k){});
// CHECK-NEXT: function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { [ native code ] }
// CHECK-NEXT: function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { [bytecode] }
print(Map.toString());
// CHECK-NEXT: function Map() { [native code] }

// Non-string .length
var foo = function badlength(a, b, c){};
Object.defineProperty(foo, "length", {value:"aa"});
print(foo);
// CHECK-NEXT: function badlength() { [ native code ] }
// CHECK-NEXT: function badlength() { [bytecode] }

print('call');
// CHECK-LABEL: call
Expand Down
4 changes: 2 additions & 2 deletions test/repl/pretty.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ null
"asdf"
// CHECK-NEXT: "asdf"
(function(){})
// CHECK-NEXT: function () { [ native code ] }
// CHECK-NEXT: function () { [bytecode] }

a = [1,2, function(){}, null]
// CHECK-NEXT: [ 1, 2, [Function], null, [length]: 4 ]
Expand Down Expand Up @@ -61,7 +61,7 @@ a.arr.cycle = a;
// CHECK-NEXT: { x: 1, [z]: 3, arr: [ "foo", 4, [length]: 2, cycle: [cyclic] ] }

a = function foo() {}
// CHECK-NEXT: function foo() { [ native code ] }
// CHECK-NEXT: function foo() { [bytecode] }
a = [function foo() {}]
// CHECK-NEXT: [ [Function foo], [length]: 1 ]

Expand Down
4 changes: 2 additions & 2 deletions test/serialize/function-usercode.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ serializeVM(function() {
print('toString');
// CHECK-LABEL: toString
print(F2);
// CHECK-NEXT: function F2(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { [ native code ] }
// CHECK-NEXT: function F2(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { [bytecode] }

// Non-string .length
print(foo);
// CHECK-NEXT: function badlength() { [ native code ] }
// CHECK-NEXT: function badlength() { [bytecode] }

print('call');
// CHECK-LABEL: call
Expand Down

0 comments on commit d5ad9be

Please sign in to comment.