summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/TupleObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/builtin/TupleObject.cpp')
-rw-r--r--js/src/builtin/TupleObject.cpp102
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};