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 #ifndef wasm_initexpr_h
20 #define wasm_initexpr_h
21 
22 #include "wasm/WasmConstants.h"
23 #include "wasm/WasmSerialize.h"
24 #include "wasm/WasmTypeDecls.h"
25 #include "wasm/WasmValType.h"
26 #include "wasm/WasmValue.h"
27 
28 namespace js {
29 namespace wasm {
30 
31 class Decoder;
32 struct ModuleEnvironment;
33 
34 enum class InitExprKind {
35   None,
36   Literal,
37   Variable,
38 };
39 
40 // A InitExpr describes a deferred initializer expression, used to initialize
41 // a global or a table element offset. Such expressions are created during
42 // decoding and actually executed on module instantiation.
43 
44 class InitExpr {
45   InitExprKind kind_;
46   // The bytecode for this constant expression if this is not a literal.
47   Bytes bytecode_;
48   // The value if this is a literal.
49   LitVal literal_;
50   // The value type of this constant expression in either case.
51   ValType type_;
52 
53  public:
InitExpr()54   InitExpr() : kind_(InitExprKind::None) {}
55 
InitExpr(LitVal literal)56   explicit InitExpr(LitVal literal)
57       : kind_(InitExprKind::Literal),
58         literal_(literal),
59         type_(literal.type()) {}
60 
61   // Decode and validate a constant expression given at the current
62   // position of the decoder. Upon failure, the decoder contains the failure
63   // message or else the failure was an OOM.
64   static bool decodeAndValidate(Decoder& d, ModuleEnvironment* env,
65                                 ValType expected, InitExpr* expr);
66 
67   // Evaluate the constant expresssion with the given context. This may only
68   // fail due to an OOM, as all InitExpr's are required to have been validated.
69   bool evaluate(JSContext* cx, const ValVector& globalImportValues,
70                 HandleWasmInstanceObject instanceObj,
71                 MutableHandleVal result) const;
72 
isLiteral()73   bool isLiteral() const { return kind_ == InitExprKind::Literal; }
74 
75   // Gets the result of this expression if it was determined to be a literal.
literal()76   LitVal literal() const {
77     MOZ_ASSERT(isLiteral());
78     return literal_;
79   }
80 
81   // Get the type of the resulting value of this expression.
type()82   ValType type() const { return type_; }
83 
84   // Allow moving, but not implicit copying
85   InitExpr(const InitExpr&) = delete;
86   InitExpr& operator=(const InitExpr&) = delete;
87   InitExpr(InitExpr&&) = default;
88   InitExpr& operator=(InitExpr&&) = default;
89 
90   // Allow explicit cloning
91   [[nodiscard]] bool clone(const InitExpr& src);
92 
93   WASM_DECLARE_SERIALIZABLE(InitExpr)
94 };
95 
96 }  // namespace wasm
97 }  // namespace js
98 
99 #endif  // wasm_initexpr_h
100