/* * Save the current jitStack status to the label. * This is done when the label is referenced the first time. */ static int _ILJitLabelSaveStack(ILJITCoder *coder, ILJITLabel *label) { int coderStackHeight = _ILJitStackHeight(coder); #ifdef _IL_JIT_ENABLE_INLINE int coderStackBase; if(coder->currentInlineContext) { coderStackBase = coder->currentInlineContext->stackBase; coderStackHeight -= coderStackBase; } else { coderStackBase = 0; } #else /* !_IL_JIT_ENABLE_INLINE */ int coderStackBase = 0; #endif /* !_IL_JIT_ENABLE_INLINE */ if(((label->labelType & (_IL_JIT_LABEL_NORMAL | _IL_JIT_LABEL_STARTCATCH)) != 0) && (coderStackHeight > 0)) { int current = 0; ILJitValue *stack = ILMemStackAllocItem(&(coder->stackStates), coderStackHeight * sizeof(ILJitValue)); if(!stack) { return 0; } /* Now save the current stack state. */ for(current = 0; current < coderStackHeight; current++) { ILJitStackItem *stackItem = _ILJitStackItemGet(coder, coderStackBase + current); stack[current] = _ILJitStackItemValue(*stackItem); if(jit_value_is_constant(_ILJitStackItemValue(*stackItem))) { /* We have to handle this case different. */ /* Create a local value of the type of the constant. */ ILJitValue temp = jit_value_create(coder->jitFunction, jit_value_get_type(_ILJitStackItemValue(*stackItem))); /* and store the value of the constant in the new temporary. */ jit_insn_store(coder->jitFunction, temp, _ILJitStackItemValue(*stackItem)); /* Now replace the constant with the new temporary. */ stack[current] = temp; _ILJitStackItemSetValue(*stackItem, temp); } else if(_ILJitStackItemNeedsDupOnLabel(*stackItem)) { ILJitValue temp = jit_insn_dup(coder->jitFunction, _ILJitStackItemValue(*stackItem)); stack[current] = temp; _ILJitStackItemSetValue(*stackItem, temp); } } label->jitStack = stack; label->stackSize = coderStackHeight; } return 1; }
jit_value jit_function::insn_dup(const jit_value& value) { value_wrap(jit_insn_dup(func, value.raw())); }