diff options
Diffstat (limited to 'js/src/builtin/TupleObject.cpp')
-rw-r--r-- | js/src/builtin/TupleObject.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/js/src/builtin/TupleObject.cpp b/js/src/builtin/TupleObject.cpp new file mode 100644 index 0000000000..524e909262 --- /dev/null +++ b/js/src/builtin/TupleObject.cpp @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "builtin/TupleObject.h" + +#include "mozilla/Assertions.h" + +#include "jsapi.h" + +#include "vm/NativeObject.h" +#include "vm/ObjectOperations.h" +#include "vm/TupleType.h" + +#include "vm/JSObject-inl.h" +#include "vm/NativeObject-inl.h" + +using namespace js; + +// Record and Tuple proposal section 9.2.1 + +TupleObject* TupleObject::create(JSContext* cx, Handle<TupleType*> tuple) { + TupleObject* tup = NewBuiltinClassInstance<TupleObject>(cx); + if (!tup) { + return nullptr; + } + tup->setFixedSlot(PrimitiveValueSlot, ExtendedPrimitiveValue(*tuple)); + return tup; +} + +// Caller is responsible for rooting the result +TupleType& TupleObject::unbox() const { + return getFixedSlot(PrimitiveValueSlot).toExtendedPrimitive().as<TupleType>(); +} + +// Caller is responsible for rooting the result +mozilla::Maybe<TupleType&> TupleObject::maybeUnbox(JSObject* obj) { + Maybe<TupleType&> result = mozilla::Nothing(); + if (obj->is<TupleType>()) { + result.emplace(obj->as<TupleType>()); + } else if (obj->is<TupleObject>()) { + result.emplace(obj->as<TupleObject>().unbox()); + } + return result; +} + +bool js::IsTuple(JSObject& obj) { + return (obj.is<TupleType>() || obj.is<TupleObject>()); +} + +// Caller is responsible for rooting the result +mozilla::Maybe<TupleType&> js::ThisTupleValue(JSContext* cx, HandleValue val) { + if (!js::IsTuple(val)) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_BAD_TUPLE_OBJECT); + return mozilla::Nothing(); + } + Maybe<TupleType&> result = mozilla::Nothing(); + result.emplace(TupleType::thisTupleValue(val)); + return (result); +} + +bool tup_mayResolve(const JSAtomState&, jsid id, JSObject*) { + // tup_resolve ignores non-integer ids. + return id.isInt(); +} + +bool tup_resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp) { + RootedValue value(cx); + *resolvedp = obj->as<TupleObject>().unbox().getOwnProperty(id, &value); + + if (*resolvedp) { + static const unsigned TUPLE_ELEMENT_ATTRS = + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT; + return DefineDataProperty(cx, obj, id, value, + TUPLE_ELEMENT_ATTRS | JSPROP_RESOLVING); + } + + return true; +} + +const JSClassOps TupleObjectClassOps = { + nullptr, // addProperty + nullptr, // delProperty + nullptr, // enumerate + nullptr, // newEnumerate + tup_resolve, // resolve + tup_mayResolve, // mayResolve + nullptr, // finalize + nullptr, // call + nullptr, // construct + nullptr, // trace +}; + +const JSClass TupleObject::class_ = { + "TupleObject", + JSCLASS_HAS_RESERVED_SLOTS(SlotCount) | + JSCLASS_HAS_CACHED_PROTO(JSProto_Tuple), + &TupleObjectClassOps}; |