@@ -93,7 +93,7 @@ const funcRef = func => {
93
93
}
94
94
95
95
const wasm = [ ] ;
96
- const offset = func . constr ? 0 : 4 ;
96
+ const offset = func . constr ? 0 : ( func . method ? 2 : 4 ) ;
97
97
for ( let i = 0 ; i < func . params . length ; i ++ ) {
98
98
if ( func . internal && func . name . includes ( '_prototype_' ) && i < 2 ) {
99
99
// special case: use real this for prototype internals
@@ -456,7 +456,7 @@ const lookup = (scope, name, failEarly = false) => {
456
456
// todo: not compliant
457
457
let len = countLength ( scope ) ;
458
458
const names = new Array ( len ) ;
459
- const off = scope . constr ? 4 : 0 ;
459
+ const off = scope . constr ? 4 : ( scope . method ? 2 : 0 ) ;
460
460
for ( const x in scope . locals ) {
461
461
const i = scope . locals [ x ] . idx - off ;
462
462
if ( i >= 0 && i % 2 === 0 && i < len * 2 ) {
@@ -1716,7 +1716,7 @@ const getNodeType = (scope, node) => {
1716
1716
1717
1717
if ( node . type === 'ThisExpression' ) {
1718
1718
if ( scope . overrideThisType ) return scope . overrideThisType ;
1719
- if ( ! scope . constr ) return getType ( scope , 'globalThis' ) ;
1719
+ if ( ! scope . constr && ! scope . method ) return getType ( scope , 'globalThis' ) ;
1720
1720
return [ [ Opcodes . local_get , scope . locals [ '#this#type' ] . idx ] ] ;
1721
1721
}
1722
1722
@@ -2636,6 +2636,11 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2636
2636
paramOffset += 4 ;
2637
2637
}
2638
2638
2639
+ if ( func && func . method ) {
2640
+ out . push ( ...( decl . _thisWasm ?? createThisArg ( scope , decl ) ) ) ;
2641
+ paramOffset += 2 ;
2642
+ }
2643
+
2639
2644
if ( func && args . length < paramCount ) {
2640
2645
// too little args, push undefineds
2641
2646
const underflow = paramCount - ( func . hasRestArgument ? 1 : 0 ) - args . length ;
@@ -2720,7 +2725,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2720
2725
const generateThis = ( scope , decl ) => {
2721
2726
if ( scope . overrideThis ) return scope . overrideThis ;
2722
2727
2723
- if ( ! scope . constr ) {
2728
+ if ( ! scope . constr && ! scope . method ) {
2724
2729
// this in a non-constructor context is a reference to globalThis
2725
2730
return [
2726
2731
...generate ( scope , { type : 'Identifier' , name : 'globalThis' } )
@@ -5527,7 +5532,10 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
5527
5532
5528
5533
for ( const x of decl . properties ) {
5529
5534
// method, shorthand are made into useful values by parser for us :)
5530
- let { type, argument, computed, kind, value } = x ;
5535
+ let { type, argument, computed, kind, value, method } = x ;
5536
+
5537
+ // tag function as not a constructor
5538
+ if ( method ) value . _method = true ;
5531
5539
5532
5540
if ( type === 'SpreadElement' ) {
5533
5541
out . push (
@@ -5620,6 +5628,7 @@ const countParams = (func, name = undefined) => {
5620
5628
name ??= func . name ;
5621
5629
let params = func . params . length ;
5622
5630
if ( func . constr ) params -= 4 ;
5631
+ if ( func . method ) params -= 2 ;
5623
5632
if ( ! func . internal || builtinFuncs [ name ] ?. typedParams ) params = Math . floor ( params / 2 ) ;
5624
5633
5625
5634
return func . argc = params ;
@@ -6123,6 +6132,9 @@ const generateClass = (scope, decl) => {
6123
6132
let { type, value, kind, static : _static , computed } = x ;
6124
6133
if ( kind === 'constructor' ) continue ;
6125
6134
6135
+ // tag function as not a constructor
6136
+ if ( type === 'MethodDefinition' ) value . _method = true ;
6137
+
6126
6138
if ( type === 'StaticBlock' ) {
6127
6139
// todo: make this more compliant
6128
6140
out . push (
@@ -6448,7 +6460,8 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6448
6460
name,
6449
6461
index : currentFuncIndex ++ ,
6450
6462
arrow,
6451
- constr : ! arrow && ! decl . generator && ! decl . async ,
6463
+ constr : ! arrow && ! decl . generator && ! decl . async && ! decl . _method , // constructable
6464
+ method : decl . _method || decl . generator || decl . async , // has this but not constructable
6452
6465
async : decl . async ,
6453
6466
subclass : decl . _subclass , _onlyConstr : decl . _onlyConstr , _onlyThisMethod : decl . _onlyThisMethod ,
6454
6467
strict : scope . strict || decl . strict ,
@@ -6679,6 +6692,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6679
6692
6680
6693
const args = [ ] ;
6681
6694
if ( func . constr ) args . push ( { name : '#newtarget' } , { name : '#this' } ) ;
6695
+ if ( func . method ) args . push ( { name : '#this' } ) ;
6682
6696
6683
6697
let jsLength = 0 ;
6684
6698
for ( let i = 0 ; i < params . length ; i ++ ) {
@@ -6719,7 +6733,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6719
6733
args . push ( { name, def, destr, type : typedInput && params [ i ] . typeAnnotation } ) ;
6720
6734
}
6721
6735
6722
- func . params = new Array ( ( params . length + ( func . constr ? 2 : 0 ) ) * 2 ) . fill ( 0 ) . map ( ( _ , i ) => i % 2 ? Valtype . i32 : valtypeBinary ) ;
6736
+ func . params = new Array ( ( params . length + ( func . constr ? 2 : ( func . method ? 1 : 0 ) ) ) * 2 ) . fill ( 0 ) . map ( ( _ , i ) => i % 2 ? Valtype . i32 : valtypeBinary ) ;
6723
6737
func . jsLength = jsLength ;
6724
6738
6725
6739
// force generate for main
0 commit comments