JumpList.h (2756B)
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 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef frontend_JumpList_h 8 #define frontend_JumpList_h 9 10 #include <stddef.h> // ptrdiff_t 11 12 #include "frontend/BytecodeOffset.h" // BytecodeOffset 13 #include "js/TypeDecls.h" // jsbytecode 14 15 namespace js { 16 namespace frontend { 17 18 // Linked list of jump instructions that need to be patched. The linked list is 19 // stored in the bytes of the incomplete bytecode that will be patched, so no 20 // extra memory is needed, and patching the instructions destroys the list. 21 // 22 // Example: 23 // 24 // JumpList brList; 25 // if (!emitJump(JSOp::JumpIfFalse, &brList)) { 26 // return false; 27 // } 28 // ... 29 // JumpTarget label; 30 // if (!emitJumpTarget(&label)) { 31 // return false; 32 // } 33 // ... 34 // if (!emitJump(JSOp::Goto, &brList)) { 35 // return false; 36 // } 37 // ... 38 // patchJumpsToTarget(brList, label); 39 // 40 // +-> (the delta is END_OF_LIST_DELTA (=0) for the last 41 // | item) 42 // | 43 // | 44 // JumpIfFalse .. <+ + +-+ JumpIfFalse .. 45 // .. | | .. 46 // label: | +-> label: 47 // JumpTarget | | JumpTarget 48 // .. | | .. 49 // Goto .. <+ +----+ +-+ Goto .. <+ 50 // | | 51 // | | 52 // + + 53 // brList brList 54 // 55 // | ^ 56 // +------- patchJumpsToTarget -------+ 57 // 58 59 // Offset of a jump target instruction, used for patching jump instructions. 60 struct JumpTarget { 61 BytecodeOffset offset = BytecodeOffset::invalidOffset(); 62 }; 63 64 struct JumpList { 65 // Delta value for pre-patchJumpsToTarget that marks the end of the link. 66 static const ptrdiff_t END_OF_LIST_DELTA = 0; 67 68 // -1 is used to mark the end of jump lists. 69 JumpList() : offset(BytecodeOffset::invalidOffset()) {} 70 71 BytecodeOffset offset; 72 73 // Add a jump instruction to the list. 74 void push(jsbytecode* code, BytecodeOffset jumpOffset); 75 76 // Patch all jump instructions in this list to jump to `target`. This 77 // clobbers the list. 78 void patchAll(jsbytecode* code, JumpTarget target); 79 }; 80 81 } /* namespace frontend */ 82 } /* namespace js */ 83 84 #endif /* frontend_JumpList_h */