@@ -3,6 +3,7 @@ package goja
3
3
import (
4
4
"math"
5
5
"sort"
6
+ "sync"
6
7
)
7
8
8
9
func (r * Runtime ) newArray (prototype * Object ) (a * arrayObject ) {
@@ -19,7 +20,7 @@ func (r *Runtime) newArray(prototype *Object) (a *arrayObject) {
19
20
}
20
21
21
22
func (r * Runtime ) newArrayObject () * arrayObject {
22
- return r .newArray (r .global . ArrayPrototype )
23
+ return r .newArray (r .getArrayPrototype () )
23
24
}
24
25
25
26
func setArrayValues (a * arrayObject , values []Value ) * arrayObject {
@@ -96,7 +97,7 @@ func (r *Runtime) builtin_newArray(args []Value, proto *Object) *Object {
96
97
if float64 (al ) == float64 (f ) {
97
98
return r .newArrayLength (al )
98
99
} else {
99
- panic (r .newError (r .global . RangeError , "Invalid array length" ))
100
+ panic (r .newError (r .getRangeError () , "Invalid array length" ))
100
101
}
101
102
}
102
103
return setArrayValues (r .newArray (proto ), []Value {args [0 ]}).val
@@ -1259,7 +1260,7 @@ func (r *Runtime) checkStdArray(v Value) *arrayObject {
1259
1260
1260
1261
func (r * Runtime ) checkStdArrayIter (v Value ) * arrayObject {
1261
1262
if arr := r .checkStdArray (v ); arr != nil &&
1262
- arr .getSym (SymIterator , nil ) == r .global . arrayValues {
1263
+ arr .getSym (SymIterator , nil ) == r .getArrayValues () {
1263
1264
1264
1265
return arr
1265
1266
}
@@ -1398,80 +1399,110 @@ func (r *Runtime) arrayIterProto_next(call FunctionCall) Value {
1398
1399
panic (r .NewTypeError ("Method Array Iterator.prototype.next called on incompatible receiver %s" , r .objectproto_toString (FunctionCall {This : thisObj })))
1399
1400
}
1400
1401
1401
- func ( r * Runtime ) createArrayProto ( val * Object ) objectImpl {
1402
- o := & arrayObject {
1403
- baseObject : baseObject {
1404
- class : classArray ,
1405
- val : val ,
1406
- extensible : true ,
1407
- prototype : r . global . ObjectPrototype ,
1408
- },
1409
- }
1410
- o . init ()
1411
-
1412
- o . _putProp ( "at " , r . newNativeFunc (r .arrayproto_at , nil , "at " , nil , 1 ), true , false , true )
1413
- o . _putProp ( "constructor " , r . global . Array , true , false , true )
1414
- o . _putProp ( "concat " , r . newNativeFunc (r .arrayproto_concat , nil , "concat " , nil , 1 ), true , false , true )
1415
- o . _putProp ( "copyWithin " , r . newNativeFunc (r .arrayproto_copyWithin , nil , "copyWithin " , nil , 2 ), true , false , true )
1416
- o . _putProp ( "entries " , r . newNativeFunc (r .arrayproto_entries , nil , "entries " , nil , 0 ), true , false , true )
1417
- o . _putProp ( "every " , r . newNativeFunc (r .arrayproto_every , nil , "every " , nil , 1 ), true , false , true )
1418
- o . _putProp ( "fill " , r . newNativeFunc (r .arrayproto_fill , nil , "fill " , nil , 1 ), true , false , true )
1419
- o . _putProp ( "filter " , r . newNativeFunc (r .arrayproto_filter , nil , "filter " , nil , 1 ), true , false , true )
1420
- o . _putProp ( "find " , r . newNativeFunc (r .arrayproto_find , nil , "find " , nil , 1 ), true , false , true )
1421
- o . _putProp ( "findIndex " , r . newNativeFunc (r .arrayproto_findIndex , nil , "findIndex " , nil , 1 ), true , false , true )
1422
- o . _putProp ( "findLast " , r . newNativeFunc (r .arrayproto_findLast , nil , "findLast " , nil , 1 ), true , false , true )
1423
- o . _putProp ( "findLastIndex " , r . newNativeFunc (r .arrayproto_findLastIndex , nil , "findLastIndex " , nil , 1 ), true , false , true )
1424
- o . _putProp ( "flat " , r . newNativeFunc (r .arrayproto_flat , nil , "flat " , nil , 0 ), true , false , true )
1425
- o . _putProp ( "flatMap " , r . newNativeFunc (r .arrayproto_flatMap , nil , "flatMap " , nil , 1 ), true , false , true )
1426
- o . _putProp ( "forEach " , r . newNativeFunc (r .arrayproto_forEach , nil , "forEach " , nil , 1 ), true , false , true )
1427
- o . _putProp ( "includes " , r . newNativeFunc (r .arrayproto_includes , nil , "includes " , nil , 1 ), true , false , true )
1428
- o . _putProp ( "indexOf " , r . newNativeFunc (r .arrayproto_indexOf , nil , "indexOf " , nil , 1 ), true , false , true )
1429
- o . _putProp ( "join " , r . newNativeFunc (r .arrayproto_join , nil , "join " , nil , 1 ), true , false , true )
1430
- o . _putProp ( "keys " , r . newNativeFunc (r .arrayproto_keys , nil , "keys " , nil , 0 ), true , false , true )
1431
- o . _putProp ( "lastIndexOf " , r . newNativeFunc (r .arrayproto_lastIndexOf , nil , "lastIndexOf " , nil , 1 ), true , false , true )
1432
- o . _putProp ( "map " , r . newNativeFunc (r .arrayproto_map , nil , "map " , nil , 1 ), true , false , true )
1433
- o . _putProp ( "pop " , r . newNativeFunc (r .arrayproto_pop , nil , "pop " , nil , 0 ), true , false , true )
1434
- o . _putProp ( "push " , r . newNativeFunc (r .arrayproto_push , nil , "push " , nil , 1 ), true , false , true )
1435
- o . _putProp ( "reduce " , r . newNativeFunc (r .arrayproto_reduce , nil , "reduce " , nil , 1 ), true , false , true )
1436
- o . _putProp ( "reduceRight " , r . newNativeFunc (r .arrayproto_reduceRight , nil , "reduceRight " , nil , 1 ), true , false , true )
1437
- o . _putProp ( "reverse " , r . newNativeFunc (r .arrayproto_reverse , nil , "reverse " , nil , 0 ), true , false , true )
1438
- o . _putProp ( "shift " , r . newNativeFunc (r .arrayproto_shift , nil , "shift " , nil , 0 ), true , false , true )
1439
- o . _putProp ( "slice " , r . newNativeFunc (r .arrayproto_slice , nil , "slice " , nil , 2 ), true , false , true )
1440
- o . _putProp ( "some " , r . newNativeFunc (r .arrayproto_some , nil , "some " , nil , 1 ), true , false , true )
1441
- o . _putProp ( "sort " , r . newNativeFunc (r .arrayproto_sort , nil , "sort " , nil , 1 ), true , false , true )
1442
- o . _putProp ( "splice " , r . newNativeFunc ( r . arrayproto_splice , nil , "splice" , nil , 2 ), true , false , true )
1443
- o . _putProp ( "toLocaleString " , r . newNativeFunc (r .arrayproto_toLocaleString , nil , "toLocaleString " , nil , 0 ), true , false , true )
1444
- o . _putProp ( "toString " , r . global . arrayToString , true , false , true )
1445
- o . _putProp ( "unshift" , r . newNativeFunc ( r . arrayproto_unshift , nil , "unshift" , nil , 1 ), true , false , true )
1446
- o . _putProp ( "values" , r . global . arrayValues , true , false , true )
1447
-
1448
- o . _putSym ( SymIterator , valueProp ( r . global . arrayValues , true , false , true ) )
1449
-
1450
- bl := r . newBaseObject ( nil , classObject )
1451
- bl .setOwnStr ("copyWithin " , valueTrue , true )
1452
- bl .setOwnStr ("entries " , valueTrue , true )
1453
- bl .setOwnStr ("fill " , valueTrue , true )
1454
- bl .setOwnStr ("find " , valueTrue , true )
1455
- bl .setOwnStr ("findIndex " , valueTrue , true )
1456
- bl .setOwnStr ("findLast " , valueTrue , true )
1457
- bl .setOwnStr ("findLastIndex " , valueTrue , true )
1458
- bl .setOwnStr ("flat " , valueTrue , true )
1459
- bl .setOwnStr ("flatMap " , valueTrue , true )
1460
- bl .setOwnStr ("includes " , valueTrue , true )
1461
- bl .setOwnStr ("keys " , valueTrue , true )
1462
- bl .setOwnStr ("values " , valueTrue , true )
1463
- bl . setOwnStr ( "groupBy" , valueTrue , true )
1464
- bl .setOwnStr ( "groupByToMap" , valueTrue , true )
1465
- o . _putSym ( SymUnscopables , valueProp ( bl . val , false , false , true ) )
1402
+ func createArrayProtoTemplate () * objectTemplate {
1403
+ t := newObjectTemplate ()
1404
+ t . protoFactory = func ( r * Runtime ) * Object {
1405
+ return r . global . ObjectPrototype
1406
+ }
1407
+
1408
+ t . putStr ( "length" , func ( r * Runtime ) Value { return valueProp ( _positiveZero , true , false , false ) })
1409
+
1410
+ t . putStr ( "constructor" , func ( r * Runtime ) Value { return valueProp ( r . getArray (), true , false , true ) })
1411
+
1412
+ t . putStr ( "at" , func ( r * Runtime ) Value { return r . methodProp ( r . arrayproto_at , "at" , 1 ) })
1413
+ t . putStr ( "concat " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_concat , "concat " , 1 ) } )
1414
+ t . putStr ( "copyWithin " , func ( r * Runtime ) Value { return r . methodProp ( r . arrayproto_copyWithin , "copyWithin" , 2 ) } )
1415
+ t . putStr ( "entries " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_entries , "entries " , 0 ) } )
1416
+ t . putStr ( "every " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_every , "every " , 1 ) } )
1417
+ t . putStr ( "fill " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_fill , "fill " , 1 ) } )
1418
+ t . putStr ( "filter " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_filter , "filter " , 1 ) } )
1419
+ t . putStr ( "find " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_find , "find " , 1 ) } )
1420
+ t . putStr ( "findIndex " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_findIndex , "findIndex " , 1 ) } )
1421
+ t . putStr ( "findLast " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_findLast , "findLast " , 1 ) } )
1422
+ t . putStr ( "findLastIndex " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_findLastIndex , "findLastIndex " , 1 ) } )
1423
+ t . putStr ( "flat " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_flat , "flat " , 0 ) } )
1424
+ t . putStr ( "flatMap " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_flatMap , "flatMap " , 1 ) } )
1425
+ t . putStr ( "forEach " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_forEach , "forEach " , 1 ) } )
1426
+ t . putStr ( "includes " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_includes , "includes " , 1 ) } )
1427
+ t . putStr ( "indexOf " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_indexOf , "indexOf " , 1 ) } )
1428
+ t . putStr ( "join " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_join , "join " , 1 ) } )
1429
+ t . putStr ( "keys " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_keys , "keys " , 0 ) } )
1430
+ t . putStr ( "lastIndexOf " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_lastIndexOf , "lastIndexOf " , 1 ) } )
1431
+ t . putStr ( "map " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_map , "map " , 1 ) } )
1432
+ t . putStr ( "pop " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_pop , "pop " , 0 ) } )
1433
+ t . putStr ( "push " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_push , "push " , 1 ) } )
1434
+ t . putStr ( "reduce " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_reduce , "reduce " , 1 ) } )
1435
+ t . putStr ( "reduceRight " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_reduceRight , "reduceRight " , 1 ) } )
1436
+ t . putStr ( "reverse " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_reverse , "reverse " , 0 ) } )
1437
+ t . putStr ( "shift " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_shift , "shift " , 0 ) } )
1438
+ t . putStr ( "slice " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_slice , "slice " , 2 ) } )
1439
+ t . putStr ( "some " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_some , "some " , 1 ) } )
1440
+ t . putStr ( "sort " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_sort , "sort " , 1 ) } )
1441
+ t . putStr ( "splice " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_splice , "splice " , 2 ) } )
1442
+ t . putStr ( "toLocaleString " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_toLocaleString , "toLocaleString " , 0 ) } )
1443
+ t . putStr ( "toString " , func ( r * Runtime ) Value { return valueProp ( r . getArrayToString ( ), true , false , true ) } )
1444
+ t . putStr ( "unshift " , func ( r * Runtime ) Value { return r . methodProp (r .arrayproto_unshift , "unshift " , 1 ) } )
1445
+ t . putStr ( "values " , func ( r * Runtime ) Value { return valueProp ( r . getArrayValues () , true , false , true ) } )
1446
+
1447
+ t . putSym ( SymIterator , func ( r * Runtime ) Value { return valueProp ( r . getArrayValues () , true , false , true ) } )
1448
+ t . putSym ( SymUnscopables , func ( r * Runtime ) Value {
1449
+ bl := r . newBaseObject ( nil , classObject )
1450
+ bl . setOwnStr ( "copyWithin" , valueTrue , true )
1451
+ bl . setOwnStr ( "entries" , valueTrue , true )
1452
+ bl .setOwnStr ("fill " , valueTrue , true )
1453
+ bl .setOwnStr ("find " , valueTrue , true )
1454
+ bl .setOwnStr ("findIndex " , valueTrue , true )
1455
+ bl .setOwnStr ("findLast " , valueTrue , true )
1456
+ bl .setOwnStr ("findLastIndex " , valueTrue , true )
1457
+ bl .setOwnStr ("flat " , valueTrue , true )
1458
+ bl .setOwnStr ("flatMap " , valueTrue , true )
1459
+ bl .setOwnStr ("includes " , valueTrue , true )
1460
+ bl .setOwnStr ("keys " , valueTrue , true )
1461
+ bl .setOwnStr ("values " , valueTrue , true )
1462
+ bl .setOwnStr ("groupBy " , valueTrue , true )
1463
+ bl .setOwnStr ("groupByToMap " , valueTrue , true )
1464
+
1465
+ return valueProp ( bl .val , false , false , true )
1466
+ } )
1466
1467
1467
- return o
1468
+ return t
1469
+ }
1470
+
1471
+ var arrayProtoTemplate * objectTemplate
1472
+ var arrayProtoTemplateOnce sync.Once
1473
+
1474
+ func getArrayProtoTemplate () * objectTemplate {
1475
+ arrayProtoTemplateOnce .Do (func () {
1476
+ arrayProtoTemplate = createArrayProtoTemplate ()
1477
+ })
1478
+ return arrayProtoTemplate
1479
+ }
1480
+
1481
+ func (r * Runtime ) getArrayPrototype () * Object {
1482
+ ret := r .global .ArrayPrototype
1483
+ if ret == nil {
1484
+ ret = & Object {runtime : r }
1485
+ r .global .ArrayPrototype = ret
1486
+ r .newTemplatedArrayObject (getArrayProtoTemplate (), ret )
1487
+ }
1488
+ return ret
1489
+ }
1490
+
1491
+ func (r * Runtime ) getArray () * Object {
1492
+ ret := r .global .Array
1493
+ if ret == nil {
1494
+ ret = & Object {runtime : r }
1495
+ ret .self = r .createArray (ret )
1496
+ r .global .Array = ret
1497
+ }
1498
+ return ret
1468
1499
}
1469
1500
1470
1501
func (r * Runtime ) createArray (val * Object ) objectImpl {
1471
- o := r .newNativeFuncConstructObj (val , r .builtin_newArray , "Array" , r .global . ArrayPrototype , 1 )
1472
- o ._putProp ("from" , r .newNativeFunc (r .array_from , nil , "from" , nil , 1 ), true , false , true )
1473
- o ._putProp ("isArray" , r .newNativeFunc (r .array_isArray , nil , "isArray" , nil , 1 ), true , false , true )
1474
- o ._putProp ("of" , r .newNativeFunc (r .array_of , nil , "of" , nil , 0 ), true , false , true )
1502
+ o := r .newNativeFuncConstructObj (val , r .builtin_newArray , "Array" , r .getArrayPrototype () , 1 )
1503
+ o ._putProp ("from" , r .newNativeFunc (r .array_from , "from" , 1 ), true , false , true )
1504
+ o ._putProp ("isArray" , r .newNativeFunc (r .array_isArray , "isArray" , 1 ), true , false , true )
1505
+ o ._putProp ("of" , r .newNativeFunc (r .array_of , "of" , 0 ), true , false , true )
1475
1506
r .putSpeciesReturnThis (o )
1476
1507
1477
1508
return o
@@ -1480,20 +1511,28 @@ func (r *Runtime) createArray(val *Object) objectImpl {
1480
1511
func (r * Runtime ) createArrayIterProto (val * Object ) objectImpl {
1481
1512
o := newBaseObjectObj (val , r .getIteratorPrototype (), classObject )
1482
1513
1483
- o ._putProp ("next" , r .newNativeFunc (r .arrayIterProto_next , nil , "next" , nil , 0 ), true , false , true )
1514
+ o ._putProp ("next" , r .newNativeFunc (r .arrayIterProto_next , "next" , 0 ), true , false , true )
1484
1515
o ._putSym (SymToStringTag , valueProp (asciiString (classArrayIterator ), false , false , true ))
1485
1516
1486
1517
return o
1487
1518
}
1488
1519
1489
- func (r * Runtime ) initArray () {
1490
- r .global .arrayValues = r .newNativeFunc (r .arrayproto_values , nil , "values" , nil , 0 )
1491
- r .global .arrayToString = r .newNativeFunc (r .arrayproto_toString , nil , "toString" , nil , 0 )
1492
-
1493
- r .global .ArrayPrototype = r .newLazyObject (r .createArrayProto )
1520
+ func (r * Runtime ) getArrayValues () * Object {
1521
+ ret := r .global .arrayValues
1522
+ if ret == nil {
1523
+ ret = r .newNativeFunc (r .arrayproto_values , "values" , 0 )
1524
+ r .global .arrayValues = ret
1525
+ }
1526
+ return ret
1527
+ }
1494
1528
1495
- r .global .Array = r .newLazyObject (r .createArray )
1496
- r .addToGlobal ("Array" , r .global .Array )
1529
+ func (r * Runtime ) getArrayToString () * Object {
1530
+ ret := r .global .arrayToString
1531
+ if ret == nil {
1532
+ ret = r .newNativeFunc (r .arrayproto_toString , "toString" , 0 )
1533
+ r .global .arrayToString = ret
1534
+ }
1535
+ return ret
1497
1536
}
1498
1537
1499
1538
func (r * Runtime ) getArrayIteratorPrototype () * Object {
1 commit comments
Calvinnix commentedon Sep 11, 2023
Fantastic addition! Great work on this!