Rename IS_SPEC_OBJECT macro to IS_RECEIVER.
And remove confusing comment. R=bmeurer@chromium.org BUG= Review URL: https://codereview.chromium.org/1531843003 Cr-Commit-Position: refs/heads/master@{#32935}
This commit is contained in:
parent
0d83aad557
commit
fe484ff648
@ -116,7 +116,7 @@ function ClearMirrorCache(value) {
|
||||
|
||||
|
||||
function ObjectIsPromise(value) {
|
||||
return IS_SPEC_OBJECT(value) &&
|
||||
return IS_RECEIVER(value) &&
|
||||
!IS_UNDEFINED(%DebugGetProperty(value, promiseStatusSymbol));
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ function ArrayIteratorNext() {
|
||||
var value = UNDEFINED;
|
||||
var done = true;
|
||||
|
||||
if (!IS_SPEC_OBJECT(iterator) ||
|
||||
if (!IS_RECEIVER(iterator) ||
|
||||
!HAS_DEFINED_PRIVATE(iterator, arrayIteratorNextIndexSymbol)) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'Array Iterator.prototype.next', this);
|
||||
|
@ -1774,7 +1774,7 @@ function ArrayFrom(arrayLike, mapfn, receiver) {
|
||||
while (true) {
|
||||
var next = iterator.next();
|
||||
|
||||
if (!IS_SPEC_OBJECT(next)) {
|
||||
if (!IS_RECEIVER(next)) {
|
||||
throw MakeTypeError(kIteratorResultNotAnObject, next);
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ function GetExistingHash(key) {
|
||||
if ((field & 1 /* Name::kHashNotComputedMask */) === 0) {
|
||||
return field >>> 2 /* Name::kHashShift */;
|
||||
}
|
||||
} else if (IS_SPEC_OBJECT(key) && !%_IsJSProxy(key) && !IS_GLOBAL(key)) {
|
||||
} else if (IS_RECEIVER(key) && !%_IsJSProxy(key) && !IS_GLOBAL(key)) {
|
||||
var hash = GET_PRIVATE(key, hashCodeSymbol);
|
||||
return hash;
|
||||
}
|
||||
@ -294,7 +294,7 @@ function MapConstructor(iterable) {
|
||||
}
|
||||
|
||||
for (var nextItem of iterable) {
|
||||
if (!IS_SPEC_OBJECT(nextItem)) {
|
||||
if (!IS_RECEIVER(nextItem)) {
|
||||
throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
|
||||
}
|
||||
%_Call(adder, this, nextItem[0], nextItem[1]);
|
||||
|
@ -23,7 +23,7 @@ utils.Import(function(from) {
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function ReflectEnumerate(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj))
|
||||
if (!IS_RECEIVER(obj))
|
||||
throw MakeTypeError(kCalledOnNonObject, "Reflect.enumerate")
|
||||
return (function* () { for (var x in obj) yield x })();
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ utils.Import(function(from) {
|
||||
// ES6 draft 12-06-13, section 21.2.5.3
|
||||
// + https://bugs.ecmascript.org/show_bug.cgi?id=3423
|
||||
function RegExpGetFlags() {
|
||||
if (!IS_SPEC_OBJECT(this)) {
|
||||
if (!IS_RECEIVER(this)) {
|
||||
throw MakeTypeError(
|
||||
kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this));
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ function CreateDataProperty(o, p, v) {
|
||||
|
||||
function InternalizeJSONProperty(holder, name, reviver) {
|
||||
var val = holder[name];
|
||||
if (IS_SPEC_OBJECT(val)) {
|
||||
if (IS_RECEIVER(val)) {
|
||||
if (%is_arraylike(val)) {
|
||||
var length = TO_LENGTH(val.length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
@ -150,7 +150,7 @@ function SerializeObject(value, replacer, stack, indent, gap) {
|
||||
|
||||
function JSONSerialize(key, holder, replacer, stack, indent, gap) {
|
||||
var value = holder[key];
|
||||
if (IS_SPEC_OBJECT(value)) {
|
||||
if (IS_RECEIVER(value)) {
|
||||
var toJSON = value.toJSON;
|
||||
if (IS_CALLABLE(toJSON)) {
|
||||
value = %_Call(toJSON, value, key);
|
||||
@ -167,7 +167,7 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
|
||||
return value ? "true" : "false";
|
||||
} else if (IS_NULL(value)) {
|
||||
return "null";
|
||||
} else if (IS_SPEC_OBJECT(value) && !IS_CALLABLE(value)) {
|
||||
} else if (IS_RECEIVER(value) && !IS_CALLABLE(value)) {
|
||||
// Non-callable object. If it's a primitive wrapper, it must be unwrapped.
|
||||
if (%is_arraylike(value)) {
|
||||
return SerializeArray(value, replacer, stack, indent, gap);
|
||||
|
@ -120,15 +120,10 @@ macro IS_SET_ITERATOR(arg) = (%_ClassOf(arg) === 'Set Iterator');
|
||||
macro IS_MAP_ITERATOR(arg) = (%_ClassOf(arg) === 'Map Iterator');
|
||||
macro IS_STRONG(arg) = (%IsStrong(arg));
|
||||
|
||||
# Macro for ECMAScript 5 queries of the type:
|
||||
# "Type(O) is object."
|
||||
# This is the same as being either a function or an object in V8 terminology
|
||||
# (including proxies).
|
||||
# In addition, an undetectable object is also included by this.
|
||||
macro IS_SPEC_OBJECT(arg) = (%_IsJSReceiver(arg));
|
||||
# Macro for ES queries of the type: "Type(O) is Object."
|
||||
macro IS_RECEIVER(arg) = (%_IsJSReceiver(arg));
|
||||
|
||||
# Macro for ECMAScript 5 queries of the type:
|
||||
# "IsCallable(O)"
|
||||
# Macro for ES queries of the type: "IsCallable(O)"
|
||||
macro IS_CALLABLE(arg) = (typeof(arg) === 'function');
|
||||
|
||||
# Macro for ES6 CheckObjectCoercible
|
||||
|
@ -143,7 +143,7 @@ function NoSideEffectsToString(obj) {
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_SPEC_OBJECT(obj)) {
|
||||
if (IS_RECEIVER(obj)) {
|
||||
// When internally formatting error objects, use a side-effects-free version
|
||||
// of Error.prototype.toString independent of the actually installed
|
||||
// toString method.
|
||||
@ -939,7 +939,7 @@ utils.InstallFunctions(GlobalError.prototype, DONT_ENUM,
|
||||
['toString', ErrorToString]);
|
||||
|
||||
function ErrorToString() {
|
||||
if (!IS_SPEC_OBJECT(this)) {
|
||||
if (!IS_RECEIVER(this)) {
|
||||
throw MakeTypeError(kCalledOnNonObject, "Error.prototype.toString");
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ function ConvertAcceptListToTypeMap(arg) {
|
||||
if (IS_UNDEFINED(arg))
|
||||
return arg;
|
||||
|
||||
if (!IS_SPEC_OBJECT(arg)) throw MakeTypeError(kObserveInvalidAccept);
|
||||
if (!IS_RECEIVER(arg)) throw MakeTypeError(kObserveInvalidAccept);
|
||||
|
||||
var len = TO_INTEGER(arg.length);
|
||||
if (len < 0) len = 0;
|
||||
@ -380,7 +380,7 @@ function CallbackInfoNormalize(callback) {
|
||||
|
||||
|
||||
function ObjectObserve(object, callback, acceptList) {
|
||||
if (!IS_SPEC_OBJECT(object))
|
||||
if (!IS_RECEIVER(object))
|
||||
throw MakeTypeError(kObserveNonObject, "observe", "observe");
|
||||
if (%IsJSGlobalProxy(object))
|
||||
throw MakeTypeError(kObserveGlobalProxy, "observe");
|
||||
@ -405,7 +405,7 @@ function NativeObjectObserve(object, callback, acceptList) {
|
||||
|
||||
|
||||
function ObjectUnobserve(object, callback) {
|
||||
if (!IS_SPEC_OBJECT(object))
|
||||
if (!IS_RECEIVER(object))
|
||||
throw MakeTypeError(kObserveNonObject, "unobserve", "unobserve");
|
||||
if (%IsJSGlobalProxy(object))
|
||||
throw MakeTypeError(kObserveGlobalProxy, "unobserve");
|
||||
@ -564,7 +564,7 @@ function NotifyChange(type, object, name, oldValue) {
|
||||
|
||||
|
||||
function ObjectNotifierNotify(changeRecord) {
|
||||
if (!IS_SPEC_OBJECT(this))
|
||||
if (!IS_RECEIVER(this))
|
||||
throw MakeTypeError(kCalledOnNonObject, "notify");
|
||||
|
||||
var objectInfo = ObjectInfoGetFromNotifier(this);
|
||||
@ -578,7 +578,7 @@ function ObjectNotifierNotify(changeRecord) {
|
||||
|
||||
|
||||
function ObjectNotifierPerformChange(changeType, changeFn) {
|
||||
if (!IS_SPEC_OBJECT(this))
|
||||
if (!IS_RECEIVER(this))
|
||||
throw MakeTypeError(kCalledOnNonObject, "performChange");
|
||||
|
||||
var objectInfo = ObjectInfoGetFromNotifier(this);
|
||||
@ -604,13 +604,13 @@ function NativeObjectNotifierPerformChange(objectInfo, changeType, changeFn) {
|
||||
ObjectInfoRemovePerformingType(objectInfo, changeType);
|
||||
}
|
||||
|
||||
if (IS_SPEC_OBJECT(changeRecord))
|
||||
if (IS_RECEIVER(changeRecord))
|
||||
ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType);
|
||||
}
|
||||
|
||||
|
||||
function ObjectGetNotifier(object) {
|
||||
if (!IS_SPEC_OBJECT(object))
|
||||
if (!IS_RECEIVER(object))
|
||||
throw MakeTypeError(kObserveNonObject, "getNotifier", "getNotifier");
|
||||
if (%IsJSGlobalProxy(object))
|
||||
throw MakeTypeError(kObserveGlobalProxy, "getNotifier");
|
||||
|
@ -117,7 +117,7 @@ function PromiseDone(promise, status, value, promiseQueue) {
|
||||
}
|
||||
|
||||
function PromiseCoerce(constructor, x) {
|
||||
if (!IsPromise(x) && IS_SPEC_OBJECT(x)) {
|
||||
if (!IsPromise(x) && IS_RECEIVER(x)) {
|
||||
var then;
|
||||
try {
|
||||
then = x.then;
|
||||
@ -185,7 +185,7 @@ function PromiseNopResolver() {}
|
||||
// For bootstrapper.
|
||||
|
||||
function IsPromise(x) {
|
||||
return IS_SPEC_OBJECT(x) && HAS_DEFINED_PRIVATE(x, promiseStatusSymbol);
|
||||
return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStatusSymbol);
|
||||
}
|
||||
|
||||
function PromiseCreate() {
|
||||
@ -194,7 +194,7 @@ function PromiseCreate() {
|
||||
|
||||
function PromiseResolve(promise, x) {
|
||||
if (GET_PRIVATE(promise, promiseStatusSymbol) === 0) {
|
||||
if (IS_SPEC_OBJECT(x)) {
|
||||
if (IS_RECEIVER(x)) {
|
||||
// 25.4.1.3.2 steps 8-12
|
||||
try {
|
||||
var then = x.then;
|
||||
|
@ -35,7 +35,7 @@ function ProxyEnumerate(trap, handler, target) {
|
||||
// 7. Let trapResult be ? Call(trap, handler, «target»).
|
||||
var trap_result = %_Call(trap, handler, target);
|
||||
// 8. If Type(trapResult) is not Object, throw a TypeError exception.
|
||||
if (!IS_SPEC_OBJECT(trap_result)) {
|
||||
if (!IS_RECEIVER(trap_result)) {
|
||||
throw MakeTypeError(kProxyEnumerateNonObject);
|
||||
}
|
||||
// 9. Return trapResult.
|
||||
|
@ -46,7 +46,7 @@ var RegExpLastMatchInfo = new InternalPackedArray(
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function IsRegExp(o) {
|
||||
if (!IS_SPEC_OBJECT(o)) return false;
|
||||
if (!IS_RECEIVER(o)) return false;
|
||||
var is_regexp = o[matchSymbol];
|
||||
if (!IS_UNDEFINED(is_regexp)) return TO_BOOLEAN(is_regexp);
|
||||
return IS_REGEXP(o);
|
||||
|
@ -46,7 +46,7 @@ function StringIteratorNext() {
|
||||
var value = UNDEFINED;
|
||||
var done = true;
|
||||
|
||||
if (!IS_SPEC_OBJECT(iterator) ||
|
||||
if (!IS_RECEIVER(iterator) ||
|
||||
!HAS_DEFINED_PRIVATE(iterator, stringIteratorNextIndexSymbol)) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'String Iterator.prototype.next');
|
||||
|
@ -163,7 +163,7 @@ function ObjectHasOwnProperty(value) {
|
||||
|
||||
// ES6 19.1.3.3 Object.prototype.isPrototypeOf(V)
|
||||
function ObjectIsPrototypeOf(V) {
|
||||
if (!IS_SPEC_OBJECT(V)) return false;
|
||||
if (!IS_RECEIVER(V)) return false;
|
||||
var O = TO_OBJECT(this);
|
||||
return %_HasInPrototypeChain(V, O);
|
||||
}
|
||||
@ -289,7 +289,7 @@ function FromGenericPropertyDescriptor(desc) {
|
||||
|
||||
// ES6 6.2.4.5
|
||||
function ToPropertyDescriptor(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj)) throw MakeTypeError(kPropertyDescObject, obj);
|
||||
if (!IS_RECEIVER(obj)) throw MakeTypeError(kPropertyDescObject, obj);
|
||||
|
||||
var desc = new PropertyDescriptor();
|
||||
|
||||
@ -784,11 +784,11 @@ function ObjectGetPrototypeOf(obj) {
|
||||
function ObjectSetPrototypeOf(obj, proto) {
|
||||
CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf");
|
||||
|
||||
if (proto !== null && !IS_SPEC_OBJECT(proto)) {
|
||||
if (proto !== null && !IS_RECEIVER(proto)) {
|
||||
throw MakeTypeError(kProtoObjectOrNull, proto);
|
||||
}
|
||||
|
||||
if (IS_SPEC_OBJECT(obj)) {
|
||||
if (IS_RECEIVER(obj)) {
|
||||
%SetPrototype(obj, proto);
|
||||
}
|
||||
|
||||
@ -811,7 +811,7 @@ function ObjectGetOwnPropertyNames(obj) {
|
||||
|
||||
// ES5 section 15.2.3.5.
|
||||
function ObjectCreate(proto, properties) {
|
||||
if (!IS_SPEC_OBJECT(proto) && proto !== null) {
|
||||
if (!IS_RECEIVER(proto) && proto !== null) {
|
||||
throw MakeTypeError(kProtoObjectOrNull, proto);
|
||||
}
|
||||
var obj = {};
|
||||
@ -826,7 +826,7 @@ function ObjectDefineProperty(obj, p, attributes) {
|
||||
// The new pure-C++ implementation doesn't support O.o.
|
||||
// TODO(jkummerow): Implement missing features and remove fallback path.
|
||||
if (%IsObserved(obj)) {
|
||||
if (!IS_SPEC_OBJECT(obj)) {
|
||||
if (!IS_RECEIVER(obj)) {
|
||||
throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty");
|
||||
}
|
||||
var name = TO_NAME(p);
|
||||
@ -848,7 +848,7 @@ function ObjectDefineProperties(obj, properties) {
|
||||
// The new pure-C++ implementation doesn't support O.o.
|
||||
// TODO(jkummerow): Implement missing features and remove fallback path.
|
||||
if (%IsObserved(obj)) {
|
||||
if (!IS_SPEC_OBJECT(obj)) {
|
||||
if (!IS_RECEIVER(obj)) {
|
||||
throw MakeTypeError(kCalledOnNonObject, "Object.defineProperties");
|
||||
}
|
||||
var props = TO_OBJECT(properties);
|
||||
@ -868,42 +868,42 @@ function ObjectDefineProperties(obj, properties) {
|
||||
|
||||
// ES6 19.1.2.17
|
||||
function ObjectSealJS(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj)) return obj;
|
||||
if (!IS_RECEIVER(obj)) return obj;
|
||||
return %ObjectSeal(obj);
|
||||
}
|
||||
|
||||
|
||||
// ES6 19.1.2.5
|
||||
function ObjectFreezeJS(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj)) return obj;
|
||||
if (!IS_RECEIVER(obj)) return obj;
|
||||
return %ObjectFreeze(obj);
|
||||
}
|
||||
|
||||
|
||||
// ES6 19.1.2.15
|
||||
function ObjectPreventExtension(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj)) return obj;
|
||||
if (!IS_RECEIVER(obj)) return obj;
|
||||
return %PreventExtensions(obj);
|
||||
}
|
||||
|
||||
|
||||
// ES6 19.1.2.13
|
||||
function ObjectIsSealed(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj)) return true;
|
||||
if (!IS_RECEIVER(obj)) return true;
|
||||
return %ObjectIsSealed(obj);
|
||||
}
|
||||
|
||||
|
||||
// ES6 19.1.2.12
|
||||
function ObjectIsFrozen(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj)) return true;
|
||||
if (!IS_RECEIVER(obj)) return true;
|
||||
return %ObjectIsFrozen(obj);
|
||||
}
|
||||
|
||||
|
||||
// ES6 19.1.2.11
|
||||
function ObjectIsExtensible(obj) {
|
||||
if (!IS_SPEC_OBJECT(obj)) return false;
|
||||
if (!IS_RECEIVER(obj)) return false;
|
||||
return %IsExtensible(obj);
|
||||
}
|
||||
|
||||
@ -918,7 +918,7 @@ function ObjectGetProto() {
|
||||
function ObjectSetProto(proto) {
|
||||
CHECK_OBJECT_COERCIBLE(this, "Object.prototype.__proto__");
|
||||
|
||||
if ((IS_SPEC_OBJECT(proto) || IS_NULL(proto)) && IS_SPEC_OBJECT(this)) {
|
||||
if ((IS_RECEIVER(proto) || IS_NULL(proto)) && IS_RECEIVER(this)) {
|
||||
%SetPrototype(this, proto);
|
||||
}
|
||||
}
|
||||
@ -1428,7 +1428,7 @@ function GetIterator(obj, method) {
|
||||
throw MakeTypeError(kNotIterable, obj);
|
||||
}
|
||||
var iterator = %_Call(method, obj);
|
||||
if (!IS_SPEC_OBJECT(iterator)) {
|
||||
if (!IS_RECEIVER(iterator)) {
|
||||
throw MakeTypeError(kNotAnIterator, iterator);
|
||||
}
|
||||
return iterator;
|
||||
|
@ -41,7 +41,7 @@ function WeakMapConstructor(iterable) {
|
||||
throw MakeTypeError(kPropertyNotFunction, adder, 'set', this);
|
||||
}
|
||||
for (var nextItem of iterable) {
|
||||
if (!IS_SPEC_OBJECT(nextItem)) {
|
||||
if (!IS_RECEIVER(nextItem)) {
|
||||
throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
|
||||
}
|
||||
%_Call(adder, this, nextItem[0], nextItem[1]);
|
||||
@ -55,7 +55,7 @@ function WeakMapGet(key) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'WeakMap.prototype.get', this);
|
||||
}
|
||||
if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
|
||||
if (!IS_RECEIVER(key)) return UNDEFINED;
|
||||
var hash = GetExistingHash(key);
|
||||
if (IS_UNDEFINED(hash)) return UNDEFINED;
|
||||
return %WeakCollectionGet(this, key, hash);
|
||||
@ -67,7 +67,7 @@ function WeakMapSet(key, value) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'WeakMap.prototype.set', this);
|
||||
}
|
||||
if (!IS_SPEC_OBJECT(key)) throw MakeTypeError(kInvalidWeakMapKey);
|
||||
if (!IS_RECEIVER(key)) throw MakeTypeError(kInvalidWeakMapKey);
|
||||
return %WeakCollectionSet(this, key, value, GetHash(key));
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ function WeakMapHas(key) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'WeakMap.prototype.has', this);
|
||||
}
|
||||
if (!IS_SPEC_OBJECT(key)) return false;
|
||||
if (!IS_RECEIVER(key)) return false;
|
||||
var hash = GetExistingHash(key);
|
||||
if (IS_UNDEFINED(hash)) return false;
|
||||
return %WeakCollectionHas(this, key, hash);
|
||||
@ -89,7 +89,7 @@ function WeakMapDelete(key) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'WeakMap.prototype.delete', this);
|
||||
}
|
||||
if (!IS_SPEC_OBJECT(key)) return false;
|
||||
if (!IS_RECEIVER(key)) return false;
|
||||
var hash = GetExistingHash(key);
|
||||
if (IS_UNDEFINED(hash)) return false;
|
||||
return %WeakCollectionDelete(this, key, hash);
|
||||
@ -141,7 +141,7 @@ function WeakSetAdd(value) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'WeakSet.prototype.add', this);
|
||||
}
|
||||
if (!IS_SPEC_OBJECT(value)) throw MakeTypeError(kInvalidWeakSetValue);
|
||||
if (!IS_RECEIVER(value)) throw MakeTypeError(kInvalidWeakSetValue);
|
||||
return %WeakCollectionSet(this, value, true, GetHash(value));
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ function WeakSetHas(value) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'WeakSet.prototype.has', this);
|
||||
}
|
||||
if (!IS_SPEC_OBJECT(value)) return false;
|
||||
if (!IS_RECEIVER(value)) return false;
|
||||
var hash = GetExistingHash(value);
|
||||
if (IS_UNDEFINED(hash)) return false;
|
||||
return %WeakCollectionHas(this, value, hash);
|
||||
@ -163,7 +163,7 @@ function WeakSetDelete(value) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver,
|
||||
'WeakSet.prototype.delete', this);
|
||||
}
|
||||
if (!IS_SPEC_OBJECT(value)) return false;
|
||||
if (!IS_RECEIVER(value)) return false;
|
||||
var hash = GetExistingHash(value);
|
||||
if (IS_UNDEFINED(hash)) return false;
|
||||
return %WeakCollectionDelete(this, value, hash);
|
||||
|
Loading…
Reference in New Issue
Block a user