package goja

import (
	
	
	
	

	
)

type objectGoSlice struct {
	baseObject
	data       *[]interface{}
	lengthProp valueProperty
	origIsPtr  bool
}

func ( *Runtime) ( *[]interface{},  bool) *objectGoSlice {
	 := &Object{runtime: }
	 := &objectGoSlice{
		baseObject: baseObject{
			val: ,
		},
		data:      ,
		origIsPtr: ,
	}
	.self = 
	.init()

	return 
}

func ( *objectGoSlice) () {
	.baseObject.init()
	.class = classArray
	.prototype = .val.runtime.getArrayPrototype()
	.lengthProp.writable = true
	.extensible = true
	.baseObject._put("length", &.lengthProp)
}

func ( *objectGoSlice) () {
	.lengthProp.value = intToValue(int64(len(*.data)))
}

func ( *objectGoSlice) ( int) Value {
	return .val.runtime.ToValue((*.data)[])
}

func ( *objectGoSlice) ( unistring.String,  Value) Value {
	var  Value
	if  := strToGoIdx();  >= 0 &&  < len(*.data) {
		 = ._getIdx()
	} else if  == "length" {
		.updateLen()
		 = &.lengthProp
	}

	return .getStrWithOwnProp(, , )
}

func ( *objectGoSlice) ( valueInt,  Value) Value {
	if  := int64();  >= 0 &&  < int64(len(*.data)) {
		return ._getIdx(int())
	}
	if .prototype != nil {
		if  == nil {
			return .prototype.self.getIdx(, .val)
		}
		return .prototype.self.getIdx(, )
	}
	return nil
}

func ( *objectGoSlice) ( unistring.String) Value {
	if  := strToGoIdx();  >= 0 {
		if  < len(*.data) {
			return &valueProperty{
				value:      ._getIdx(),
				writable:   true,
				enumerable: true,
			}
		}
		return nil
	}
	if  == "length" {
		.updateLen()
		return &.lengthProp
	}
	return nil
}

func ( *objectGoSlice) ( valueInt) Value {
	if  := int64();  >= 0 &&  < int64(len(*.data)) {
		return &valueProperty{
			value:      ._getIdx(int()),
			writable:   true,
			enumerable: true,
		}
	}
	return nil
}

func ( *objectGoSlice) ( int) {
	 := cap(*.data)
	if  <  {
		 := make([]interface{}, , growCap(, len(*.data), ))
		copy(, *.data)
		*.data = 
	} else {
		 := (*.data)[len(*.data):]
		for  := range  {
			[] = nil
		}
		*.data = (*.data)[:]
	}
}

func ( *objectGoSlice) ( int) {
	 := (*.data)[:]
	for  := range  {
		[] = nil
	}
	*.data = (*.data)[:]
}

func ( *objectGoSlice) ( int,  Value,  bool) {
	if  >= len(*.data) {
		.grow( + 1)
	}
	(*.data)[] = .Export()
}

func ( *objectGoSlice) ( uint32,  bool) bool {
	if bits.UintSize == 32 &&  > math.MaxInt32 {
		panic(rangeError("Integer value overflows 32-bit int"))
	}
	 := int()
	 := len(*.data)
	if  >  {
		.grow()
	} else if  <  {
		.shrink()
	}
	return true
}

func ( *objectGoSlice) ( valueInt,  Value,  bool) bool {
	if  := toIntStrict(int64());  >= 0 {
		if  >= len(*.data) {
			if ,  := ._setForeignIdx(, nil, , .val, );  {
				return 
			}
		}
		.putIdx(, , )
	} else {
		 := .string()
		if ,  := ._setForeignStr(, nil, , .val, ); ! {
			.val.runtime.typeErrorResult(, "Can't set property '%s' on Go slice", )
			return false
		} else {
			return 
		}
	}
	return true
}

func ( *objectGoSlice) ( unistring.String,  Value,  bool) bool {
	if  := strToGoIdx();  >= 0 {
		if  >= len(*.data) {
			if ,  := ._setForeignStr(, nil, , .val, );  {
				return 
			}
		}
		.putIdx(, , )
	} else {
		if  == "length" {
			return .putLength(.val.runtime.toLengthUint32(), )
		}
		if ,  := ._setForeignStr(, nil, , .val, ); ! {
			.val.runtime.typeErrorResult(, "Can't set property '%s' on Go slice", )
			return false
		} else {
			return 
		}
	}
	return true
}

