WasmInitExpr.h (4273B)
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 CodeMetadata; 33 34 // Validates a constant expression. Returns an optional literal value if the 35 // final value was from a simple instruction such as i32.const. 36 [[nodiscard]] bool DecodeConstantExpression(Decoder& d, CodeMetadata* codeMeta, 37 ValType expected, 38 mozilla::Maybe<LitVal>* literal); 39 40 enum class InitExprKind { 41 None, 42 Literal, 43 Variable, 44 }; 45 46 // A InitExpr describes a WebAssembly constant expression, such as those used to 47 // initialize a global, specify memory offsets in data segments, or populate 48 // element segments. Such expressions are created during decoding and actually 49 // executed on module instantiation. 50 // 51 // An InitExpr can only contain constant instructions, which are defined here in 52 // the spec: 53 // 54 // https://webassembly.github.io/spec/core/valid/instructions.html#constant-expressions 55 56 class InitExpr { 57 InitExprKind kind_; 58 // The bytecode for this constant expression. 59 Bytes bytecode_; 60 // The value, only if this is a literal. 61 LitVal literal_; 62 // The value type of this constant expression. 63 ValType type_; 64 65 public: 66 InitExpr() : kind_(InitExprKind::None) {} 67 68 explicit InitExpr(LitVal literal) 69 : kind_(InitExprKind::Literal), 70 literal_(literal), 71 type_(literal.type()) {} 72 73 // Decode and validate a constant expression given at the current 74 // position of the decoder. Upon failure, the decoder contains the failure 75 // message or else the failure was an OOM. 76 static bool decodeAndValidate(Decoder& d, CodeMetadata* codeMeta, 77 ValType expected, InitExpr* expr); 78 79 // Decode and evaluate a constant expression at the current position of the 80 // decoder. Does not validate the expression first, since all InitExprs are 81 // required to have been validated. Failure conditions are the same as 82 // InitExpr::evaluate, i.e. failing only on OOM. 83 [[nodiscard]] static bool decodeAndEvaluate( 84 JSContext* cx, Handle<WasmInstanceObject*> instanceObj, Decoder& d, 85 ValType expectedType, MutableHandleVal result); 86 87 // Evaluate the constant expression with the given context. This may only fail 88 // due to an OOM, as all InitExpr's are required to have been validated. 89 bool evaluate(JSContext* cx, Handle<WasmInstanceObject*> instanceObj, 90 MutableHandleVal result) const; 91 92 bool isLiteral() const { return kind_ == InitExprKind::Literal; } 93 94 // Gets the result of this expression if it was determined to be a literal. 95 LitVal literal() const { 96 MOZ_ASSERT(isLiteral()); 97 return literal_; 98 } 99 100 // Get the type of the resulting value of this expression. 101 ValType type() const { return type_; } 102 103 // Return the raw bytecode for the expression. 104 const Bytes& bytecode() const { return bytecode_; } 105 106 // Allow moving, but not implicit copying 107 InitExpr(const InitExpr&) = delete; 108 InitExpr& operator=(const InitExpr&) = delete; 109 InitExpr(InitExpr&&) = default; 110 InitExpr& operator=(InitExpr&&) = default; 111 112 // Allow explicit cloning 113 [[nodiscard]] bool clone(const InitExpr& src); 114 115 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; 116 WASM_DECLARE_FRIEND_SERIALIZE(InitExpr); 117 }; 118 119 } // namespace wasm 120 } // namespace js 121 122 #endif // wasm_initexpr_h