Пример #1
0
func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
	if typ.Kind() != Func {
		panic("reflect: call of MakeFunc with non-Func type")
	}

	t := typ.common()
	ftyp := (*funcType)(unsafe.Pointer(t))

	fv := func() js.Object {
		args := make([]Value, ftyp.NumIn())
		for i := range args {
			argType := ftyp.In(i).common()
			args[i] = makeValue(argType, js.Arguments[i], 0)
		}
		resultsSlice := fn(args)
		switch ftyp.NumOut() {
		case 0:
			return nil
		case 1:
			return js.InternalObject(resultsSlice[0].iword())
		default:
			results := js.Global.Get("Array").New(ftyp.NumOut())
			for i, r := range resultsSlice {
				results.SetIndex(i, js.InternalObject(r.iword()))
			}
			return results
		}
	}

	return Value{t, unsafe.Pointer(js.InternalObject(fv).Unsafe()), 0, flag(Func) << flagKindShift}
}
Пример #2
0
func (v Value) Slice3(i, j, k int) Value {
	var (
		cap int
		typ Type
		s   js.Object
	)
	switch kind := v.kind(); kind {
	case Array:
		if v.flag&flagAddr == 0 {
			panic("reflect.Value.Slice: slice of unaddressable array")
		}
		tt := (*arrayType)(unsafe.Pointer(v.typ))
		cap = int(tt.len)
		typ = SliceOf(tt.elem)
		s = jsType(typ).New(js.InternalObject(v.iword()))

	case Slice:
		typ = v.typ
		s = js.InternalObject(v.iword())
		cap = s.Get("$capacity").Int()

	default:
		panic(&ValueError{"reflect.Value.Slice3", kind})
	}

	if i < 0 || j < i || k < j || k > cap {
		panic("reflect.Value.Slice3: slice index out of bounds")
	}

	return makeValue(typ, js.Global.Call("$subslice", s, i, j, k), v.flag&flagRO)
}
Пример #3
0
func (v Value) object() *js.Object {
	if v.typ.Kind() == Array || v.typ.Kind() == Struct {
		return js.InternalObject(v.ptr)
	}
	if v.flag&flagIndir != 0 {
		val := js.InternalObject(v.ptr).Call("$get")
		if val != js.Global.Get("$ifaceNil") && val.Get("constructor") != jsType(v.typ) {
			switch v.typ.Kind() {
			case Uint64, Int64:
				val = jsType(v.typ).New(val.Get("$high"), val.Get("$low"))
			case Complex64, Complex128:
				val = jsType(v.typ).New(val.Get("$real"), val.Get("$imag"))
			case Slice:
				if val == val.Get("constructor").Get("nil") {
					val = jsType(v.typ).Get("nil")
					break
				}
				newVal := jsType(v.typ).New(val.Get("$array"))
				newVal.Set("$offset", val.Get("$offset"))
				newVal.Set("$length", val.Get("$length"))
				newVal.Set("$capacity", val.Get("$capacity"))
				val = newVal
			}
		}
		return js.InternalObject(val.Unsafe())
	}
	return js.InternalObject(v.ptr)
}
Пример #4
0
func (r *rngReader) Read(b []byte) (n int, err error) {
	array := js.InternalObject(b).Get("$array")
	offset := js.InternalObject(b).Get("$offset").Int()

	// browser
	crypto := js.Global.Get("crypto")
	if crypto == js.Undefined {
		crypto = js.Global.Get("msCrypto")
	}
	if crypto != js.Undefined {
		if crypto.Get("getRandomValues") != js.Undefined {
			n = len(b)
			if n > 65536 {
				// Avoid QuotaExceededError thrown by getRandomValues
				// when length is more than 65536, as specified in
				// http://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
				n = 65536
			}
			crypto.Call("getRandomValues", array.Call("subarray", offset, offset+n))
			return n, nil
		}
	}

	// Node.js
	if require := js.Global.Get("require"); require != js.Undefined {
		if randomBytes := require.Invoke("crypto").Get("randomBytes"); randomBytes != js.Undefined {
			array.Call("set", randomBytes.Invoke(len(b)), offset)
			return len(b), nil
		}
	}

	return 0, errors.New("crypto/rand not available in this environment")
}
Пример #5
0
func Copy(dst, src Value) int {
	dk := dst.kind()
	if dk != Array && dk != Slice {
		panic(&ValueError{"reflect.Copy", dk})
	}
	if dk == Array {
		dst.mustBeAssignable()
	}
	dst.mustBeExported()

	sk := src.kind()
	if sk != Array && sk != Slice {
		panic(&ValueError{"reflect.Copy", sk})
	}
	src.mustBeExported()

	typesMustMatch("reflect.Copy", dst.typ.Elem(), src.typ.Elem())

	dstVal := js.InternalObject(dst.iword())
	if dk == Array {
		dstVal = jsType(SliceOf(dst.typ.Elem())).New(dstVal)
	}

	srcVal := js.InternalObject(src.iword())
	if sk == Array {
		srcVal = jsType(SliceOf(src.typ.Elem())).New(srcVal)
	}

	return js.Global.Call("$copySlice", dstVal, srcVal).Int()
}
Пример #6
0
func zeroVal(typ Type) js.Object {
	switch typ.Kind() {
	case Bool:
		return js.InternalObject(false)
	case Int, Int8, Int16, Int32, Uint, Uint8, Uint16, Uint32, Uintptr, Float32, Float64:
		return js.InternalObject(0)
	case Int64, Uint64, Complex64, Complex128:
		return jsType(typ).New(0, 0)
	case Array:
		elemType := typ.Elem()
		return js.Global.Call("go$makeNativeArray", jsType(elemType).Get("kind"), typ.Len(), func() js.Object { return zeroVal(elemType) })
	case Func:
		return js.Global.Get("go$throwNilPointerError")
	case Interface:
		return nil
	case Map:
		return js.InternalObject(false)
	case Chan, Ptr, Slice:
		return jsType(typ).Get("nil")
	case String:
		return js.InternalObject("")
	case Struct:
		return jsType(typ).Get("Ptr").New()
	default:
		panic(&ValueError{"reflect.Zero", typ.Kind()})
	}
}
Пример #7
0
func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer) {
	k := js.InternalObject(key).Call("$get")
	if !k.Get("$key").IsUndefined() {
		k = k.Call("$key")
	}
	js.InternalObject(m).Delete(k.Str())
}
Пример #8
0
func mapaccess(t *rtype, m, key unsafe.Pointer) unsafe.Pointer {
	k := jsType(t.Key()).Call("keyFor", js.InternalObject(key).Call("$get")).String()
	entry := js.InternalObject(m).Get(k)
	if entry == js.Undefined {
		return nil
	}
	return unsafe.Pointer(js.Global.Call("$newDataPointer", entry.Get("v"), jsType(PtrTo(t.Elem()))).Unsafe())
}
Пример #9
0
func Main2(pkgPath string, dir string, names []string, tests []func(*T)) {
	flag.Parse()
	if len(tests) == 0 {
		fmt.Println("testing: warning: no tests to run")
	}

	d, err := os.Open(dir)
	if err != nil {
		panic(err)
	}
	d.Chdir()

	ok := true
	start := time.Now()
	for i := 0; i < len(tests); i++ {
		t := &T{
			common: common{
				start: time.Now(),
			},
			name: names[i],
		}
		t.self = t
		if *chatty {
			fmt.Printf("=== RUN %s\n", t.name)
		}
		err := runTest.Invoke(js.InternalObject(tests[i]), js.InternalObject(t))
		js.Global.Set("$jsErr", nil)
		if err != nil {
			switch {
			case !err.Get("$exit").IsUndefined():
				// test failed or skipped
				err = nil
			case !err.Get("$notSupported").IsUndefined():
				t.log(err.Get("message").Str())
				t.skip()
				err = nil
			default:
				t.Fail()
			}
		}
		t.common.duration = time.Now().Sub(t.common.start)
		t.report()
		if err != nil {
			throw.Invoke(js.InternalObject(err))
		}
		ok = ok && !t.common.failed
	}
	duration := time.Now().Sub(start)

	status := "ok  "
	exitCode := 0
	if !ok {
		status = "FAIL"
		exitCode = 1
	}
	fmt.Printf("%s\t%s\t%.3fs\n", status, pkgPath, duration.Seconds())
	os.Exit(exitCode)
}
Пример #10
0
func (v *Value) Store(x interface{}) {
	if x == nil {
		panic("sync/atomic: store of nil value into Value")
	}
	if v.v != nil && js.InternalObject(x).Get("constructor") != js.InternalObject(v.v).Get("constructor") {
		panic("sync/atomic: store of inconsistently typed value into Value")
	}
	v.v = x
}
Пример #11
0
func ValueOf(i interface{}) Value {
	if i == nil {
		return Value{}
	}
	c := js.InternalObject(i).Get("constructor")
	if c.Get("kind").IsUndefined() { // js.Object
		return Value{jsObject(), nil, js.InternalObject(i).Unsafe(), flag(Interface) << flagKindShift}
	}
	return makeValue(reflectType(c), js.InternalObject(i).Get("$val"), 0)
}
Пример #12
0
func mapaccess(t *rtype, m, key unsafe.Pointer) unsafe.Pointer {
	k := js.InternalObject(key)
	if !k.Get("$key").IsUndefined() {
		k = k.Call("$key")
	}
	entry := js.InternalObject(m).Get(k.Str())
	if entry.IsUndefined() {
		return nil
	}
	return makePointer(t.Elem(), entry.Get("v"))
}
Пример #13
0
func mapaccess(t *rtype, m, key unsafe.Pointer) unsafe.Pointer {
	k := js.InternalObject(key).Call("$get")
	if !k.Get("$key").IsUndefined() {
		k = k.Call("$key")
	}
	entry := js.InternalObject(m).Get(k.Str())
	if entry.IsUndefined() {
		return nil
	}
	return unsafe.Pointer(js.Global.Call("$newDataPointer", entry.Get("v"), jsType(PtrTo(t.Elem()))).Unsafe())
}
Пример #14
0
func mapaccess(t *rtype, m iword, key iword) (val iword, ok bool) {
	k := js.InternalObject(key)
	if !k.Get("go$key").IsUndefined() {
		k = k.Call("go$key")
	}
	entry := js.InternalObject(m).Get(k.Str())
	if entry.IsUndefined() {
		return nil, false
	}
	return makeIword(t.Elem(), entry.Get("v")), true
}
Пример #15
0
func chansend(t *rtype, ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool {
	comms := [][]interface{}{{js.InternalObject(ch), js.InternalObject(val).Call("$get")}}
	if nb {
		comms = append(comms, []interface{}{})
	}
	selectRes := selectHelper(comms)
	if nb && selectRes.Index(0).Int() == 1 {
		return false
	}
	return true
}
Пример #16
0
func makeMethodValue(op string, v Value) Value {
	if v.flag&flagMethod == 0 {
		panic("reflect: internal error: invalid use of makePartialFunc")
	}

	_, fn, rcvr := methodReceiver(op, v, int(v.flag)>>flagMethodShift)
	fv := func() js.Object {
		return js.InternalObject(fn).Call("apply", rcvr, js.Arguments)
	}
	return Value{v.Type().common(), unsafe.Pointer(js.InternalObject(fv).Unsafe()), v.flag&flagRO | flag(Func)<<flagKindShift}
}
Пример #17
0
func DeepEqual(a1, a2 interface{}) bool {
	i1 := js.InternalObject(a1)
	i2 := js.InternalObject(a2)
	if i1 == i2 {
		return true
	}
	if i1 == nil || i2 == nil || i1.Get("constructor") != i2.Get("constructor") {
		return false
	}
	return deepValueEqualJs(ValueOf(a1), ValueOf(a2), nil)
}
Пример #18
0
func (v Value) Len() int {
	switch k := v.kind(); k {
	case Array, Slice, String:
		return js.InternalObject(v.iword()).Length()
	// case Chan:
	// 	return chanlen(v.iword())
	case Map:
		return js.Global.Call("$keys", js.InternalObject(v.iword())).Length()
	default:
		panic(&ValueError{"reflect.Value.Len", k})
	}
}
Пример #19
0
func (v Value) Index(i int) Value {
	switch k := v.kind(); k {
	case Array:
		tt := (*arrayType)(unsafe.Pointer(v.typ))
		if i < 0 || i > int(tt.len) {
			panic("reflect: array index out of range")
		}
		typ := tt.elem
		fl := v.flag & (flagRO | flagIndir | flagAddr)
		fl |= flag(typ.Kind())

		a := js.InternalObject(v.ptr)
		if fl&flagIndir != 0 && typ.Kind() != Array && typ.Kind() != Struct {
			return Value{typ, unsafe.Pointer(jsType(PtrTo(typ)).New(
				js.InternalObject(func() *js.Object { return wrapJsObject(typ, a.Index(i)) }),
				js.InternalObject(func(x *js.Object) { a.SetIndex(i, unwrapJsObject(typ, x)) }),
			).Unsafe()), fl}
		}
		return makeValue(typ, wrapJsObject(typ, a.Index(i)), fl)

	case Slice:
		s := v.object()
		if i < 0 || i >= s.Get("$length").Int() {
			panic("reflect: slice index out of range")
		}
		tt := (*sliceType)(unsafe.Pointer(v.typ))
		typ := tt.elem
		fl := flagAddr | flagIndir | v.flag&flagRO
		fl |= flag(typ.Kind())

		i += s.Get("$offset").Int()
		a := s.Get("$array")
		if fl&flagIndir != 0 && typ.Kind() != Array && typ.Kind() != Struct {
			return Value{typ, unsafe.Pointer(jsType(PtrTo(typ)).New(
				js.InternalObject(func() *js.Object { return wrapJsObject(typ, a.Index(i)) }),
				js.InternalObject(func(x *js.Object) { a.SetIndex(i, unwrapJsObject(typ, x)) }),
			).Unsafe()), fl}
		}
		return makeValue(typ, wrapJsObject(typ, a.Index(i)), fl)

	case String:
		str := *(*string)(v.ptr)
		if i < 0 || i >= len(str) {
			panic("reflect: string index out of range")
		}
		fl := v.flag&flagRO | flag(Uint8)
		c := str[i]
		return Value{uint8Type, unsafe.Pointer(&c), fl | flagIndir}

	default:
		panic(&ValueError{"reflect.Value.Index", k})
	}
}
Пример #20
0
func chanrecv(t *rtype, ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool) {
	comms := [][]interface{}{{js.InternalObject(ch)}}
	if nb {
		comms = append(comms, []interface{}{})
	}
	selectRes := selectHelper(comms)
	if nb && selectRes.Index(0).Int() == 1 {
		return false, false
	}
	recvRes := selectRes.Index(1)
	js.InternalObject(val).Call("$set", recvRes.Index(0))
	return true, recvRes.Index(1).Bool()
}
Пример #21
0
func (v Value) SetCap(n int) {
	v.mustBeAssignable()
	v.mustBe(Slice)
	s := js.InternalObject(v.val).Call("go$get")
	if n < s.Length() || n > s.Get("capacity").Int() {
		panic("reflect: slice capacity out of range in SetCap")
	}
	newSlice := jsType(v.typ).New(s.Get("array"))
	newSlice.Set("offset", s.Get("offset"))
	newSlice.Set("length", s.Get("length"))
	newSlice.Set("capacity", n)
	js.InternalObject(v.val).Call("go$set", newSlice)
}
Пример #22
0
func (v Value) SetLen(n int) {
	v.mustBeAssignable()
	v.mustBe(Slice)
	s := js.InternalObject(v.ptr).Call("$get")
	if n < 0 || n > s.Get("$capacity").Int() {
		panic("reflect: slice length out of range in SetLen")
	}
	newSlice := jsType(v.typ).New(s.Get("$array"))
	newSlice.Set("$offset", s.Get("$offset"))
	newSlice.Set("$length", n)
	newSlice.Set("$capacity", s.Get("$capacity"))
	js.InternalObject(v.ptr).Call("$set", newSlice)
}
Пример #23
0
// MarshalIndentString is like MarshalIndent, but outputs a string
func MarshalIndentString(v interface{}, prefix, indent string) (json string, err error) {
	defer func() {
		if e := recover(); e != nil {
			if er, ok := e.(*js.Error); ok {
				err = er
			}
		}
	}()
	str := js.Global.Get("JSON").Call("stringify", js.InternalObject(toObject).Invoke(js.InternalObject(v)), nil, indent)
	if len(prefix) > 0 {
		str = str.Call("replace", "\n", "\n"+prefix)
	}
	return str.String(), nil
}
Пример #24
0
func mapassign(t *rtype, m, key, val unsafe.Pointer) {
	kv, k := keyFor(t, key)
	jsVal := js.InternalObject(val).Call("$get")
	et := t.Elem()
	if et.Kind() == Struct {
		newVal := jsType(et).Call("zero")
		copyStruct(newVal, jsVal, et)
		jsVal = newVal
	}
	entry := js.Global.Get("Object").New()
	entry.Set("k", kv)
	entry.Set("v", jsVal)
	js.InternalObject(m).Set(k, entry)
}
Пример #25
0
func rselect(rselects []runtimeSelect) (chosen int, recvOK bool) {
	comms := make([][]*js.Object, len(rselects))
	for i, s := range rselects {
		switch SelectDir(s.dir) {
		case SelectDefault:
			comms[i] = []*js.Object{}
		case SelectRecv:
			ch := js.Global.Get("$chanNil")
			if js.InternalObject(s.ch) != js.InternalObject(0) {
				ch = js.InternalObject(s.ch)
			}
			comms[i] = []*js.Object{ch}
		case SelectSend:
			ch := js.Global.Get("$chanNil")
			var val *js.Object
			if js.InternalObject(s.ch) != js.InternalObject(0) {
				ch = js.InternalObject(s.ch)
				val = js.InternalObject(s.val).Call("$get")
			}
			comms[i] = []*js.Object{ch, val}
		}
	}
	selectRes := selectHelper(comms)
	c := selectRes.Index(0).Int()
	if SelectDir(rselects[c].dir) == SelectRecv {
		recvRes := selectRes.Index(1)
		js.InternalObject(rselects[c].val).Call("$set", recvRes.Index(0))
		return c, recvRes.Index(1).Bool()
	}
	return c, false
}
Пример #26
0
func (v Value) Len() int {
	switch k := v.kind(); k {
	case Array, String:
		return js.InternalObject(v.iword()).Length()
	case Slice:
		return js.InternalObject(v.iword()).Get("$length").Int()
	case Chan:
		return js.InternalObject(v.iword()).Get("$buffer").Get("length").Int()
	case Map:
		return js.Global.Call("$keys", js.InternalObject(v.iword())).Length()
	default:
		panic(&ValueError{"reflect.Value.Len", k})
	}
}
Пример #27
0
func (v Value) IsNil() bool {
	switch k := v.kind(); k {
	case Chan, Ptr, Slice:
		return v.iword() == iword(jsType(v.typ).Get("nil").Unsafe())
	case Func:
		return v.iword() == iword(js.Global.Get("$throwNilPointerError").Unsafe())
	case Map:
		return v.iword() == iword(js.InternalObject(false).Unsafe())
	case Interface:
		return js.InternalObject(v.iword()).IsNull()
	default:
		panic(&ValueError{"reflect.Value.IsNil", k})
	}
}
Пример #28
0
func (v Value) Field(i int) Value {
	if v.kind() != Struct {
		panic(&ValueError{"reflect.Value.Field", v.kind()})
	}
	tt := (*structType)(unsafe.Pointer(v.typ))
	if uint(i) >= uint(len(tt.fields)) {
		panic("reflect: Field index out of range")
	}

	prop := jsType(v.typ).Get("fields").Index(i).Get("prop").String()
	field := &tt.fields[i]
	typ := field.typ

	fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
	if !field.name.isExported() {
		if field.name.name() == "" {
			fl |= flagEmbedRO
		} else {
			fl |= flagStickyRO
		}
	}

	if tag := tt.fields[i].name.tag(); tag != "" && i != 0 {
		if jsTag := getJsTag(tag); jsTag != "" {
			for {
				v = v.Field(0)
				if v.typ == jsObjectPtr {
					o := v.object().Get("object")
					return Value{typ, unsafe.Pointer(jsType(PtrTo(typ)).New(
						js.InternalObject(func() *js.Object { return js.Global.Call("$internalize", o.Get(jsTag), jsType(typ)) }),
						js.InternalObject(func(x *js.Object) { o.Set(jsTag, js.Global.Call("$externalize", x, jsType(typ))) }),
					).Unsafe()), fl}
				}
				if v.typ.Kind() == Ptr {
					v = v.Elem()
				}
			}
		}
	}

	s := js.InternalObject(v.ptr)
	if fl&flagIndir != 0 && typ.Kind() != Array && typ.Kind() != Struct {
		return Value{typ, unsafe.Pointer(jsType(PtrTo(typ)).New(
			js.InternalObject(func() *js.Object { return wrapJsObject(typ, s.Get(prop)) }),
			js.InternalObject(func(x *js.Object) { s.Set(prop, unwrapJsObject(typ, x)) }),
		).Unsafe()), fl}
	}
	return makeValue(typ, wrapJsObject(typ, s.Get(prop)), fl)
}
Пример #29
0
func makeMethodValue(op string, v Value) Value {
	if v.flag&flagMethod == 0 {
		panic("reflect: internal error: invalid use of makePartialFunc")
	}

	_, _, fn := methodReceiver(op, v, int(v.flag)>>flagMethodShift)
	rcvr := v.object()
	if isWrapped(v.typ) {
		rcvr = jsType(v.typ).New(rcvr)
	}
	fv := js.Global.Call("$makeFunc", js.InternalObject(func(arguments []*js.Object) *js.Object {
		return js.InternalObject(fn).Call("apply", rcvr, arguments)
	}))
	return Value{v.Type().common(), unsafe.Pointer(fv.Unsafe()), v.flag&flagRO | flag(Func)}
}
Пример #30
0
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
	if f := syscall("Syscall"); f != nil {
		r := f.Invoke(trap, a1, a2, a3)
		return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
	}
	if trap == SYS_WRITE && (a1 == 1 || a1 == 2) {
		array := js.InternalObject(a2)
		slice := make([]byte, array.Length())
		js.InternalObject(slice).Set("$array", array)
		printToConsole(slice)
		return uintptr(array.Length()), 0, 0
	}
	printWarning()
	return uintptr(minusOne), 0, EACCES
}