github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/object_args.go (about) 1 package goja 2 3 import "github.com/nuvolaris/goja/unistring" 4 5 type argumentsObject struct { 6 baseObject 7 length int 8 } 9 10 type mappedProperty struct { 11 valueProperty 12 v *Value 13 } 14 15 func (a *argumentsObject) getStr(name unistring.String, receiver Value) Value { 16 return a.getStrWithOwnProp(a.getOwnPropStr(name), name, receiver) 17 } 18 19 func (a *argumentsObject) getOwnPropStr(name unistring.String) Value { 20 if mapped, ok := a.values[name].(*mappedProperty); ok { 21 if mapped.writable && mapped.enumerable && mapped.configurable { 22 return *mapped.v 23 } 24 return &valueProperty{ 25 value: *mapped.v, 26 writable: mapped.writable, 27 configurable: mapped.configurable, 28 enumerable: mapped.enumerable, 29 } 30 } 31 32 return a.baseObject.getOwnPropStr(name) 33 } 34 35 func (a *argumentsObject) init() { 36 a.baseObject.init() 37 a._putProp("length", intToValue(int64(a.length)), true, false, true) 38 } 39 40 func (a *argumentsObject) setOwnStr(name unistring.String, val Value, throw bool) bool { 41 if prop, ok := a.values[name].(*mappedProperty); ok { 42 if !prop.writable { 43 a.val.runtime.typeErrorResult(throw, "Property is not writable: %s", name) 44 return false 45 } 46 *prop.v = val 47 return true 48 } 49 return a.baseObject.setOwnStr(name, val, throw) 50 } 51 52 func (a *argumentsObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) { 53 return a._setForeignStr(name, a.getOwnPropStr(name), val, receiver, throw) 54 } 55 56 func (a *argumentsObject) deleteStr(name unistring.String, throw bool) bool { 57 if prop, ok := a.values[name].(*mappedProperty); ok { 58 if !a.checkDeleteProp(name, &prop.valueProperty, throw) { 59 return false 60 } 61 a._delete(name) 62 return true 63 } 64 65 return a.baseObject.deleteStr(name, throw) 66 } 67 68 type argumentsPropIter struct { 69 wrapped iterNextFunc 70 } 71 72 func (i *argumentsPropIter) next() (propIterItem, iterNextFunc) { 73 var item propIterItem 74 item, i.wrapped = i.wrapped() 75 if i.wrapped == nil { 76 return propIterItem{}, nil 77 } 78 if prop, ok := item.value.(*mappedProperty); ok { 79 item.value = *prop.v 80 } 81 return item, i.next 82 } 83 84 func (a *argumentsObject) iterateStringKeys() iterNextFunc { 85 return (&argumentsPropIter{ 86 wrapped: a.baseObject.iterateStringKeys(), 87 }).next 88 } 89 90 func (a *argumentsObject) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool { 91 if mapped, ok := a.values[name].(*mappedProperty); ok { 92 existing := &valueProperty{ 93 configurable: mapped.configurable, 94 writable: true, 95 enumerable: mapped.enumerable, 96 value: *mapped.v, 97 } 98 99 val, ok := a.baseObject._defineOwnProperty(name, existing, descr, throw) 100 if !ok { 101 return false 102 } 103 104 if prop, ok := val.(*valueProperty); ok { 105 if !prop.accessor { 106 *mapped.v = prop.value 107 } 108 if prop.accessor || !prop.writable { 109 a._put(name, prop) 110 return true 111 } 112 mapped.configurable = prop.configurable 113 mapped.enumerable = prop.enumerable 114 } else { 115 *mapped.v = val 116 mapped.configurable = true 117 mapped.enumerable = true 118 } 119 120 return true 121 } 122 123 return a.baseObject.defineOwnPropertyStr(name, descr, throw) 124 } 125 126 func (a *argumentsObject) export(ctx *objectExportCtx) interface{} { 127 if v, exists := ctx.get(a.val); exists { 128 return v 129 } 130 arr := make([]interface{}, a.length) 131 ctx.put(a.val, arr) 132 for i := range arr { 133 v := a.getIdx(valueInt(int64(i)), nil) 134 if v != nil { 135 arr[i] = exportValue(v, ctx) 136 } 137 } 138 return arr 139 }