mirror of
				https://github.com/robertkrimen/otto
				synced 2025-10-19 19:55:30 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			173 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package otto
 | |
| 
 | |
| import (
 | |
| 	"strconv"
 | |
| )
 | |
| 
 | |
| func (runtime *_runtime) newArrayObject(valueArray []Value) *_object {
 | |
| 	self := runtime.newObject()
 | |
| 	self.class = "Array"
 | |
| 	self.stash = newArrayStash(valueArray, self.stash)
 | |
| 	return self
 | |
| }
 | |
| 
 | |
| // _arrayStash
 | |
| 
 | |
| type _arrayStash struct {
 | |
| 	valueArray []Value
 | |
| 	_stash
 | |
| }
 | |
| 
 | |
| func newArrayStash(valueArray []Value, stash _stash) *_arrayStash {
 | |
| 	self := &_arrayStash{
 | |
| 		valueArray,
 | |
| 		stash,
 | |
| 	}
 | |
| 	return self
 | |
| }
 | |
| 
 | |
| // read
 | |
| 
 | |
| func (self *_arrayStash) test(name string) bool {
 | |
| 	// length
 | |
| 	if name == "length" {
 | |
| 		return true
 | |
| 	}
 | |
| 
 | |
| 	// .0, .1, .2, ...
 | |
| 	index := stringToArrayIndex(name)
 | |
| 	if index >= 0 {
 | |
| 		return index < int64(len(self.valueArray)) && self.valueArray[index]._valueType != valueEmpty
 | |
| 	}
 | |
| 
 | |
| 	return self._stash.test(name)
 | |
| }
 | |
| 
 | |
| func (self *_arrayStash) get(name string) Value {
 | |
| 	// length
 | |
| 	if name == "length" {
 | |
| 		return toValue(len(self.valueArray))
 | |
| 	}
 | |
| 
 | |
| 	// .0, .1, .2, ...
 | |
| 	index := stringToArrayIndex(name)
 | |
| 	if index >= 0 {
 | |
| 		if index < int64(len(self.valueArray)) {
 | |
| 			value := self.valueArray[index]
 | |
| 			if value._valueType != valueEmpty {
 | |
| 				return value
 | |
| 			}
 | |
| 		}
 | |
| 		return UndefinedValue()
 | |
| 	}
 | |
| 
 | |
| 	return self._stash.get(name)
 | |
| }
 | |
| 
 | |
| func (self *_arrayStash) property(name string) *_property {
 | |
| 	// length
 | |
| 	if name == "length" {
 | |
| 		return &_property{
 | |
| 			value: toValue(len(self.valueArray)),
 | |
| 			mode:  0100, // +w-ec
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// .0, .1, .2, ...
 | |
| 	index := stringToArrayIndex(name)
 | |
| 	if index >= 0 {
 | |
| 		value := UndefinedValue()
 | |
| 		if index < int64(len(self.valueArray)) {
 | |
| 			value = self.valueArray[index]
 | |
| 		}
 | |
| 		return &_property{
 | |
| 			value: value,
 | |
| 			mode:  0111, // +wec
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return self._stash.property(name)
 | |
| }
 | |
| 
 | |
| func (self *_arrayStash) enumerate(each func(string)) {
 | |
| 	// .0, .1, .2, ...
 | |
| 	for index, _ := range self.valueArray {
 | |
| 		if self.valueArray[index]._valueType == valueEmpty {
 | |
| 			continue // A sparse array
 | |
| 		}
 | |
| 		name := strconv.FormatInt(int64(index), 10)
 | |
| 		each(name)
 | |
| 	}
 | |
| 	self._stash.enumerate(each)
 | |
| }
 | |
| 
 | |
| // write
 | |
| 
 | |
| func (self *_arrayStash) canPut(name string) bool {
 | |
| 	// length
 | |
| 	if name == "length" {
 | |
| 		return true
 | |
| 	}
 | |
| 
 | |
| 	// .0, .1, .2, ...
 | |
| 	index := stringToArrayIndex(name)
 | |
| 	if index >= 0 {
 | |
| 		return true
 | |
| 	}
 | |
| 
 | |
| 	return self._stash.canPut(name)
 | |
| }
 | |
| 
 | |
| func (self *_arrayStash) put(name string, value Value) {
 | |
| 	// length
 | |
| 	if name == "length" {
 | |
| 		value := uint(toUint32(value))
 | |
| 		length := uint(len(self.valueArray))
 | |
| 		if value > length {
 | |
| 			valueArray := make([]Value, value)
 | |
| 			copy(valueArray, self.valueArray)
 | |
| 			self.valueArray = valueArray
 | |
| 		} else if value < length {
 | |
| 			self.valueArray = self.valueArray[:value]
 | |
| 		}
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// .0, .1, .2, ...
 | |
| 	index := stringToArrayIndex(name)
 | |
| 	if index >= 0 {
 | |
| 		// May be able to do tricky stuff here
 | |
| 		// with checking cap() after len(), but not
 | |
| 		// sure if worth it
 | |
| 		if index < int64(len(self.valueArray)) {
 | |
| 			self.valueArray[index] = value
 | |
| 			return
 | |
| 		}
 | |
| 		valueArray := make([]Value, index+1)
 | |
| 		copy(valueArray, self.valueArray)
 | |
| 		valueArray[index] = value
 | |
| 		self.valueArray = valueArray
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	self._stash.put(name, value)
 | |
| }
 | |
| 
 | |
| func (self *_arrayStash) delete(name string) {
 | |
| 	// length
 | |
| 	if name == "length" {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// .0, .1, .2, ...
 | |
| 	index := stringToArrayIndex(name)
 | |
| 	if index >= 0 {
 | |
| 		if index < int64(len(self.valueArray)) {
 | |
| 			self.valueArray[index] = emptyValue()
 | |
| 		}
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	self._stash.delete(name)
 | |
| }
 | 
