Browse Source

Exposed Symbol

Dmitry Panov 4 years ago
parent
commit
6060b0671c
23 changed files with 280 additions and 162 deletions
  1. 8 8
      builtin_array.go
  2. 1 1
      builtin_date.go
  3. 1 1
      builtin_function.go
  4. 1 1
      builtin_json.go
  5. 4 4
      builtin_map.go
  6. 1 1
      builtin_math.go
  7. 1 1
      builtin_object.go
  8. 3 3
      builtin_proxy.go
  9. 5 5
      builtin_regexp.go
  10. 4 4
      builtin_set.go
  11. 10 10
      builtin_string.go
  12. 33 33
      builtin_symbol.go
  13. 7 7
      builtin_typedarrays.go
  14. 1 1
      builtin_weakmap.go
  15. 1 1
      builtin_weakset.go
  16. 2 2
      map_test.go
  17. 29 29
      object.go
  18. 9 9
      object_lazy.go
  19. 12 12
      proxy.go
  20. 6 6
      runtime.go
  21. 49 0
      runtime_test.go
  22. 90 21
      value.go
  23. 2 2
      vm.go

+ 8 - 8
builtin_array.go

@@ -38,7 +38,7 @@ func arraySpeciesCreate(obj *Object, size int64) *Object {
 	if isArray(obj) {
 		v := obj.self.getStr("constructor", nil)
 		if constructObj, ok := v.(*Object); ok {
-			v = constructObj.self.getSym(symSpecies, nil)
+			v = constructObj.self.getSym(SymSpecies, nil)
 			if v == _null {
 				v = nil
 			}
@@ -256,7 +256,7 @@ func (r *Runtime) arrayproto_toLocaleString(call FunctionCall) Value {
 }
 
 func isConcatSpreadable(obj *Object) bool {
-	spreadable := obj.self.getSym(symIsConcatSpreadable, nil)
+	spreadable := obj.self.getSym(SymIsConcatSpreadable, nil)
 	if spreadable != nil && spreadable != _undefined {
 		return spreadable.ToBoolean()
 	}
@@ -1045,7 +1045,7 @@ func (r *Runtime) checkStdArray(v Value) *arrayObject {
 
 func (r *Runtime) checkStdArrayIter(v Value) *arrayObject {
 	if arr := r.checkStdArray(v); arr != nil &&
-		arr.getSym(symIterator, nil) == r.global.arrayValues {
+		arr.getSym(SymIterator, nil) == r.global.arrayValues {
 
 		return arr
 	}
@@ -1084,7 +1084,7 @@ func (r *Runtime) array_from(call FunctionCall) Value {
 		}
 	}
 	var arr *Object
-	if usingIterator := toMethod(r.getV(items, symIterator)); usingIterator != nil {
+	if usingIterator := toMethod(r.getV(items, SymIterator)); usingIterator != nil {
 		if ctor != nil {
 			arr = ctor([]Value{}, nil)
 		} else {
@@ -1228,7 +1228,7 @@ func (r *Runtime) createArrayProto(val *Object) objectImpl {
 	r.global.arrayValues = valuesFunc
 	o._putProp("values", valuesFunc, true, false, true)
 
-	o._putSym(symIterator, valueProp(valuesFunc, true, false, true))
+	o._putSym(SymIterator, valueProp(valuesFunc, true, false, true))
 
 	bl := r.newBaseObject(nil, classObject)
 	bl.setOwnStr("copyWithin", valueTrue, true)
@@ -1239,7 +1239,7 @@ func (r *Runtime) createArrayProto(val *Object) objectImpl {
 	bl.setOwnStr("includes", valueTrue, true)
 	bl.setOwnStr("keys", valueTrue, true)
 	bl.setOwnStr("values", valueTrue, true)
-	o._putSym(symUnscopables, valueProp(bl.val, false, false, true))
+	o._putSym(SymUnscopables, valueProp(bl.val, false, false, true))
 
 	return o
 }
@@ -1249,7 +1249,7 @@ func (r *Runtime) createArray(val *Object) objectImpl {
 	o._putProp("from", r.newNativeFunc(r.array_from, nil, "from", nil, 1), true, false, true)
 	o._putProp("isArray", r.newNativeFunc(r.array_isArray, nil, "isArray", nil, 1), true, false, true)
 	o._putProp("of", r.newNativeFunc(r.array_of, nil, "of", nil, 0), true, false, true)
-	o._putSym(symSpecies, &valueProperty{
+	o._putSym(SymSpecies, &valueProperty{
 		getterFunc:   r.newNativeFunc(r.returnThis, nil, "get [Symbol.species]", nil, 0),
 		accessor:     true,
 		configurable: true,
@@ -1262,7 +1262,7 @@ func (r *Runtime) createArrayIterProto(val *Object) objectImpl {
 	o := newBaseObjectObj(val, r.global.IteratorPrototype, classObject)
 
 	o._putProp("next", r.newNativeFunc(r.arrayIterProto_next, nil, "next", nil, 0), true, false, true)
-	o._putSym(symToStringTag, valueProp(asciiString(classArrayIterator), false, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classArrayIterator), false, false, true))
 
 	return o
 }

+ 1 - 1
builtin_date.go

@@ -991,7 +991,7 @@ func (r *Runtime) createDateProto(val *Object) objectImpl {
 	o._putProp("toISOString", r.newNativeFunc(r.dateproto_toISOString, nil, "toISOString", nil, 0), true, false, true)
 	o._putProp("toJSON", r.newNativeFunc(r.dateproto_toJSON, nil, "toJSON", nil, 1), true, false, true)
 
-	o._putSym(symToPrimitive, valueProp(r.newNativeFunc(r.dateproto_toPrimitive, nil, "[Symbol.toPrimitive]", nil, 1), false, false, true))
+	o._putSym(SymToPrimitive, valueProp(r.newNativeFunc(r.dateproto_toPrimitive, nil, "[Symbol.toPrimitive]", nil, 1), false, false, true))
 
 	return o
 }

+ 1 - 1
builtin_function.go

@@ -189,7 +189,7 @@ func (r *Runtime) initFunction() {
 	o._putProp("bind", r.newNativeFunc(r.functionproto_bind, nil, "bind", nil, 1), true, false, true)
 	o._putProp("call", r.newNativeFunc(r.functionproto_call, nil, "call", nil, 1), true, false, true)
 	o._putProp("toString", r.newNativeFunc(r.functionproto_toString, nil, "toString", nil, 0), true, false, true)
-	o._putSym(symHasInstance, valueProp(r.newNativeFunc(r.functionproto_hasInstance, nil, "[Symbol.hasInstance]", nil, 1), false, false, false))
+	o._putSym(SymHasInstance, valueProp(r.newNativeFunc(r.functionproto_hasInstance, nil, "[Symbol.hasInstance]", nil, 1), false, false, false))
 
 	r.global.Function = r.newNativeFuncConstruct(r.builtin_Function, "Function", r.global.FunctionPrototype, 1)
 	r.addToGlobal("Function", r.global.Function)

+ 1 - 1
builtin_json.go

@@ -502,7 +502,7 @@ func (r *Runtime) initJSON() {
 	JSON := r.newBaseObject(r.global.ObjectPrototype, "JSON")
 	JSON._putProp("parse", r.newNativeFunc(r.builtinJSON_parse, nil, "parse", nil, 2), true, false, true)
 	JSON._putProp("stringify", r.newNativeFunc(r.builtinJSON_stringify, nil, "stringify", nil, 3), true, false, true)
-	JSON._putSym(symToStringTag, valueProp(asciiString(classJSON), false, false, true))
+	JSON._putSym(SymToStringTag, valueProp(asciiString(classJSON), false, false, true))
 
 	r.addToGlobal("JSON", JSON.val)
 }

+ 4 - 4
builtin_map.go

@@ -235,15 +235,15 @@ func (r *Runtime) createMapProto(val *Object) objectImpl {
 
 	entriesFunc := r.newNativeFunc(r.mapProto_entries, nil, "entries", nil, 0)
 	o._putProp("entries", entriesFunc, true, false, true)
-	o._putSym(symIterator, valueProp(entriesFunc, true, false, true))
-	o._putSym(symToStringTag, valueProp(asciiString(classMap), false, false, true))
+	o._putSym(SymIterator, valueProp(entriesFunc, true, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classMap), false, false, true))
 
 	return o
 }
 
 func (r *Runtime) createMap(val *Object) objectImpl {
 	o := r.newNativeConstructOnly(val, r.builtin_newMap, r.global.MapPrototype, "Map", 0)
-	o._putSym(symSpecies, &valueProperty{
+	o._putSym(SymSpecies, &valueProperty{
 		getterFunc:   r.newNativeFunc(r.returnThis, nil, "get [Symbol.species]", nil, 0),
 		accessor:     true,
 		configurable: true,
@@ -256,7 +256,7 @@ func (r *Runtime) createMapIterProto(val *Object) objectImpl {
 	o := newBaseObjectObj(val, r.global.IteratorPrototype, classObject)
 
 	o._putProp("next", r.newNativeFunc(r.mapIterProto_next, nil, "next", nil, 0), true, false, true)
-	o._putSym(symToStringTag, valueProp(asciiString(classMapIterator), false, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classMapIterator), false, false, true))
 
 	return o
 }

+ 1 - 1
builtin_math.go

@@ -282,7 +282,7 @@ func (r *Runtime) createMath(val *Object) objectImpl {
 	m._putProp("PI", valueFloat(math.Pi), false, false, false)
 	m._putProp("SQRT1_2", valueFloat(sqrt1_2), false, false, false)
 	m._putProp("SQRT2", valueFloat(math.Sqrt2), false, false, false)
-	m._putSym(symToStringTag, valueProp(asciiString(classMath), false, false, true))
+	m._putSym(SymToStringTag, valueProp(asciiString(classMath), false, false, true))
 
 	m._putProp("abs", r.newNativeFunc(r.math_abs, nil, "abs", nil, 1), true, false, true)
 	m._putProp("acos", r.newNativeFunc(r.math_acos, nil, "acos", nil, 1), true, false, true)

+ 1 - 1
builtin_object.go

@@ -410,7 +410,7 @@ func (r *Runtime) objectproto_toString(call FunctionCall) Value {
 		} else {
 			clsName = obj.self.className()
 		}
-		if tag := obj.self.getSym(symToStringTag, nil); tag != nil {
+		if tag := obj.self.getSym(SymToStringTag, nil); tag != nil {
 			if str, ok := tag.(valueString); ok {
 				clsName = str.String()
 			}

+ 3 - 3
builtin_proxy.go

@@ -73,7 +73,7 @@ func (r *Runtime) proxyproto_nativehandler_getOwnPropertyDescriptor(native func(
 			if len(call.Arguments) >= 2 {
 				if t, ok := call.Argument(0).(*Object); ok {
 					switch p := call.Argument(1).(type) {
-					case *valueSymbol:
+					case *Symbol:
 						return _undefined
 					default:
 						desc := native(t, p.String())
@@ -109,7 +109,7 @@ func (r *Runtime) proxyproto_nativehandler_gen_obj_string_bool(name proxyTrap, n
 			if len(call.Arguments) >= 2 {
 				if t, ok := call.Argument(0).(*Object); ok {
 					switch p := call.Argument(1).(type) {
-					case *valueSymbol:
+					case *Symbol:
 						return valueFalse
 					default:
 						o := native(t, p.String())
@@ -129,7 +129,7 @@ func (r *Runtime) proxyproto_nativehandler_get(native func(*Object, string, *Obj
 				if t, ok := call.Argument(0).(*Object); ok {
 					if r, ok := call.Argument(2).(*Object); ok {
 						switch p := call.Argument(1).(type) {
-						case *valueSymbol:
+						case *Symbol:
 							return _undefined
 						default:
 							return native(t, p.String(), r)

+ 5 - 5
builtin_regexp.go

@@ -1144,15 +1144,15 @@ func (r *Runtime) initRegExp() {
 		accessor:     true,
 	}, false)
 
-	o._putSym(symMatch, valueProp(r.newNativeFunc(r.regexpproto_stdMatcher, nil, "[Symbol.match]", nil, 1), true, false, true))
-	o._putSym(symSearch, valueProp(r.newNativeFunc(r.regexpproto_stdSearch, nil, "[Symbol.search]", nil, 1), true, false, true))
-	o._putSym(symSplit, valueProp(r.newNativeFunc(r.regexpproto_stdSplitter, nil, "[Symbol.split]", nil, 2), true, false, true))
-	o._putSym(symReplace, valueProp(r.newNativeFunc(r.regexpproto_stdReplacer, nil, "[Symbol.replace]", nil, 2), true, false, true))
+	o._putSym(SymMatch, valueProp(r.newNativeFunc(r.regexpproto_stdMatcher, nil, "[Symbol.match]", nil, 1), true, false, true))
+	o._putSym(SymSearch, valueProp(r.newNativeFunc(r.regexpproto_stdSearch, nil, "[Symbol.search]", nil, 1), true, false, true))
+	o._putSym(SymSplit, valueProp(r.newNativeFunc(r.regexpproto_stdSplitter, nil, "[Symbol.split]", nil, 2), true, false, true))
+	o._putSym(SymReplace, valueProp(r.newNativeFunc(r.regexpproto_stdReplacer, nil, "[Symbol.replace]", nil, 2), true, false, true))
 	o.guard("exec", "global", "multiline", "ignoreCase", "unicode", "sticky")
 
 	r.global.RegExp = r.newNativeFunc(r.builtin_RegExp, r.builtin_newRegExp, "RegExp", r.global.RegExpPrototype, 2)
 	rx := r.global.RegExp.self
-	rx._putSym(symSpecies, &valueProperty{
+	rx._putSym(SymSpecies, &valueProperty{
 		getterFunc:   r.newNativeFunc(r.returnThis, nil, "get [Symbol.species]", nil, 0),
 		accessor:     true,
 		configurable: true,

+ 4 - 4
builtin_set.go

@@ -210,15 +210,15 @@ func (r *Runtime) createSetProto(val *Object) objectImpl {
 	o._putProp("values", valuesFunc, true, false, true)
 	o._putProp("keys", valuesFunc, true, false, true)
 	o._putProp("entries", r.newNativeFunc(r.setProto_entries, nil, "entries", nil, 0), true, false, true)
-	o._putSym(symIterator, valueProp(valuesFunc, true, false, true))
-	o._putSym(symToStringTag, valueProp(asciiString(classSet), false, false, true))
+	o._putSym(SymIterator, valueProp(valuesFunc, true, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classSet), false, false, true))
 
 	return o
 }
 
 func (r *Runtime) createSet(val *Object) objectImpl {
 	o := r.newNativeConstructOnly(val, r.builtin_newSet, r.global.SetPrototype, "Set", 0)
-	o._putSym(symSpecies, &valueProperty{
+	o._putSym(SymSpecies, &valueProperty{
 		getterFunc:   r.newNativeFunc(r.returnThis, nil, "get [Symbol.species]", nil, 0),
 		accessor:     true,
 		configurable: true,
@@ -231,7 +231,7 @@ func (r *Runtime) createSetIterProto(val *Object) objectImpl {
 	o := newBaseObjectObj(val, r.global.IteratorPrototype, classObject)
 
 	o._putProp("next", r.newNativeFunc(r.setIterProto_next, nil, "next", nil, 0), true, false, true)
-	o._putSym(symToStringTag, valueProp(asciiString(classSetIterator), false, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classSetIterator), false, false, true))
 
 	return o
 }

+ 10 - 10
builtin_string.go

@@ -26,8 +26,8 @@ func toString(arg Value) valueString {
 	if s, ok := arg.(valueString); ok {
 		return s
 	}
-	if s, ok := arg.(*valueSymbol); ok {
-		return s.desc
+	if s, ok := arg.(*Symbol); ok {
+		return s.descriptiveString()
 	}
 	return arg.toString()
 }
@@ -344,7 +344,7 @@ func (r *Runtime) stringproto_match(call FunctionCall) Value {
 	r.checkObjectCoercible(call.This)
 	regexp := call.Argument(0)
 	if regexp != _undefined && regexp != _null {
-		if matcher := toMethod(r.getV(regexp, symMatch)); matcher != nil {
+		if matcher := toMethod(r.getV(regexp, SymMatch)); matcher != nil {
 			return matcher(FunctionCall{
 				This:      regexp,
 				Arguments: []Value{call.This},
@@ -361,7 +361,7 @@ func (r *Runtime) stringproto_match(call FunctionCall) Value {
 		rx = r.newRegExp(regexp, nil, r.global.RegExpPrototype).self.(*regexpObject)
 	}
 
-	if matcher, ok := r.toObject(rx.getSym(symMatch, nil)).self.assertCallable(); ok {
+	if matcher, ok := r.toObject(rx.getSym(SymMatch, nil)).self.assertCallable(); ok {
 		return matcher(FunctionCall{
 			This:      rx.val,
 			Arguments: []Value{call.This.toString()},
@@ -624,7 +624,7 @@ func (r *Runtime) stringproto_replace(call FunctionCall) Value {
 	searchValue := call.Argument(0)
 	replaceValue := call.Argument(1)
 	if searchValue != _undefined && searchValue != _null {
-		if replacer := toMethod(r.getV(searchValue, symReplace)); replacer != nil {
+		if replacer := toMethod(r.getV(searchValue, SymReplace)); replacer != nil {
 			return replacer(FunctionCall{
 				This:      searchValue,
 				Arguments: []Value{call.This, replaceValue},
@@ -648,7 +648,7 @@ func (r *Runtime) stringproto_search(call FunctionCall) Value {
 	r.checkObjectCoercible(call.This)
 	regexp := call.Argument(0)
 	if regexp != _undefined && regexp != _null {
-		if searcher := toMethod(r.getV(regexp, symSearch)); searcher != nil {
+		if searcher := toMethod(r.getV(regexp, SymSearch)); searcher != nil {
 			return searcher(FunctionCall{
 				This:      regexp,
 				Arguments: []Value{call.This},
@@ -665,7 +665,7 @@ func (r *Runtime) stringproto_search(call FunctionCall) Value {
 		rx = r.newRegExp(regexp, nil, r.global.RegExpPrototype).self.(*regexpObject)
 	}
 
-	if searcher, ok := r.toObject(rx.getSym(symSearch, nil)).self.assertCallable(); ok {
+	if searcher, ok := r.toObject(rx.getSym(SymSearch, nil)).self.assertCallable(); ok {
 		return searcher(FunctionCall{
 			This:      rx.val,
 			Arguments: []Value{call.This.toString()},
@@ -721,7 +721,7 @@ func (r *Runtime) stringproto_split(call FunctionCall) Value {
 	separatorValue := call.Argument(0)
 	limitValue := call.Argument(1)
 	if separatorValue != _undefined && separatorValue != _null {
-		if splitter := toMethod(r.getV(separatorValue, symSplit)); splitter != nil {
+		if splitter := toMethod(r.getV(separatorValue, SymSplit)); splitter != nil {
 			return splitter(FunctionCall{
 				This:      separatorValue,
 				Arguments: []Value{call.This, limitValue},
@@ -902,7 +902,7 @@ func (r *Runtime) createStringIterProto(val *Object) objectImpl {
 	o := newBaseObjectObj(val, r.global.IteratorPrototype, classObject)
 
 	o._putProp("next", r.newNativeFunc(r.stringIterProto_next, nil, "next", nil, 0), true, false, true)
-	o._putSym(symToStringTag, valueProp(asciiString(classStringIterator), false, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classStringIterator), false, false, true))
 
 	return o
 }
@@ -942,7 +942,7 @@ func (r *Runtime) initString() {
 	o._putProp("trimStart", r.newNativeFunc(r.stringproto_trimStart, nil, "trimStart", nil, 0), true, false, true)
 	o._putProp("valueOf", r.newNativeFunc(r.stringproto_valueOf, nil, "valueOf", nil, 0), true, false, true)
 
-	o._putSym(symIterator, valueProp(r.newNativeFunc(r.stringproto_iterator, nil, "[Symbol.iterator]", nil, 0), true, false, true))
+	o._putSym(SymIterator, valueProp(r.newNativeFunc(r.stringproto_iterator, nil, "[Symbol.iterator]", nil, 0), true, false, true))
 
 	// Annex B
 	o._putProp("substr", r.newNativeFunc(r.stringproto_substr, nil, "substr", nil, 2), true, false, true)

+ 33 - 33
builtin_symbol.go

@@ -3,17 +3,17 @@ package goja
 import "github.com/dop251/goja/unistring"
 
 var (
-	symHasInstance        = newSymbol(asciiString("Symbol.hasInstance"))
-	symIsConcatSpreadable = newSymbol(asciiString("Symbol.isConcatSpreadable"))
-	symIterator           = newSymbol(asciiString("Symbol.iterator"))
-	symMatch              = newSymbol(asciiString("Symbol.match"))
-	symReplace            = newSymbol(asciiString("Symbol.replace"))
-	symSearch             = newSymbol(asciiString("Symbol.search"))
-	symSpecies            = newSymbol(asciiString("Symbol.species"))
-	symSplit              = newSymbol(asciiString("Symbol.split"))
-	symToPrimitive        = newSymbol(asciiString("Symbol.toPrimitive"))
-	symToStringTag        = newSymbol(asciiString("Symbol.toStringTag"))
-	symUnscopables        = newSymbol(asciiString("Symbol.unscopables"))
+	SymHasInstance        = newSymbol(asciiString("Symbol.hasInstance"))
+	SymIsConcatSpreadable = newSymbol(asciiString("Symbol.isConcatSpreadable"))
+	SymIterator           = newSymbol(asciiString("Symbol.iterator"))
+	SymMatch              = newSymbol(asciiString("Symbol.match"))
+	SymReplace            = newSymbol(asciiString("Symbol.replace"))
+	SymSearch             = newSymbol(asciiString("Symbol.search"))
+	SymSpecies            = newSymbol(asciiString("Symbol.species"))
+	SymSplit              = newSymbol(asciiString("Symbol.split"))
+	SymToPrimitive        = newSymbol(asciiString("Symbol.toPrimitive"))
+	SymToStringTag        = newSymbol(asciiString("Symbol.toStringTag"))
+	SymUnscopables        = newSymbol(asciiString("Symbol.unscopables"))
 )
 
 func (r *Runtime) builtin_symbol(call FunctionCall) Value {
@@ -27,11 +27,11 @@ func (r *Runtime) builtin_symbol(call FunctionCall) Value {
 }
 
 func (r *Runtime) symbolproto_tostring(call FunctionCall) Value {
-	sym, ok := call.This.(*valueSymbol)
+	sym, ok := call.This.(*Symbol)
 	if !ok {
 		if obj, ok := call.This.(*Object); ok {
 			if v, ok := obj.self.(*primitiveValueObject); ok {
-				if sym1, ok := v.pValue.(*valueSymbol); ok {
+				if sym1, ok := v.pValue.(*Symbol); ok {
 					sym = sym1
 				}
 			}
@@ -40,18 +40,18 @@ func (r *Runtime) symbolproto_tostring(call FunctionCall) Value {
 	if sym == nil {
 		panic(r.NewTypeError("Method Symbol.prototype.toString is called on incompatible receiver"))
 	}
-	return sym.desc
+	return sym.descriptiveString()
 }
 
 func (r *Runtime) symbolproto_valueOf(call FunctionCall) Value {
-	_, ok := call.This.(*valueSymbol)
+	_, ok := call.This.(*Symbol)
 	if ok {
 		return call.This
 	}
 
 	if obj, ok := call.This.(*Object); ok {
 		if v, ok := obj.self.(*primitiveValueObject); ok {
-			if sym, ok := v.pValue.(*valueSymbol); ok {
+			if sym, ok := v.pValue.(*Symbol); ok {
 				return sym
 			}
 		}
@@ -67,7 +67,7 @@ func (r *Runtime) symbol_for(call FunctionCall) Value {
 		return v
 	}
 	if r.symbolRegistry == nil {
-		r.symbolRegistry = make(map[unistring.String]*valueSymbol)
+		r.symbolRegistry = make(map[unistring.String]*Symbol)
 	}
 	v := newSymbol(key)
 	r.symbolRegistry[keyStr] = v
@@ -76,7 +76,7 @@ func (r *Runtime) symbol_for(call FunctionCall) Value {
 
 func (r *Runtime) symbol_keyfor(call FunctionCall) Value {
 	arg := call.Argument(0)
-	sym, ok := arg.(*valueSymbol)
+	sym, ok := arg.(*Symbol)
 	if !ok {
 		panic(r.NewTypeError("%s is not a symbol", arg.String()))
 	}
@@ -100,8 +100,8 @@ func (r *Runtime) createSymbolProto(val *Object) objectImpl {
 	o._putProp("constructor", r.global.Symbol, true, false, true)
 	o._putProp("toString", r.newNativeFunc(r.symbolproto_tostring, nil, "toString", nil, 0), true, false, true)
 	o._putProp("valueOf", r.newNativeFunc(r.symbolproto_valueOf, nil, "valueOf", nil, 0), true, false, true)
-	o._putSym(symToPrimitive, valueProp(r.newNativeFunc(r.symbolproto_valueOf, nil, "[Symbol.toPrimitive]", nil, 1), false, false, true))
-	o._putSym(symToStringTag, valueProp(newStringValue("Symbol"), false, false, true))
+	o._putSym(SymToPrimitive, valueProp(r.newNativeFunc(r.symbolproto_valueOf, nil, "[Symbol.toPrimitive]", nil, 1), false, false, true))
+	o._putSym(SymToStringTag, valueProp(newStringValue("Symbol"), false, false, true))
 
 	return o
 }
@@ -112,21 +112,21 @@ func (r *Runtime) createSymbol(val *Object) objectImpl {
 	o._putProp("for", r.newNativeFunc(r.symbol_for, nil, "for", nil, 1), true, false, true)
 	o._putProp("keyFor", r.newNativeFunc(r.symbol_keyfor, nil, "keyFor", nil, 1), true, false, true)
 
-	for _, s := range []*valueSymbol{
-		symHasInstance,
-		symIsConcatSpreadable,
-		symIterator,
-		symMatch,
-		symReplace,
-		symSearch,
-		symSpecies,
-		symSplit,
-		symToPrimitive,
-		symToStringTag,
-		symUnscopables,
+	for _, s := range []*Symbol{
+		SymHasInstance,
+		SymIsConcatSpreadable,
+		SymIterator,
+		SymMatch,
+		SymReplace,
+		SymSearch,
+		SymSpecies,
+		SymSplit,
+		SymToPrimitive,
+		SymToStringTag,
+		SymUnscopables,
 	} {
 		n := s.desc.(asciiString)
-		n = n[len("Symbol(Symbol.") : len(n)-1]
+		n = n[len("Symbol."):]
 		o._putProp(unistring.String(n), s, false, false, false)
 	}
 

+ 7 - 7
builtin_typedarrays.go

@@ -1090,7 +1090,7 @@ func (r *Runtime) typedArrayFrom(ctor, items *Object, mapFn, thisValue Value) *O
 			thisValue = _undefined
 		}
 	}
-	usingIter := toMethod(items.self.getSym(symIterator, nil))
+	usingIter := toMethod(items.self.getSym(SymIterator, nil))
 	if usingIter != nil {
 		iter := r.getIterator(items, usingIter)
 		var values []Value
@@ -1251,14 +1251,14 @@ func (r *Runtime) createArrayBufferProto(val *Object) objectImpl {
 	b._put("byteLength", byteLengthProp)
 	b._putProp("constructor", r.global.ArrayBuffer, true, false, true)
 	b._putProp("slice", r.newNativeFunc(r.arrayBufferProto_slice, nil, "slice", nil, 2), true, false, true)
-	b._putSym(symToStringTag, valueProp(asciiString("ArrayBuffer"), false, false, true))
+	b._putSym(SymToStringTag, valueProp(asciiString("ArrayBuffer"), false, false, true))
 	return b
 }
 
 func (r *Runtime) createArrayBuffer(val *Object) objectImpl {
 	o := r.newNativeConstructOnly(val, r.builtin_newArrayBuffer, r.global.ArrayBufferPrototype, "ArrayBuffer", 1)
 	o._putProp("isView", r.newNativeFunc(r.arrayBuffer_isView, nil, "isView", nil, 1), true, false, true)
-	o._putSym(symSpecies, &valueProperty{
+	o._putSym(SymSpecies, &valueProperty{
 		getterFunc:   r.newNativeFunc(r.returnThis, nil, "get [Symbol.species]", nil, 0),
 		accessor:     true,
 		configurable: true,
@@ -1300,7 +1300,7 @@ func (r *Runtime) createDataViewProto(val *Object) objectImpl {
 	b._putProp("setUint8", r.newNativeFunc(r.dataViewProto_setUint8, nil, "setUint8", nil, 2), true, false, true)
 	b._putProp("setUint16", r.newNativeFunc(r.dataViewProto_setUint16, nil, "setUint16", nil, 2), true, false, true)
 	b._putProp("setUint32", r.newNativeFunc(r.dataViewProto_setUint32, nil, "setUint32", nil, 2), true, false, true)
-	b._putSym(symToStringTag, valueProp(asciiString("DataView"), false, false, true))
+	b._putSym(SymToStringTag, valueProp(asciiString("DataView"), false, false, true))
 
 	return b
 }
@@ -1359,8 +1359,8 @@ func (r *Runtime) createTypedArrayProto(val *Object) objectImpl {
 	b._putProp("toString", r.global.arrayToString, true, false, true)
 	valuesFunc := r.newNativeFunc(r.typedArrayProto_values, nil, "values", nil, 0)
 	b._putProp("values", valuesFunc, true, false, true)
-	b._putSym(symIterator, valueProp(valuesFunc, true, false, true))
-	b._putSym(symToStringTag, &valueProperty{
+	b._putSym(SymIterator, valueProp(valuesFunc, true, false, true))
+	b._putSym(SymToStringTag, &valueProperty{
 		getterFunc:   r.newNativeFunc(r.typedArrayProto_toStringTag, nil, "get [Symbol.toStringTag]", nil, 0),
 		accessor:     true,
 		configurable: true,
@@ -1373,7 +1373,7 @@ func (r *Runtime) createTypedArray(val *Object) objectImpl {
 	o := r.newNativeConstructOnly(val, r.newTypedArray, r.global.TypedArrayPrototype, "TypedArray", 0)
 	o._putProp("from", r.newNativeFunc(r.typedArray_from, nil, "from", nil, 1), true, false, true)
 	o._putProp("of", r.newNativeFunc(r.typedArray_of, nil, "of", nil, 0), true, false, true)
-	o._putSym(symSpecies, &valueProperty{
+	o._putSym(SymSpecies, &valueProperty{
 		getterFunc:   r.newNativeFunc(r.returnThis, nil, "get [Symbol.species]", nil, 0),
 		accessor:     true,
 		configurable: true,

+ 1 - 1
builtin_weakmap.go

@@ -183,7 +183,7 @@ func (r *Runtime) createWeakMapProto(val *Object) objectImpl {
 	o._putProp("has", r.newNativeFunc(r.weakMapProto_has, nil, "has", nil, 1), true, false, true)
 	o._putProp("get", r.newNativeFunc(r.weakMapProto_get, nil, "get", nil, 1), true, false, true)
 
-	o._putSym(symToStringTag, valueProp(asciiString(classWeakMap), false, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classWeakMap), false, false, true))
 
 	return o
 }

+ 1 - 1
builtin_weakset.go

@@ -139,7 +139,7 @@ func (r *Runtime) createWeakSetProto(val *Object) objectImpl {
 	o._putProp("delete", r.newNativeFunc(r.weakSetProto_delete, nil, "delete", nil, 1), true, false, true)
 	o._putProp("has", r.newNativeFunc(r.weakSetProto_has, nil, "has", nil, 1), true, false, true)
 
-	o._putSym(symToStringTag, valueProp(asciiString(classWeakSet), false, false, true))
+	o._putSym(SymToStringTag, valueProp(asciiString(classWeakSet), false, false, true))
 
 	return o
 }

+ 2 - 2
map_test.go

@@ -23,8 +23,8 @@ func TestMapHash(t *testing.T) {
 	testMapHashVal(asciiString("Test"), asciiString("Test"), true, t)
 	testMapHashVal(newStringValue("Тест"), newStringValue("Тест"), true, t)
 	testMapHashVal(floatToValue(1.2345), floatToValue(1.2345), true, t)
-	testMapHashVal(symIterator, symToStringTag, false, t)
-	testMapHashVal(symIterator, symIterator, true, t)
+	testMapHashVal(SymIterator, SymToStringTag, false, t)
+	testMapHashVal(SymIterator, SymIterator, true, t)
 
 	// The following tests introduce indeterministic behaviour
 	//testMapHashVal(asciiString("Test"), asciiString("Test1"), false, t)

+ 29 - 29
object.go

@@ -202,35 +202,35 @@ type objectImpl interface {
 	className() string
 	getStr(p unistring.String, receiver Value) Value
 	getIdx(p valueInt, receiver Value) Value
-	getSym(p *valueSymbol, receiver Value) Value
+	getSym(p *Symbol, receiver Value) Value
 
 	getOwnPropStr(unistring.String) Value
 	getOwnPropIdx(valueInt) Value
-	getOwnPropSym(*valueSymbol) Value
+	getOwnPropSym(*Symbol) Value
 
 	setOwnStr(p unistring.String, v Value, throw bool) bool
 	setOwnIdx(p valueInt, v Value, throw bool) bool
-	setOwnSym(p *valueSymbol, v Value, throw bool) bool
+	setOwnSym(p *Symbol, v Value, throw bool) bool
 
 	setForeignStr(p unistring.String, v, receiver Value, throw bool) (res bool, handled bool)
 	setForeignIdx(p valueInt, v, receiver Value, throw bool) (res bool, handled bool)
-	setForeignSym(p *valueSymbol, v, receiver Value, throw bool) (res bool, handled bool)
+	setForeignSym(p *Symbol, v, receiver Value, throw bool) (res bool, handled bool)
 
 	hasPropertyStr(unistring.String) bool
 	hasPropertyIdx(idx valueInt) bool
-	hasPropertySym(s *valueSymbol) bool
+	hasPropertySym(s *Symbol) bool
 
 	hasOwnPropertyStr(unistring.String) bool
 	hasOwnPropertyIdx(valueInt) bool
-	hasOwnPropertySym(s *valueSymbol) bool
+	hasOwnPropertySym(s *Symbol) bool
 
 	defineOwnPropertyStr(name unistring.String, desc PropertyDescriptor, throw bool) bool
 	defineOwnPropertyIdx(name valueInt, desc PropertyDescriptor, throw bool) bool
-	defineOwnPropertySym(name *valueSymbol, desc PropertyDescriptor, throw bool) bool
+	defineOwnPropertySym(name *Symbol, desc PropertyDescriptor, throw bool) bool
 
 	deleteStr(name unistring.String, throw bool) bool
 	deleteIdx(idx valueInt, throw bool) bool
-	deleteSym(s *valueSymbol, throw bool) bool
+	deleteSym(s *Symbol, throw bool) bool
 
 	toPrimitiveNumber() Value
 	toPrimitiveString() Value
@@ -252,7 +252,7 @@ type objectImpl interface {
 	ownPropertyKeys(all bool, accum []Value) []Value
 
 	_putProp(name unistring.String, value Value, writable, enumerable, configurable bool) Value
-	_putSym(s *valueSymbol, prop Value)
+	_putSym(s *Symbol, prop Value)
 }
 
 type baseObject struct {
@@ -334,7 +334,7 @@ func (o *baseObject) hasPropertyIdx(idx valueInt) bool {
 	return o.val.self.hasPropertyStr(idx.string())
 }
 
-func (o *baseObject) hasPropertySym(s *valueSymbol) bool {
+func (o *baseObject) hasPropertySym(s *Symbol) bool {
 	if o.hasOwnPropertySym(s) {
 		return true
 	}
@@ -380,7 +380,7 @@ func (o *baseObject) getIdx(idx valueInt, receiver Value) Value {
 	return o.val.self.getStr(idx.string(), receiver)
 }
 
-func (o *baseObject) getSym(s *valueSymbol, receiver Value) Value {
+func (o *baseObject) getSym(s *Symbol, receiver Value) Value {
 	return o.getWithOwnProp(o.getOwnPropSym(s), s, receiver)
 }
 
@@ -407,7 +407,7 @@ func (o *baseObject) getOwnPropIdx(idx valueInt) Value {
 	return o.val.self.getOwnPropStr(idx.string())
 }
 
-func (o *baseObject) getOwnPropSym(s *valueSymbol) Value {
+func (o *baseObject) getOwnPropSym(s *Symbol) Value {
 	if o.symValues != nil {
 		return o.symValues.get(s)
 	}
@@ -454,7 +454,7 @@ func (o *baseObject) deleteIdx(idx valueInt, throw bool) bool {
 	return o.val.self.deleteStr(idx.string(), throw)
 }
 
-func (o *baseObject) deleteSym(s *valueSymbol, throw bool) bool {
+func (o *baseObject) deleteSym(s *Symbol, throw bool) bool {
 	if o.symValues != nil {
 		if val := o.symValues.get(s); val != nil {
 			if !o.checkDelete(s.desc.string(), val, throw) {
@@ -532,7 +532,7 @@ func (o *baseObject) setOwnIdx(idx valueInt, val Value, throw bool) bool {
 	return o.val.self.setOwnStr(idx.string(), val, throw)
 }
 
-func (o *baseObject) setOwnSym(name *valueSymbol, val Value, throw bool) bool {
+func (o *baseObject) setOwnSym(name *Symbol, val Value, throw bool) bool {
 	var ownDesc Value
 	if o.symValues != nil {
 		ownDesc = o.symValues.get(name)
@@ -623,7 +623,7 @@ func (o *baseObject) setForeignIdx(name valueInt, val, receiver Value, throw boo
 	return o.val.self.setForeignStr(name.string(), val, receiver, throw)
 }
 
-func (o *baseObject) setForeignSym(name *valueSymbol, val, receiver Value, throw bool) (bool, bool) {
+func (o *baseObject) setForeignSym(name *Symbol, val, receiver Value, throw bool) (bool, bool) {
 	var prop Value
 	if o.symValues != nil {
 		prop = o.symValues.get(name)
@@ -650,7 +650,7 @@ func (o *baseObject) setForeignSym(name *valueSymbol, val, receiver Value, throw
 	return false, false
 }
 
-func (o *baseObject) hasOwnPropertySym(s *valueSymbol) bool {
+func (o *baseObject) hasOwnPropertySym(s *Symbol) bool {
 	if o.symValues != nil {
 		return o.symValues.has(s)
 	}
@@ -785,7 +785,7 @@ func (o *baseObject) defineOwnPropertyIdx(idx valueInt, desc PropertyDescriptor,
 	return o.val.self.defineOwnPropertyStr(idx.string(), desc, throw)
 }
 
-func (o *baseObject) defineOwnPropertySym(s *valueSymbol, descr PropertyDescriptor, throw bool) bool {
+func (o *baseObject) defineOwnPropertySym(s *Symbol, descr PropertyDescriptor, throw bool) bool {
 	var existingVal Value
 	if o.symValues != nil {
 		existingVal = o.symValues.get(s)
@@ -826,7 +826,7 @@ func (o *baseObject) _putProp(name unistring.String, value Value, writable, enum
 	return prop
 }
 
-func (o *baseObject) _putSym(s *valueSymbol, prop Value) {
+func (o *baseObject) _putSym(s *Symbol, prop Value) {
 	if o.symValues == nil {
 		o.symValues = newOrderedMap(nil)
 	}
@@ -887,7 +887,7 @@ func (o *baseObject) toPrimitive() Value {
 }
 
 func (o *Object) tryExoticToPrimitive(hint Value) Value {
-	exoticToPrimitive := toMethod(o.self.getSym(symToPrimitive, nil))
+	exoticToPrimitive := toMethod(o.self.getSym(SymToPrimitive, nil))
 	if exoticToPrimitive != nil {
 		ret := exoticToPrimitive(FunctionCall{
 			This:      o,
@@ -1202,7 +1202,7 @@ func toMethod(v Value) func(FunctionCall) Value {
 }
 
 func instanceOfOperator(o Value, c *Object) bool {
-	if instOfHandler := toMethod(c.self.getSym(symHasInstance, c)); instOfHandler != nil {
+	if instOfHandler := toMethod(c.self.getSym(SymHasInstance, c)); instOfHandler != nil {
 		return instOfHandler(FunctionCall{
 			This:      c,
 			Arguments: []Value{o},
@@ -1216,7 +1216,7 @@ func (o *Object) get(p Value, receiver Value) Value {
 	switch p := p.(type) {
 	case valueInt:
 		return o.self.getIdx(p, receiver)
-	case *valueSymbol:
+	case *Symbol:
 		return o.self.getSym(p, receiver)
 	default:
 		return o.self.getStr(p.string(), receiver)
@@ -1227,7 +1227,7 @@ func (o *Object) getOwnProp(p Value) Value {
 	switch p := p.(type) {
 	case valueInt:
 		return o.self.getOwnPropIdx(p)
-	case *valueSymbol:
+	case *Symbol:
 		return o.self.getOwnPropSym(p)
 	default:
 		return o.self.getOwnPropStr(p.string())
@@ -1238,7 +1238,7 @@ func (o *Object) hasOwnProperty(p Value) bool {
 	switch p := p.(type) {
 	case valueInt:
 		return o.self.hasOwnPropertyIdx(p)
-	case *valueSymbol:
+	case *Symbol:
 		return o.self.hasOwnPropertySym(p)
 	default:
 		return o.self.hasOwnPropertyStr(p.string())
@@ -1249,7 +1249,7 @@ func (o *Object) hasProperty(p Value) bool {
 	switch p := p.(type) {
 	case valueInt:
 		return o.self.hasPropertyIdx(p)
-	case *valueSymbol:
+	case *Symbol:
 		return o.self.hasPropertySym(p)
 	default:
 		return o.self.hasPropertyStr(p.string())
@@ -1297,7 +1297,7 @@ func (o *Object) set(name Value, val, receiver Value, throw bool) bool {
 	switch name := name.(type) {
 	case valueInt:
 		return o.setIdx(name, val, receiver, throw)
-	case *valueSymbol:
+	case *Symbol:
 		return o.setSym(name, val, receiver, throw)
 	default:
 		return o.setStr(name.string(), val, receiver, throw)
@@ -1308,7 +1308,7 @@ func (o *Object) setOwn(name Value, val Value, throw bool) bool {
 	switch name := name.(type) {
 	case valueInt:
 		return o.self.setOwnIdx(name, val, throw)
-	case *valueSymbol:
+	case *Symbol:
 		return o.self.setOwnSym(name, val, throw)
 	default:
 		return o.self.setOwnStr(name.string(), val, throw)
@@ -1352,7 +1352,7 @@ func (o *Object) setIdx(name valueInt, val, receiver Value, throw bool) bool {
 	return true
 }
 
-func (o *Object) setSym(name *valueSymbol, val, receiver Value, throw bool) bool {
+func (o *Object) setSym(name *Symbol, val, receiver Value, throw bool) bool {
 	if receiver == o {
 		return o.self.setOwnSym(name, val, throw)
 	} else {
@@ -1393,7 +1393,7 @@ func (o *Object) delete(n Value, throw bool) bool {
 	switch n := n.(type) {
 	case valueInt:
 		return o.self.deleteIdx(n, throw)
-	case *valueSymbol:
+	case *Symbol:
 		return o.self.deleteSym(n, throw)
 	default:
 		return o.self.deleteStr(n.string(), throw)
@@ -1404,7 +1404,7 @@ func (o *Object) defineOwnProperty(n Value, desc PropertyDescriptor, throw bool)
 	switch n := n.(type) {
 	case valueInt:
 		return o.self.defineOwnPropertyIdx(n, desc, throw)
-	case *valueSymbol:
+	case *Symbol:
 		return o.self.defineOwnPropertySym(n, desc, throw)
 	default:
 		return o.self.defineOwnPropertyStr(n.string(), desc, throw)

+ 9 - 9
object_lazy.go

@@ -23,7 +23,7 @@ func (o *lazyObject) getIdx(p valueInt, receiver Value) Value {
 	return obj.getIdx(p, receiver)
 }
 
-func (o *lazyObject) getSym(p *valueSymbol, receiver Value) Value {
+func (o *lazyObject) getSym(p *Symbol, receiver Value) Value {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.getSym(p, receiver)
@@ -35,7 +35,7 @@ func (o *lazyObject) getOwnPropIdx(idx valueInt) Value {
 	return obj.getOwnPropIdx(idx)
 }
 
-func (o *lazyObject) getOwnPropSym(s *valueSymbol) Value {
+func (o *lazyObject) getOwnPropSym(s *Symbol) Value {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.getOwnPropSym(s)
@@ -47,7 +47,7 @@ func (o *lazyObject) hasPropertyIdx(idx valueInt) bool {
 	return obj.hasPropertyIdx(idx)
 }
 
-func (o *lazyObject) hasPropertySym(s *valueSymbol) bool {
+func (o *lazyObject) hasPropertySym(s *Symbol) bool {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.hasPropertySym(s)
@@ -59,7 +59,7 @@ func (o *lazyObject) hasOwnPropertyIdx(idx valueInt) bool {
 	return obj.hasOwnPropertyIdx(idx)
 }
 
-func (o *lazyObject) hasOwnPropertySym(s *valueSymbol) bool {
+func (o *lazyObject) hasOwnPropertySym(s *Symbol) bool {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.hasOwnPropertySym(s)
@@ -77,7 +77,7 @@ func (o *lazyObject) defineOwnPropertyIdx(name valueInt, desc PropertyDescriptor
 	return obj.defineOwnPropertyIdx(name, desc, throw)
 }
 
-func (o *lazyObject) defineOwnPropertySym(name *valueSymbol, desc PropertyDescriptor, throw bool) bool {
+func (o *lazyObject) defineOwnPropertySym(name *Symbol, desc PropertyDescriptor, throw bool) bool {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.defineOwnPropertySym(name, desc, throw)
@@ -89,7 +89,7 @@ func (o *lazyObject) deleteIdx(idx valueInt, throw bool) bool {
 	return obj.deleteIdx(idx, throw)
 }
 
-func (o *lazyObject) deleteSym(s *valueSymbol, throw bool) bool {
+func (o *lazyObject) deleteSym(s *Symbol, throw bool) bool {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.deleteSym(s, throw)
@@ -119,7 +119,7 @@ func (o *lazyObject) setOwnIdx(p valueInt, v Value, throw bool) bool {
 	return obj.setOwnIdx(p, v, throw)
 }
 
-func (o *lazyObject) setOwnSym(p *valueSymbol, v Value, throw bool) bool {
+func (o *lazyObject) setOwnSym(p *Symbol, v Value, throw bool) bool {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.setOwnSym(p, v, throw)
@@ -137,7 +137,7 @@ func (o *lazyObject) setForeignIdx(p valueInt, v, receiver Value, throw bool) (b
 	return obj.setForeignIdx(p, v, receiver, throw)
 }
 
-func (o *lazyObject) setForeignSym(p *valueSymbol, v, receiver Value, throw bool) (bool, bool) {
+func (o *lazyObject) setForeignSym(p *Symbol, v, receiver Value, throw bool) (bool, bool) {
 	obj := o.create(o.val)
 	o.val.self = obj
 	return obj.setForeignSym(p, v, receiver, throw)
@@ -159,7 +159,7 @@ func (o *lazyObject) _putProp(unistring.String, Value, bool, bool, bool) Value {
 	panic("cannot use _putProp() in lazy object")
 }
 
-func (o *lazyObject) _putSym(*valueSymbol, Value) {
+func (o *lazyObject) _putSym(*Symbol, Value) {
 	panic("cannot use _putSym() in lazy object")
 }
 

+ 12 - 12
proxy.go

@@ -248,7 +248,7 @@ func (p *proxyObject) defineOwnPropertyIdx(idx valueInt, descr PropertyDescripto
 	return p.target.self.defineOwnPropertyIdx(idx, descr, throw)
 }
 
-func (p *proxyObject) defineOwnPropertySym(s *valueSymbol, descr PropertyDescriptor, throw bool) bool {
+func (p *proxyObject) defineOwnPropertySym(s *Symbol, descr PropertyDescriptor, throw bool) bool {
 	if v, ok := p.proxyDefineOwnProperty(s, descr, throw); ok {
 		return v
 	}
@@ -291,7 +291,7 @@ func (p *proxyObject) hasPropertyIdx(idx valueInt) bool {
 	return p.target.self.hasPropertyIdx(idx)
 }
 
-func (p *proxyObject) hasPropertySym(s *valueSymbol) bool {
+func (p *proxyObject) hasPropertySym(s *Symbol) bool {
 	if b, ok := p.proxyHas(s); ok {
 		return b
 	}
@@ -307,7 +307,7 @@ func (p *proxyObject) hasOwnPropertyIdx(idx valueInt) bool {
 	return p.getOwnPropIdx(idx) != nil
 }
 
-func (p *proxyObject) hasOwnPropertySym(s *valueSymbol) bool {
+func (p *proxyObject) hasOwnPropertySym(s *Symbol) bool {
 	return p.getOwnPropSym(s) != nil
 }
 
@@ -381,7 +381,7 @@ func (p *proxyObject) getOwnPropIdx(idx valueInt) Value {
 	return p.target.self.getOwnPropIdx(idx)
 }
 
-func (p *proxyObject) getOwnPropSym(s *valueSymbol) Value {
+func (p *proxyObject) getOwnPropSym(s *Symbol) Value {
 	if v, ok := p.proxyGetOwnPropertyDescriptor(s); ok {
 		return v
 	}
@@ -403,7 +403,7 @@ func (p *proxyObject) getIdx(idx valueInt, receiver Value) Value {
 	return p.target.self.getIdx(idx, receiver)
 }
 
-func (p *proxyObject) getSym(s *valueSymbol, receiver Value) Value {
+func (p *proxyObject) getSym(s *Symbol, receiver Value) Value {
 	if v, ok := p.proxyGet(s, receiver); ok {
 		return v
 	}
@@ -472,7 +472,7 @@ func (p *proxyObject) setOwnIdx(idx valueInt, v Value, throw bool) bool {
 	return p.target.setIdx(idx, v, p.val, throw)
 }
 
-func (p *proxyObject) setOwnSym(s *valueSymbol, v Value, throw bool) bool {
+func (p *proxyObject) setOwnSym(s *Symbol, v Value, throw bool) bool {
 	if res, ok := p.proxySet(s, v, p.val, throw); ok {
 		return res
 	}
@@ -493,7 +493,7 @@ func (p *proxyObject) setForeignIdx(idx valueInt, v, receiver Value, throw bool)
 	return p.target.setIdx(idx, v, receiver, throw), true
 }
 
-func (p *proxyObject) setForeignSym(s *valueSymbol, v, receiver Value, throw bool) (bool, bool) {
+func (p *proxyObject) setForeignSym(s *Symbol, v, receiver Value, throw bool) (bool, bool) {
 	if res, ok := p.proxySet(s, v, receiver, throw); ok {
 		return res, true
 	}
@@ -532,7 +532,7 @@ func (p *proxyObject) deleteIdx(idx valueInt, throw bool) bool {
 	return p.target.self.deleteIdx(idx, throw)
 }
 
-func (p *proxyObject) deleteSym(s *valueSymbol, throw bool) bool {
+func (p *proxyObject) deleteSym(s *Symbol, throw bool) bool {
 	if ret, ok := p.proxyDelete(s); ok {
 		return ret
 	}
@@ -557,7 +557,7 @@ func (p *proxyObject) proxyOwnKeys() ([]Value, bool) {
 		for k := int64(0); k < l; k++ {
 			item := keys.self.getIdx(valueInt(k), nil)
 			if _, ok := item.(valueString); !ok {
-				if _, ok := item.(*valueSymbol); !ok {
+				if _, ok := item.(*Symbol); !ok {
 					panic(p.val.runtime.NewTypeError("%s is not a valid property name", item.String()))
 				}
 			}
@@ -719,13 +719,13 @@ func (p *proxyObject) filterKeys(vals []Value, all, symbols bool) []Value {
 		for i, val := range vals {
 			var prop Value
 			if symbols {
-				if s, ok := val.(*valueSymbol); ok {
+				if s, ok := val.(*Symbol); ok {
 					prop = p.getOwnPropSym(s)
 				} else {
 					continue
 				}
 			} else {
-				if _, ok := val.(*valueSymbol); !ok {
+				if _, ok := val.(*Symbol); !ok {
 					prop = p.getOwnPropStr(val.string())
 				} else {
 					continue
@@ -746,7 +746,7 @@ func (p *proxyObject) filterKeys(vals []Value, all, symbols bool) []Value {
 	} else {
 		k := 0
 		for i, val := range vals {
-			if _, ok := val.(*valueSymbol); ok != symbols {
+			if _, ok := val.(*Symbol); ok != symbols {
 				continue
 			}
 			if k != i {

+ 6 - 6
runtime.go

@@ -162,7 +162,7 @@ type Runtime struct {
 	now             Now
 	_collator       *collate.Collator
 
-	symbolRegistry map[unistring.String]*valueSymbol
+	symbolRegistry map[unistring.String]*Symbol
 
 	typeInfoCache   map[reflect.Type]*reflectTypeInfo
 	fieldNameMapper FieldNameMapper
@@ -332,7 +332,7 @@ func (r *Runtime) addToGlobal(name string, value Value) {
 func (r *Runtime) createIterProto(val *Object) objectImpl {
 	o := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
 
-	o._putSym(symIterator, valueProp(r.newNativeFunc(r.returnThis, nil, "[Symbol.iterator]", nil, 0), true, false, true))
+	o._putSym(SymIterator, valueProp(r.newNativeFunc(r.returnThis, nil, "[Symbol.iterator]", nil, 0), true, false, true))
 	return o
 }
 
@@ -2124,7 +2124,7 @@ func (r *Runtime) toNumber(v Value) Value {
 func (r *Runtime) speciesConstructor(o, defaultConstructor *Object) func(args []Value, newTarget *Object) *Object {
 	c := o.self.getStr("constructor", nil)
 	if c != nil && c != _undefined {
-		c = r.toObject(c).self.getSym(symSpecies, nil)
+		c = r.toObject(c).self.getSym(SymSpecies, nil)
 	}
 	if c == nil || c == _undefined || c == _null {
 		c = defaultConstructor
@@ -2135,7 +2135,7 @@ func (r *Runtime) speciesConstructor(o, defaultConstructor *Object) func(args []
 func (r *Runtime) speciesConstructorObj(o, defaultConstructor *Object) *Object {
 	c := o.self.getStr("constructor", nil)
 	if c != nil && c != _undefined {
-		c = r.toObject(c).self.getSym(symSpecies, nil)
+		c = r.toObject(c).self.getSym(SymSpecies, nil)
 	}
 	if c == nil || c == _undefined || c == _null {
 		return defaultConstructor
@@ -2172,7 +2172,7 @@ func (r *Runtime) getV(v Value, p Value) Value {
 
 func (r *Runtime) getIterator(obj Value, method func(FunctionCall) Value) *Object {
 	if method == nil {
-		method = toMethod(r.getV(obj, symIterator))
+		method = toMethod(r.getV(obj, SymIterator))
 		if method == nil {
 			panic(r.NewTypeError("object is not iterable"))
 		}
@@ -2310,7 +2310,7 @@ func isArray(object *Object) bool {
 
 func isRegexp(v Value) bool {
 	if o, ok := v.(*Object); ok {
-		matcher := o.self.getSym(symMatch, nil)
+		matcher := o.self.getSym(SymMatch, nil)
 		if matcher != nil && matcher != _undefined {
 			return matcher.ToBoolean()
 		}

+ 49 - 0
runtime_test.go

@@ -1752,6 +1752,55 @@ func TestNativeCtorNonNewCall(t *testing.T) {
 	}
 }
 
+func ExampleNewSymbol() {
+	sym1 := NewSymbol("66")
+	sym2 := NewSymbol("66")
+	fmt.Printf("%s %s %v", sym1, sym2, sym1.Equals(sym2))
+	// Output: 66 66 false
+}
+
+func ExampleObject_SetSymbol() {
+	type IterResult struct {
+		Done  bool
+		Value Value
+	}
+
+	vm := New()
+	vm.SetFieldNameMapper(UncapFieldNameMapper()) // to use IterResult
+
+	o := vm.NewObject()
+	o.SetSymbol(SymIterator, func() *Object {
+		count := 0
+		iter := vm.NewObject()
+		iter.Set("next", func() IterResult {
+			if count < 10 {
+				count++
+				return IterResult{
+					Value: vm.ToValue(count),
+				}
+			}
+			return IterResult{
+				Done: true,
+			}
+		})
+		return iter
+	})
+	vm.Set("o", o)
+
+	res, err := vm.RunString(`
+	var acc = "";
+	for (var v of o) {
+		acc += v + " ";
+	}
+	acc;
+	`)
+	if err != nil {
+		panic(err)
+	}
+	fmt.Println(res)
+	// Output: 1 2 3 4 5 6 7 8 9 10
+}
+
 /*
 func TestArrayConcatSparse(t *testing.T) {
 function foo(a,b,c)

+ 90 - 21
value.go

@@ -88,7 +88,12 @@ type valueNull struct{}
 type valueUndefined struct {
 	valueNull
 }
-type valueSymbol struct {
+
+// *Symbol is a Value containing ECMAScript Symbol primitive. Symbols must only be created
+// using NewSymbol(). Zero values and copying of values (i.e. *s1 = *s2) are not permitted.
+// Well-known Symbols can be accessed using Sym* package variables (SymIterator, etc...)
+// Symbols can be shared by multiple Runtimes.
+type Symbol struct {
 	h    uintptr
 	desc valueString
 }
@@ -736,6 +741,12 @@ func (o *Object) Get(name string) Value {
 	return o.self.getStr(unistring.NewFromString(name), nil)
 }
 
+// GetSymbol returns the value of a symbol property. Use one of the Sym* values for well-known
+// symbols (such as SymIterator, SymToStringTag, etc...).
+func (o *Object) GetSymbol(sym *Symbol) Value {
+	return o.self.getSym(sym, nil)
+}
+
 func (o *Object) Keys() (keys []string) {
 	names := o.self.ownKeys(false, nil)
 	keys = make([]string, 0, len(names))
@@ -746,6 +757,15 @@ func (o *Object) Keys() (keys []string) {
 	return
 }
 
+func (o *Object) Symbols() []*Symbol {
+	symbols := o.self.ownSymbols(false, nil)
+	ret := make([]*Symbol, len(symbols))
+	for i, sym := range symbols {
+		ret[i], _ = sym.(*Symbol)
+	}
+	return ret
+}
+
 // DefineDataProperty is a Go equivalent of Object.defineProperty(o, name, {value: value, writable: writable,
 // configurable: configurable, enumerable: enumerable})
 func (o *Object) DefineDataProperty(name string, value Value, writable, configurable, enumerable Flag) error {
@@ -772,18 +792,56 @@ func (o *Object) DefineAccessorProperty(name string, getter, setter Value, confi
 	})
 }
 
+// DefineDataPropertySymbol is a Go equivalent of Object.defineProperty(o, name, {value: value, writable: writable,
+// configurable: configurable, enumerable: enumerable})
+func (o *Object) DefineDataPropertySymbol(name *Symbol, value Value, writable, configurable, enumerable Flag) error {
+	return tryFunc(func() {
+		o.self.defineOwnPropertySym(name, PropertyDescriptor{
+			Value:        value,
+			Writable:     writable,
+			Configurable: configurable,
+			Enumerable:   enumerable,
+		}, true)
+	})
+}
+
+// DefineAccessorPropertySymbol is a Go equivalent of Object.defineProperty(o, name, {get: getter, set: setter,
+// configurable: configurable, enumerable: enumerable})
+func (o *Object) DefineAccessorPropertySymbol(name *Symbol, getter, setter Value, configurable, enumerable Flag) error {
+	return tryFunc(func() {
+		o.self.defineOwnPropertySym(name, PropertyDescriptor{
+			Getter:       getter,
+			Setter:       setter,
+			Configurable: configurable,
+			Enumerable:   enumerable,
+		}, true)
+	})
+}
+
 func (o *Object) Set(name string, value interface{}) error {
 	return tryFunc(func() {
 		o.self.setOwnStr(unistring.NewFromString(name), o.runtime.ToValue(value), true)
 	})
 }
 
+func (o *Object) SetSymbol(name *Symbol, value interface{}) error {
+	return tryFunc(func() {
+		o.self.setOwnSym(name, o.runtime.ToValue(value), true)
+	})
+}
+
 func (o *Object) Delete(name string) error {
 	return tryFunc(func() {
 		o.self.deleteStr(unistring.NewFromString(name), true)
 	})
 }
 
+func (o *Object) DeleteSymbol(name *Symbol) error {
+	return tryFunc(func() {
+		o.self.deleteSym(name, true)
+	})
+}
+
 // MarshalJSON returns JSON representation of the Object. It is equivalent to JSON.stringify(o).
 // Note, this implements json.Marshaler so that json.Marshal() can be used without the need to Export().
 func (o *Object) MarshalJSON() ([]byte, error) {
@@ -890,70 +948,70 @@ func (o valueUnresolved) hash(*maphash.Hash) uint64 {
 	return 0
 }
 
-func (s *valueSymbol) ToInteger() int64 {
+func (s *Symbol) ToInteger() int64 {
 	panic(typeError("Cannot convert a Symbol value to a number"))
 }
 
-func (s *valueSymbol) toString() valueString {
+func (s *Symbol) toString() valueString {
 	panic(typeError("Cannot convert a Symbol value to a string"))
 }
 
-func (s *valueSymbol) ToString() Value {
+func (s *Symbol) ToString() Value {
 	return s
 }
 
-func (s *valueSymbol) String() string {
+func (s *Symbol) String() string {
 	return s.desc.String()
 }
 
-func (s *valueSymbol) string() unistring.String {
+func (s *Symbol) string() unistring.String {
 	return s.desc.string()
 }
 
-func (s *valueSymbol) ToFloat() float64 {
+func (s *Symbol) ToFloat() float64 {
 	panic(typeError("Cannot convert a Symbol value to a number"))
 }
 
-func (s *valueSymbol) ToNumber() Value {
+func (s *Symbol) ToNumber() Value {
 	panic(typeError("Cannot convert a Symbol value to a number"))
 }
 
-func (s *valueSymbol) ToBoolean() bool {
+func (s *Symbol) ToBoolean() bool {
 	return true
 }
 
-func (s *valueSymbol) ToObject(r *Runtime) *Object {
+func (s *Symbol) ToObject(r *Runtime) *Object {
 	return s.baseObject(r)
 }
 
-func (s *valueSymbol) SameAs(other Value) bool {
-	if s1, ok := other.(*valueSymbol); ok {
+func (s *Symbol) SameAs(other Value) bool {
+	if s1, ok := other.(*Symbol); ok {
 		return s == s1
 	}
 	return false
 }
 
-func (s *valueSymbol) Equals(o Value) bool {
+func (s *Symbol) Equals(o Value) bool {
 	return s.SameAs(o)
 }
 
-func (s *valueSymbol) StrictEquals(o Value) bool {
+func (s *Symbol) StrictEquals(o Value) bool {
 	return s.SameAs(o)
 }
 
-func (s *valueSymbol) Export() interface{} {
+func (s *Symbol) Export() interface{} {
 	return s.String()
 }
 
-func (s *valueSymbol) ExportType() reflect.Type {
+func (s *Symbol) ExportType() reflect.Type {
 	return reflectTypeString
 }
 
-func (s *valueSymbol) baseObject(r *Runtime) *Object {
+func (s *Symbol) baseObject(r *Runtime) *Object {
 	return r.newPrimitiveObject(s, r.global.SymbolPrototype, "Symbol")
 }
 
-func (s *valueSymbol) hash(*maphash.Hash) uint64 {
+func (s *Symbol) hash(*maphash.Hash) uint64 {
 	return uint64(s.h)
 }
 
@@ -964,9 +1022,9 @@ func exportValue(v Value, ctx *objectExportCtx) interface{} {
 	return v.Export()
 }
 
-func newSymbol(s valueString) *valueSymbol {
-	r := &valueSymbol{
-		desc: asciiString("Symbol(").concat(s).concat(asciiString(")")),
+func newSymbol(s valueString) *Symbol {
+	r := &Symbol{
+		desc: s,
 	}
 	// This may need to be reconsidered in the future.
 	// Depending on changes in Go's allocation policy and/or introduction of a compacting GC
@@ -976,6 +1034,17 @@ func newSymbol(s valueString) *valueSymbol {
 	return r
 }
 
+func NewSymbol(s string) *Symbol {
+	return newSymbol(newStringValue(s))
+}
+
+func (s *Symbol) descriptiveString() valueString {
+	if s.desc == nil {
+		return stringEmpty
+	}
+	return asciiString("Symbol(").concat(s.desc).concat(asciiString(")"))
+}
+
 func init() {
 	for i := 0; i < 256; i++ {
 		intCache[i] = valueInt(i - 128)

+ 2 - 2
vm.go

@@ -205,7 +205,7 @@ func (s *valueStack) expand(idx int) {
 
 func stashObjHas(obj *Object, name unistring.String) bool {
 	if obj.self.hasPropertyStr(name) {
-		if unscopables, ok := obj.self.getSym(symUnscopables, nil).(*Object); ok {
+		if unscopables, ok := obj.self.getSym(SymUnscopables, nil).(*Object); ok {
 			if b := unscopables.self.getStr(name, nil); b != nil {
 				return !b.ToBoolean()
 			}
@@ -2356,7 +2356,7 @@ func (_typeof) exec(vm *vm) {
 		r = stringString
 	case valueInt, valueFloat:
 		r = stringNumber
-	case *valueSymbol:
+	case *Symbol:
 		r = stringSymbol
 	default:
 		panic(fmt.Errorf("Unknown type: %T", v))