123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package goja
- import "github.com/dop251/goja/unistring"
- type argumentsObject struct {
- baseObject
- length int
- }
- type mappedProperty struct {
- valueProperty
- v *Value
- }
- func (a *argumentsObject) getStr(name unistring.String, receiver Value) Value {
- return a.getStrWithOwnProp(a.getOwnPropStr(name), name, receiver)
- }
- func (a *argumentsObject) getOwnPropStr(name unistring.String) Value {
- if mapped, ok := a.values[name].(*mappedProperty); ok {
- if mapped.writable && mapped.enumerable && mapped.configurable {
- return *mapped.v
- }
- return &valueProperty{
- value: *mapped.v,
- writable: mapped.writable,
- configurable: mapped.configurable,
- enumerable: mapped.enumerable,
- }
- }
- return a.baseObject.getOwnPropStr(name)
- }
- func (a *argumentsObject) init() {
- a.baseObject.init()
- a._putProp("length", intToValue(int64(a.length)), true, false, true)
- }
- func (a *argumentsObject) setOwnStr(name unistring.String, val Value, throw bool) bool {
- if prop, ok := a.values[name].(*mappedProperty); ok {
- if !prop.writable {
- a.val.runtime.typeErrorResult(throw, "Property is not writable: %s", name)
- return false
- }
- *prop.v = val
- return true
- }
- return a.baseObject.setOwnStr(name, val, throw)
- }
- func (a *argumentsObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
- return a._setForeignStr(name, a.getOwnPropStr(name), val, receiver, throw)
- }
- func (a *argumentsObject) deleteStr(name unistring.String, throw bool) bool {
- if prop, ok := a.values[name].(*mappedProperty); ok {
- if !a.checkDeleteProp(name, &prop.valueProperty, throw) {
- return false
- }
- a._delete(name)
- return true
- }
- return a.baseObject.deleteStr(name, throw)
- }
- type argumentsPropIter struct {
- wrapped iterNextFunc
- }
- func (i *argumentsPropIter) next() (propIterItem, iterNextFunc) {
- var item propIterItem
- item, i.wrapped = i.wrapped()
- if i.wrapped == nil {
- return propIterItem{}, nil
- }
- if prop, ok := item.value.(*mappedProperty); ok {
- item.value = *prop.v
- }
- return item, i.next
- }
- func (a *argumentsObject) iterateStringKeys() iterNextFunc {
- return (&argumentsPropIter{
- wrapped: a.baseObject.iterateStringKeys(),
- }).next
- }
- func (a *argumentsObject) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
- if mapped, ok := a.values[name].(*mappedProperty); ok {
- existing := &valueProperty{
- configurable: mapped.configurable,
- writable: true,
- enumerable: mapped.enumerable,
- value: *mapped.v,
- }
- val, ok := a.baseObject._defineOwnProperty(name, existing, descr, throw)
- if !ok {
- return false
- }
- if prop, ok := val.(*valueProperty); ok {
- if !prop.accessor {
- *mapped.v = prop.value
- }
- if prop.accessor || !prop.writable {
- a._put(name, prop)
- return true
- }
- mapped.configurable = prop.configurable
- mapped.enumerable = prop.enumerable
- } else {
- *mapped.v = val
- mapped.configurable = true
- mapped.enumerable = true
- }
- return true
- }
- return a.baseObject.defineOwnPropertyStr(name, descr, throw)
- }
- func (a *argumentsObject) export(ctx *objectExportCtx) interface{} {
- if v, exists := ctx.get(a.val); exists {
- return v
- }
- arr := make([]interface{}, a.length)
- ctx.put(a.val, arr)
- for i := range arr {
- v := a.getIdx(valueInt(int64(i)), nil)
- if v != nil {
- arr[i] = exportValue(v, ctx)
- }
- }
- return arr
- }
|