Tuple* Tuple::tuple_dup(STATE) { native_int fields = num_fields(); Tuple* tup = state->vm()->new_young_tuple_dirty(fields); if(likely(tup)) { for(native_int i = 0; i < fields; i++) { Object *obj = field[i]; // fields equals size so bounds checking is unecessary tup->field[i] = obj; // Because tup is promised to be a young object, // we can elide the write barrier usage. } return tup; } // Otherwise, use slower creation path that might create // a mature object. tup = create(state, fields); for(native_int i = 0; i < fields; i++) { Object *obj = field[i]; // fields equals size so bounds checking is unecessary tup->field[i] = obj; tup->write_barrier(state, obj); } return tup; }
Tuple* Tuple::from(STATE, size_t fields, ...) { va_list ar; Tuple* tup = create(state, fields); va_start(ar, fields); for(size_t i = 0; i < fields; i++) { Object *obj = va_arg(ar, Object*); // fields equals size so bounds checking is unecessary tup->field[i] = obj; if(obj->reference_p()) tup->write_barrier(state, obj); } va_end(ar); return tup; }
// @todo performance primitive; could be replaced with Ruby Tuple* Tuple::pattern(STATE, Fixnum* size, Object* val) { native_int cnt = size->to_native(); Tuple* tuple = Tuple::create(state, cnt); // val is referend size times, we only need to hit the write // barrier once if(val->reference_p()) tuple->write_barrier(state, val); for(native_int i = 0; i < cnt; i++) { // bounds checking is covered because we instantiated the tuple // in this method tuple->field[i] = val; } return tuple; }
Tuple* Tuple::from(STATE, native_int fields, ...) { if(fields < 0) { rubinius::bug("Invalid tuple size"); } va_list ar; Tuple* tup = create(state, fields); va_start(ar, fields); for(native_int i = 0; i < fields; i++) { Object *obj = va_arg(ar, Object*); // fields equals size so bounds checking is unecessary tup->field[i] = obj; tup->write_barrier(state, obj); } va_end(ar); return tup; }
// @todo performance primitive; could be replaced with Ruby Tuple* Tuple::pattern(STATE, Fixnum* size, Object* val) { native_int cnt = size->to_native(); if(cnt < 0) { Exception::argument_error(state, "negative tuple size"); } Tuple* tuple = Tuple::create(state, cnt); for(native_int i = 0; i < cnt; i++) { // bounds checking is covered because we instantiated the tuple // in this method tuple->field[i] = val; } // val is referend size times, we only need to hit the write // barrier once tuple->write_barrier(state, val); return tuple; }