diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/src/wasm/WasmAnyRef.cpp | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/wasm/WasmAnyRef.cpp')
-rw-r--r-- | js/src/wasm/WasmAnyRef.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/js/src/wasm/WasmAnyRef.cpp b/js/src/wasm/WasmAnyRef.cpp new file mode 100644 index 0000000000..8e3f716d41 --- /dev/null +++ b/js/src/wasm/WasmAnyRef.cpp @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * + * Copyright 2023 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wasm/WasmAnyRef.h" + +#include "vm/JSContext.h" +#include "vm/JSObject.h" +#include "vm/NativeObject.h" + +#include "vm/JSObject-inl.h" + +using namespace js; +using namespace js::wasm; + +class WasmValueBox : public NativeObject { + public: + static const unsigned VALUE_SLOT = 0; + static const unsigned RESERVED_SLOTS = 1; + static const JSClass class_; + + static WasmValueBox* create(JSContext* cx, HandleValue value); + Value value() const { return getFixedSlot(VALUE_SLOT); } +}; + +const JSClass WasmValueBox::class_ = { + "WasmValueBox", JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS)}; + +WasmValueBox* WasmValueBox::create(JSContext* cx, HandleValue value) { + WasmValueBox* obj = NewObjectWithGivenProto<WasmValueBox>(cx, nullptr); + if (!obj) { + return nullptr; + } + obj->setFixedSlot(VALUE_SLOT, value); + return obj; +} + +const JSClass* AnyRef::valueBoxClass() { return &WasmValueBox::class_; } + +size_t AnyRef::valueBoxOffsetOfValue() { + return NativeObject::getFixedSlotOffset(WasmValueBox::VALUE_SLOT); +} + +bool AnyRef::fromJSValue(JSContext* cx, HandleValue value, + MutableHandleAnyRef result) { + if (value.isNull()) { + result.set(AnyRef::null()); + return true; + } + + if (value.isString()) { + JSString* string = value.toString(); + result.set(AnyRef::fromJSString(string)); + return true; + } + + if (value.isObject()) { + JSObject& obj = value.toObject(); + MOZ_ASSERT(!obj.is<WasmValueBox>()); + MOZ_ASSERT(obj.compartment() == cx->compartment()); + result.set(AnyRef::fromJSObject(obj)); + return true; + } + + if (value.isInt32() && !int32NeedsBoxing(value.toInt32())) { + result.set(AnyRef::fromInt32(value.toInt32())); + return true; + } + + if (value.isDouble()) { + double doubleValue = value.toDouble(); + int32_t intValue; + if (mozilla::NumberIsInt32(doubleValue, &intValue) && + !int32NeedsBoxing(intValue)) { + result.set(AnyRef::fromInt32(intValue)); + return true; + } + } + + JSObject* box = AnyRef::boxValue(cx, value); + if (!box) { + return false; + } + result.set(AnyRef::fromJSObject(*box)); + return true; +} + +JSObject* AnyRef::boxValue(JSContext* cx, HandleValue value) { + MOZ_ASSERT(AnyRef::valueNeedsBoxing(value)); + return WasmValueBox::create(cx, value); +} + +Value wasm::AnyRef::toJSValue() const { + // If toJSValue needs to allocate then we need a more complicated API, and + // we need to root the value in the callers, see comments in callExport(). + Value value; + if (isNull()) { + value.setNull(); + } else if (isJSString()) { + value.setString(toJSString()); + } else if (isI31()) { + value.setInt32(toI31()); + } else { + JSObject& obj = toJSObject(); + if (obj.is<WasmValueBox>()) { + value = obj.as<WasmValueBox>().value(); + } else { + value.setObject(obj); + } + } + return value; +} |