Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 165ce97

Browse files
Made changes per suggestions and help
1 parent e7a03aa commit 165ce97

File tree

2 files changed

+52
-34
lines changed

2 files changed

+52
-34
lines changed

compiler/natives/src/reflect/reflect.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -1339,9 +1339,7 @@ func (v Value) grow(n int) {
13391339
cap := s.Get(`$capacity`).Int()
13401340
if len+n > cap {
13411341
ns := js.Global.Call("$growSlice", s, len+n)
1342-
s.Set(`$capacity`, ns.Get(`$capacity`))
1343-
s.Set(`$array`, ns.Get(`$array`))
1344-
s.Set(`$offset`, ns.Get(`$offset`))
1342+
js.InternalObject(v.ptr).Call("$set", ns)
13451343
}
13461344
}
13471345

compiler/prelude/prelude.js

+51-31
Original file line numberDiff line numberDiff line change
@@ -428,55 +428,75 @@ var $appendSlice = (slice, toAppend) => {
428428
return $internalAppend(slice, toAppend.$array, toAppend.$offset, toAppend.$length);
429429
};
430430

431+
// Internal helper function for appending to a slice.
432+
// The given slice will not be modified.
433+
//
434+
// If no values are being appended, the original slice will be returned.
435+
// Otherwise, a new slice will be created with the appended values.
436+
//
437+
// If the underlying array has enough capacity, it will be used.
438+
// Otherwise, a new array will be allocated with enough capacity to hold
439+
// the new values and the original array will not be modified.
431440
var $internalAppend = (slice, array, offset, length) => {
432441
if (length === 0) {
433442
return slice;
434443
}
435444

436-
var newLength = slice.$length + length;
437-
slice = $growSlice(slice, newLength);
445+
let newLength = slice.$length + length;
446+
let newSlice = $growSlice(slice, newLength);
438447

439-
var newArray = slice.$array;
440-
$copyArray(newArray, array, slice.$offset + slice.$length, offset, length, slice.constructor.elem);
441-
442-
var newSlice = new slice.constructor(newArray);
443-
newSlice.$offset = slice.$offset;
448+
let newArray = newSlice.$array;
449+
$copyArray(newArray, array, newSlice.$offset + newSlice.$length, offset, length, newSlice.constructor.elem);
450+
444451
newSlice.$length = newLength;
445-
newSlice.$capacity = slice.$capacity;
446452
return newSlice;
447453
};
448454

455+
// Calculates the new capacity for a slice that is expected to grow to at least
456+
// the given minCapacity. This follows the Go runtime's growth strategy.
457+
// The oldCapacity is the current capacity of the slice that is being grown.
449458
const $calculateNewCapacity = (minCapacity, oldCapacity) => {
450459
return Math.max(minCapacity, oldCapacity < 1024 ? oldCapacity * 2 : Math.floor(oldCapacity * 5 / 4));
451460
};
452461

462+
// Potentially grows the slice to have a capacity of at least minCapacity.
463+
//
464+
// A new slice will always be returned, even if the given slice had the required capacity.
465+
// If the slice didn't have enough capacity, the new slice will have a
466+
// new array created for it with the required minimum capacity.
467+
//
468+
// This takes the place of the growSlice function in the reflect package.
453469
var $growSlice = (slice, minCapacity) => {
454-
const oldCapacity = slice.$capacity;
455-
if (minCapacity <= oldCapacity) {
456-
return slice
457-
}
458-
459-
const newCapacity = $calculateNewCapacity(minCapacity, oldCapacity);
460-
461-
let newArray;
462-
if (slice.$array.constructor === Array) {
463-
newArray = slice.$array.slice( slice.$offset, slice.$offset + slice.$length);
464-
newArray.length = newCapacity;
465-
let zero = slice.constructor.elem.zero;
466-
for (let i = slice.$length; i < newCapacity; i++) {
467-
newArray[i] = zero();
470+
let array = slice.$array;
471+
let offset = slice.$offset;
472+
const length = slice.$length;
473+
let capacity = slice.$capacity;
474+
475+
if (minCapacity > capacity) {
476+
capacity = $calculateNewCapacity(minCapacity, capacity);
477+
478+
let newArray;
479+
if (array.constructor === Array) {
480+
newArray = array.slice(offset, offset + length);
481+
newArray.length = capacity;
482+
const zero = slice.constructor.elem.zero;
483+
for (let i = slice.$length; i < capacity; i++) {
484+
newArray[i] = zero();
485+
}
486+
} else {
487+
newArray = new array.constructor(capacity);
488+
newArray.set(array.subarray(offset, offset + length));
468489
}
469-
} else {
470-
newArray = new slice.$array.constructor(newCapacity);
471-
newArray.set(slice.$array.subarray( slice.$offset, slice.$offset + slice.$length));
490+
491+
array = newArray;
492+
offset = 0;
472493
}
473494

474-
const oldLength = slice.$length;
475-
slice = new slice.constructor(newArray);
476-
slice.$offset = 0;
477-
slice.$length = oldLength;
478-
slice.$capacity = newCapacity;
479-
return slice;
495+
let newSlice = new slice.constructor(array);
496+
newSlice.$offset = offset;
497+
newSlice.$length = length;
498+
newSlice.$capacity = capacity;
499+
return newSlice;
480500
};
481501

482502
var $equal = (a, b, type) => {

0 commit comments

Comments
 (0)