123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- package goja
- import (
- "fmt"
- )
- func (r *Runtime) builtin_Object(args []Value, proto *Object) *Object {
- if len(args) > 0 {
- arg := args[0]
- if arg != _undefined && arg != _null {
- return arg.ToObject(r)
- }
- }
- return r.NewObject()
- }
- func (r *Runtime) object_getPrototypeOf(call FunctionCall) Value {
- o := call.Argument(0).ToObject(r)
- p := o.self.proto()
- if p == nil {
- return _null
- }
- return p
- }
- func (r *Runtime) object_getOwnPropertyDescriptor(call FunctionCall) Value {
- obj := call.Argument(0).ToObject(r)
- propName := call.Argument(1).String()
- desc := obj.self.getOwnProp(propName)
- if desc == nil {
- return _undefined
- }
- var writable, configurable, enumerable, accessor bool
- var get, set *Object
- var value Value
- if v, ok := desc.(*valueProperty); ok {
- writable = v.writable
- configurable = v.configurable
- enumerable = v.enumerable
- accessor = v.accessor
- value = v.value
- get = v.getterFunc
- set = v.setterFunc
- } else {
- writable = true
- configurable = true
- enumerable = true
- value = desc
- }
- ret := r.NewObject()
- o := ret.self
- if !accessor {
- o.putStr("value", value, false)
- o.putStr("writable", r.toBoolean(writable), false)
- } else {
- if get != nil {
- o.putStr("get", get, false)
- } else {
- o.putStr("get", _undefined, false)
- }
- if set != nil {
- o.putStr("set", set, false)
- } else {
- o.putStr("set", _undefined, false)
- }
- }
- o.putStr("enumerable", r.toBoolean(enumerable), false)
- o.putStr("configurable", r.toBoolean(configurable), false)
- return ret
- }
- func (r *Runtime) object_getOwnPropertyNames(call FunctionCall) Value {
- // ES6
- obj := call.Argument(0).ToObject(r)
- // obj := r.toObject(call.Argument(0))
- var values []Value
- for item, f := obj.self.enumerate(true, false)(); f != nil; item, f = f() {
- values = append(values, newStringValue(item.name))
- }
- return r.newArrayValues(values)
- }
- func (r *Runtime) toPropertyDescr(v Value) (ret propertyDescr) {
- if o, ok := v.(*Object); ok {
- descr := o.self
- ret.Value = descr.getStr("value")
- if p := descr.getStr("writable"); p != nil {
- ret.Writable = ToFlag(p.ToBoolean())
- }
- if p := descr.getStr("enumerable"); p != nil {
- ret.Enumerable = ToFlag(p.ToBoolean())
- }
- if p := descr.getStr("configurable"); p != nil {
- ret.Configurable = ToFlag(p.ToBoolean())
- }
- ret.Getter = descr.getStr("get")
- ret.Setter = descr.getStr("set")
- if ret.Getter != nil && ret.Getter != _undefined {
- if _, ok := r.toObject(ret.Getter).self.assertCallable(); !ok {
- r.typeErrorResult(true, "getter must be a function")
- }
- }
- if ret.Setter != nil && ret.Setter != _undefined {
- if _, ok := r.toObject(ret.Setter).self.assertCallable(); !ok {
- r.typeErrorResult(true, "setter must be a function")
- }
- }
- if (ret.Getter != nil || ret.Setter != nil) && (ret.Value != nil || ret.Writable != FLAG_NOT_SET) {
- r.typeErrorResult(true, "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute")
- return
- }
- } else {
- r.typeErrorResult(true, "Property description must be an object: %s", v.String())
- }
- return
- }
- func (r *Runtime) _defineProperties(o *Object, p Value) {
- type propItem struct {
- name string
- prop propertyDescr
- }
- props := p.ToObject(r)
- var list []propItem
- for item, f := props.self.enumerate(false, false)(); f != nil; item, f = f() {
- list = append(list, propItem{
- name: item.name,
- prop: r.toPropertyDescr(props.self.getStr(item.name)),
- })
- }
- for _, prop := range list {
- o.self.defineOwnProperty(newStringValue(prop.name), prop.prop, true)
- }
- }
- func (r *Runtime) object_create(call FunctionCall) Value {
- var proto *Object
- if arg := call.Argument(0); arg != _null {
- if o, ok := arg.(*Object); ok {
- proto = o
- } else {
- r.typeErrorResult(true, "Object prototype may only be an Object or null: %s", arg.String())
- }
- }
- o := r.newBaseObject(proto, classObject).val
- if props := call.Argument(1); props != _undefined {
- r._defineProperties(o, props)
- }
- return o
- }
- func (r *Runtime) object_defineProperty(call FunctionCall) (ret Value) {
- if obj, ok := call.Argument(0).(*Object); ok {
- descr := r.toPropertyDescr(call.Argument(2))
- obj.self.defineOwnProperty(call.Argument(1), descr, true)
- ret = call.Argument(0)
- } else {
- r.typeErrorResult(true, "Object.defineProperty called on non-object")
- }
- return
- }
- func (r *Runtime) object_defineProperties(call FunctionCall) Value {
- obj := r.toObject(call.Argument(0))
- r._defineProperties(obj, call.Argument(1))
- return obj
- }
- func (r *Runtime) object_seal(call FunctionCall) Value {
- // ES6
- arg := call.Argument(0)
- if obj, ok := arg.(*Object); ok {
- descr := propertyDescr{
- Writable: FLAG_TRUE,
- Enumerable: FLAG_TRUE,
- Configurable: FLAG_FALSE,
- }
- for item, f := obj.self.enumerate(true, false)(); f != nil; item, f = f() {
- v := obj.self.getOwnProp(item.name)
- if prop, ok := v.(*valueProperty); ok {
- if !prop.configurable {
- continue
- }
- prop.configurable = false
- } else {
- descr.Value = v
- obj.self.defineOwnProperty(newStringValue(item.name), descr, true)
- //obj.self._putProp(item.name, v, true, true, false)
- }
- }
- obj.self.preventExtensions()
- return obj
- }
- return arg
- }
- func (r *Runtime) object_freeze(call FunctionCall) Value {
- arg := call.Argument(0)
- if obj, ok := arg.(*Object); ok {
- descr := propertyDescr{
- Writable: FLAG_FALSE,
- Enumerable: FLAG_TRUE,
- Configurable: FLAG_FALSE,
- }
- for item, f := obj.self.enumerate(true, false)(); f != nil; item, f = f() {
- v := obj.self.getOwnProp(item.name)
- if prop, ok := v.(*valueProperty); ok {
- prop.configurable = false
- if prop.value != nil {
- prop.writable = false
- }
- } else {
- descr.Value = v
- obj.self.defineOwnProperty(newStringValue(item.name), descr, true)
- }
- }
- obj.self.preventExtensions()
- return obj
- } else {
- // ES6 behavior
- return arg
- }
- }
- func (r *Runtime) object_preventExtensions(call FunctionCall) (ret Value) {
- arg := call.Argument(0)
- if obj, ok := arg.(*Object); ok {
- obj.self.preventExtensions()
- return obj
- }
- // ES6
- //r.typeErrorResult(true, "Object.preventExtensions called on non-object")
- //panic("Unreachable")
- return arg
- }
- func (r *Runtime) object_isSealed(call FunctionCall) Value {
- if obj, ok := call.Argument(0).(*Object); ok {
- if obj.self.isExtensible() {
- return valueFalse
- }
- for item, f := obj.self.enumerate(true, false)(); f != nil; item, f = f() {
- prop := obj.self.getOwnProp(item.name)
- if prop, ok := prop.(*valueProperty); ok {
- if prop.configurable {
- return valueFalse
- }
- } else {
- return valueFalse
- }
- }
- } else {
- // ES6
- //r.typeErrorResult(true, "Object.isSealed called on non-object")
- return valueTrue
- }
- return valueTrue
- }
- func (r *Runtime) object_isFrozen(call FunctionCall) Value {
- if obj, ok := call.Argument(0).(*Object); ok {
- if obj.self.isExtensible() {
- return valueFalse
- }
- for item, f := obj.self.enumerate(true, false)(); f != nil; item, f = f() {
- prop := obj.self.getOwnProp(item.name)
- if prop, ok := prop.(*valueProperty); ok {
- if prop.configurable || prop.value != nil && prop.writable {
- return valueFalse
- }
- } else {
- return valueFalse
- }
- }
- } else {
- // ES6
- //r.typeErrorResult(true, "Object.isFrozen called on non-object")
- return valueTrue
- }
- return valueTrue
- }
- func (r *Runtime) object_isExtensible(call FunctionCall) Value {
- if obj, ok := call.Argument(0).(*Object); ok {
- if obj.self.isExtensible() {
- return valueTrue
- }
- return valueFalse
- } else {
- // ES6
- //r.typeErrorResult(true, "Object.isExtensible called on non-object")
- return valueFalse
- }
- }
- func (r *Runtime) object_keys(call FunctionCall) Value {
- // ES6
- obj := call.Argument(0).ToObject(r)
- //if obj, ok := call.Argument(0).(*valueObject); ok {
- var keys []Value
- for item, f := obj.self.enumerate(false, false)(); f != nil; item, f = f() {
- keys = append(keys, newStringValue(item.name))
- }
- return r.newArrayValues(keys)
- //} else {
- // r.typeErrorResult(true, "Object.keys called on non-object")
- //}
- //return nil
- }
- func (r *Runtime) objectproto_hasOwnProperty(call FunctionCall) Value {
- p := call.Argument(0).String()
- o := call.This.ToObject(r)
- if o.self.hasOwnPropertyStr(p) {
- return valueTrue
- } else {
- return valueFalse
- }
- }
- func (r *Runtime) objectproto_isPrototypeOf(call FunctionCall) Value {
- if v, ok := call.Argument(0).(*Object); ok {
- o := call.This.ToObject(r)
- for {
- v = v.self.proto()
- if v == nil {
- break
- }
- if v == o {
- return valueTrue
- }
- }
- }
- return valueFalse
- }
- func (r *Runtime) objectproto_propertyIsEnumerable(call FunctionCall) Value {
- p := call.Argument(0).ToString()
- o := call.This.ToObject(r)
- pv := o.self.getOwnProp(p.String())
- if pv == nil {
- return valueFalse
- }
- if prop, ok := pv.(*valueProperty); ok {
- if !prop.enumerable {
- return valueFalse
- }
- }
- return valueTrue
- }
- func (r *Runtime) objectproto_toString(call FunctionCall) Value {
- switch o := call.This.(type) {
- case valueNull:
- return stringObjectNull
- case valueUndefined:
- return stringObjectUndefined
- case *Object:
- return newStringValue(fmt.Sprintf("[object %s]", o.self.className()))
- default:
- obj := call.This.ToObject(r)
- return newStringValue(fmt.Sprintf("[object %s]", obj.self.className()))
- }
- }
- func (r *Runtime) objectproto_toLocaleString(call FunctionCall) Value {
- return call.This.ToObject(r).ToString()
- }
- func (r *Runtime) objectproto_valueOf(call FunctionCall) Value {
- return call.This.ToObject(r)
- }
- func (r *Runtime) initObject() {
- o := r.global.ObjectPrototype.self
- o._putProp("toString", r.newNativeFunc(r.objectproto_toString, nil, "toString", nil, 0), true, false, true)
- o._putProp("toLocaleString", r.newNativeFunc(r.objectproto_toLocaleString, nil, "toLocaleString", nil, 0), true, false, true)
- o._putProp("valueOf", r.newNativeFunc(r.objectproto_valueOf, nil, "valueOf", nil, 0), true, false, true)
- o._putProp("hasOwnProperty", r.newNativeFunc(r.objectproto_hasOwnProperty, nil, "hasOwnProperty", nil, 1), true, false, true)
- o._putProp("isPrototypeOf", r.newNativeFunc(r.objectproto_isPrototypeOf, nil, "isPrototypeOf", nil, 1), true, false, true)
- o._putProp("propertyIsEnumerable", r.newNativeFunc(r.objectproto_propertyIsEnumerable, nil, "propertyIsEnumerable", nil, 1), true, false, true)
- r.global.Object = r.newNativeFuncConstruct(r.builtin_Object, classObject, r.global.ObjectPrototype, 1)
- o = r.global.Object.self
- o._putProp("defineProperty", r.newNativeFunc(r.object_defineProperty, nil, "defineProperty", nil, 3), true, false, true)
- o._putProp("defineProperties", r.newNativeFunc(r.object_defineProperties, nil, "defineProperties", nil, 2), true, false, true)
- o._putProp("getOwnPropertyDescriptor", r.newNativeFunc(r.object_getOwnPropertyDescriptor, nil, "getOwnPropertyDescriptor", nil, 2), true, false, true)
- o._putProp("getPrototypeOf", r.newNativeFunc(r.object_getPrototypeOf, nil, "getPrototypeOf", nil, 1), true, false, true)
- o._putProp("getOwnPropertyNames", r.newNativeFunc(r.object_getOwnPropertyNames, nil, "getOwnPropertyNames", nil, 1), true, false, true)
- o._putProp("create", r.newNativeFunc(r.object_create, nil, "create", nil, 2), true, false, true)
- o._putProp("seal", r.newNativeFunc(r.object_seal, nil, "seal", nil, 1), true, false, true)
- o._putProp("freeze", r.newNativeFunc(r.object_freeze, nil, "freeze", nil, 1), true, false, true)
- o._putProp("preventExtensions", r.newNativeFunc(r.object_preventExtensions, nil, "preventExtensions", nil, 1), true, false, true)
- o._putProp("isSealed", r.newNativeFunc(r.object_isSealed, nil, "isSealed", nil, 1), true, false, true)
- o._putProp("isFrozen", r.newNativeFunc(r.object_isFrozen, nil, "isFrozen", nil, 1), true, false, true)
- o._putProp("isExtensible", r.newNativeFunc(r.object_isExtensible, nil, "isExtensible", nil, 1), true, false, true)
- o._putProp("keys", r.newNativeFunc(r.object_keys, nil, "keys", nil, 1), true, false, true)
- r.addToGlobal("Object", r.global.Object)
- }
|