1 package goja
2
3 import (
4 "github.com/dop251/goja/ast"
5 "github.com/dop251/goja/file"
6 "github.com/dop251/goja/token"
7 "github.com/dop251/goja/unistring"
8 )
9
10 type compiledExpr interface {
11 emitGetter(putOnStack bool)
12 emitSetter(valueExpr compiledExpr, putOnStack bool)
13 emitRef()
14 emitUnary(prepare, body func(), postfix, putOnStack bool)
15 deleteExpr() compiledExpr
16 constant() bool
17 addSrcMap()
18 }
19
20 type compiledExprOrRef interface {
21 compiledExpr
22 emitGetterOrRef()
23 }
24
25 type compiledCallExpr struct {
26 baseCompiledExpr
27 args []compiledExpr
28 callee compiledExpr
29
30 isVariadic bool
31 }
32
33 type compiledNewExpr struct {
34 compiledCallExpr
35 }
36
37 type compiledObjectLiteral struct {
38 baseCompiledExpr
39 expr *ast.ObjectLiteral
40 }
41
42 type compiledArrayLiteral struct {
43 baseCompiledExpr
44 expr *ast.ArrayLiteral
45 }
46
47 type compiledRegexpLiteral struct {
48 baseCompiledExpr
49 expr *ast.RegExpLiteral
50 }
51
52 type compiledLiteral struct {
53 baseCompiledExpr
54 val Value
55 }
56
57 type compiledTemplateLiteral struct {
58 baseCompiledExpr
59 tag compiledExpr
60 elements []*ast.TemplateElement
61 expressions []compiledExpr
62 }
63
64 type compiledAssignExpr struct {
65 baseCompiledExpr
66 left, right compiledExpr
67 operator token.Token
68 }
69
70 type compiledObjectAssignmentPattern struct {
71 baseCompiledExpr
72 expr *ast.ObjectPattern
73 }
74
75 type compiledArrayAssignmentPattern struct {
76 baseCompiledExpr
77 expr *ast.ArrayPattern
78 }
79
80 type deleteGlobalExpr struct {
81 baseCompiledExpr
82 name unistring.String
83 }
84
85 type deleteVarExpr struct {
86 baseCompiledExpr
87 name unistring.String
88 }
89
90 type deletePropExpr struct {
91 baseCompiledExpr
92 left compiledExpr
93 name unistring.String
94 }
95
96 type deleteElemExpr struct {
97 baseCompiledExpr
98 left, member compiledExpr
99 }
100
101 type constantExpr struct {
102 baseCompiledExpr
103 val Value
104 }
105
106 type baseCompiledExpr struct {
107 c *compiler
108 offset int
109 }
110
111 type compiledIdentifierExpr struct {
112 baseCompiledExpr
113 name unistring.String
114 }
115
116 type compiledAwaitExpression struct {
117 baseCompiledExpr
118 arg compiledExpr
119 }
120
121 type compiledYieldExpression struct {
122 baseCompiledExpr
123 arg compiledExpr
124 delegate bool
125 }
126
127 type funcType uint8
128
129 const (
130 funcNone funcType = iota
131 funcRegular
132 funcArrow
133 funcMethod
134 funcClsInit
135 funcCtor
136 funcDerivedCtor
137 )
138
139 type compiledFunctionLiteral struct {
140 baseCompiledExpr
141 name *ast.Identifier
142 parameterList *ast.ParameterList
143 body []ast.Statement
144 source string
145 declarationList []*ast.VariableDeclaration
146 lhsName unistring.String
147 strict *ast.StringLiteral
148 homeObjOffset uint32
149 typ funcType
150 isExpr bool
151
152 isAsync, isGenerator bool
153 }
154
155 type compiledBracketExpr struct {
156 baseCompiledExpr
157 left, member compiledExpr
158 }
159
160 type compiledThisExpr struct {
161 baseCompiledExpr
162 }
163
164 type compiledSuperExpr struct {
165 baseCompiledExpr
166 }
167
168 type compiledNewTarget struct {
169 baseCompiledExpr
170 }
171
172 type compiledSequenceExpr struct {
173 baseCompiledExpr
174 sequence []compiledExpr
175 }
176
177 type compiledUnaryExpr struct {
178 baseCompiledExpr
179 operand compiledExpr
180 operator token.Token
181 postfix bool
182 }
183
184 type compiledConditionalExpr struct {
185 baseCompiledExpr
186 test, consequent, alternate compiledExpr
187 }
188
189 type compiledLogicalOr struct {
190 baseCompiledExpr
191 left, right compiledExpr
192 }
193
194 type compiledCoalesce struct {
195 baseCompiledExpr
196 left, right compiledExpr
197 }
198
199 type compiledLogicalAnd struct {
200 baseCompiledExpr
201 left, right compiledExpr
202 }
203
204 type compiledBinaryExpr struct {
205 baseCompiledExpr
206 left, right compiledExpr
207 operator token.Token
208 }
209
210 type compiledEnumGetExpr struct {
211 baseCompiledExpr
212 }
213
214 type defaultDeleteExpr struct {
215 baseCompiledExpr
216 expr compiledExpr
217 }
218
219 type compiledSpreadCallArgument struct {
220 baseCompiledExpr
221 expr compiledExpr
222 }
223
224 type compiledOptionalChain struct {
225 baseCompiledExpr
226 expr compiledExpr
227 }
228
229 type compiledOptional struct {
230 baseCompiledExpr
231 expr compiledExpr
232 }
233
234 func (e *defaultDeleteExpr) emitGetter(putOnStack bool) {
235 e.expr.emitGetter(false)
236 if putOnStack {
237 e.c.emit(loadVal(e.c.p.defineLiteralValue(valueTrue)))
238 }
239 }
240
241 func (c *compiler) compileExpression(v ast.Expression) compiledExpr {
242
243 switch v := v.(type) {
244 case nil:
245 return nil
246 case *ast.AssignExpression:
247 return c.compileAssignExpression(v)
248 case *ast.NumberLiteral:
249 return c.compileNumberLiteral(v)
250 case *ast.StringLiteral:
251 return c.compileStringLiteral(v)
252 case *ast.TemplateLiteral:
253 return c.compileTemplateLiteral(v)
254 case *ast.BooleanLiteral:
255 return c.compileBooleanLiteral(v)
256 case *ast.NullLiteral:
257 r := &compiledLiteral{
258 val: _null,
259 }
260 r.init(c, v.Idx0())
261 return r
262 case *ast.Identifier:
263 return c.compileIdentifierExpression(v)
264 case *ast.CallExpression:
265 return c.compileCallExpression(v)
266 case *ast.ObjectLiteral:
267 return c.compileObjectLiteral(v)
268 case *ast.ArrayLiteral:
269 return c.compileArrayLiteral(v)
270 case *ast.RegExpLiteral:
271 return c.compileRegexpLiteral(v)
272 case *ast.BinaryExpression:
273 return c.compileBinaryExpression(v)
274 case *ast.UnaryExpression:
275 return c.compileUnaryExpression(v)
276 case *ast.ConditionalExpression:
277 return c.compileConditionalExpression(v)
278 case *ast.FunctionLiteral:
279 return c.compileFunctionLiteral(v, true)
280 case *ast.ArrowFunctionLiteral:
281 return c.compileArrowFunctionLiteral(v)
282 case *ast.ClassLiteral:
283 return c.compileClassLiteral(v, true)
284 case *ast.DotExpression:
285 return c.compileDotExpression(v)
286 case *ast.PrivateDotExpression:
287 return c.compilePrivateDotExpression(v)
288 case *ast.BracketExpression:
289 return c.compileBracketExpression(v)
290 case *ast.ThisExpression:
291 r := &compiledThisExpr{}
292 r.init(c, v.Idx0())
293 return r
294 case *ast.SuperExpression:
295 c.throwSyntaxError(int(v.Idx0())-1, "'super' keyword unexpected here")
296 panic("unreachable")
297 case *ast.SequenceExpression:
298 return c.compileSequenceExpression(v)
299 case *ast.NewExpression:
300 return c.compileNewExpression(v)
301 case *ast.MetaProperty:
302 return c.compileMetaProperty(v)
303 case *ast.ObjectPattern:
304 return c.compileObjectAssignmentPattern(v)
305 case *ast.ArrayPattern:
306 return c.compileArrayAssignmentPattern(v)
307 case *ast.OptionalChain:
308 r := &compiledOptionalChain{
309 expr: c.compileExpression(v.Expression),
310 }
311 r.init(c, v.Idx0())
312 return r
313 case *ast.Optional:
314 r := &compiledOptional{
315 expr: c.compileExpression(v.Expression),
316 }
317 r.init(c, v.Idx0())
318 return r
319 case *ast.AwaitExpression:
320 r := &compiledAwaitExpression{
321 arg: c.compileExpression(v.Argument),
322 }
323 r.init(c, v.Await)
324 return r
325 case *ast.YieldExpression:
326 r := &compiledYieldExpression{
327 arg: c.compileExpression(v.Argument),
328 delegate: v.Delegate,
329 }
330 r.init(c, v.Yield)
331 return r
332 default:
333 c.assert(false, int(v.Idx0())-1, "Unknown expression type: %T", v)
334 panic("unreachable")
335 }
336 }
337
338 func (e *baseCompiledExpr) constant() bool {
339 return false
340 }
341
342 func (e *baseCompiledExpr) init(c *compiler, idx file.Idx) {
343 e.c = c
344 e.offset = int(idx) - 1
345 }
346
347 func (e *baseCompiledExpr) emitSetter(compiledExpr, bool) {
348 e.c.throwSyntaxError(e.offset, "Not a valid left-value expression")
349 }
350
351 func (e *baseCompiledExpr) emitRef() {
352 e.c.assert(false, e.offset, "Cannot emit reference for this type of expression")
353 }
354
355 func (e *baseCompiledExpr) deleteExpr() compiledExpr {
356 r := &constantExpr{
357 val: valueTrue,
358 }
359 r.init(e.c, file.Idx(e.offset+1))
360 return r
361 }
362
363 func (e *baseCompiledExpr) emitUnary(func(), func(), bool, bool) {
364 e.c.throwSyntaxError(e.offset, "Not a valid left-value expression")
365 }
366
367 func (e *baseCompiledExpr) addSrcMap() {
368 if e.offset >= 0 {
369 e.c.p.addSrcMap(e.offset)
370 }
371 }
372
373 func (e *constantExpr) emitGetter(putOnStack bool) {
374 if putOnStack {
375 e.addSrcMap()
376 e.c.emit(loadVal(e.c.p.defineLiteralValue(e.val)))
377 }
378 }
379
380 func (e *compiledIdentifierExpr) emitGetter(putOnStack bool) {
381 e.addSrcMap()
382 if b, noDynamics := e.c.scope.lookupName(e.name); noDynamics {
383 e.c.assert(b != nil, e.offset, "No dynamics and not found")
384 if putOnStack {
385 b.emitGet()
386 } else {
387 b.emitGetP()
388 }
389 } else {
390 if b != nil {
391 b.emitGetVar(false)
392 } else {
393 e.c.emit(loadDynamic(e.name))
394 }
395 if !putOnStack {
396 e.c.emit(pop)
397 }
398 }
399 }
400
401 func (e *compiledIdentifierExpr) emitGetterOrRef() {
402 e.addSrcMap()
403 if b, noDynamics := e.c.scope.lookupName(e.name); noDynamics {
404 e.c.assert(b != nil, e.offset, "No dynamics and not found")
405 b.emitGet()
406 } else {
407 if b != nil {
408 b.emitGetVar(false)
409 } else {
410 e.c.emit(loadDynamicRef(e.name))
411 }
412 }
413 }
414
415 func (e *compiledIdentifierExpr) emitGetterAndCallee() {
416 e.addSrcMap()
417 if b, noDynamics := e.c.scope.lookupName(e.name); noDynamics {
418 e.c.assert(b != nil, e.offset, "No dynamics and not found")
419 e.c.emit(loadUndef)
420 b.emitGet()
421 } else {
422 if b != nil {
423 b.emitGetVar(true)
424 } else {
425 e.c.emit(loadDynamicCallee(e.name))
426 }
427 }
428 }
429
430 func (e *compiledIdentifierExpr) emitVarSetter1(putOnStack bool, emitRight func(isRef bool)) {
431 e.addSrcMap()
432 c := e.c
433
434 if b, noDynamics := c.scope.lookupName(e.name); noDynamics {
435 if c.scope.strict {
436 c.checkIdentifierLName(e.name, e.offset)
437 }
438 emitRight(false)
439 if b != nil {
440 if putOnStack {
441 b.emitSet()
442 } else {
443 b.emitSetP()
444 }
445 } else {
446 if c.scope.strict {
447 c.emit(setGlobalStrict(e.name))
448 } else {
449 c.emit(setGlobal(e.name))
450 }
451 if !putOnStack {
452 c.emit(pop)
453 }
454 }
455 } else {
456 c.emitVarRef(e.name, e.offset, b)
457 emitRight(true)
458 if putOnStack {
459 c.emit(putValue)
460 } else {
461 c.emit(putValueP)
462 }
463 }
464 }
465
466 func (e *compiledIdentifierExpr) emitVarSetter(valueExpr compiledExpr, putOnStack bool) {
467 e.emitVarSetter1(putOnStack, func(bool) {
468 e.c.emitNamedOrConst(valueExpr, e.name)
469 })
470 }
471
472 func (c *compiler) emitVarRef(name unistring.String, offset int, b *binding) {
473 if c.scope.strict {
474 c.checkIdentifierLName(name, offset)
475 }
476
477 if b != nil {
478 b.emitResolveVar(c.scope.strict)
479 } else {
480 if c.scope.strict {
481 c.emit(resolveVar1Strict(name))
482 } else {
483 c.emit(resolveVar1(name))
484 }
485 }
486 }
487
488 func (e *compiledIdentifierExpr) emitRef() {
489 b, _ := e.c.scope.lookupName(e.name)
490 e.c.emitVarRef(e.name, e.offset, b)
491 }
492
493 func (e *compiledIdentifierExpr) emitSetter(valueExpr compiledExpr, putOnStack bool) {
494 e.emitVarSetter(valueExpr, putOnStack)
495 }
496
497 func (e *compiledIdentifierExpr) emitUnary(prepare, body func(), postfix, putOnStack bool) {
498 if putOnStack {
499 e.emitVarSetter1(true, func(isRef bool) {
500 e.c.emit(loadUndef)
501 if isRef {
502 e.c.emit(getValue)
503 } else {
504 e.emitGetter(true)
505 }
506 if prepare != nil {
507 prepare()
508 }
509 if !postfix {
510 body()
511 }
512 e.c.emit(rdupN(1))
513 if postfix {
514 body()
515 }
516 })
517 e.c.emit(pop)
518 } else {
519 e.emitVarSetter1(false, func(isRef bool) {
520 if isRef {
521 e.c.emit(getValue)
522 } else {
523 e.emitGetter(true)
524 }
525 body()
526 })
527 }
528 }
529
530 func (e *compiledIdentifierExpr) deleteExpr() compiledExpr {
531 if e.c.scope.strict {
532 e.c.throwSyntaxError(e.offset, "Delete of an unqualified identifier in strict mode")
533 panic("Unreachable")
534 }
535 if b, noDynamics := e.c.scope.lookupName(e.name); noDynamics {
536 if b == nil {
537 r := &deleteGlobalExpr{
538 name: e.name,
539 }
540 r.init(e.c, file.Idx(0))
541 return r
542 }
543 } else {
544 if b == nil {
545 r := &deleteVarExpr{
546 name: e.name,
547 }
548 r.init(e.c, file.Idx(e.offset+1))
549 return r
550 }
551 }
552 r := &compiledLiteral{
553 val: valueFalse,
554 }
555 r.init(e.c, file.Idx(e.offset+1))
556 return r
557 }
558
559 type compiledSuperDotExpr struct {
560 baseCompiledExpr
561 name unistring.String
562 }
563
564 func (e *compiledSuperDotExpr) emitGetter(putOnStack bool) {
565 e.c.emitLoadThis()
566 e.c.emit(loadSuper)
567 e.addSrcMap()
568 e.c.emit(getPropRecv(e.name))
569 if !putOnStack {
570 e.c.emit(pop)
571 }
572 }
573
574 func (e *compiledSuperDotExpr) emitSetter(valueExpr compiledExpr, putOnStack bool) {
575 e.c.emitLoadThis()
576 e.c.emit(loadSuper)
577 valueExpr.emitGetter(true)
578 e.addSrcMap()
579 if putOnStack {
580 if e.c.scope.strict {
581 e.c.emit(setPropRecvStrict(e.name))
582 } else {
583 e.c.emit(setPropRecv(e.name))
584 }
585 } else {
586 if e.c.scope.strict {
587 e.c.emit(setPropRecvStrictP(e.name))
588 } else {
589 e.c.emit(setPropRecvP(e.name))
590 }
591 }
592 }
593
594 func (e *compiledSuperDotExpr) emitUnary(prepare, body func(), postfix, putOnStack bool) {
595 if !putOnStack {
596 e.c.emitLoadThis()
597 e.c.emit(loadSuper, dupLast(2), getPropRecv(e.name))
598 body()
599 e.addSrcMap()
600 if e.c.scope.strict {
601 e.c.emit(setPropRecvStrictP(e.name))
602 } else {
603 e.c.emit(setPropRecvP(e.name))
604 }
605 } else {
606 if !postfix {
607 e.c.emitLoadThis()
608 e.c.emit(loadSuper, dupLast(2), getPropRecv(e.name))
609 if prepare != nil {
610 prepare()
611 }
612 body()
613 e.addSrcMap()
614 if e.c.scope.strict {
615 e.c.emit(setPropRecvStrict(e.name))
616 } else {
617 e.c.emit(setPropRecv(e.name))
618 }
619 } else {
620 e.c.emit(loadUndef)
621 e.c.emitLoadThis()
622 e.c.emit(loadSuper, dupLast(2), getPropRecv(e.name))
623 if prepare != nil {
624 prepare()
625 }
626 e.c.emit(rdupN(3))
627 body()
628 e.addSrcMap()
629 if e.c.scope.strict {
630 e.c.emit(setPropRecvStrictP(e.name))
631 } else {
632 e.c.emit(setPropRecvP(e.name))
633 }
634 }
635 }
636 }
637
638 func (e *compiledSuperDotExpr) emitRef() {
639 e.c.emitLoadThis()
640 e.c.emit(loadSuper)
641 if e.c.scope.strict {
642 e.c.emit(getPropRefRecvStrict(e.name))
643 } else {
644 e.c.emit(getPropRefRecv(e.name))
645 }
646 }
647
648 func (e *compiledSuperDotExpr) deleteExpr() compiledExpr {
649 return e.c.superDeleteError(e.offset)
650 }
651
652 type compiledDotExpr struct {
653 baseCompiledExpr
654 left compiledExpr
655 name unistring.String
656 }
657
658 type compiledPrivateDotExpr struct {
659 baseCompiledExpr
660 left compiledExpr
661 name unistring.String
662 }
663
664 func (c *compiler) checkSuperBase(idx file.Idx) {
665 if s := c.scope.nearestThis(); s != nil {
666 switch s.funcType {
667 case funcMethod, funcClsInit, funcCtor, funcDerivedCtor:
668 return
669 }
670 }
671 c.throwSyntaxError(int(idx)-1, "'super' keyword unexpected here")
672 panic("unreachable")
673 }
674
675 func (c *compiler) compileDotExpression(v *ast.DotExpression) compiledExpr {
676 if sup, ok := v.Left.(*ast.SuperExpression); ok {
677 c.checkSuperBase(sup.Idx)
678 r := &compiledSuperDotExpr{
679 name: v.Identifier.Name,
680 }
681 r.init(c, v.Identifier.Idx)
682 return r
683 }
684
685 r := &compiledDotExpr{
686 left: c.compileExpression(v.Left),
687 name: v.Identifier.Name,
688 }
689 r.init(c, v.Identifier.Idx)
690 return r
691 }
692
693 func (c *compiler) compilePrivateDotExpression(v *ast.PrivateDotExpression) compiledExpr {
694 r := &compiledPrivateDotExpr{
695 left: c.compileExpression(v.Left),
696 name: v.Identifier.Name,
697 }
698 r.init(c, v.Identifier.Idx)
699 return r
700 }
701
702 func (e *compiledPrivateDotExpr) _emitGetter(rn *resolvedPrivateName, id *privateId) {
703 if rn != nil {
704 e.c.emit((*getPrivatePropRes)(rn))
705 } else {
706 e.c.emit((*getPrivatePropId)(id))
707 }
708 }
709
710 func (e *compiledPrivateDotExpr) _emitSetter(rn *resolvedPrivateName, id *privateId) {
711 if rn != nil {
712 e.c.emit((*setPrivatePropRes)(rn))
713 } else {
714 e.c.emit((*setPrivatePropId)(id))
715 }
716 }
717
718 func (e *compiledPrivateDotExpr) _emitSetterP(rn *resolvedPrivateName, id *privateId) {
719 if rn != nil {
720 e.c.emit((*setPrivatePropResP)(rn))
721 } else {
722 e.c.emit((*setPrivatePropIdP)(id))
723 }
724 }
725
726 func (e *compiledPrivateDotExpr) emitGetter(putOnStack bool) {
727 e.left.emitGetter(true)
728 e.addSrcMap()
729 rn, id := e.c.resolvePrivateName(e.name, e.offset)
730 e._emitGetter(rn, id)
731 if !putOnStack {
732 e.c.emit(pop)
733 }
734 }
735
736 func (e *compiledPrivateDotExpr) emitSetter(v compiledExpr, putOnStack bool) {
737 rn, id := e.c.resolvePrivateName(e.name, e.offset)
738 e.left.emitGetter(true)
739 v.emitGetter(true)
740 e.addSrcMap()
741 if putOnStack {
742 e._emitSetter(rn, id)
743 } else {
744 e._emitSetterP(rn, id)
745 }
746 }
747
748 func (e *compiledPrivateDotExpr) emitUnary(prepare, body func(), postfix, putOnStack bool) {
749 rn, id := e.c.resolvePrivateName(e.name, e.offset)
750 if !putOnStack {
751 e.left.emitGetter(true)
752 e.c.emit(dup)
753 e._emitGetter(rn, id)
754 body()
755 e.addSrcMap()
756 e._emitSetterP(rn, id)
757 } else {
758 if !postfix {
759 e.left.emitGetter(true)
760 e.c.emit(dup)
761 e._emitGetter(rn, id)
762 if prepare != nil {
763 prepare()
764 }
765 body()
766 e.addSrcMap()
767 e._emitSetter(rn, id)
768 } else {
769 e.c.emit(loadUndef)
770 e.left.emitGetter(true)
771 e.c.emit(dup)
772 e._emitGetter(rn, id)
773 if prepare != nil {
774 prepare()
775 }
776 e.c.emit(rdupN(2))
777 body()
778 e.addSrcMap()
779 e._emitSetterP(rn, id)
780 }
781 }
782 }
783
784 func (e *compiledPrivateDotExpr) deleteExpr() compiledExpr {
785 e.c.throwSyntaxError(e.offset, "Private fields can not be deleted")
786 panic("unreachable")
787 }
788
789 func (e *compiledPrivateDotExpr) emitRef() {
790 e.left.emitGetter(true)
791 rn, id := e.c.resolvePrivateName(e.name, e.offset)
792 if rn != nil {
793 e.c.emit((*getPrivateRefRes)(rn))
794 } else {
795 e.c.emit((*getPrivateRefId)(id))
796 }
797 }
798
799 type compiledSuperBracketExpr struct {
800 baseCompiledExpr
801 member compiledExpr
802 }
803
804 func (e *compiledSuperBracketExpr) emitGetter(putOnStack bool) {
805 e.c.emitLoadThis()
806 e.member.emitGetter(true)
807 e.c.emit(loadSuper)
808 e.addSrcMap()
809 e.c.emit(getElemRecv)
810 if !putOnStack {
811 e.c.emit(pop)
812 }
813 }
814
815 func (e *compiledSuperBracketExpr) emitSetter(valueExpr compiledExpr, putOnStack bool) {
816 e.c.emitLoadThis()
817 e.member.emitGetter(true)
818 e.c.emit(loadSuper)
819 valueExpr.emitGetter(true)
820 e.addSrcMap()
821 if putOnStack {
822 if e.c.scope.strict {
823 e.c.emit(setElemRecvStrict)
824 } else {
825 e.c.emit(setElemRecv)
826 }
827 } else {
828 if e.c.scope.strict {
829 e.c.emit(setElemRecvStrictP)
830 } else {
831 e.c.emit(setElemRecvP)
832 }
833 }
834 }
835
836 func (e *compiledSuperBracketExpr) emitUnary(prepare, body func(), postfix, putOnStack bool) {
837 if !putOnStack {
838 e.c.emitLoadThis()
839 e.member.emitGetter(true)
840 e.c.emit(loadSuper, dupLast(3), getElemRecv)
841 body()
842 e.addSrcMap()
843 if e.c.scope.strict {
844 e.c.emit(setElemRecvStrictP)
845 } else {
846 e.c.emit(setElemRecvP)
847 }
848 } else {
849 if !postfix {
850 e.c.emitLoadThis()
851 e.member.emitGetter(true)
852 e.c.emit(loadSuper, dupLast(3), getElemRecv)
853 if prepare != nil {
854 prepare()
855 }
856 body()
857 e.addSrcMap()
858 if e.c.scope.strict {
859 e.c.emit(setElemRecvStrict)
860 } else {
861 e.c.emit(setElemRecv)
862 }
863 } else {
864 e.c.emit(loadUndef)
865 e.c.emitLoadThis()
866 e.member.emitGetter(true)
867 e.c.emit(loadSuper, dupLast(3), getElemRecv)
868 if prepare != nil {
869 prepare()
870 }
871 e.c.emit(rdupN(4))
872 body()
873 e.addSrcMap()
874 if e.c.scope.strict {
875 e.c.emit(setElemRecvStrictP)
876 } else {
877 e.c.emit(setElemRecvP)
878 }
879 }
880 }
881 }
882
883 func (e *compiledSuperBracketExpr) emitRef() {
884 e.c.emitLoadThis()
885 e.member.emitGetter(true)
886 e.c.emit(loadSuper)
887 if e.c.scope.strict {
888 e.c.emit(getElemRefRecvStrict)
889 } else {
890 e.c.emit(getElemRefRecv)
891 }
892 }
893
894 func (c *compiler) superDeleteError(offset int) compiledExpr {
895 return c.compileEmitterExpr(func() {
896 c.emit(throwConst{referenceError("Unsupported reference to 'super'")})
897 }, file.Idx(offset+1))
898 }
899
900 func (e *compiledSuperBracketExpr) deleteExpr() compiledExpr {
901 return e.c.superDeleteError(e.offset)
902 }
903
904 func (c *compiler) checkConstantString(expr compiledExpr) (unistring.String, bool) {
905 if expr.constant() {
906 if val, ex := c.evalConst(expr); ex == nil {
907 if s, ok := val.(String); ok {
908 return s.string(), true
909 }
910 }
911 }
912 return "", false
913 }
914
915 func (c *compiler) compileBracketExpression(v *ast.BracketExpression) compiledExpr {
916 if sup, ok := v.Left.(*ast.SuperExpression); ok {
917 c.checkSuperBase(sup.Idx)
918 member := c.compileExpression(v.Member)
919 if name, ok := c.checkConstantString(member); ok {
920 r := &compiledSuperDotExpr{
921 name: name,
922 }
923 r.init(c, v.LeftBracket)
924 return r
925 }
926
927 r := &compiledSuperBracketExpr{
928 member: member,
929 }
930 r.init(c, v.LeftBracket)
931 return r
932 }
933
934 left := c.compileExpression(v.Left)
935 member := c.compileExpression(v.Member)
936 if name, ok := c.checkConstantString(member); ok {
937 r := &compiledDotExpr{
938 left: left,
939 name: name,
940 }
941 r.init(c, v.LeftBracket)
942 return r
943 }
944
945 r := &compiledBracketExpr{
946 left: left,
947 member: member,
948 }
949 r.init(c, v.LeftBracket)
950 return r
951 }
952
953 func (e *compiledDotExpr) emitGetter(putOnStack bool) {
954 e.left.emitGetter(true)
955 e.addSrcMap()
956 e.c.emit(getProp(e.name))
957 if !putOnStack {
958 e.c.emit(pop)
959 }
960 }
961
962 func (e *compiledDotExpr) emitRef() {
963 e.left.emitGetter(true)
964 if e.c.scope.strict {
965 e.c.emit(getPropRefStrict(e.name))
966 } else {
967 e.c.emit(getPropRef(e.name))
968 }
969 }
970
971 func (e *compiledDotExpr) emitSetter(valueExpr compiledExpr, putOnStack bool) {
972 e.left.emitGetter(true)
973 valueExpr.emitGetter(true)
974 e.addSrcMap()
975 if e.c.scope.strict {
976 if putOnStack {
977 e.c.emit(setPropStrict(e.name))
978 } else {
979 e.c.emit(setPropStrictP(e.name))
980 }
981 } else {
982 if putOnStack {
983 e.c.emit(setProp(e.name))
984 } else {
985 e.c.emit(setPropP(e.name))
986 }
987 }
988 }
989
990 func (e *compiledDotExpr) emitUnary(prepare, body func(), postfix, putOnStack bool) {
991 if !putOnStack {
992 e.left.emitGetter(true)
993 e.c.emit(dup)
994 e.c.emit(getProp(e.name))
995 body()
996 e.addSrcMap()
997 if e.c.scope.strict {
998 e.c.emit(setPropStrictP(e.name))
999 } else {
1000 e.c.emit(setPropP(e.name))
1001 }
1002 } else {
1003 if !postfix {
1004 e.left.emitGetter(true)
1005 e.c.emit(dup)
1006 e.c.emit(getProp(e.name))
1007 if prepare != nil {
1008 prepare()
1009 }
1010 body()
1011 e.addSrcMap()
1012 if e.c.scope.strict {
1013 e.c.emit(setPropStrict(e.name))
1014 } else {
1015 e.c.emit(setProp(e.name))
1016 }
1017 } else {
1018 e.c.emit(loadUndef)
1019 e.left.emitGetter(true)
1020 e.c.emit(dup)
1021 e.c.emit(getProp(e.name))
1022 if prepare != nil {
1023 prepare()
1024 }
1025 e.c.emit(rdupN(2))
1026 body()
1027 e.addSrcMap()
1028 if e.c.scope.strict {
1029 e.c.emit(setPropStrictP(e.name))
1030 } else {
1031 e.c.emit(setPropP(e.name))
1032 }
1033 }
1034 }
1035 }
1036
1037 func (e *compiledDotExpr) deleteExpr() compiledExpr {
1038 r := &deletePropExpr{
1039 left: e.left,
1040 name: e.name,
1041 }
1042 r.init(e.c, file.Idx(e.offset)+1)
1043 return r
1044 }
1045
1046 func (e *compiledBracketExpr) emitGetter(putOnStack bool) {
1047 e.left.emitGetter(true)
1048 e.member.emitGetter(true)
1049 e.addSrcMap()
1050 e.c.emit(getElem)
1051 if !putOnStack {
1052 e.c.emit(pop)
1053 }
1054 }
1055
1056 func (e *compiledBracketExpr) emitRef() {
1057 e.left.emitGetter(true)
1058 e.member.emitGetter(true)
1059 if e.c.scope.strict {
1060 e.c.emit(getElemRefStrict)
1061 } else {
1062 e.c.emit(getElemRef)
1063 }
1064 }
1065
1066 func (e *compiledBracketExpr) emitSetter(valueExpr compiledExpr, putOnStack bool) {
1067 e.left.emitGetter(true)
1068 e.member.emitGetter(true)
1069 valueExpr.emitGetter(true)
1070 e.addSrcMap()
1071 if e.c.scope.strict {
1072 if putOnStack {
1073 e.c.emit(setElemStrict)
1074 } else {
1075 e.c.emit(setElemStrictP)
1076 }
1077 } else {
1078 if putOnStack {
1079 e.c.emit(setElem)
1080 } else {
1081 e.c.emit(setElemP)
1082 }
1083 }
1084 }
1085
1086 func (e *compiledBracketExpr) emitUnary(prepare, body func(), postfix, putOnStack bool) {
1087 if !putOnStack {
1088 e.left.emitGetter(true)
1089 e.member.emitGetter(true)
1090 e.c.emit(dupLast(2), getElem)
1091 body()
1092 e.addSrcMap()
1093 if e.c.scope.strict {
1094 e.c.emit(setElemStrict, pop)
1095 } else {
1096 e.c.emit(setElem, pop)
1097 }
1098 } else {
1099 if !postfix {
1100 e.left.emitGetter(true)
1101 e.member.emitGetter(true)
1102 e.c.emit(dupLast(2), getElem)
1103 if prepare != nil {
1104 prepare()
1105 }
1106 body()
1107 e.addSrcMap()
1108 if e.c.scope.strict {
1109 e.c.emit(setElemStrict)
1110 } else {
1111 e.c.emit(setElem)
1112 }
1113 } else {
1114 e.c.emit(loadUndef)
1115 e.left.emitGetter(true)
1116 e.member.emitGetter(true)
1117 e.c.emit(dupLast(2), getElem)
1118 if prepare != nil {
1119 prepare()
1120 }
1121 e.c.emit(rdupN(3))
1122 body()
1123 e.addSrcMap()
1124 if e.c.scope.strict {
1125 e.c.emit(setElemStrict, pop)
1126 } else {
1127 e.c.emit(setElem, pop)
1128 }
1129 }
1130 }
1131 }
1132
1133 func (e *compiledBracketExpr) deleteExpr() compiledExpr {
1134 r := &deleteElemExpr{
1135 left: e.left,
1136 member: e.member,
1137 }
1138 r.init(e.c, file.Idx(e.offset)+1)
1139 return r
1140 }
1141
1142 func (e *deleteElemExpr) emitGetter(putOnStack bool) {
1143 e.left.emitGetter(true)
1144 e.member.emitGetter(true)
1145 e.addSrcMap()
1146 if e.c.scope.strict {
1147 e.c.emit(deleteElemStrict)
1148 } else {
1149 e.c.emit(deleteElem)
1150 }
1151 if !putOnStack {
1152 e.c.emit(pop)
1153 }
1154 }
1155
1156 func (e *deletePropExpr) emitGetter(putOnStack bool) {
1157 e.left.emitGetter(true)
1158 e.addSrcMap()
1159 if e.c.scope.strict {
1160 e.c.emit(deletePropStrict(e.name))
1161 } else {
1162 e.c.emit(deleteProp(e.name))
1163 }
1164 if !putOnStack {
1165 e.c.emit(pop)
1166 }
1167 }
1168
1169 func (e *deleteVarExpr) emitGetter(putOnStack bool) {
1170
1174 e.c.emit(deleteVar(e.name))
1175 if !putOnStack {
1176 e.c.emit(pop)
1177 }
1178 }
1179
1180 func (e *deleteGlobalExpr) emitGetter(putOnStack bool) {
1181
1185
1186 e.c.emit(deleteGlobal(e.name))
1187 if !putOnStack {
1188 e.c.emit(pop)
1189 }
1190 }
1191
1192 func (e *compiledAssignExpr) emitGetter(putOnStack bool) {
1193 switch e.operator {
1194 case token.ASSIGN:
1195 e.left.emitSetter(e.right, putOnStack)
1196 case token.PLUS:
1197 e.left.emitUnary(nil, func() {
1198 e.right.emitGetter(true)
1199 e.c.emit(add)
1200 }, false, putOnStack)
1201 case token.MINUS:
1202 e.left.emitUnary(nil, func() {
1203 e.right.emitGetter(true)
1204 e.c.emit(sub)
1205 }, false, putOnStack)
1206 case token.MULTIPLY:
1207 e.left.emitUnary(nil, func() {
1208 e.right.emitGetter(true)
1209 e.c.emit(mul)
1210 }, false, putOnStack)
1211 case token.EXPONENT:
1212 e.left.emitUnary(nil, func() {
1213 e.right.emitGetter(true)
1214 e.c.emit(exp)
1215 }, false, putOnStack)
1216 case token.SLASH:
1217 e.left.emitUnary(nil, func() {
1218 e.right.emitGetter(true)
1219 e.c.emit(div)
1220 }, false, putOnStack)
1221 case token.REMAINDER:
1222 e.left.emitUnary(nil, func() {
1223 e.right.emitGetter(true)
1224 e.c.emit(mod)
1225 }, false, putOnStack)
1226 case token.OR:
1227 e.left.emitUnary(nil, func() {
1228 e.right.emitGetter(true)
1229 e.c.emit(or)
1230 }, false, putOnStack)
1231 case token.AND:
1232 e.left.emitUnary(nil, func() {
1233 e.right.emitGetter(true)
1234 e.c.emit(and)
1235 }, false, putOnStack)
1236 case token.EXCLUSIVE_OR:
1237 e.left.emitUnary(nil, func() {
1238 e.right.emitGetter(true)
1239 e.c.emit(xor)
1240 }, false, putOnStack)
1241 case token.SHIFT_LEFT:
1242 e.left.emitUnary(nil, func() {
1243 e.right.emitGetter(true)
1244 e.c.emit(sal)
1245 }, false, putOnStack)
1246 case token.SHIFT_RIGHT:
1247 e.left.emitUnary(nil, func() {
1248 e.right.emitGetter(true)
1249 e.c.emit(sar)
1250 }, false, putOnStack)
1251 case token.UNSIGNED_SHIFT_RIGHT:
1252 e.left.emitUnary(nil, func() {
1253 e.right.emitGetter(true)
1254 e.c.emit(shr)
1255 }, false, putOnStack)
1256 default:
1257 e.c.assert(false, e.offset, "Unknown assign operator: %s", e.operator.String())
1258 panic("unreachable")
1259 }
1260 }
1261
1262 func (e *compiledLiteral) emitGetter(putOnStack bool) {
1263 if putOnStack {
1264 e.c.emit(loadVal(e.c.p.defineLiteralValue(e.val)))
1265 }
1266 }
1267
1268 func (e *compiledLiteral) constant() bool {
1269 return true
1270 }
1271
1272 func (e *compiledTemplateLiteral) emitGetter(putOnStack bool) {
1273 if e.tag == nil {
1274 if len(e.elements) == 0 {
1275 e.c.emit(loadVal(e.c.p.defineLiteralValue(stringEmpty)))
1276 } else {
1277 tail := e.elements[len(e.elements)-1].Parsed
1278 if len(e.elements) == 1 {
1279 e.c.emit(loadVal(e.c.p.defineLiteralValue(stringValueFromRaw(tail))))
1280 } else {
1281 stringCount := 0
1282 if head := e.elements[0].Parsed; head != "" {
1283 e.c.emit(loadVal(e.c.p.defineLiteralValue(stringValueFromRaw(head))))
1284 stringCount++
1285 }
1286 e.expressions[0].emitGetter(true)
1287 e.c.emit(_toString{})
1288 stringCount++
1289 for i := 1; i < len(e.elements)-1; i++ {
1290 if elt := e.elements[i].Parsed; elt != "" {
1291 e.c.emit(loadVal(e.c.p.defineLiteralValue(stringValueFromRaw(elt))))
1292 stringCount++
1293 }
1294 e.expressions[i].emitGetter(true)
1295 e.c.emit(_toString{})
1296 stringCount++
1297 }
1298 if tail != "" {
1299 e.c.emit(loadVal(e.c.p.defineLiteralValue(stringValueFromRaw(tail))))
1300 stringCount++
1301 }
1302 e.c.emit(concatStrings(stringCount))
1303 }
1304 }
1305 } else {
1306 cooked := make([]Value, len(e.elements))
1307 raw := make([]Value, len(e.elements))
1308 for i, elt := range e.elements {
1309 raw[i] = &valueProperty{
1310 enumerable: true,
1311 value: newStringValue(elt.Literal),
1312 }
1313 var cookedVal Value
1314 if elt.Valid {
1315 cookedVal = stringValueFromRaw(elt.Parsed)
1316 } else {
1317 cookedVal = _undefined
1318 }
1319 cooked[i] = &valueProperty{
1320 enumerable: true,
1321 value: cookedVal,
1322 }
1323 }
1324 e.c.emitCallee(e.tag)
1325 e.c.emit(&getTaggedTmplObject{
1326 raw: raw,
1327 cooked: cooked,
1328 })
1329 for _, expr := range e.expressions {
1330 expr.emitGetter(true)
1331 }
1332 e.c.emit(call(len(e.expressions) + 1))
1333 }
1334 if !putOnStack {
1335 e.c.emit(pop)
1336 }
1337 }
1338
1339 func (c *compiler) compileParameterBindingIdentifier(name unistring.String, offset int) (*binding, bool) {
1340 if c.scope.strict {
1341 c.checkIdentifierName(name, offset)
1342 c.checkIdentifierLName(name, offset)
1343 }
1344 return c.scope.bindNameShadow(name)
1345 }
1346
1347 func (c *compiler) compileParameterPatternIdBinding(name unistring.String, offset int) {
1348 if _, unique := c.compileParameterBindingIdentifier(name, offset); !unique {
1349 c.throwSyntaxError(offset, "Duplicate parameter name not allowed in this context")
1350 }
1351 }
1352
1353 func (c *compiler) compileParameterPatternBinding(item ast.Expression) {
1354 c.createBindings(item, c.compileParameterPatternIdBinding)
1355 }
1356
1357 func (c *compiler) newCode(length, minCap int) (buf []instruction) {
1358 if c.codeScratchpad != nil {
1359 buf = c.codeScratchpad
1360 c.codeScratchpad = nil
1361 }
1362 if cap(buf) < minCap {
1363 buf = make([]instruction, length, minCap)
1364 } else {
1365 buf = buf[:length]
1366 }
1367 return
1368 }
1369
1370 func (e *compiledFunctionLiteral) compile() (prg *Program, name unistring.String, length int, strict bool) {
1371 e.c.assert(e.typ != funcNone, e.offset, "compiledFunctionLiteral.typ is not set")
1372
1373 savedPrg := e.c.p
1374 preambleLen := 8
1375 e.c.p = &Program{
1376 src: e.c.p.src,
1377 code: e.c.newCode(preambleLen, 16),
1378 srcMap: []srcMapItem{{srcPos: e.offset}},
1379 }
1380 e.c.newScope()
1381 s := e.c.scope
1382 s.funcType = e.typ
1383
1384 if e.name != nil {
1385 name = e.name.Name
1386 } else {
1387 name = e.lhsName
1388 }
1389
1390 if name != "" {
1391 e.c.p.funcName = name
1392 }
1393 savedBlock := e.c.block
1394 defer func() {
1395 e.c.block = savedBlock
1396 }()
1397
1398 e.c.block = &block{
1399 typ: blockScope,
1400 }
1401
1402 if !s.strict {
1403 s.strict = e.strict != nil
1404 }
1405
1406 hasPatterns := false
1407 hasInits := false
1408 firstDupIdx := -1
1409
1410 if e.parameterList.Rest != nil {
1411 hasPatterns = true
1412 }
1413
1414
1415 for _, item := range e.parameterList.List {
1416 switch tgt := item.Target.(type) {
1417 case *ast.Identifier:
1418 offset := int(tgt.Idx) - 1
1419 b, unique := e.c.compileParameterBindingIdentifier(tgt.Name, offset)
1420 if !unique {
1421 firstDupIdx = offset
1422 }
1423 b.isArg = true
1424 case ast.Pattern:
1425 b := s.addBinding(int(item.Idx0()) - 1)
1426 b.isArg = true
1427 hasPatterns = true
1428 default:
1429 e.c.throwSyntaxError(int(item.Idx0())-1, "Unsupported BindingElement type: %T", item)
1430 return
1431 }
1432 if item.Initializer != nil {
1433 hasInits = true
1434 }
1435
1436 if firstDupIdx >= 0 && (hasPatterns || hasInits || s.strict || e.typ == funcArrow || e.typ == funcMethod) {
1437 e.c.throwSyntaxError(firstDupIdx, "Duplicate parameter name not allowed in this context")
1438 return
1439 }
1440
1441 if (hasPatterns || hasInits) && e.strict != nil {
1442 e.c.throwSyntaxError(int(e.strict.Idx)-1, "Illegal 'use strict' directive in function with non-simple parameter list")
1443 return
1444 }
1445
1446 if !hasInits {
1447 length++
1448 }
1449 }
1450
1451 var thisBinding *binding
1452 if e.typ != funcArrow {
1453 thisBinding = s.createThisBinding()
1454 }
1455
1456
1457 if hasPatterns {
1458 for _, item := range e.parameterList.List {
1459 switch tgt := item.Target.(type) {
1460 case *ast.Identifier:
1461
1462 default:
1463 e.c.compileParameterPatternBinding(tgt)
1464 }
1465 }
1466 if rest := e.parameterList.Rest; rest != nil {
1467 e.c.compileParameterPatternBinding(rest)
1468 }
1469 }
1470
1471 paramsCount := len(e.parameterList.List)
1472
1473 s.numArgs = paramsCount
1474 body := e.body
1475 funcs := e.c.extractFunctions(body)
1476 var calleeBinding *binding
1477
1478 emitArgsRestMark := -1
1479 firstForwardRef := -1
1480 enterFunc2Mark := -1
1481
1482 if hasPatterns || hasInits {
1483 if e.isExpr && e.name != nil {
1484 if b, created := s.bindNameLexical(e.name.Name, false, 0); created {
1485 b.isConst = true
1486 calleeBinding = b
1487 }
1488 }
1489 for i, item := range e.parameterList.List {
1490 if pattern, ok := item.Target.(ast.Pattern); ok {
1491 i := i
1492 e.c.compilePatternInitExpr(func() {
1493 if firstForwardRef == -1 {
1494 s.bindings[i].emitGet()
1495 } else {
1496 e.c.emit(loadStackLex(-i - 1))
1497 }
1498 }, item.Initializer, item.Target.Idx0()).emitGetter(true)
1499 e.c.emitPattern(pattern, func(target, init compiledExpr) {
1500 e.c.emitPatternLexicalAssign(target, init)
1501 }, false)
1502 } else if item.Initializer != nil {
1503 markGet := len(e.c.p.code)
1504 e.c.emit(nil)
1505 mark := len(e.c.p.code)
1506 e.c.emit(nil)
1507 e.c.emitExpr(e.c.compileExpression(item.Initializer), true)
1508 if firstForwardRef == -1 && (s.isDynamic() || s.bindings[i].useCount() > 0) {
1509 firstForwardRef = i
1510 }
1511 if firstForwardRef == -1 {
1512 s.bindings[i].emitGetAt(markGet)
1513 } else {
1514 e.c.p.code[markGet] = loadStackLex(-i - 1)
1515 }
1516 s.bindings[i].emitInitP()
1517 e.c.p.code[mark] = jdefP(len(e.c.p.code) - mark)
1518 } else {
1519 if firstForwardRef == -1 && s.bindings[i].useCount() > 0 {
1520 firstForwardRef = i
1521 }
1522 if firstForwardRef != -1 {
1523 e.c.emit(loadStackLex(-i - 1))
1524 s.bindings[i].emitInitP()
1525 }
1526 }
1527 }
1528 if rest := e.parameterList.Rest; rest != nil {
1529 e.c.emitAssign(rest, e.c.compileEmitterExpr(
1530 func() {
1531 emitArgsRestMark = len(e.c.p.code)
1532 e.c.emit(createArgsRestStack(paramsCount))
1533 }, rest.Idx0()),
1534 func(target, init compiledExpr) {
1535 e.c.emitPatternLexicalAssign(target, init)
1536 })
1537 }
1538 if firstForwardRef != -1 {
1539 for _, b := range s.bindings {
1540 b.inStash = true
1541 }
1542 s.argsInStash = true
1543 s.needStash = true
1544 }
1545
1546 e.c.newBlockScope()
1547 varScope := e.c.scope
1548 varScope.variable = true
1549 enterFunc2Mark = len(e.c.p.code)
1550 e.c.emit(nil)
1551 e.c.compileDeclList(e.declarationList, false)
1552 e.c.createFunctionBindings(funcs)
1553 e.c.compileLexicalDeclarationsFuncBody(body, calleeBinding)
1554 for _, b := range varScope.bindings {
1555 if b.isVar {
1556 if parentBinding := s.boundNames[b.name]; parentBinding != nil && parentBinding != calleeBinding {
1557 parentBinding.emitGet()
1558 b.emitSetP()
1559 }
1560 }
1561 }
1562 } else {
1563
1564
1565 for _, b := range s.bindings[:paramsCount] {
1566 b.isVar = true
1567 }
1568 e.c.compileDeclList(e.declarationList, true)
1569 e.c.createFunctionBindings(funcs)
1570 e.c.compileLexicalDeclarations(body, true)
1571 if e.isExpr && e.name != nil {
1572 if b, created := s.bindNameLexical(e.name.Name, false, 0); created {
1573 b.isConst = true
1574 calleeBinding = b
1575 }
1576 }
1577 if calleeBinding != nil {
1578 e.c.emit(loadCallee)
1579 calleeBinding.emitInitP()
1580 }
1581 }
1582
1583 e.c.compileFunctions(funcs)
1584 if e.isGenerator {
1585 e.c.emit(yieldEmpty)
1586 }
1587 e.c.compileStatements(body, false)
1588
1589 var last ast.Statement
1590 if l := len(body); l > 0 {
1591 last = body[l-1]
1592 }
1593 if _, ok := last.(*ast.ReturnStatement); !ok {
1594 if e.typ == funcDerivedCtor {
1595 e.c.emit(loadUndef)
1596 thisBinding.markAccessPoint()
1597 e.c.emit(ret)
1598 } else {
1599 e.c.emit(loadUndef, ret)
1600 }
1601 }
1602
1603 delta := 0
1604 code := e.c.p.code
1605
1606 if s.isDynamic() && !s.argsInStash {
1607 s.moveArgsToStash()
1608 }
1609
1610 if s.argsNeeded || s.isDynamic() && e.typ != funcArrow && e.typ != funcClsInit {
1611 if e.typ == funcClsInit {
1612 e.c.throwSyntaxError(e.offset, "'arguments' is not allowed in class field initializer or static initialization block")
1613 }
1614 b, created := s.bindNameLexical("arguments", false, 0)
1615 if created || b.isVar {
1616 if !s.argsInStash {
1617 s.moveArgsToStash()
1618 }
1619 if s.strict {
1620 b.isConst = true
1621 } else {
1622 b.isVar = e.c.scope.isFunction()
1623 }
1624 pos := preambleLen - 2
1625 delta += 2
1626 if s.strict || hasPatterns || hasInits {
1627 code[pos] = createArgsUnmapped(paramsCount)
1628 } else {
1629 code[pos] = createArgsMapped(paramsCount)
1630 }
1631 pos++
1632 b.emitInitPAtScope(s, pos)
1633 }
1634 }
1635
1636 if calleeBinding != nil {
1637 if !s.isDynamic() && calleeBinding.useCount() == 0 {
1638 s.deleteBinding(calleeBinding)
1639 calleeBinding = nil
1640 } else {
1641 delta++
1642 calleeBinding.emitInitPAtScope(s, preambleLen-delta)
1643 delta++
1644 code[preambleLen-delta] = loadCallee
1645 }
1646 }
1647
1648 if thisBinding != nil {
1649 if !s.isDynamic() && thisBinding.useCount() == 0 {
1650 s.deleteBinding(thisBinding)
1651 thisBinding = nil
1652 } else {
1653 if thisBinding.inStash || s.isDynamic() {
1654 delta++
1655 thisBinding.emitInitAtScope(s, preambleLen-delta)
1656 }
1657 }
1658 }
1659
1660 stashSize, stackSize := s.finaliseVarAlloc(0)
1661
1662 if thisBinding != nil && thisBinding.inStash && (!s.argsInStash || stackSize > 0) {
1663 delta++
1664 code[preambleLen-delta] = loadStack(0)
1665 }
1666
1667 if !s.strict && thisBinding != nil {
1668 delta++
1669 code[preambleLen-delta] = boxThis
1670 }
1671 delta++
1672 delta = preambleLen - delta
1673 var enter instruction
1674 if stashSize > 0 || s.argsInStash {
1675 if firstForwardRef == -1 {
1676 enter1 := enterFunc{
1677 numArgs: uint32(paramsCount),
1678 argsToStash: s.argsInStash,
1679 stashSize: uint32(stashSize),
1680 stackSize: uint32(stackSize),
1681 extensible: s.dynamic,
1682 funcType: e.typ,
1683 }
1684 if s.isDynamic() {
1685 enter1.names = s.makeNamesMap()
1686 }
1687 enter = &enter1
1688 if enterFunc2Mark != -1 {
1689 ef2 := &enterFuncBody{
1690 extensible: e.c.scope.dynamic,
1691 funcType: e.typ,
1692 }
1693 e.c.updateEnterBlock(&ef2.enterBlock)
1694 e.c.p.code[enterFunc2Mark] = ef2
1695 }
1696 } else {
1697 enter1 := enterFunc1{
1698 stashSize: uint32(stashSize),
1699 numArgs: uint32(paramsCount),
1700 argsToCopy: uint32(firstForwardRef),
1701 extensible: s.dynamic,
1702 funcType: e.typ,
1703 }
1704 if s.isDynamic() {
1705 enter1.names = s.makeNamesMap()
1706 }
1707 enter = &enter1
1708 if enterFunc2Mark != -1 {
1709 ef2 := &enterFuncBody{
1710 adjustStack: true,
1711 extensible: e.c.scope.dynamic,
1712 funcType: e.typ,
1713 }
1714 e.c.updateEnterBlock(&ef2.enterBlock)
1715 e.c.p.code[enterFunc2Mark] = ef2
1716 }
1717 }
1718 if emitArgsRestMark != -1 && s.argsInStash {
1719 e.c.p.code[emitArgsRestMark] = createArgsRestStash
1720 }
1721 } else {
1722 enter = &enterFuncStashless{
1723 stackSize: uint32(stackSize),
1724 args: uint32(paramsCount),
1725 }
1726 if enterFunc2Mark != -1 {
1727 ef2 := &enterFuncBody{
1728 extensible: e.c.scope.dynamic,
1729 funcType: e.typ,
1730 }
1731 e.c.updateEnterBlock(&ef2.enterBlock)
1732 e.c.p.code[enterFunc2Mark] = ef2
1733 }
1734 }
1735 code[delta] = enter
1736 e.c.p.srcMap[0].pc = delta
1737 s.trimCode(delta)
1738
1739 strict = s.strict
1740 prg = e.c.p
1741
1742 if enterFunc2Mark != -1 {
1743 e.c.popScope()
1744 }
1745 e.c.popScope()
1746 e.c.p = savedPrg
1747
1748 return
1749 }
1750
1751 func (e *compiledFunctionLiteral) emitGetter(putOnStack bool) {
1752 p, name, length, strict := e.compile()
1753 switch e.typ {
1754 case funcArrow:
1755 if e.isAsync {
1756 e.c.emit(&newAsyncArrowFunc{newArrowFunc: newArrowFunc{newFunc: newFunc{prg: p, length: length, name: name, source: e.source, strict: strict}}})
1757 } else {
1758 e.c.emit(&newArrowFunc{newFunc: newFunc{prg: p, length: length, name: name, source: e.source, strict: strict}})
1759 }
1760 case funcMethod, funcClsInit:
1761 if e.isAsync {
1762 e.c.emit(&newAsyncMethod{newMethod: newMethod{newFunc: newFunc{prg: p, length: length, name: name, source: e.source, strict: strict}, homeObjOffset: e.homeObjOffset}})
1763 } else {
1764 if e.isGenerator {
1765 e.c.emit(&newGeneratorMethod{newMethod: newMethod{newFunc: newFunc{prg: p, length: length, name: name, source: e.source, strict: strict}, homeObjOffset: e.homeObjOffset}})
1766 } else {
1767 e.c.emit(&newMethod{newFunc: newFunc{prg: p, length: length, name: name, source: e.source, strict: strict}, homeObjOffset: e.homeObjOffset})
1768 }
1769 }
1770 case funcRegular:
1771 if e.isAsync {
1772 e.c.emit(&newAsyncFunc{newFunc: newFunc{prg: p, length: length, name: name, source: e.source, strict: strict}})
1773 } else {
1774 if e.isGenerator {
1775 e.c.emit(&newGeneratorFunc{newFunc: newFunc{prg: p, length: length, name: name, source: e.source, strict: strict}})
1776 } else {
1777 e.c.emit(&newFunc{prg: p, length: length, name: name, source: e.source, strict: strict})
1778 }
1779 }
1780 default:
1781 e.c.throwSyntaxError(e.offset, "Unsupported func type: %v", e.typ)
1782 }
1783 if !putOnStack {
1784 e.c.emit(pop)
1785 }
1786 }
1787
1788 func (c *compiler) compileFunctionLiteral(v *ast.FunctionLiteral, isExpr bool) *compiledFunctionLiteral {
1789 strictBody := c.isStrictStatement(v.Body)
1790 if v.Name != nil && (c.scope.strict || strictBody != nil) {
1791 c.checkIdentifierName(v.Name.Name, int(v.Name.Idx)-1)
1792 c.checkIdentifierLName(v.Name.Name, int(v.Name.Idx)-1)
1793 }
1794 if v.Async && v.Generator {
1795 c.throwSyntaxError(int(v.Function)-1, "Async generators are not supported yet")
1796 }
1797 r := &compiledFunctionLiteral{
1798 name: v.Name,
1799 parameterList: v.ParameterList,
1800 body: v.Body.List,
1801 source: v.Source,
1802 declarationList: v.DeclarationList,
1803 isExpr: isExpr,
1804 typ: funcRegular,
1805 strict: strictBody,
1806 isAsync: v.Async,
1807 isGenerator: v.Generator,
1808 }
1809 r.init(c, v.Idx0())
1810 return r
1811 }
1812
1813 type compiledClassLiteral struct {
1814 baseCompiledExpr
1815 name *ast.Identifier
1816 superClass compiledExpr
1817 body []ast.ClassElement
1818 lhsName unistring.String
1819 source string
1820 isExpr bool
1821 }
1822
1823 func (c *compiler) processKey(expr ast.Expression) (val unistring.String, computed bool) {
1824 keyExpr := c.compileExpression(expr)
1825 if keyExpr.constant() {
1826 v, ex := c.evalConst(keyExpr)
1827 if ex == nil {
1828 return v.string(), false
1829 }
1830 }
1831 keyExpr.emitGetter(true)
1832 computed = true
1833 return
1834 }
1835
1836 func (e *compiledClassLiteral) processClassKey(expr ast.Expression) (privateName *privateName, key unistring.String, computed bool) {
1837 if p, ok := expr.(*ast.PrivateIdentifier); ok {
1838 privateName = e.c.classScope.getDeclaredPrivateId(p.Name)
1839 key = privateIdString(p.Name)
1840 return
1841 }
1842 key, computed = e.c.processKey(expr)
1843 return
1844 }
1845
1846 type clsElement struct {
1847 key unistring.String
1848 privateName *privateName
1849 initializer compiledExpr
1850 body *compiledFunctionLiteral
1851 computed bool
1852 }
1853
1854 func (e *compiledClassLiteral) emitGetter(putOnStack bool) {
1855 e.c.newBlockScope()
1856 s := e.c.scope
1857 s.strict = true
1858
1859 enter := &enterBlock{}
1860 mark0 := len(e.c.p.code)
1861 e.c.emit(enter)
1862 e.c.block = &block{
1863 typ: blockScope,
1864 outer: e.c.block,
1865 }
1866 var clsBinding *binding
1867 var clsName unistring.String
1868 if name := e.name; name != nil {
1869 clsName = name.Name
1870 clsBinding = e.c.createLexicalIdBinding(clsName, true, int(name.Idx)-1)
1871 } else {
1872 clsName = e.lhsName
1873 }
1874
1875 var ctorMethod *ast.MethodDefinition
1876 ctorMethodIdx := -1
1877 staticsCount := 0
1878 instanceFieldsCount := 0
1879 hasStaticPrivateMethods := false
1880 cs := &classScope{
1881 c: e.c,
1882 outer: e.c.classScope,
1883 }
1884
1885 for idx, elt := range e.body {
1886 switch elt := elt.(type) {
1887 case *ast.ClassStaticBlock:
1888 if len(elt.Block.List) > 0 {
1889 staticsCount++
1890 }
1891 case *ast.FieldDefinition:
1892 if id, ok := elt.Key.(*ast.PrivateIdentifier); ok {
1893 cs.declarePrivateId(id.Name, ast.PropertyKindValue, elt.Static, int(elt.Idx)-1)
1894 }
1895 if elt.Static {
1896 staticsCount++
1897 } else {
1898 instanceFieldsCount++
1899 }
1900 case *ast.MethodDefinition:
1901 if !elt.Static {
1902 if id, ok := elt.Key.(*ast.StringLiteral); ok {
1903 if !elt.Computed && id.Value == "constructor" {
1904 if ctorMethod != nil {
1905 e.c.throwSyntaxError(int(id.Idx)-1, "A class may only have one constructor")
1906 }
1907 ctorMethod = elt
1908 ctorMethodIdx = idx
1909 continue
1910 }
1911 }
1912 }
1913 if id, ok := elt.Key.(*ast.PrivateIdentifier); ok {
1914 cs.declarePrivateId(id.Name, elt.Kind, elt.Static, int(elt.Idx)-1)
1915 if elt.Static {
1916 hasStaticPrivateMethods = true
1917 }
1918 }
1919 default:
1920 e.c.assert(false, int(elt.Idx0())-1, "Unsupported static element: %T", elt)
1921 }
1922 }
1923
1924 var staticInit *newStaticFieldInit
1925 if staticsCount > 0 || hasStaticPrivateMethods {
1926 staticInit = &newStaticFieldInit{}
1927 e.c.emit(staticInit)
1928 }
1929
1930 var derived bool
1931 var newClassIns *newClass
1932 if superClass := e.superClass; superClass != nil {
1933 derived = true
1934 superClass.emitGetter(true)
1935 ndc := &newDerivedClass{
1936 newClass: newClass{
1937 name: clsName,
1938 source: e.source,
1939 },
1940 }
1941 e.addSrcMap()
1942 e.c.emit(ndc)
1943 newClassIns = &ndc.newClass
1944 } else {
1945 newClassIns = &newClass{
1946 name: clsName,
1947 source: e.source,
1948 }
1949 e.addSrcMap()
1950 e.c.emit(newClassIns)
1951 }
1952
1953 e.c.classScope = cs
1954
1955 if ctorMethod != nil {
1956 newClassIns.ctor, newClassIns.length = e.c.compileCtor(ctorMethod.Body, derived)
1957 }
1958
1959 curIsPrototype := false
1960
1961 instanceFields := make([]clsElement, 0, instanceFieldsCount)
1962 staticElements := make([]clsElement, 0, staticsCount)
1963
1964
1965
1966
1967
1968
1969
1970
1971 for idx, elt := range e.body {
1972 if idx == ctorMethodIdx {
1973 continue
1974 }
1975 switch elt := elt.(type) {
1976 case *ast.ClassStaticBlock:
1977 if len(elt.Block.List) > 0 {
1978 f := e.c.compileFunctionLiteral(&ast.FunctionLiteral{
1979 Function: elt.Idx0(),
1980 ParameterList: &ast.ParameterList{},
1981 Body: elt.Block,
1982 Source: elt.Source,
1983 DeclarationList: elt.DeclarationList,
1984 }, true)
1985 f.typ = funcClsInit
1986
1987 f.homeObjOffset = 1
1988 staticElements = append(staticElements, clsElement{
1989 body: f,
1990 })
1991 }
1992 case *ast.FieldDefinition:
1993 privateName, key, computed := e.processClassKey(elt.Key)
1994 var el clsElement
1995 if elt.Initializer != nil {
1996 el.initializer = e.c.compileExpression(elt.Initializer)
1997 }
1998 el.computed = computed
1999 if computed {
2000 if elt.Static {
2001 if curIsPrototype {
2002 e.c.emit(defineComputedKey(5))
2003 } else {
2004 e.c.emit(defineComputedKey(4))
2005 }
2006 } else {
2007 if curIsPrototype {
2008 e.c.emit(defineComputedKey(3))
2009 } else {
2010 e.c.emit(defineComputedKey(2))
2011 }
2012 }
2013 } else {
2014 el.privateName = privateName
2015 el.key = key
2016 }
2017 if elt.Static {
2018 staticElements = append(staticElements, el)
2019 } else {
2020 instanceFields = append(instanceFields, el)
2021 }
2022 case *ast.MethodDefinition:
2023 if elt.Static {
2024 if curIsPrototype {
2025 e.c.emit(pop)
2026 curIsPrototype = false
2027 }
2028 } else {
2029 if !curIsPrototype {
2030 e.c.emit(dupN(1))
2031 curIsPrototype = true
2032 }
2033 }
2034 privateName, key, computed := e.processClassKey(elt.Key)
2035 lit := e.c.compileFunctionLiteral(elt.Body, true)
2036 lit.typ = funcMethod
2037 if computed {
2038 e.c.emit(_toPropertyKey{})
2039 lit.homeObjOffset = 2
2040 } else {
2041 lit.homeObjOffset = 1
2042 lit.lhsName = key
2043 }
2044 lit.emitGetter(true)
2045 if privateName != nil {
2046 var offset int
2047 if elt.Static {
2048 if curIsPrototype {
2049
2057 offset = 5
2058 } else {
2059
2066 offset = 4
2067 }
2068 } else {
2069 if curIsPrototype {
2070 offset = 3
2071 } else {
2072 offset = 2
2073 }
2074 }
2075 switch elt.Kind {
2076 case ast.PropertyKindGet:
2077 e.c.emit(&definePrivateGetter{
2078 definePrivateMethod: definePrivateMethod{
2079 idx: privateName.idx,
2080 targetOffset: offset,
2081 },
2082 })
2083 case ast.PropertyKindSet:
2084 e.c.emit(&definePrivateSetter{
2085 definePrivateMethod: definePrivateMethod{
2086 idx: privateName.idx,
2087 targetOffset: offset,
2088 },
2089 })
2090 default:
2091 e.c.emit(&definePrivateMethod{
2092 idx: privateName.idx,
2093 targetOffset: offset,
2094 })
2095 }
2096 } else if computed {
2097 switch elt.Kind {
2098 case ast.PropertyKindGet:
2099 e.c.emit(&defineGetter{})
2100 case ast.PropertyKindSet:
2101 e.c.emit(&defineSetter{})
2102 default:
2103 e.c.emit(&defineMethod{})
2104 }
2105 } else {
2106 switch elt.Kind {
2107 case ast.PropertyKindGet:
2108 e.c.emit(&defineGetterKeyed{key: key})
2109 case ast.PropertyKindSet:
2110 e.c.emit(&defineSetterKeyed{key: key})
2111 default:
2112 e.c.emit(&defineMethodKeyed{key: key})
2113 }
2114 }
2115 }
2116 }
2117 if curIsPrototype {
2118 e.c.emit(pop)
2119 }
2120
2121 if len(instanceFields) > 0 {
2122 newClassIns.initFields = e.compileFieldsAndStaticBlocks(instanceFields, "<instance_members_initializer>")
2123 }
2124 if staticInit != nil {
2125 if len(staticElements) > 0 {
2126 staticInit.initFields = e.compileFieldsAndStaticBlocks(staticElements, "<static_initializer>")
2127 }
2128 }
2129
2130 env := e.c.classScope.instanceEnv
2131 if s.dynLookup {
2132 newClassIns.privateMethods, newClassIns.privateFields = env.methods, env.fields
2133 }
2134 newClassIns.numPrivateMethods = uint32(len(env.methods))
2135 newClassIns.numPrivateFields = uint32(len(env.fields))
2136 newClassIns.hasPrivateEnv = len(e.c.classScope.privateNames) > 0
2137
2138 if (clsBinding != nil && clsBinding.useCount() > 0) || s.dynLookup {
2139 if clsBinding != nil {
2140
2141
2142
2143
2144 clsBinding.moveToStash()
2145 clsBinding.emitInit()
2146 }
2147 } else {
2148 if clsBinding != nil {
2149 s.deleteBinding(clsBinding)
2150 clsBinding = nil
2151 }
2152 e.c.p.code[mark0] = jump(1)
2153 }
2154
2155 if staticsCount > 0 || hasStaticPrivateMethods {
2156 ise := &initStaticElements{}
2157 e.c.emit(ise)
2158 env := e.c.classScope.staticEnv
2159 staticInit.numPrivateFields = uint32(len(env.fields))
2160 staticInit.numPrivateMethods = uint32(len(env.methods))
2161 if s.dynLookup {
2162
2163
2164 ise.privateFields = env.fields
2165 ise.privateMethods = env.methods
2166 }
2167 } else {
2168 e.c.emit(endVariadic)
2169 }
2170
2171 if !putOnStack {
2172 e.c.emit(pop)
2173 }
2174
2175 if clsBinding != nil || s.dynLookup {
2176 e.c.leaveScopeBlock(enter)
2177 e.c.assert(enter.stackSize == 0, e.offset, "enter.StackSize != 0 in compiledClassLiteral")
2178 } else {
2179 e.c.block = e.c.block.outer
2180 }
2181 if len(e.c.classScope.privateNames) > 0 {
2182 e.c.emit(popPrivateEnv{})
2183 }
2184 e.c.classScope = e.c.classScope.outer
2185 e.c.popScope()
2186 }
2187
2188 func (e *compiledClassLiteral) compileFieldsAndStaticBlocks(elements []clsElement, funcName unistring.String) *Program {
2189 savedPrg := e.c.p
2190 savedBlock := e.c.block
2191 defer func() {
2192 e.c.p = savedPrg
2193 e.c.block = savedBlock
2194 }()
2195
2196 e.c.block = &block{
2197 typ: blockScope,
2198 }
2199
2200 e.c.p = &Program{
2201 src: savedPrg.src,
2202 funcName: funcName,
2203 code: e.c.newCode(2, 16),
2204 }
2205
2206 e.c.newScope()
2207 s := e.c.scope
2208 s.funcType = funcClsInit
2209 thisBinding := s.createThisBinding()
2210
2211 valIdx := 0
2212 for _, elt := range elements {
2213 if elt.body != nil {
2214 e.c.emit(dup)
2215 elt.body.emitGetter(true)
2216 elt.body.addSrcMap()
2217 e.c.emit(call(0), pop)
2218 } else {
2219 if elt.computed {
2220 e.c.emit(loadComputedKey(valIdx))
2221 valIdx++
2222 }
2223 if init := elt.initializer; init != nil {
2224 if !elt.computed {
2225 e.c.emitNamedOrConst(init, elt.key)
2226 } else {
2227 e.c.emitExpr(init, true)
2228 }
2229 } else {
2230 e.c.emit(loadUndef)
2231 }
2232 if elt.privateName != nil {
2233 e.c.emit(&definePrivateProp{
2234 idx: elt.privateName.idx,
2235 })
2236 } else if elt.computed {
2237 e.c.emit(defineProp{})
2238 } else {
2239 e.c.emit(definePropKeyed(elt.key))
2240 }
2241 }
2242 }
2243
2244 if s.isDynamic() || thisBinding.useCount() > 0 {
2245 if s.isDynamic() || thisBinding.inStash {
2246 thisBinding.emitInitAt(1)
2247 }
2248 } else {
2249 s.deleteBinding(thisBinding)
2250 }
2251 stashSize, stackSize := s.finaliseVarAlloc(0)
2252 e.c.assert(stackSize == 0, e.offset, "stackSize != 0 in initFields")
2253 if stashSize > 0 {
2254 e.c.assert(stashSize == 1, e.offset, "stashSize != 1 in initFields")
2255 enter := &enterFunc{
2256 stashSize: 1,
2257 funcType: funcClsInit,
2258 }
2259 if s.dynLookup {
2260 enter.names = s.makeNamesMap()
2261 }
2262 e.c.p.code[0] = enter
2263 s.trimCode(0)
2264 } else {
2265 s.trimCode(2)
2266 }
2267 res := e.c.p
2268 e.c.popScope()
2269 return res
2270 }
2271
2272 func (c *compiler) compileClassLiteral(v *ast.ClassLiteral, isExpr bool) *compiledClassLiteral {
2273 if v.Name != nil {
2274 c.checkIdentifierLName(v.Name.Name, int(v.Name.Idx)-1)
2275 }
2276 r := &compiledClassLiteral{
2277 name: v.Name,
2278 superClass: c.compileExpression(v.SuperClass),
2279 body: v.Body,
2280 source: v.Source,
2281 isExpr: isExpr,
2282 }
2283 r.init(c, v.Idx0())
2284 return r
2285 }
2286
2287 func (c *compiler) compileCtor(ctor *ast.FunctionLiteral, derived bool) (p *Program, length int) {
2288 f := c.compileFunctionLiteral(ctor, true)
2289 if derived {
2290 f.typ = funcDerivedCtor
2291 } else {
2292 f.typ = funcCtor
2293 }
2294 p, _, length, _ = f.compile()
2295 return
2296 }
2297
2298 func (c *compiler) compileArrowFunctionLiteral(v *ast.ArrowFunctionLiteral) *compiledFunctionLiteral {
2299 var strictBody *ast.StringLiteral
2300 var body []ast.Statement
2301 switch b := v.Body.(type) {
2302 case *ast.BlockStatement:
2303 strictBody = c.isStrictStatement(b)
2304 body = b.List
2305 case *ast.ExpressionBody:
2306 body = []ast.Statement{
2307 &ast.ReturnStatement{
2308 Argument: b.Expression,
2309 },
2310 }
2311 default:
2312 c.throwSyntaxError(int(b.Idx0())-1, "Unsupported ConciseBody type: %T", b)
2313 }
2314 r := &compiledFunctionLiteral{
2315 parameterList: v.ParameterList,
2316 body: body,
2317 source: v.Source,
2318 declarationList: v.DeclarationList,
2319 isExpr: true,
2320 typ: funcArrow,
2321 strict: strictBody,
2322 isAsync: v.Async,
2323 }
2324 r.init(c, v.Idx0())
2325 return r
2326 }
2327
2328 func (c *compiler) emitLoadThis() {
2329 b, eval := c.scope.lookupThis()
2330 if b != nil {
2331 b.emitGet()
2332 } else {
2333 if eval {
2334 c.emit(getThisDynamic{})
2335 } else {
2336 c.emit(loadGlobalObject)
2337 }
2338 }
2339 }
2340
2341 func (e *compiledThisExpr) emitGetter(putOnStack bool) {
2342 e.addSrcMap()
2343 e.c.emitLoadThis()
2344 if !putOnStack {
2345 e.c.emit(pop)
2346 }
2347 }
2348
2349 func (e *compiledSuperExpr) emitGetter(putOnStack bool) {
2350 if putOnStack {
2351 e.c.emit(loadSuper)
2352 }
2353 }
2354
2355 func (e *compiledNewExpr) emitGetter(putOnStack bool) {
2356 if e.isVariadic {
2357 e.c.emit(startVariadic)
2358 }
2359 e.callee.emitGetter(true)
2360 for _, expr := range e.args {
2361 expr.emitGetter(true)
2362 }
2363 e.addSrcMap()
2364 if e.isVariadic {
2365 e.c.emit(newVariadic, endVariadic)
2366 } else {
2367 e.c.emit(_new(len(e.args)))
2368 }
2369 if !putOnStack {
2370 e.c.emit(pop)
2371 }
2372 }
2373
2374 func (c *compiler) compileCallArgs(list []ast.Expression) (args []compiledExpr, isVariadic bool) {
2375 args = make([]compiledExpr, len(list))
2376 for i, argExpr := range list {
2377 if spread, ok := argExpr.(*ast.SpreadElement); ok {
2378 args[i] = c.compileSpreadCallArgument(spread)
2379 isVariadic = true
2380 } else {
2381 args[i] = c.compileExpression(argExpr)
2382 }
2383 }
2384 return
2385 }
2386
2387 func (c *compiler) compileNewExpression(v *ast.NewExpression) compiledExpr {
2388 args, isVariadic := c.compileCallArgs(v.ArgumentList)
2389 r := &compiledNewExpr{
2390 compiledCallExpr: compiledCallExpr{
2391 callee: c.compileExpression(v.Callee),
2392 args: args,
2393 isVariadic: isVariadic,
2394 },
2395 }
2396 r.init(c, v.Idx0())
2397 return r
2398 }
2399
2400 func (e *compiledNewTarget) emitGetter(putOnStack bool) {
2401 if s := e.c.scope.nearestThis(); s == nil || s.funcType == funcNone {
2402 e.c.throwSyntaxError(e.offset, "new.target expression is not allowed here")
2403 }
2404 if putOnStack {
2405 e.addSrcMap()
2406 e.c.emit(loadNewTarget)
2407 }
2408 }
2409
2410 func (c *compiler) compileMetaProperty(v *ast.MetaProperty) compiledExpr {
2411 if v.Meta.Name == "new" || v.Property.Name != "target" {
2412 r := &compiledNewTarget{}
2413 r.init(c, v.Idx0())
2414 return r
2415 }
2416 c.throwSyntaxError(int(v.Idx)-1, "Unsupported meta property: %s.%s", v.Meta.Name, v.Property.Name)
2417 return nil
2418 }
2419
2420 func (e *compiledSequenceExpr) emitGetter(putOnStack bool) {
2421 if len(e.sequence) > 0 {
2422 for i := 0; i < len(e.sequence)-1; i++ {
2423 e.sequence[i].emitGetter(false)
2424 }
2425 e.sequence[len(e.sequence)-1].emitGetter(putOnStack)
2426 }
2427 }
2428
2429 func (c *compiler) compileSequenceExpression(v *ast.SequenceExpression) compiledExpr {
2430 s := make([]compiledExpr, len(v.Sequence))
2431 for i, expr := range v.Sequence {
2432 s[i] = c.compileExpression(expr)
2433 }
2434 r := &compiledSequenceExpr{
2435 sequence: s,
2436 }
2437 var idx file.Idx
2438 if len(v.Sequence) > 0 {
2439 idx = v.Idx0()
2440 }
2441 r.init(c, idx)
2442 return r
2443 }
2444
2445 func (c *compiler) emitThrow(v Value) {
2446 if o, ok := v.(*Object); ok {
2447 t := nilSafe(o.self.getStr("name", nil)).toString().String()
2448 switch t {
2449 case "TypeError":
2450 c.emit(loadDynamic(t))
2451 msg := o.self.getStr("message", nil)
2452 if msg != nil {
2453 c.emit(loadVal(c.p.defineLiteralValue(msg)))
2454 c.emit(_new(1))
2455 } else {
2456 c.emit(_new(0))
2457 }
2458 c.emit(throw)
2459 return
2460 }
2461 }
2462 c.assert(false, 0, "unknown exception type thrown while evaluating constant expression: %s", v.String())
2463 panic("unreachable")
2464 }
2465
2466 func (c *compiler) emitConst(expr compiledExpr, putOnStack bool) {
2467 v, ex := c.evalConst(expr)
2468 if ex == nil {
2469 if putOnStack {
2470 c.emit(loadVal(c.p.defineLiteralValue(v)))
2471 }
2472 } else {
2473 c.emitThrow(ex.val)
2474 }
2475 }
2476
2477 func (c *compiler) evalConst(expr compiledExpr) (Value, *Exception) {
2478 if expr, ok := expr.(*compiledLiteral); ok {
2479 return expr.val, nil
2480 }
2481 if c.evalVM == nil {
2482 c.evalVM = New().vm
2483 }
2484 var savedPrg *Program
2485 createdPrg := false
2486 if c.evalVM.prg == nil {
2487 c.evalVM.prg = &Program{
2488 src: c.p.src,
2489 }
2490 savedPrg = c.p
2491 c.p = c.evalVM.prg
2492 createdPrg = true
2493 }
2494 savedPc := len(c.p.code)
2495 expr.emitGetter(true)
2496 c.evalVM.pc = savedPc
2497 ex := c.evalVM.runTry()
2498 if createdPrg {
2499 c.evalVM.prg = nil
2500 c.evalVM.pc = 0
2501 c.p = savedPrg
2502 } else {
2503 c.evalVM.prg.code = c.evalVM.prg.code[:savedPc]
2504 c.p.code = c.evalVM.prg.code
2505 }
2506 if ex == nil {
2507 return c.evalVM.pop(), nil
2508 }
2509 return nil, ex
2510 }
2511
2512 func (e *compiledUnaryExpr) constant() bool {
2513 return e.operand.constant()
2514 }
2515
2516 func (e *compiledUnaryExpr) emitGetter(putOnStack bool) {
2517 var prepare, body func()
2518
2519 toNumber := func() {
2520 e.addSrcMap()
2521 e.c.emit(toNumber)
2522 }
2523
2524 switch e.operator {
2525 case token.NOT:
2526 e.operand.emitGetter(true)
2527 e.c.emit(not)
2528 goto end
2529 case token.BITWISE_NOT:
2530 e.operand.emitGetter(true)
2531 e.c.emit(bnot)
2532 goto end
2533 case token.TYPEOF:
2534 if o, ok := e.operand.(compiledExprOrRef); ok {
2535 o.emitGetterOrRef()
2536 } else {
2537 e.operand.emitGetter(true)
2538 }
2539 e.c.emit(typeof)
2540 goto end
2541 case token.DELETE:
2542 e.operand.deleteExpr().emitGetter(putOnStack)
2543 return
2544 case token.MINUS:
2545 e.c.emitExpr(e.operand, true)
2546 e.c.emit(neg)
2547 goto end
2548 case token.PLUS:
2549 e.c.emitExpr(e.operand, true)
2550 e.c.emit(plus)
2551 goto end
2552 case token.INCREMENT:
2553 prepare = toNumber
2554 body = func() {
2555 e.c.emit(inc)
2556 }
2557 case token.DECREMENT:
2558 prepare = toNumber
2559 body = func() {
2560 e.c.emit(dec)
2561 }
2562 case token.VOID:
2563 e.c.emitExpr(e.operand, false)
2564 if putOnStack {
2565 e.c.emit(loadUndef)
2566 }
2567 return
2568 default:
2569 e.c.assert(false, e.offset, "Unknown unary operator: %s", e.operator.String())
2570 panic("unreachable")
2571 }
2572
2573 e.operand.emitUnary(prepare, body, e.postfix, putOnStack)
2574 return
2575
2576 end:
2577 if !putOnStack {
2578 e.c.emit(pop)
2579 }
2580 }
2581
2582 func (c *compiler) compileUnaryExpression(v *ast.UnaryExpression) compiledExpr {
2583 r := &compiledUnaryExpr{
2584 operand: c.compileExpression(v.Operand),
2585 operator: v.Operator,
2586 postfix: v.Postfix,
2587 }
2588 r.init(c, v.Idx0())
2589 return r
2590 }
2591
2592 func (e *compiledConditionalExpr) emitGetter(putOnStack bool) {
2593 e.test.emitGetter(true)
2594 j := len(e.c.p.code)
2595 e.c.emit(nil)
2596 e.consequent.emitGetter(putOnStack)
2597 j1 := len(e.c.p.code)
2598 e.c.emit(nil)
2599 e.c.p.code[j] = jne(len(e.c.p.code) - j)
2600 e.alternate.emitGetter(putOnStack)
2601 e.c.p.code[j1] = jump(len(e.c.p.code) - j1)
2602 }
2603
2604 func (c *compiler) compileConditionalExpression(v *ast.ConditionalExpression) compiledExpr {
2605 r := &compiledConditionalExpr{
2606 test: c.compileExpression(v.Test),
2607 consequent: c.compileExpression(v.Consequent),
2608 alternate: c.compileExpression(v.Alternate),
2609 }
2610 r.init(c, v.Idx0())
2611 return r
2612 }
2613
2614 func (e *compiledLogicalOr) constant() bool {
2615 if e.left.constant() {
2616 if v, ex := e.c.evalConst(e.left); ex == nil {
2617 if v.ToBoolean() {
2618 return true
2619 }
2620 return e.right.constant()
2621 } else {
2622 return true
2623 }
2624 }
2625
2626 return false
2627 }
2628
2629 func (e *compiledLogicalOr) emitGetter(putOnStack bool) {
2630 if e.left.constant() {
2631 if v, ex := e.c.evalConst(e.left); ex == nil {
2632 if !v.ToBoolean() {
2633 e.c.emitExpr(e.right, putOnStack)
2634 } else {
2635 if putOnStack {
2636 e.c.emit(loadVal(e.c.p.defineLiteralValue(v)))
2637 }
2638 }
2639 } else {
2640 e.c.emitThrow(ex.val)
2641 }
2642 return
2643 }
2644 e.c.emitExpr(e.left, true)
2645 j := len(e.c.p.code)
2646 e.addSrcMap()
2647 e.c.emit(nil)
2648 e.c.emitExpr(e.right, true)
2649 e.c.p.code[j] = jeq1(len(e.c.p.code) - j)
2650 if !putOnStack {
2651 e.c.emit(pop)
2652 }
2653 }
2654
2655 func (e *compiledCoalesce) constant() bool {
2656 if e.left.constant() {
2657 if v, ex := e.c.evalConst(e.left); ex == nil {
2658 if v != _null && v != _undefined {
2659 return true
2660 }
2661 return e.right.constant()
2662 } else {
2663 return true
2664 }
2665 }
2666
2667 return false
2668 }
2669
2670 func (e *compiledCoalesce) emitGetter(putOnStack bool) {
2671 if e.left.constant() {
2672 if v, ex := e.c.evalConst(e.left); ex == nil {
2673 if v == _undefined || v == _null {
2674 e.c.emitExpr(e.right, putOnStack)
2675 } else {
2676 if putOnStack {
2677 e.c.emit(loadVal(e.c.p.defineLiteralValue(v)))
2678 }
2679 }
2680 } else {
2681 e.c.emitThrow(ex.val)
2682 }
2683 return
2684 }
2685 e.c.emitExpr(e.left, true)
2686 j := len(e.c.p.code)
2687 e.addSrcMap()
2688 e.c.emit(nil)
2689 e.c.emitExpr(e.right, true)
2690 e.c.p.code[j] = jcoalesc(len(e.c.p.code) - j)
2691 if !putOnStack {
2692 e.c.emit(pop)
2693 }
2694 }
2695
2696 func (e *compiledLogicalAnd) constant() bool {
2697 if e.left.constant() {
2698 if v, ex := e.c.evalConst(e.left); ex == nil {
2699 if !v.ToBoolean() {
2700 return true
2701 } else {
2702 return e.right.constant()
2703 }
2704 } else {
2705 return true
2706 }
2707 }
2708
2709 return false
2710 }
2711
2712 func (e *compiledLogicalAnd) emitGetter(putOnStack bool) {
2713 var j int
2714 if e.left.constant() {
2715 if v, ex := e.c.evalConst(e.left); ex == nil {
2716 if !v.ToBoolean() {
2717 e.c.emit(loadVal(e.c.p.defineLiteralValue(v)))
2718 } else {
2719 e.c.emitExpr(e.right, putOnStack)
2720 }
2721 } else {
2722 e.c.emitThrow(ex.val)
2723 }
2724 return
2725 }
2726 e.left.emitGetter(true)
2727 j = len(e.c.p.code)
2728 e.addSrcMap()
2729 e.c.emit(nil)
2730 e.c.emitExpr(e.right, true)
2731 e.c.p.code[j] = jneq1(len(e.c.p.code) - j)
2732 if !putOnStack {
2733 e.c.emit(pop)
2734 }
2735 }
2736
2737 func (e *compiledBinaryExpr) constant() bool {
2738 return e.left.constant() && e.right.constant()
2739 }
2740
2741 func (e *compiledBinaryExpr) emitGetter(putOnStack bool) {
2742 e.c.emitExpr(e.left, true)
2743 e.c.emitExpr(e.right, true)
2744 e.addSrcMap()
2745
2746 switch e.operator {
2747 case token.LESS:
2748 e.c.emit(op_lt)
2749 case token.GREATER:
2750 e.c.emit(op_gt)
2751 case token.LESS_OR_EQUAL:
2752 e.c.emit(op_lte)
2753 case token.GREATER_OR_EQUAL:
2754 e.c.emit(op_gte)
2755 case token.EQUAL:
2756 e.c.emit(op_eq)
2757 case token.NOT_EQUAL:
2758 e.c.emit(op_neq)
2759 case token.STRICT_EQUAL:
2760 e.c.emit(op_strict_eq)
2761 case token.STRICT_NOT_EQUAL:
2762 e.c.emit(op_strict_neq)
2763 case token.PLUS:
2764 e.c.emit(add)
2765 case token.MINUS:
2766 e.c.emit(sub)
2767 case token.MULTIPLY:
2768 e.c.emit(mul)
2769 case token.EXPONENT:
2770 e.c.emit(exp)
2771 case token.SLASH:
2772 e.c.emit(div)
2773 case token.REMAINDER:
2774 e.c.emit(mod)
2775 case token.AND:
2776 e.c.emit(and)
2777 case token.OR:
2778 e.c.emit(or)
2779 case token.EXCLUSIVE_OR:
2780 e.c.emit(xor)
2781 case token.INSTANCEOF:
2782 e.c.emit(op_instanceof)
2783 case token.IN:
2784 e.c.emit(op_in)
2785 case token.SHIFT_LEFT:
2786 e.c.emit(sal)
2787 case token.SHIFT_RIGHT:
2788 e.c.emit(sar)
2789 case token.UNSIGNED_SHIFT_RIGHT:
2790 e.c.emit(shr)
2791 default:
2792 e.c.assert(false, e.offset, "Unknown operator: %s", e.operator.String())
2793 panic("unreachable")
2794 }
2795
2796 if !putOnStack {
2797 e.c.emit(pop)
2798 }
2799 }
2800
2801 func (c *compiler) compileBinaryExpression(v *ast.BinaryExpression) compiledExpr {
2802
2803 switch v.Operator {
2804 case token.LOGICAL_OR:
2805 return c.compileLogicalOr(v.Left, v.Right, v.Idx0())
2806 case token.COALESCE:
2807 return c.compileCoalesce(v.Left, v.Right, v.Idx0())
2808 case token.LOGICAL_AND:
2809 return c.compileLogicalAnd(v.Left, v.Right, v.Idx0())
2810 }
2811
2812 if id, ok := v.Left.(*ast.PrivateIdentifier); ok {
2813 return c.compilePrivateIn(id, v.Right, id.Idx)
2814 }
2815
2816 r := &compiledBinaryExpr{
2817 left: c.compileExpression(v.Left),
2818 right: c.compileExpression(v.Right),
2819 operator: v.Operator,
2820 }
2821 r.init(c, v.Idx0())
2822 return r
2823 }
2824
2825 type compiledPrivateIn struct {
2826 baseCompiledExpr
2827 id unistring.String
2828 right compiledExpr
2829 }
2830
2831 func (e *compiledPrivateIn) emitGetter(putOnStack bool) {
2832 e.right.emitGetter(true)
2833 rn, id := e.c.resolvePrivateName(e.id, e.offset)
2834 if rn != nil {
2835 e.c.emit((*privateInRes)(rn))
2836 } else {
2837 e.c.emit((*privateInId)(id))
2838 }
2839 if !putOnStack {
2840 e.c.emit(pop)
2841 }
2842 }
2843
2844 func (c *compiler) compilePrivateIn(id *ast.PrivateIdentifier, right ast.Expression, idx file.Idx) compiledExpr {
2845 r := &compiledPrivateIn{
2846 id: id.Name,
2847 right: c.compileExpression(right),
2848 }
2849 r.init(c, idx)
2850 return r
2851 }
2852
2853 func (c *compiler) compileLogicalOr(left, right ast.Expression, idx file.Idx) compiledExpr {
2854 r := &compiledLogicalOr{
2855 left: c.compileExpression(left),
2856 right: c.compileExpression(right),
2857 }
2858 r.init(c, idx)
2859 return r
2860 }
2861
2862 func (c *compiler) compileCoalesce(left, right ast.Expression, idx file.Idx) compiledExpr {
2863 r := &compiledCoalesce{
2864 left: c.compileExpression(left),
2865 right: c.compileExpression(right),
2866 }
2867 r.init(c, idx)
2868 return r
2869 }
2870
2871 func (c *compiler) compileLogicalAnd(left, right ast.Expression, idx file.Idx) compiledExpr {
2872 r := &compiledLogicalAnd{
2873 left: c.compileExpression(left),
2874 right: c.compileExpression(right),
2875 }
2876 r.init(c, idx)
2877 return r
2878 }
2879
2880 func (e *compiledObjectLiteral) emitGetter(putOnStack bool) {
2881 e.addSrcMap()
2882 e.c.emit(newObject)
2883 hasProto := false
2884 for _, prop := range e.expr.Value {
2885 switch prop := prop.(type) {
2886 case *ast.PropertyKeyed:
2887 key, computed := e.c.processKey(prop.Key)
2888 valueExpr := e.c.compileExpression(prop.Value)
2889 var ne namedEmitter
2890 if fn, ok := valueExpr.(*compiledFunctionLiteral); ok {
2891 if fn.name == nil {
2892 ne = fn
2893 }
2894 switch prop.Kind {
2895 case ast.PropertyKindMethod, ast.PropertyKindGet, ast.PropertyKindSet:
2896 fn.typ = funcMethod
2897 if computed {
2898 fn.homeObjOffset = 2
2899 } else {
2900 fn.homeObjOffset = 1
2901 }
2902 }
2903 } else if v, ok := valueExpr.(namedEmitter); ok {
2904 ne = v
2905 }
2906 if computed {
2907 e.c.emit(_toPropertyKey{})
2908 e.c.emitExpr(valueExpr, true)
2909 switch prop.Kind {
2910 case ast.PropertyKindValue:
2911 if ne != nil {
2912 e.c.emit(setElem1Named)
2913 } else {
2914 e.c.emit(setElem1)
2915 }
2916 case ast.PropertyKindMethod:
2917 e.c.emit(&defineMethod{enumerable: true})
2918 case ast.PropertyKindGet:
2919 e.c.emit(&defineGetter{enumerable: true})
2920 case ast.PropertyKindSet:
2921 e.c.emit(&defineSetter{enumerable: true})
2922 default:
2923 e.c.assert(false, e.offset, "unknown property kind: %s", prop.Kind)
2924 panic("unreachable")
2925 }
2926 } else {
2927 isProto := key == __proto__ && !prop.Computed
2928 if isProto {
2929 if hasProto {
2930 e.c.throwSyntaxError(int(prop.Idx0())-1, "Duplicate __proto__ fields are not allowed in object literals")
2931 } else {
2932 hasProto = true
2933 }
2934 }
2935 if ne != nil && !isProto {
2936 ne.emitNamed(key)
2937 } else {
2938 e.c.emitExpr(valueExpr, true)
2939 }
2940 switch prop.Kind {
2941 case ast.PropertyKindValue:
2942 if isProto {
2943 e.c.emit(setProto)
2944 } else {
2945 e.c.emit(putProp(key))
2946 }
2947 case ast.PropertyKindMethod:
2948 e.c.emit(&defineMethodKeyed{key: key, enumerable: true})
2949 case ast.PropertyKindGet:
2950 e.c.emit(&defineGetterKeyed{key: key, enumerable: true})
2951 case ast.PropertyKindSet:
2952 e.c.emit(&defineSetterKeyed{key: key, enumerable: true})
2953 default:
2954 e.c.assert(false, e.offset, "unknown property kind: %s", prop.Kind)
2955 panic("unreachable")
2956 }
2957 }
2958 case *ast.PropertyShort:
2959 key := prop.Name.Name
2960 if prop.Initializer != nil {
2961 e.c.throwSyntaxError(int(prop.Initializer.Idx0())-1, "Invalid shorthand property initializer")
2962 }
2963 if e.c.scope.strict && key == "let" {
2964 e.c.throwSyntaxError(e.offset, "'let' cannot be used as a shorthand property in strict mode")
2965 }
2966 e.c.compileIdentifierExpression(&prop.Name).emitGetter(true)
2967 e.c.emit(putProp(key))
2968 case *ast.SpreadElement:
2969 e.c.compileExpression(prop.Expression).emitGetter(true)
2970 e.c.emit(copySpread)
2971 default:
2972 e.c.assert(false, e.offset, "unknown Property type: %T", prop)
2973 panic("unreachable")
2974 }
2975 }
2976 if !putOnStack {
2977 e.c.emit(pop)
2978 }
2979 }
2980
2981 func (c *compiler) compileObjectLiteral(v *ast.ObjectLiteral) compiledExpr {
2982 r := &compiledObjectLiteral{
2983 expr: v,
2984 }
2985 r.init(c, v.Idx0())
2986 return r
2987 }
2988
2989 func (e *compiledArrayLiteral) emitGetter(putOnStack bool) {
2990 e.addSrcMap()
2991 hasSpread := false
2992 mark := len(e.c.p.code)
2993 e.c.emit(nil)
2994 for _, v := range e.expr.Value {
2995 if spread, ok := v.(*ast.SpreadElement); ok {
2996 hasSpread = true
2997 e.c.compileExpression(spread.Expression).emitGetter(true)
2998 e.c.emit(pushArraySpread)
2999 } else {
3000 if v != nil {
3001 e.c.emitExpr(e.c.compileExpression(v), true)
3002 } else {
3003 e.c.emit(loadNil)
3004 }
3005 e.c.emit(pushArrayItem)
3006 }
3007 }
3008 var objCount uint32
3009 if !hasSpread {
3010 objCount = uint32(len(e.expr.Value))
3011 }
3012 e.c.p.code[mark] = newArray(objCount)
3013 if !putOnStack {
3014 e.c.emit(pop)
3015 }
3016 }
3017
3018 func (c *compiler) compileArrayLiteral(v *ast.ArrayLiteral) compiledExpr {
3019 r := &compiledArrayLiteral{
3020 expr: v,
3021 }
3022 r.init(c, v.Idx0())
3023 return r
3024 }
3025
3026 func (e *compiledRegexpLiteral) emitGetter(putOnStack bool) {
3027 if putOnStack {
3028 pattern, err := compileRegexp(e.expr.Pattern, e.expr.Flags)
3029 if err != nil {
3030 e.c.throwSyntaxError(e.offset, err.Error())
3031 }
3032
3033 e.c.emit(&newRegexp{pattern: pattern, src: newStringValue(e.expr.Pattern)})
3034 }
3035 }
3036
3037 func (c *compiler) compileRegexpLiteral(v *ast.RegExpLiteral) compiledExpr {
3038 r := &compiledRegexpLiteral{
3039 expr: v,
3040 }
3041 r.init(c, v.Idx0())
3042 return r
3043 }
3044
3045 func (c *compiler) emitCallee(callee compiledExpr) (calleeName unistring.String) {
3046 switch callee := callee.(type) {
3047 case *compiledDotExpr:
3048 callee.left.emitGetter(true)
3049 c.emit(getPropCallee(callee.name))
3050 case *compiledPrivateDotExpr:
3051 callee.left.emitGetter(true)
3052 rn, id := c.resolvePrivateName(callee.name, callee.offset)
3053 if rn != nil {
3054 c.emit((*getPrivatePropResCallee)(rn))
3055 } else {
3056 c.emit((*getPrivatePropIdCallee)(id))
3057 }
3058 case *compiledSuperDotExpr:
3059 c.emitLoadThis()
3060 c.emit(loadSuper)
3061 c.emit(getPropRecvCallee(callee.name))
3062 case *compiledBracketExpr:
3063 callee.left.emitGetter(true)
3064 callee.member.emitGetter(true)
3065 c.emit(getElemCallee)
3066 case *compiledSuperBracketExpr:
3067 c.emitLoadThis()
3068 c.emit(loadSuper)
3069 callee.member.emitGetter(true)
3070 c.emit(getElemRecvCallee)
3071 case *compiledIdentifierExpr:
3072 calleeName = callee.name
3073 callee.emitGetterAndCallee()
3074 case *compiledOptionalChain:
3075 c.startOptChain()
3076 c.emitCallee(callee.expr)
3077 c.endOptChain()
3078 case *compiledOptional:
3079 c.emitCallee(callee.expr)
3080 c.block.conts = append(c.block.conts, len(c.p.code))
3081 c.emit(nil)
3082 case *compiledSuperExpr:
3083
3084 default:
3085 c.emit(loadUndef)
3086 callee.emitGetter(true)
3087 }
3088 return
3089 }
3090
3091 func (e *compiledCallExpr) emitGetter(putOnStack bool) {
3092 if e.isVariadic {
3093 e.c.emit(startVariadic)
3094 }
3095 calleeName := e.c.emitCallee(e.callee)
3096
3097 for _, expr := range e.args {
3098 expr.emitGetter(true)
3099 }
3100
3101 e.addSrcMap()
3102 if _, ok := e.callee.(*compiledSuperExpr); ok {
3103 b, eval := e.c.scope.lookupThis()
3104 e.c.assert(eval || b != nil, e.offset, "super call, but no 'this' binding")
3105 if eval {
3106 e.c.emit(resolveThisDynamic{})
3107 } else {
3108 b.markAccessPoint()
3109 e.c.emit(resolveThisStack{})
3110 }
3111 if e.isVariadic {
3112 e.c.emit(superCallVariadic)
3113 } else {
3114 e.c.emit(superCall(len(e.args)))
3115 }
3116 } else if calleeName == "eval" {
3117 foundVar := false
3118 for sc := e.c.scope; sc != nil; sc = sc.outer {
3119 if !foundVar && (sc.variable || sc.isFunction()) {
3120 foundVar = true
3121 if !sc.strict {
3122 sc.dynamic = true
3123 }
3124 }
3125 sc.dynLookup = true
3126 }
3127
3128 if e.c.scope.strict {
3129 if e.isVariadic {
3130 e.c.emit(callEvalVariadicStrict)
3131 } else {
3132 e.c.emit(callEvalStrict(len(e.args)))
3133 }
3134 } else {
3135 if e.isVariadic {
3136 e.c.emit(callEvalVariadic)
3137 } else {
3138 e.c.emit(callEval(len(e.args)))
3139 }
3140 }
3141 } else {
3142 if e.isVariadic {
3143 e.c.emit(callVariadic)
3144 } else {
3145 e.c.emit(call(len(e.args)))
3146 }
3147 }
3148 if e.isVariadic {
3149 e.c.emit(endVariadic)
3150 }
3151 if !putOnStack {
3152 e.c.emit(pop)
3153 }
3154 }
3155
3156 func (e *compiledCallExpr) deleteExpr() compiledExpr {
3157 r := &defaultDeleteExpr{
3158 expr: e,
3159 }
3160 r.init(e.c, file.Idx(e.offset+1))
3161 return r
3162 }
3163
3164 func (c *compiler) compileSpreadCallArgument(spread *ast.SpreadElement) compiledExpr {
3165 r := &compiledSpreadCallArgument{
3166 expr: c.compileExpression(spread.Expression),
3167 }
3168 r.init(c, spread.Idx0())
3169 return r
3170 }
3171
3172 func (c *compiler) compileCallee(v ast.Expression) compiledExpr {
3173 if sup, ok := v.(*ast.SuperExpression); ok {
3174 if s := c.scope.nearestThis(); s != nil && s.funcType == funcDerivedCtor {
3175 e := &compiledSuperExpr{}
3176 e.init(c, sup.Idx)
3177 return e
3178 }
3179 c.throwSyntaxError(int(v.Idx0())-1, "'super' keyword unexpected here")
3180 panic("unreachable")
3181 }
3182 return c.compileExpression(v)
3183 }
3184
3185 func (c *compiler) compileCallExpression(v *ast.CallExpression) compiledExpr {
3186
3187 args := make([]compiledExpr, len(v.ArgumentList))
3188 isVariadic := false
3189 for i, argExpr := range v.ArgumentList {
3190 if spread, ok := argExpr.(*ast.SpreadElement); ok {
3191 args[i] = c.compileSpreadCallArgument(spread)
3192 isVariadic = true
3193 } else {
3194 args[i] = c.compileExpression(argExpr)
3195 }
3196 }
3197
3198 r := &compiledCallExpr{
3199 args: args,
3200 callee: c.compileCallee(v.Callee),
3201 isVariadic: isVariadic,
3202 }
3203 r.init(c, v.LeftParenthesis)
3204 return r
3205 }
3206
3207 func (c *compiler) compileIdentifierExpression(v *ast.Identifier) compiledExpr {
3208 if c.scope.strict {
3209 c.checkIdentifierName(v.Name, int(v.Idx)-1)
3210 }
3211
3212 r := &compiledIdentifierExpr{
3213 name: v.Name,
3214 }
3215 r.offset = int(v.Idx) - 1
3216 r.init(c, v.Idx0())
3217 return r
3218 }
3219
3220 func (c *compiler) compileNumberLiteral(v *ast.NumberLiteral) compiledExpr {
3221 if c.scope.strict && len(v.Literal) > 1 && v.Literal[0] == '0' && v.Literal[1] <= '7' && v.Literal[1] >= '0' {
3222 c.throwSyntaxError(int(v.Idx)-1, "Octal literals are not allowed in strict mode")
3223 panic("Unreachable")
3224 }
3225 var val Value
3226 switch num := v.Value.(type) {
3227 case int64:
3228 val = intToValue(num)
3229 case float64:
3230 val = floatToValue(num)
3231 default:
3232 c.assert(false, int(v.Idx)-1, "Unsupported number literal type: %T", v.Value)
3233 panic("unreachable")
3234 }
3235 r := &compiledLiteral{
3236 val: val,
3237 }
3238 r.init(c, v.Idx0())
3239 return r
3240 }
3241
3242 func (c *compiler) compileStringLiteral(v *ast.StringLiteral) compiledExpr {
3243 r := &compiledLiteral{
3244 val: stringValueFromRaw(v.Value),
3245 }
3246 r.init(c, v.Idx0())
3247 return r
3248 }
3249
3250 func (c *compiler) compileTemplateLiteral(v *ast.TemplateLiteral) compiledExpr {
3251 r := &compiledTemplateLiteral{}
3252 if v.Tag != nil {
3253 r.tag = c.compileExpression(v.Tag)
3254 }
3255 ce := make([]compiledExpr, len(v.Expressions))
3256 for i, expr := range v.Expressions {
3257 ce[i] = c.compileExpression(expr)
3258 }
3259 r.expressions = ce
3260 r.elements = v.Elements
3261 r.init(c, v.Idx0())
3262 return r
3263 }
3264
3265 func (c *compiler) compileBooleanLiteral(v *ast.BooleanLiteral) compiledExpr {
3266 var val Value
3267 if v.Value {
3268 val = valueTrue
3269 } else {
3270 val = valueFalse
3271 }
3272
3273 r := &compiledLiteral{
3274 val: val,
3275 }
3276 r.init(c, v.Idx0())
3277 return r
3278 }
3279
3280 func (c *compiler) compileAssignExpression(v *ast.AssignExpression) compiledExpr {
3281
3282
3283 r := &compiledAssignExpr{
3284 left: c.compileExpression(v.Left),
3285 right: c.compileExpression(v.Right),
3286 operator: v.Operator,
3287 }
3288 r.init(c, v.Idx0())
3289 return r
3290 }
3291
3292 func (e *compiledEnumGetExpr) emitGetter(putOnStack bool) {
3293 e.c.emit(enumGet)
3294 if !putOnStack {
3295 e.c.emit(pop)
3296 }
3297 }
3298
3299 func (c *compiler) compileObjectAssignmentPattern(v *ast.ObjectPattern) compiledExpr {
3300 r := &compiledObjectAssignmentPattern{
3301 expr: v,
3302 }
3303 r.init(c, v.Idx0())
3304 return r
3305 }
3306
3307 func (e *compiledObjectAssignmentPattern) emitGetter(putOnStack bool) {
3308 if putOnStack {
3309 e.c.emit(loadUndef)
3310 }
3311 }
3312
3313 func (c *compiler) compileArrayAssignmentPattern(v *ast.ArrayPattern) compiledExpr {
3314 r := &compiledArrayAssignmentPattern{
3315 expr: v,
3316 }
3317 r.init(c, v.Idx0())
3318 return r
3319 }
3320
3321 func (e *compiledArrayAssignmentPattern) emitGetter(putOnStack bool) {
3322 if putOnStack {
3323 e.c.emit(loadUndef)
3324 }
3325 }
3326
3327 func (c *compiler) emitExpr(expr compiledExpr, putOnStack bool) {
3328 if expr.constant() {
3329 c.emitConst(expr, putOnStack)
3330 } else {
3331 expr.emitGetter(putOnStack)
3332 }
3333 }
3334
3335 type namedEmitter interface {
3336 emitNamed(name unistring.String)
3337 }
3338
3339 func (c *compiler) emitNamed(expr compiledExpr, name unistring.String) {
3340 if en, ok := expr.(namedEmitter); ok {
3341 en.emitNamed(name)
3342 } else {
3343 expr.emitGetter(true)
3344 }
3345 }
3346
3347 func (c *compiler) emitNamedOrConst(expr compiledExpr, name unistring.String) {
3348 if expr.constant() {
3349 c.emitConst(expr, true)
3350 } else {
3351 c.emitNamed(expr, name)
3352 }
3353 }
3354
3355 func (e *compiledFunctionLiteral) emitNamed(name unistring.String) {
3356 e.lhsName = name
3357 e.emitGetter(true)
3358 }
3359
3360 func (e *compiledClassLiteral) emitNamed(name unistring.String) {
3361 e.lhsName = name
3362 e.emitGetter(true)
3363 }
3364
3365 func (c *compiler) emitPattern(pattern ast.Pattern, emitter func(target, init compiledExpr), putOnStack bool) {
3366 switch pattern := pattern.(type) {
3367 case *ast.ObjectPattern:
3368 c.emitObjectPattern(pattern, emitter, putOnStack)
3369 case *ast.ArrayPattern:
3370 c.emitArrayPattern(pattern, emitter, putOnStack)
3371 default:
3372 c.assert(false, int(pattern.Idx0())-1, "unsupported Pattern: %T", pattern)
3373 panic("unreachable")
3374 }
3375 }
3376
3377 func (c *compiler) emitAssign(target ast.Expression, init compiledExpr, emitAssignSimple func(target, init compiledExpr)) {
3378 pattern, isPattern := target.(ast.Pattern)
3379 if isPattern {
3380 init.emitGetter(true)
3381 c.emitPattern(pattern, emitAssignSimple, false)
3382 } else {
3383 emitAssignSimple(c.compileExpression(target), init)
3384 }
3385 }
3386
3387 func (c *compiler) emitObjectPattern(pattern *ast.ObjectPattern, emitAssign func(target, init compiledExpr), putOnStack bool) {
3388 if pattern.Rest != nil {
3389 c.emit(createDestructSrc)
3390 } else {
3391 c.emit(checkObjectCoercible)
3392 }
3393 for _, prop := range pattern.Properties {
3394 switch prop := prop.(type) {
3395 case *ast.PropertyShort:
3396 c.emit(dup)
3397 emitAssign(c.compileIdentifierExpression(&prop.Name), c.compilePatternInitExpr(func() {
3398 c.emit(getProp(prop.Name.Name))
3399 }, prop.Initializer, prop.Idx0()))
3400 case *ast.PropertyKeyed:
3401 c.emit(dup)
3402 c.compileExpression(prop.Key).emitGetter(true)
3403 c.emit(_toPropertyKey{})
3404 var target ast.Expression
3405 var initializer ast.Expression
3406 if e, ok := prop.Value.(*ast.AssignExpression); ok {
3407 target = e.Left
3408 initializer = e.Right
3409 } else {
3410 target = prop.Value
3411 }
3412 c.emitAssign(target, c.compilePatternInitExpr(func() {
3413 c.emit(getKey)
3414 }, initializer, prop.Idx0()), emitAssign)
3415 default:
3416 c.throwSyntaxError(int(prop.Idx0()-1), "Unsupported AssignmentProperty type: %T", prop)
3417 }
3418 }
3419 if pattern.Rest != nil {
3420 emitAssign(c.compileExpression(pattern.Rest), c.compileEmitterExpr(func() {
3421 c.emit(copyRest)
3422 }, pattern.Rest.Idx0()))
3423 c.emit(pop)
3424 }
3425 if !putOnStack {
3426 c.emit(pop)
3427 }
3428 }
3429
3430 func (c *compiler) emitArrayPattern(pattern *ast.ArrayPattern, emitAssign func(target, init compiledExpr), putOnStack bool) {
3431 c.emit(iterate)
3432 for _, elt := range pattern.Elements {
3433 switch elt := elt.(type) {
3434 case nil:
3435 c.emit(iterGetNextOrUndef{}, pop)
3436 case *ast.AssignExpression:
3437 c.emitAssign(elt.Left, c.compilePatternInitExpr(func() {
3438 c.emit(iterGetNextOrUndef{})
3439 }, elt.Right, elt.Idx0()), emitAssign)
3440 default:
3441 c.emitAssign(elt, c.compileEmitterExpr(func() {
3442 c.emit(iterGetNextOrUndef{})
3443 }, elt.Idx0()), emitAssign)
3444 }
3445 }
3446 if pattern.Rest != nil {
3447 c.emitAssign(pattern.Rest, c.compileEmitterExpr(func() {
3448 c.emit(newArrayFromIter)
3449 }, pattern.Rest.Idx0()), emitAssign)
3450 } else {
3451 c.emit(enumPopClose)
3452 }
3453
3454 if !putOnStack {
3455 c.emit(pop)
3456 }
3457 }
3458
3459 func (e *compiledObjectAssignmentPattern) emitSetter(valueExpr compiledExpr, putOnStack bool) {
3460 valueExpr.emitGetter(true)
3461 e.c.emitObjectPattern(e.expr, e.c.emitPatternAssign, putOnStack)
3462 }
3463
3464 func (e *compiledArrayAssignmentPattern) emitSetter(valueExpr compiledExpr, putOnStack bool) {
3465 valueExpr.emitGetter(true)
3466 e.c.emitArrayPattern(e.expr, e.c.emitPatternAssign, putOnStack)
3467 }
3468
3469 type compiledPatternInitExpr struct {
3470 baseCompiledExpr
3471 emitSrc func()
3472 def compiledExpr
3473 }
3474
3475 func (e *compiledPatternInitExpr) emitGetter(putOnStack bool) {
3476 if !putOnStack {
3477 return
3478 }
3479 e.emitSrc()
3480 if e.def != nil {
3481 mark := len(e.c.p.code)
3482 e.c.emit(nil)
3483 e.c.emitExpr(e.def, true)
3484 e.c.p.code[mark] = jdef(len(e.c.p.code) - mark)
3485 }
3486 }
3487
3488 func (e *compiledPatternInitExpr) emitNamed(name unistring.String) {
3489 e.emitSrc()
3490 if e.def != nil {
3491 mark := len(e.c.p.code)
3492 e.c.emit(nil)
3493 e.c.emitNamedOrConst(e.def, name)
3494 e.c.p.code[mark] = jdef(len(e.c.p.code) - mark)
3495 }
3496 }
3497
3498 func (c *compiler) compilePatternInitExpr(emitSrc func(), def ast.Expression, idx file.Idx) compiledExpr {
3499 r := &compiledPatternInitExpr{
3500 emitSrc: emitSrc,
3501 def: c.compileExpression(def),
3502 }
3503 r.init(c, idx)
3504 return r
3505 }
3506
3507 type compiledEmitterExpr struct {
3508 baseCompiledExpr
3509 emitter func()
3510 namedEmitter func(name unistring.String)
3511 }
3512
3513 func (e *compiledEmitterExpr) emitGetter(putOnStack bool) {
3514 if e.emitter != nil {
3515 e.emitter()
3516 } else {
3517 e.namedEmitter("")
3518 }
3519 if !putOnStack {
3520 e.c.emit(pop)
3521 }
3522 }
3523
3524 func (e *compiledEmitterExpr) emitNamed(name unistring.String) {
3525 if e.namedEmitter != nil {
3526 e.namedEmitter(name)
3527 } else {
3528 e.emitter()
3529 }
3530 }
3531
3532 func (c *compiler) compileEmitterExpr(emitter func(), idx file.Idx) *compiledEmitterExpr {
3533 r := &compiledEmitterExpr{
3534 emitter: emitter,
3535 }
3536 r.init(c, idx)
3537 return r
3538 }
3539
3540 func (e *compiledSpreadCallArgument) emitGetter(putOnStack bool) {
3541 e.expr.emitGetter(putOnStack)
3542 if putOnStack {
3543 e.c.emit(pushSpread)
3544 }
3545 }
3546
3547 func (c *compiler) startOptChain() {
3548 c.block = &block{
3549 typ: blockOptChain,
3550 outer: c.block,
3551 }
3552 }
3553
3554 func (c *compiler) endOptChain() {
3555 lbl := len(c.p.code)
3556 for _, item := range c.block.breaks {
3557 c.p.code[item] = jopt(lbl - item)
3558 }
3559 for _, item := range c.block.conts {
3560 c.p.code[item] = joptc(lbl - item)
3561 }
3562 c.block = c.block.outer
3563 }
3564
3565 func (e *compiledOptionalChain) emitGetter(putOnStack bool) {
3566 e.c.startOptChain()
3567 e.expr.emitGetter(true)
3568 e.c.endOptChain()
3569 if !putOnStack {
3570 e.c.emit(pop)
3571 }
3572 }
3573
3574 func (e *compiledOptional) emitGetter(putOnStack bool) {
3575 e.expr.emitGetter(putOnStack)
3576 if putOnStack {
3577 e.c.block.breaks = append(e.c.block.breaks, len(e.c.p.code))
3578 e.c.emit(nil)
3579 }
3580 }
3581
3582 func (e *compiledAwaitExpression) emitGetter(putOnStack bool) {
3583 e.arg.emitGetter(true)
3584 e.c.emit(await)
3585 if !putOnStack {
3586 e.c.emit(pop)
3587 }
3588 }
3589
3590 func (e *compiledYieldExpression) emitGetter(putOnStack bool) {
3591 if e.arg != nil {
3592 e.arg.emitGetter(true)
3593 } else {
3594 e.c.emit(loadUndef)
3595 }
3596 if putOnStack {
3597 if e.delegate {
3598 e.c.emit(yieldDelegateRes)
3599 } else {
3600 e.c.emit(yieldRes)
3601 }
3602 } else {
3603 if e.delegate {
3604 e.c.emit(yieldDelegate)
3605 } else {
3606 e.c.emit(yield)
3607 }
3608 }
3609 }
3610
View as plain text