/* -*- 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 tuple) { TupleObject* tup = NewBuiltinClassInstance(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(); } // Caller is responsible for rooting the result mozilla::Maybe TupleObject::maybeUnbox(JSObject* obj) { Maybe result = mozilla::Nothing(); if (obj->is()) { result.emplace(obj->as()); } else if (obj->is()) { result.emplace(obj->as().unbox()); } return result; } bool js::IsTuple(JSObject& obj) { return (obj.is() || obj.is()); } // Caller is responsible for rooting the result mozilla::Maybe js::ThisTupleValue(JSContext* cx, HandleValue val) { if (!js::IsTuple(val)) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_TUPLE_OBJECT); return mozilla::Nothing(); } Maybe 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().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};