Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / src / wasm / WasmAnyRef.cpp
blob8e3f716d41836dd5fac584536a137941bb147e8b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
4 * Copyright 2023 Mozilla Foundation
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #include "wasm/WasmAnyRef.h"
21 #include "vm/JSContext.h"
22 #include "vm/JSObject.h"
23 #include "vm/NativeObject.h"
25 #include "vm/JSObject-inl.h"
27 using namespace js;
28 using namespace js::wasm;
30 class WasmValueBox : public NativeObject {
31 public:
32 static const unsigned VALUE_SLOT = 0;
33 static const unsigned RESERVED_SLOTS = 1;
34 static const JSClass class_;
36 static WasmValueBox* create(JSContext* cx, HandleValue value);
37 Value value() const { return getFixedSlot(VALUE_SLOT); }
40 const JSClass WasmValueBox::class_ = {
41 "WasmValueBox", JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS)};
43 WasmValueBox* WasmValueBox::create(JSContext* cx, HandleValue value) {
44 WasmValueBox* obj = NewObjectWithGivenProto<WasmValueBox>(cx, nullptr);
45 if (!obj) {
46 return nullptr;
48 obj->setFixedSlot(VALUE_SLOT, value);
49 return obj;
52 const JSClass* AnyRef::valueBoxClass() { return &WasmValueBox::class_; }
54 size_t AnyRef::valueBoxOffsetOfValue() {
55 return NativeObject::getFixedSlotOffset(WasmValueBox::VALUE_SLOT);
58 bool AnyRef::fromJSValue(JSContext* cx, HandleValue value,
59 MutableHandleAnyRef result) {
60 if (value.isNull()) {
61 result.set(AnyRef::null());
62 return true;
65 if (value.isString()) {
66 JSString* string = value.toString();
67 result.set(AnyRef::fromJSString(string));
68 return true;
71 if (value.isObject()) {
72 JSObject& obj = value.toObject();
73 MOZ_ASSERT(!obj.is<WasmValueBox>());
74 MOZ_ASSERT(obj.compartment() == cx->compartment());
75 result.set(AnyRef::fromJSObject(obj));
76 return true;
79 if (value.isInt32() && !int32NeedsBoxing(value.toInt32())) {
80 result.set(AnyRef::fromInt32(value.toInt32()));
81 return true;
84 if (value.isDouble()) {
85 double doubleValue = value.toDouble();
86 int32_t intValue;
87 if (mozilla::NumberIsInt32(doubleValue, &intValue) &&
88 !int32NeedsBoxing(intValue)) {
89 result.set(AnyRef::fromInt32(intValue));
90 return true;
94 JSObject* box = AnyRef::boxValue(cx, value);
95 if (!box) {
96 return false;
98 result.set(AnyRef::fromJSObject(*box));
99 return true;
102 JSObject* AnyRef::boxValue(JSContext* cx, HandleValue value) {
103 MOZ_ASSERT(AnyRef::valueNeedsBoxing(value));
104 return WasmValueBox::create(cx, value);
107 Value wasm::AnyRef::toJSValue() const {
108 // If toJSValue needs to allocate then we need a more complicated API, and
109 // we need to root the value in the callers, see comments in callExport().
110 Value value;
111 if (isNull()) {
112 value.setNull();
113 } else if (isJSString()) {
114 value.setString(toJSString());
115 } else if (isI31()) {
116 value.setInt32(toI31());
117 } else {
118 JSObject& obj = toJSObject();
119 if (obj.is<WasmValueBox>()) {
120 value = obj.as<WasmValueBox>().value();
121 } else {
122 value.setObject(obj);
125 return value;