func ( *objectGoSlice) ( valueInt, ,  Value,  bool) (bool, bool) {
	return ._setForeignIdx(, trueValIfPresent(.hasOwnPropertyIdx()), , , )
}

func ( *objectGoSlice) ( unistring.String, ,  Value,  bool) (bool, bool) {
	return ._setForeignStr(, trueValIfPresent(.hasOwnPropertyStr()), , , )
}

func ( *objectGoSlice) ( valueInt) bool {
	if  := int64();  >= 0 {
		return  < int64(len(*.data))
	}
	return false
}

func ( *objectGoSlice) ( unistring.String) bool {
	if  := strToIdx64();  >= 0 {
		return  < int64(len(*.data))
	}
	return  == "length"
}

func ( *objectGoSlice) ( valueInt,  PropertyDescriptor,  bool) bool {
	if  := toIntStrict(int64());  >= 0 {
		if !.val.runtime.checkHostObjectPropertyDescr(.string(), , ) {
			return false
		}
		 := .Value
		if  == nil {
			 = _undefined
		}
		.putIdx(, , )
		return true
	}
	.val.runtime.typeErrorResult(, "Cannot define property '%d' on a Go slice", )
	return false
}

func ( *objectGoSlice) ( unistring.String,  PropertyDescriptor,  bool) bool {
	if  := strToGoIdx();  >= 0 {
		if !.val.runtime.checkHostObjectPropertyDescr(, , ) {
			return false
		}
		 := .Value
		if  == nil {
			 = _undefined
		}
		.putIdx(, , )
		return true
	}
	if  == "length" {
		return .val.runtime.defineArrayLength(&.lengthProp, , .putLength, )
	}
	.val.runtime.typeErrorResult(, "Cannot define property '%s' on a Go slice", )
	return false
}

func ( *objectGoSlice) ( int64) {
	if  < int64(len(*.data)) {
		(*.data)[] = nil
	}
}

func ( *objectGoSlice) ( unistring.String,  bool) bool {
	if  := strToIdx64();  >= 0 {
		._deleteIdx()
		return true
	}
	return .baseObject.deleteStr(, )
}

func ( *objectGoSlice) ( valueInt,  bool) bool {
	 := int64()
	if  >= 0 {
		._deleteIdx()
	}
	return true
}

type goslicePropIter struct {
	o          *objectGoSlice
	idx, limit int
}

func ( *goslicePropIter) () (propIterItem, iterNextFunc) {
	if .idx < .limit && .idx < len(*.o.data) {
		 := strconv.Itoa(.idx)
		.idx++
		return propIterItem{name: newStringValue(), enumerable: _ENUM_TRUE}, .
	}

	return propIterItem{}, nil
}

func ( *objectGoSlice) () iterNextFunc {
	return (&goslicePropIter{
		o:     ,
		limit: len(*.data),
	}).next
}

func ( *objectGoSlice) ( bool,  []Value) []Value {
	for  := range *.data {
		 = append(, asciiString(strconv.Itoa()))
	}

	return 
}

func ( *objectGoSlice) (*objectExportCtx) interface{} {
	if .origIsPtr {
		return .data
	}
	return *.data
}

func ( *objectGoSlice) () reflect.Type {
	if .origIsPtr {
		return reflectTypeArrayPtr
	}
	return reflectTypeArray
}

func ( *objectGoSlice) ( objectImpl) bool {
	if ,  := .(*objectGoSlice);  {
		return .data == .data
	}
	return false
}

func ( *objectGoSlice) () Value {
	return .val
}

func ( *objectGoSlice) () reflect.Value {
	return reflect.ValueOf(.data).Elem()
}

func ( *objectGoSlice) ( reflect.Value) {
	.data = .Addr().Interface().(*[]interface{})
}

func ( *objectGoSlice) () int {
	return len(*.data)
}

func ( *objectGoSlice) ( int) Value {
	return .getIdx(valueInt(), nil)
}

func ( *objectGoSlice) ( int,  int) {
	(*.data)[], (*.data)[] = (*.data)[], (*.data)[]
}