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:
3 *
4 * Copyright 2021 Mozilla Foundation
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 */
18
19 #include "wasm/WasmValType.h"
20
21 #include "js/friend/ErrorMessages.h" // JSMSG_*
22 #include "js/Printf.h"
23 #include "js/Value.h"
24 #include "vm/StringType.h"
25 #include "wasm/WasmJS.h"
26
27 using namespace js;
28 using namespace js::wasm;
29
ToValType(JSContext * cx,HandleValue v,ValType * out)30 bool wasm::ToValType(JSContext* cx, HandleValue v, ValType* out) {
31 RootedString typeStr(cx, ToString(cx, v));
32 if (!typeStr) {
33 return false;
34 }
35
36 RootedLinearString typeLinearStr(cx, typeStr->ensureLinear(cx));
37 if (!typeLinearStr) {
38 return false;
39 }
40
41 if (StringEqualsLiteral(typeLinearStr, "i32")) {
42 *out = ValType::I32;
43 } else if (StringEqualsLiteral(typeLinearStr, "i64")) {
44 *out = ValType::I64;
45 } else if (StringEqualsLiteral(typeLinearStr, "f32")) {
46 *out = ValType::F32;
47 } else if (StringEqualsLiteral(typeLinearStr, "f64")) {
48 *out = ValType::F64;
49 #ifdef ENABLE_WASM_SIMD
50 } else if (SimdAvailable(cx) && StringEqualsLiteral(typeLinearStr, "v128")) {
51 *out = ValType::V128;
52 #endif
53 } else if (StringEqualsLiteral(typeLinearStr, "funcref")) {
54 *out = RefType::func();
55 } else if (StringEqualsLiteral(typeLinearStr, "externref")) {
56 *out = RefType::extern_();
57 #ifdef ENABLE_WASM_GC
58 } else if (GcAvailable(cx) && StringEqualsLiteral(typeLinearStr, "eqref")) {
59 *out = RefType::eq();
60 #endif
61 } else {
62 JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
63 JSMSG_WASM_BAD_STRING_VAL_TYPE);
64 return false;
65 }
66
67 return true;
68 }
69
ToString(ValType type)70 UniqueChars wasm::ToString(ValType type) {
71 const char* literal = nullptr;
72 switch (type.kind()) {
73 case ValType::I32:
74 literal = "i32";
75 break;
76 case ValType::I64:
77 literal = "i64";
78 break;
79 case ValType::V128:
80 literal = "v128";
81 break;
82 case ValType::F32:
83 literal = "f32";
84 break;
85 case ValType::F64:
86 literal = "f64";
87 break;
88 case ValType::Ref:
89 if (type.isNullable() && !type.isTypeIndex()) {
90 switch (type.refTypeKind()) {
91 case RefType::Func:
92 literal = "funcref";
93 break;
94 case RefType::Extern:
95 literal = "externref";
96 break;
97 case RefType::Eq:
98 literal = "eqref";
99 break;
100 case RefType::TypeIndex:
101 MOZ_ASSERT_UNREACHABLE();
102 }
103 } else {
104 const char* heapType = nullptr;
105 switch (type.refTypeKind()) {
106 case RefType::Func:
107 heapType = "func";
108 break;
109 case RefType::Extern:
110 heapType = "extern";
111 break;
112 case RefType::Eq:
113 heapType = "eq";
114 break;
115 case RefType::TypeIndex:
116 return JS_smprintf("(ref %s%d)", type.isNullable() ? "null " : "",
117 type.refType().typeIndex());
118 }
119 return JS_smprintf("(ref %s%s)", type.isNullable() ? "null " : "",
120 heapType);
121 }
122 break;
123 case ValType::Rtt:
124 return JS_smprintf("(rtt %d %d)", type.rttDepth(), type.typeIndex());
125 }
126 return JS_smprintf("%s", literal);
127 }
128
ToString(const Maybe<ValType> & type)129 UniqueChars wasm::ToString(const Maybe<ValType>& type) {
130 return type ? ToString(type.ref()) : JS_smprintf("%s", "void");
131 }
132