SymbolPrototype.cpp [plain text]
#include "config.h"
#include "SymbolPrototype.h"
#include "Error.h"
#include "JSCInlines.h"
#include "JSString.h"
#include "SymbolObject.h"
namespace JSC {
static EncodedJSValue JSC_HOST_CALL symbolProtoGetterDescription(ExecState*);
static EncodedJSValue JSC_HOST_CALL symbolProtoFuncToString(ExecState*);
static EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState*);
}
#include "SymbolPrototype.lut.h"
namespace JSC {
const ClassInfo SymbolPrototype::s_info = { "Symbol", &Base::s_info, &symbolPrototypeTable, nullptr, CREATE_METHOD_TABLE(SymbolPrototype) };
SymbolPrototype::SymbolPrototype(VM& vm, Structure* structure)
: Base(vm, structure)
{
}
void SymbolPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
{
Base::finishCreation(vm);
putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Symbol"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
ASSERT(inherits(vm, info()));
JSFunction* toPrimitiveFunction = JSFunction::create(vm, globalObject, 1, "[Symbol.toPrimitive]"_s, symbolProtoFuncValueOf, NoIntrinsic);
putDirectWithoutTransition(vm, vm.propertyNames->toPrimitiveSymbol, toPrimitiveFunction, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
}
static const ASCIILiteral SymbolDescriptionTypeError { "Symbol.prototype.description requires that |this| be a symbol or a symbol object"_s };
static const ASCIILiteral SymbolToStringTypeError { "Symbol.prototype.toString requires that |this| be a symbol or a symbol object"_s };
static const ASCIILiteral SymbolValueOfTypeError { "Symbol.prototype.valueOf requires that |this| be a symbol or a symbol object"_s };
inline Symbol* tryExtractSymbol(VM& vm, JSValue thisValue)
{
if (thisValue.isSymbol())
return asSymbol(thisValue);
if (!thisValue.isObject())
return nullptr;
JSObject* thisObject = asObject(thisValue);
if (!thisObject->inherits<SymbolObject>(vm))
return nullptr;
return asSymbol(jsCast<SymbolObject*>(thisObject)->internalValue());
}
EncodedJSValue JSC_HOST_CALL symbolProtoGetterDescription(ExecState* exec)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
Symbol* symbol = tryExtractSymbol(vm, exec->thisValue());
if (!symbol)
return throwVMTypeError(exec, scope, SymbolDescriptionTypeError);
scope.release();
return JSValue::encode(jsString(&vm, symbol->description()));
}
EncodedJSValue JSC_HOST_CALL symbolProtoFuncToString(ExecState* exec)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
Symbol* symbol = tryExtractSymbol(vm, exec->thisValue());
if (!symbol)
return throwVMTypeError(exec, scope, SymbolToStringTypeError);
scope.release();
return JSValue::encode(jsNontrivialString(&vm, symbol->descriptiveString()));
}
EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState* exec)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
Symbol* symbol = tryExtractSymbol(vm, exec->thisValue());
if (!symbol)
return throwVMTypeError(exec, scope, SymbolValueOfTypeError);
scope.release();
return JSValue::encode(symbol);
}
}