TEST(tagged, tiny_bit_set) { // Initialization. value_t regular = new_flag_set(kFlagSetAllOff); for (size_t i = 0; i < kFlagSetMaxSize; i++) ASSERT_FALSE(get_flag_set_at(regular, 1 << i)); value_t inverse = new_flag_set(kFlagSetAllOn); for (size_t i = 0; i < kFlagSetMaxSize; i++) ASSERT_TRUE(get_flag_set_at(inverse, 1 << i)); // Setting/getting. pseudo_random_t random; pseudo_random_init(&random, 42342); uint64_t bits = 0; for (size_t i = 0; i < 1024; i++) { size_t index = pseudo_random_next(&random, kFlagSetMaxSize); bool value = pseudo_random_next(&random, 2); regular = set_flag_set_at(regular, 1 << index, value); inverse = set_flag_set_at(inverse, 1 << index, !value); if (value) bits = bits | (1LL << index); else bits = bits & ~(1LL << index); for (size_t i = 0; i < kFlagSetMaxSize; i++) { bool bit = (bits & (1LL << i)) != 0; ASSERT_EQ(bit, get_flag_set_at(regular, 1 << i)); ASSERT_EQ(!bit, get_flag_set_at(inverse, 1 << i)); } } }
value_t compile_method_ast_to_method(runtime_t *runtime, value_t method_ast, value_t fragment) { reusable_scratch_memory_t scratch; reusable_scratch_memory_init(&scratch); TRY_FINALLY { E_TRY_DEF(signature, build_method_signature(runtime, fragment, &scratch, get_method_ast_signature(method_ast))); E_TRY_DEF(method, new_heap_method(runtime, afMutable, signature, method_ast, nothing(), fragment, new_flag_set(kFlagSetAllOff))); E_RETURN(method); } FINALLY { reusable_scratch_memory_dispose(&scratch); } YRT }
bool try_push_new_frame(frame_t *frame, size_t frame_capacity, uint32_t flags, bool is_lid) { value_t stack_piece = frame->stack_piece; CHECK_FALSE("pushing closed stack piece", is_stack_piece_closed(stack_piece)); // First record the current state of the old top frame so we can store it in // the header of the new frame. frame_t old_frame = *frame; // Determine how much room is left in the stack piece. value_t *stack_piece_start = get_stack_piece_storage(stack_piece); size_t capacity = get_integer_value(get_stack_piece_capacity(stack_piece)); value_t *stack_piece_limit = stack_piece_start + capacity; // There must always be room on a stack piece for the lid frame because it // must always be possible to close a stack if a condition occurs, which we // assume it can at any time. So we hold back a frame header's worth of stack // except when allocating the lid. if (!is_lid) stack_piece_limit -= kFrameHeaderSize; value_t *new_frame_pointer = old_frame.stack_pointer + kFrameHeaderSize; value_t *new_frame_limit = new_frame_pointer + frame_capacity; if (new_frame_limit > stack_piece_limit) return false; // Store the new frame's info in the frame struct. frame->stack_pointer = frame->frame_pointer = new_frame_pointer; frame->limit_pointer = new_frame_limit; frame->flags = new_flag_set(flags); frame->pc = 0; // Record the relevant information about the previous frame in the new frame's // header. frame_set_previous_frame_pointer(frame, old_frame.frame_pointer - stack_piece_start); frame_set_previous_limit_pointer(frame, old_frame.limit_pointer - stack_piece_start); frame_set_previous_flags(frame, old_frame.flags); frame_set_previous_pc(frame, old_frame.pc); frame_set_code_block(frame, nothing()); frame_set_argument_map(frame, nothing()); return true; }