コード例 #1
0
ファイル: genprim.c プロジェクト: georgemarrows/ponyc
void genprim_string_serialise_trace(compile_t* c, reach_type_t* t)
{
  // Generate the serialise_trace function.
  t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name),
    c->serialise_type);

  codegen_startfun(c, t->serialise_trace_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->serialise_trace_fn, LLVMCCallConv);

  LLVMValueRef ctx = LLVMGetParam(t->serialise_trace_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->serialise_trace_fn, 1);
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, "");

  // Read the size.
  LLVMValueRef size = field_value(c, object, 1);
  LLVMValueRef alloc = LLVMBuildAdd(c->builder, size,
    LLVMConstInt(c->intptr, 1, false), "");

  // Reserve space for the contents.
  LLVMValueRef ptr = field_value(c, object, 3);

  LLVMValueRef args[3];
  args[0] = ctx;
  args[1] = ptr;
  args[2] = alloc;
  gencall_runtime(c, "pony_serialise_reserve", args, 3, "");

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
コード例 #2
0
ファイル: genprim.c プロジェクト: georgemarrows/ponyc
void genprim_string_deserialise(compile_t* c, reach_type_t* t)
{
  // Generate the deserisalise function.
  t->deserialise_fn = codegen_addfun(c, genname_serialise(t->name),
    c->trace_type);

  codegen_startfun(c, t->deserialise_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->deserialise_fn, LLVMCCallConv);

  LLVMValueRef ctx = LLVMGetParam(t->deserialise_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->deserialise_fn, 1);

  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->structure_ptr,
    "");
  gendeserialise_typeid(c, t, object);

  // Deserialise the string contents.
  LLVMValueRef alloc = field_value(c, object, 2);
  LLVMValueRef ptr_offset = field_value(c, object, 3);
  ptr_offset = LLVMBuildPtrToInt(c->builder, ptr_offset, c->intptr, "");

  LLVMValueRef args[3];
  args[0] = ctx;
  args[1] = ptr_offset;
  args[2] = alloc;
  LLVMValueRef ptr_addr = gencall_runtime(c, "pony_deserialise_block", args, 3,
    "");

  LLVMValueRef ptr = LLVMBuildStructGEP(c->builder, object, 3, "");
  LLVMBuildStore(c->builder, ptr_addr, ptr);

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
コード例 #3
0
ファイル: dtree.c プロジェクト: pimms/aidt
static bool
is_set_ambiguous(const struct sample *samples, int count)
{
    // The set is ambiguous if the result field varies in the set.
    const unsigned f = SAMPLE_RESULT_FIELD;
    for (int i=1; i<count; i++) {
        if (field_value(&samples[i], f) != field_value(&samples[0], f))
            return true;
    }

    return false;
}
コード例 #4
0
ファイル: LR_MsgHandler.cpp プロジェクト: AquilaUAS/ardupilot
void LR_MsgHandler_IMT_Base::update_from_msg_imt(uint8_t imu_offset, uint8_t *msg)
{
    wait_timestamp_from_msg(msg);

    if (!use_imt) {
        return;
    }

    uint8_t this_imu_mask = 1 << imu_offset;

    float delta_time = 0;
    require_field(msg, "DelT", delta_time);
    ins.set_delta_time(delta_time);

    if (gyro_mask & this_imu_mask) {
        Vector3f d_angle;
        require_field(msg, "DelA", d_angle);
        float d_angle_dt;
        if (!field_value(msg, "DelaT", d_angle_dt)) {
            d_angle_dt = 0;
        }
        ins.set_delta_angle(imu_offset, d_angle, d_angle_dt);
    }
    if (accel_mask & this_imu_mask) {
        float dvt = 0;
        require_field(msg, "DelvT", dvt);
        Vector3f d_velocity;
        require_field(msg, "DelV", d_velocity);
        ins.set_delta_velocity(imu_offset, dvt, d_velocity);
    }
}
コード例 #5
0
void LR_MsgHandler_PARM::process_message(uint8_t *msg)
{
    const uint8_t parameter_name_len = AP_MAX_NAME_SIZE + 1; // null-term
    char parameter_name[parameter_name_len];
    uint64_t time_us;

    if (field_value(msg, "TimeUS", time_us)) {
        wait_timestamp_usec(time_us);
    } else {
        // older logs can have a lot of FMT and PARM messages up the
        // front which don't have timestamps.  Since in Replay we run
        // DataFlash's IO only when stop_clock is called, we can
        // overflow DataFlash's ringbuffer.  This should force us to
        // do IO:
        hal.scheduler->stop_clock(last_timestamp_usec);
    }

    require_field(msg, "Name", parameter_name, parameter_name_len);

    float value = require_field_float(msg, "Value");
    if (globals.no_params) {
        printf("Not changing %s to %f\n", parameter_name, value);
    } else {
        set_parameter(parameter_name, value);
    }
}
コード例 #6
0
ファイル: LR_MsgHandler.cpp プロジェクト: AquilaUAS/ardupilot
void LR_MsgHandler::wait_timestamp_from_msg(uint8_t *msg)
{
    uint64_t time_us;
    uint32_t time_ms;

    if (field_value(msg, "TimeUS", time_us)) {
        // 64-bit timestamp present - great!
        wait_timestamp_usec(time_us);
    } else if (field_value(msg, "TimeMS", time_ms)) {
        // there is special rounding code that needs to be crossed in
        // wait_timestamp:
        wait_timestamp(time_ms);
    } else {
        ::printf("No timestamp on message");
    }
}
コード例 #7
0
// ------------------------------------------------------------------
// ciInstance::field_value_by_offset
//
// Constant value of a field at the specified offset.
ciConstant ciInstance::field_value_by_offset(int field_offset) {
  ciInstanceKlass* ik = klass()->as_instance_klass();
  ciField* field = ik->get_field_by_offset(field_offset, false);
  if (field == NULL)
    return ciConstant();  // T_ILLEGAL
  return field_value(field);
}
コード例 #8
0
ファイル: db_handle.cpp プロジェクト: 10jschen/acl
int db_row::field_int(const char* name, int null_value /* = 0 */) const
{
	const char* ptr = field_value(name);
	if (ptr == NULL)
		return (null_value);
	else
		return (atoi(ptr));
}
コード例 #9
0
ファイル: db_handle.cpp プロジェクト: DavadDi/acl
acl_int64 db_row::field_int64(const char* name, acl_int64 null_value /* = 0 */) const
{
	const char* ptr = field_value(name);
	if (ptr == NULL)
		return null_value;
	else
		return ACL_DB_ATOU(ptr);
}
コード例 #10
0
ファイル: db_handle.cpp プロジェクト: DavadDi/acl
double db_row::field_double(size_t ifield, double null_value /* = 0 */) const
{
	const char* ptr = field_value(ifield);
	if (ptr == NULL)
		return null_value;
	else
		return atof(ptr);
}
コード例 #11
0
ファイル: db_handle.cpp プロジェクト: 10jschen/acl
acl_int64 db_row::field_int64(size_t ifield, acl_int64 null_value /* = 0 */) const
{
	const char* ptr = field_value(ifield);
	if (ptr == NULL)
		return (null_value);
	else
		return (ACL_DB_ATOU(ptr));
}
コード例 #12
0
ファイル: db_handle.cpp プロジェクト: DavadDi/acl
double db_row::field_double(const char* name, double null_value /* = 0 */) const
{
	const char* ptr = field_value(name);
	if (ptr == NULL)
		return null_value;
	else
		return atof(ptr);
}
コード例 #13
0
ファイル: db_handle.cpp プロジェクト: 10jschen/acl
int db_row::field_int(size_t ifield, int null_value /* = 0 */) const
{
	const char* ptr = field_value(ifield);
	if (ptr == NULL)
		return (null_value);
	else
		return (atoi(ptr));
}
コード例 #14
0
ファイル: db_handle.cpp プロジェクト: 10jschen/acl
const char* db_row::field_string(const char* name) const
{
	const char* ptr = field_value(name);
	if (ptr == NULL)
		return (NULL);
	else
		return (ptr);
}
コード例 #15
0
ファイル: db_handle.cpp プロジェクト: 10jschen/acl
const char* db_row::field_string(size_t ifield) const
{
	const char* ptr = field_value(ifield);
	if (ptr == NULL)
		return (NULL);
	else
		return (ptr);
}
コード例 #16
0
ファイル: MsgHandler.cpp プロジェクト: ysfvest/ardupilot
void MsgHandler::require_field(uint8_t *msg, const char *label, char *buffer, uint8_t bufferlen)
{
    if (! field_value(msg, label, buffer, bufferlen)) {
        char all_labels[256];
        string_for_labels(all_labels, 256);
        ::printf("Field (%s) not found; options are (%s)\n", label, all_labels);
        exit(1);
    }
}
コード例 #17
0
void LR_MsgHandler_GPS_Base::update_from_msg_gps(uint8_t gps_offset, uint8_t *msg, bool responsible_for_relalt)
{
    uint64_t time_us;
    if (! field_value(msg, "TimeUS", time_us)) {
        uint32_t timestamp;
        require_field(msg, "T", timestamp);
        time_us = timestamp * 1000;
    }
    wait_timestamp_usec(time_us);

    Location loc;
    location_from_msg(msg, loc, "Lat", "Lng", "Alt");
    Vector3f vel;
    ground_vel_from_msg(msg, vel, "Spd", "GCrs", "VZ");

    uint8_t status = require_field_uint8_t(msg, "Status");
    uint8_t hdop = 0;
    if (! field_value(msg, "HDop", hdop) &&
        ! field_value(msg, "HDp", hdop)) {
        hdop = 20;
    }
    gps.setHIL(gps_offset,
               (AP_GPS::GPS_Status)status,
               uint32_t(time_us/1000),
               loc,
               vel,
               require_field_uint8_t(msg, "NSats"),
               hdop,
               require_field_float(msg, "VZ") != 0);
    if (status == AP_GPS::GPS_OK_FIX_3D && ground_alt_cm == 0) {
        ground_alt_cm = require_field_int32_t(msg, "Alt");
    }

    if (responsible_for_relalt) {
        // this could possibly check for the presence of "RelAlt" label?
        int32_t tmp;
        if (! field_value(msg, "RAlt", tmp)) {
            tmp = require_field_int32_t(msg, "RelAlt");
        }
        rel_altitude = 0.01f * tmp;
    }
}
コード例 #18
0
ファイル: genprim.c プロジェクト: locksfree/ponyc
void genprim_array_serialise_trace(compile_t* c, reach_type_t* t)
{
  // Generate the serialise_trace function.
  t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name),
    c->trace_type);

  codegen_startfun(c, t->serialise_trace_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->serialise_trace_fn, LLVMCCallConv);
  LLVMSetLinkage(t->serialise_trace_fn, LLVMExternalLinkage);

  LLVMValueRef ctx = LLVMGetParam(t->serialise_trace_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->serialise_trace_fn, 1);
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, "");

  // Read the size.
  LLVMValueRef size = field_value(c, object, 1);

  // Calculate the size of the element type.
  ast_t* typeargs = ast_childidx(t->ast, 2);
  ast_t* typearg = ast_child(typeargs);
  reach_type_t* t_elem = reach_type(c->reach, typearg);

  size_t abisize = (size_t)LLVMABISizeOfType(c->target_data, t_elem->use_type);
  LLVMValueRef l_size = LLVMConstInt(c->intptr, abisize, false);

  // Reserve space for the array elements.
  LLVMValueRef pointer = field_value(c, object, 3);

  LLVMValueRef args[3];
  args[0] = ctx;
  args[1] = pointer;
  args[2] = LLVMBuildMul(c->builder, size, l_size, "");
  gencall_runtime(c, "pony_serialise_reserve", args, 3, "");

  // Trace the array elements.
  trace_array_elements(c, t, ctx, object, pointer);

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
コード例 #19
0
ファイル: LR_MsgHandler.cpp プロジェクト: AquilaUAS/ardupilot
void LR_MsgHandler_GPA_Base::update_from_msg_gpa(uint8_t gps_offset, uint8_t *msg)
{
    uint64_t time_us;
    require_field(msg, "TimeUS", time_us);
    wait_timestamp_usec(time_us);

    uint16_t vdop, hacc, vacc, sacc;
    require_field(msg, "VDop", vdop);
    require_field(msg, "HAcc", hacc);
    require_field(msg, "VAcc", vacc);
    require_field(msg, "SAcc", sacc);
    uint8_t have_vertical_velocity;
    if (! field_value(msg, "VV", have_vertical_velocity)) {
        have_vertical_velocity = !is_zero(gps.velocity(gps_offset).z);
    }
    uint32_t sample_ms;
    if (! field_value(msg, "SMS", sample_ms)) {
        sample_ms = 0;
    }

    gps.setHIL_Accuracy(gps_offset, vdop*0.01f, hacc*0.01f, vacc*0.01f, sacc*0.01f, have_vertical_velocity, sample_ms);
}
コード例 #20
0
ファイル: dtree.c プロジェクト: pimms/aidt
int
dt_decide(const struct decision *dec, const struct sample *sample)
{
    while (dec && dec->dest) {
        while (dec && dec->value != field_value(sample, dec->field))
            dec = dec->next;
        if (!dec)
            return -1;
        dec = dec->dest;
    }

    return dec->value;
}
コード例 #21
0
ファイル: LR_MsgHandler.cpp プロジェクト: AquilaUAS/ardupilot
void LR_MsgHandler_BARO::process_message(uint8_t *msg)
{
    wait_timestamp_from_msg(msg);
    uint32_t last_update_ms;
    if (!field_value(msg, "SMS", last_update_ms)) {
        last_update_ms = 0;
    }
    baro.setHIL(0,
		require_field_float(msg, "Press"),
		require_field_int16_t(msg, "Temp") * 0.01f,
		require_field_float(msg, "Alt"),
		require_field_float(msg, "CRt"),
                last_update_ms);
}
コード例 #22
0
ファイル: DebuggerIPCServer.cpp プロジェクト: pfpsim/PFPSim
void DebuggerIPCServer::handleGetPacketField(int id, std::string field_name) {
  DebuggerPacket *pk = data_manager->getPacket(id);
  if (pk) {
    auto dbg_info = pk->getDebugInfo();
    if (dbg_info) {
      auto raw_data = dbg_info->field_value(field_name);

      PacketFieldValueMessage message(raw_data);

      send(&message);
    }
  }

  sendRequestFailed();
}
コード例 #23
0
ファイル: genprim.c プロジェクト: georgemarrows/ponyc
static void trace_array_elements(compile_t* c, reach_type_t* t,
  LLVMValueRef ctx, LLVMValueRef object, LLVMValueRef pointer)
{
  // Get the type argument for the array. This will be used to generate the
  // per-element trace call.
  ast_t* typeargs = ast_childidx(t->ast, 2);
  ast_t* typearg = ast_child(typeargs);

  if(!gentrace_needed(typearg))
    return;

  reach_type_t* t_elem = reach_type(c->reach, typearg);
  pointer = LLVMBuildBitCast(c->builder, pointer,
    LLVMPointerType(t_elem->use_type, 0), "");

  LLVMBasicBlockRef entry_block = LLVMGetInsertBlock(c->builder);
  LLVMBasicBlockRef cond_block = codegen_block(c, "cond");
  LLVMBasicBlockRef body_block = codegen_block(c, "body");
  LLVMBasicBlockRef post_block = codegen_block(c, "post");

  // Read the size.
  LLVMValueRef size = field_value(c, object, 1);
  LLVMBuildBr(c->builder, cond_block);

  // While the index is less than the size, trace an element. The initial
  // index when coming from the entry block is zero.
  LLVMPositionBuilderAtEnd(c->builder, cond_block);
  LLVMValueRef phi = LLVMBuildPhi(c->builder, c->intptr, "");
  LLVMValueRef zero = LLVMConstInt(c->intptr, 0, false);
  LLVMAddIncoming(phi, &zero, &entry_block, 1);
  LLVMValueRef test = LLVMBuildICmp(c->builder, LLVMIntULT, phi, size, "");
  LLVMBuildCondBr(c->builder, test, body_block, post_block);

  // The phi node is the index. Get the element and trace it.
  LLVMPositionBuilderAtEnd(c->builder, body_block);
  LLVMValueRef elem_ptr = LLVMBuildGEP(c->builder, pointer, &phi, 1, "elem");
  LLVMValueRef elem = LLVMBuildLoad(c->builder, elem_ptr, "");
  gentrace(c, ctx, elem, typearg);

  // Add one to the phi node and branch back to the cond block.
  LLVMValueRef one = LLVMConstInt(c->intptr, 1, false);
  LLVMValueRef inc = LLVMBuildAdd(c->builder, phi, one, "");
  body_block = LLVMGetInsertBlock(c->builder);
  LLVMAddIncoming(phi, &inc, &body_block, 1);
  LLVMBuildBr(c->builder, cond_block);

  LLVMPositionBuilderAtEnd(c->builder, post_block);
}
コード例 #24
0
ファイル: LR_MsgHandler.cpp プロジェクト: AquilaUAS/ardupilot
void LR_MsgHandler_MAG_Base::update_from_msg_compass(uint8_t compass_offset, uint8_t *msg)
{
    wait_timestamp_from_msg(msg);

    Vector3f mag;
    require_field(msg, "Mag", mag);
    Vector3f mag_offset;
    require_field(msg, "Ofs", mag_offset);
    uint32_t last_update_usec;
    if (!field_value(msg, "S", last_update_usec)) {
        last_update_usec = AP_HAL::micros();
    }

    compass.setHIL(compass_offset, mag - mag_offset, last_update_usec);
    // compass_offset is which compass we are setting info for;
    // mag_offset is a vector indicating the compass' calibration...
    compass.set_offsets(compass_offset, mag_offset);
}
コード例 #25
0
ファイル: LR_MsgHandler.cpp プロジェクト: AquilaUAS/ardupilot
void LR_MsgHandler_GPS_Base::update_from_msg_gps(uint8_t gps_offset, uint8_t *msg)
{
    uint64_t time_us;
    if (! field_value(msg, "TimeUS", time_us)) {
        uint32_t timestamp;
        require_field(msg, "T", timestamp);
        time_us = timestamp * 1000;
    }
    wait_timestamp_usec(time_us);

    Location loc;
    location_from_msg(msg, loc, "Lat", "Lng", "Alt");
    Vector3f vel;
    ground_vel_from_msg(msg, vel, "Spd", "GCrs", "VZ");

    uint8_t status = require_field_uint8_t(msg, "Status");
    uint8_t hdop = 0;
    if (! field_value(msg, "HDop", hdop) &&
        ! field_value(msg, "HDp", hdop)) {
        hdop = 20;
    }
    uint8_t nsats = 0;
    if (! field_value(msg, "NSats", nsats) &&
        ! field_value(msg, "numSV", nsats)) {
        field_not_found(msg, "NSats");
    }
    uint16_t GWk;
    uint32_t GMS;
    if (! field_value(msg, "GWk", GWk)) {
        field_not_found(msg, "GWk");
    }
    if (! field_value(msg, "GMS", GMS)) {
        field_not_found(msg, "GMS");
    }
    gps.setHIL(gps_offset,
               (AP_GPS::GPS_Status)status,
               AP_GPS::time_epoch_convert(GWk, GMS),
               loc,
               vel,
               nsats,
               hdop);
    if (status == AP_GPS::GPS_OK_FIX_3D && ground_alt_cm == 0) {
        ground_alt_cm = require_field_int32_t(msg, "Alt");
    }
}
コード例 #26
0
ファイル: genprim.c プロジェクト: georgemarrows/ponyc
void genprim_array_trace(compile_t* c, reach_type_t* t)
{
  codegen_startfun(c, t->trace_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->trace_fn, LLVMCCallConv);
  LLVMValueRef ctx = LLVMGetParam(t->trace_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->trace_fn, 1);

  // Read the base pointer.
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, "");
  LLVMValueRef pointer = field_value(c, object, 3);

  // Trace the base pointer.
  LLVMValueRef args[2];
  args[0] = ctx;
  args[1] = pointer;
  gencall_runtime(c, "pony_trace", args, 2, "");

  trace_array_elements(c, t, ctx, object, pointer);
  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
コード例 #27
0
ファイル: ciInstance.cpp プロジェクト: guanxiaohua/TransGC
// ------------------------------------------------------------------
// ciInstance::field_value_by_offset
//
// Constant value of a field at the specified offset.
ciConstant ciInstance::field_value_by_offset(int field_offset) {
  ciInstanceKlass* ik = klass()->as_instance_klass();
  ciField* field = ik->get_field_by_offset(field_offset, false);
  return field_value(field);
}
コード例 #28
0
ファイル: genprim.c プロジェクト: georgemarrows/ponyc
void genprim_string_serialise(compile_t* c, reach_type_t* t)
{
  // Generate the serialise function.
  t->serialise_fn = codegen_addfun(c, genname_serialise(t->name),
    c->serialise_type);

  codegen_startfun(c, t->serialise_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->serialise_fn, LLVMCCallConv);

  LLVMValueRef ctx = LLVMGetParam(t->serialise_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->serialise_fn, 1);
  LLVMValueRef addr = LLVMGetParam(t->serialise_fn, 2);
  LLVMValueRef offset = LLVMGetParam(t->serialise_fn, 3);
  LLVMValueRef mut = LLVMGetParam(t->serialise_fn, 4);

  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->structure_ptr,
    "");
  LLVMValueRef offset_addr = LLVMBuildAdd(c->builder,
    LLVMBuildPtrToInt(c->builder, addr, c->intptr, ""), offset, "");

  genserialise_typeid(c, t, offset_addr);

  // Don't serialise our contents if we are opaque.
  LLVMBasicBlockRef body_block = codegen_block(c, "body");
  LLVMBasicBlockRef post_block = codegen_block(c, "post");

  LLVMValueRef test = LLVMBuildICmp(c->builder, LLVMIntNE, mut,
    LLVMConstInt(c->i32, PONY_TRACE_OPAQUE, false), "");
  LLVMBuildCondBr(c->builder, test, body_block, post_block);
  LLVMPositionBuilderAtEnd(c->builder, body_block);

  // Write the size, and rewrite alloc to be size + 1.
  LLVMValueRef size = field_value(c, object, 1);
  LLVMValueRef size_loc = field_loc(c, offset_addr, t->structure,
    c->intptr, 1);
  LLVMBuildStore(c->builder, size, size_loc);

  LLVMValueRef alloc = LLVMBuildAdd(c->builder, size,
    LLVMConstInt(c->intptr, 1, false), "");
  LLVMValueRef alloc_loc = field_loc(c, offset_addr, t->structure,
    c->intptr, 2);
  LLVMBuildStore(c->builder, alloc, alloc_loc);

  // Write the pointer.
  LLVMValueRef ptr = field_value(c, object, 3);

  LLVMValueRef args[5];
  args[0] = ctx;
  args[1] = ptr;
  LLVMValueRef ptr_offset = gencall_runtime(c, "pony_serialise_offset",
    args, 2, "");

  LLVMValueRef ptr_loc = field_loc(c, offset_addr, t->structure, c->intptr, 3);
  LLVMBuildStore(c->builder, ptr_offset, ptr_loc);

  // Serialise the string contents.
  LLVMValueRef ptr_offset_addr = LLVMBuildAdd(c->builder,
    LLVMBuildPtrToInt(c->builder, addr, c->intptr, ""), ptr_offset, "");

  args[0] = LLVMBuildIntToPtr(c->builder, ptr_offset_addr, c->void_ptr, "");
  args[1] = LLVMBuildBitCast(c->builder, field_value(c, object, 3),
    c->void_ptr, "");
  args[2] = alloc;
  args[3] = LLVMConstInt(c->i32, 1, false);
  args[4] = LLVMConstInt(c->i1, 0, false);

  if(target_is_ilp32(c->opt->triple))
  {
    gencall_runtime(c, "llvm.memcpy.p0i8.p0i8.i32", args, 5, "");
  } else {
    gencall_runtime(c, "llvm.memcpy.p0i8.p0i8.i64", args, 5, "");
  }

  LLVMBuildBr(c->builder, post_block);
  LLVMPositionBuilderAtEnd(c->builder, post_block);
  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
コード例 #29
0
ファイル: genprim.c プロジェクト: georgemarrows/ponyc
void genprim_array_deserialise(compile_t* c, reach_type_t* t)
{
  // Generate the deserisalise function.
  t->deserialise_fn = codegen_addfun(c, genname_serialise(t->name),
    c->trace_type);

  codegen_startfun(c, t->deserialise_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->deserialise_fn, LLVMCCallConv);

  LLVMValueRef ctx = LLVMGetParam(t->deserialise_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->deserialise_fn, 1);

  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->structure_ptr,
    "");
  gendeserialise_typeid(c, t, object);

  // Deserialise the array contents.
  LLVMValueRef alloc = field_value(c, object, 2);
  LLVMValueRef ptr_offset = field_value(c, object, 3);
  ptr_offset = LLVMBuildPtrToInt(c->builder, ptr_offset, c->intptr, "");

  ast_t* typeargs = ast_childidx(t->ast, 2);
  ast_t* typearg = ast_child(typeargs);

  reach_type_t* t_elem = reach_type(c->reach, typearg);
  size_t abisize = (size_t)LLVMABISizeOfType(c->target_data, t_elem->use_type);
  LLVMValueRef l_size = LLVMConstInt(c->intptr, abisize, false);

  LLVMValueRef args[3];
  args[0] = ctx;
  args[1] = ptr_offset;
  args[2] = LLVMBuildMul(c->builder, alloc, l_size, "");
  LLVMValueRef ptr = gencall_runtime(c, "pony_deserialise_block", args, 3, "");

  LLVMValueRef ptr_loc = LLVMBuildStructGEP(c->builder, object, 3, "");
  LLVMBuildStore(c->builder, ptr, ptr_loc);

  if((t_elem->underlying == TK_PRIMITIVE) && (t_elem->primitive != NULL))
  {
    // Do nothing. A memcpy is sufficient.
  } else {
    LLVMValueRef size = field_value(c, object, 1);
    ptr = LLVMBuildBitCast(c->builder, ptr,
      LLVMPointerType(t_elem->use_type, 0), "");

    LLVMBasicBlockRef entry_block = LLVMGetInsertBlock(c->builder);
    LLVMBasicBlockRef cond_block = codegen_block(c, "cond");
    LLVMBasicBlockRef body_block = codegen_block(c, "body");
    LLVMBasicBlockRef post_block = codegen_block(c, "post");

    LLVMBuildBr(c->builder, cond_block);

    // While the index is less than the size, deserialise an element. The
    // initial index when coming from the entry block is zero.
    LLVMPositionBuilderAtEnd(c->builder, cond_block);
    LLVMValueRef phi = LLVMBuildPhi(c->builder, c->intptr, "");
    LLVMValueRef zero = LLVMConstInt(c->intptr, 0, false);
    LLVMAddIncoming(phi, &zero, &entry_block, 1);
    LLVMValueRef test = LLVMBuildICmp(c->builder, LLVMIntULT, phi, size, "");
    LLVMBuildCondBr(c->builder, test, body_block, post_block);

    // The phi node is the index. Get the element and deserialise it.
    LLVMPositionBuilderAtEnd(c->builder, body_block);
    LLVMValueRef elem_ptr = LLVMBuildGEP(c->builder, ptr, &phi, 1, "");
    gendeserialise_element(c, t_elem, false, ctx, elem_ptr);

    // Add one to the phi node and branch back to the cond block.
    LLVMValueRef one = LLVMConstInt(c->intptr, 1, false);
    LLVMValueRef inc = LLVMBuildAdd(c->builder, phi, one, "");
    body_block = LLVMGetInsertBlock(c->builder);
    LLVMAddIncoming(phi, &inc, &body_block, 1);
    LLVMBuildBr(c->builder, cond_block);

    LLVMPositionBuilderAtEnd(c->builder, post_block);
  }

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
コード例 #30
0
ファイル: genprim.c プロジェクト: georgemarrows/ponyc
void genprim_array_serialise(compile_t* c, reach_type_t* t)
{
  // Generate the serialise function.
  t->serialise_fn = codegen_addfun(c, genname_serialise(t->name),
    c->serialise_type);

  codegen_startfun(c, t->serialise_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->serialise_fn, LLVMCCallConv);

  LLVMValueRef ctx = LLVMGetParam(t->serialise_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->serialise_fn, 1);
  LLVMValueRef addr = LLVMGetParam(t->serialise_fn, 2);
  LLVMValueRef offset = LLVMGetParam(t->serialise_fn, 3);
  LLVMValueRef mut = LLVMGetParam(t->serialise_fn, 4);

  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->structure_ptr,
    "");
  LLVMValueRef offset_addr = LLVMBuildAdd(c->builder,
    LLVMBuildPtrToInt(c->builder, addr, c->intptr, ""), offset, "");

  genserialise_typeid(c, t, offset_addr);

  // Don't serialise our contents if we are opaque.
  LLVMBasicBlockRef body_block = codegen_block(c, "body");
  LLVMBasicBlockRef post_block = codegen_block(c, "post");

  LLVMValueRef test = LLVMBuildICmp(c->builder, LLVMIntNE, mut,
    LLVMConstInt(c->i32, PONY_TRACE_OPAQUE, false), "");
  LLVMBuildCondBr(c->builder, test, body_block, post_block);
  LLVMPositionBuilderAtEnd(c->builder, body_block);

  // Write the size twice, effectively rewriting alloc to be the same as size.
  LLVMValueRef size = field_value(c, object, 1);

  LLVMValueRef size_loc = field_loc(c, offset_addr, t->structure,
    c->intptr, 1);
  LLVMBuildStore(c->builder, size, size_loc);

  LLVMValueRef alloc_loc = field_loc(c, offset_addr, t->structure,
    c->intptr, 2);
  LLVMBuildStore(c->builder, size, alloc_loc);

  // Write the pointer.
  LLVMValueRef ptr = field_value(c, object, 3);

  // The resulting offset will only be invalid (i.e. have the high bit set) if
  // the size is zero. For an opaque array, we don't serialise the contents,
  // so we don't get here, so we don't end up with an invalid offset.
  LLVMValueRef args[5];
  args[0] = ctx;
  args[1] = ptr;
  LLVMValueRef ptr_offset = gencall_runtime(c, "pony_serialise_offset",
    args, 2, "");

  LLVMValueRef ptr_loc = field_loc(c, offset_addr, t->structure, c->intptr, 3);
  LLVMBuildStore(c->builder, ptr_offset, ptr_loc);

  LLVMValueRef ptr_offset_addr = LLVMBuildAdd(c->builder, ptr_offset,
    LLVMBuildPtrToInt(c->builder, addr, c->intptr, ""), "");

  // Serialise elements.
  ast_t* typeargs = ast_childidx(t->ast, 2);
  ast_t* typearg = ast_child(typeargs);
  reach_type_t* t_elem = reach_type(c->reach, typearg);

  size_t abisize = (size_t)LLVMABISizeOfType(c->target_data, t_elem->use_type);
  LLVMValueRef l_size = LLVMConstInt(c->intptr, abisize, false);

  if((t_elem->underlying == TK_PRIMITIVE) && (t_elem->primitive != NULL))
  {
    // memcpy machine words
    args[0] = LLVMBuildIntToPtr(c->builder, ptr_offset_addr, c->void_ptr, "");
    args[1] = LLVMBuildBitCast(c->builder, ptr, c->void_ptr, "");
    args[2] = LLVMBuildMul(c->builder, size, l_size, "");
    args[3] = LLVMConstInt(c->i32, 1, false);
    args[4] = LLVMConstInt(c->i1, 0, false);
    if(target_is_ilp32(c->opt->triple))
    {
      gencall_runtime(c, "llvm.memcpy.p0i8.p0i8.i32", args, 5, "");
    } else {
      gencall_runtime(c, "llvm.memcpy.p0i8.p0i8.i64", args, 5, "");
    }
  } else {
    ptr = LLVMBuildBitCast(c->builder, ptr,
      LLVMPointerType(t_elem->use_type, 0), "");

    LLVMBasicBlockRef entry_block = LLVMGetInsertBlock(c->builder);
    LLVMBasicBlockRef cond_block = codegen_block(c, "cond");
    LLVMBasicBlockRef body_block = codegen_block(c, "body");
    LLVMBasicBlockRef post_block = codegen_block(c, "post");

    LLVMValueRef offset_var = LLVMBuildAlloca(c->builder, c->intptr, "");
    LLVMBuildStore(c->builder, ptr_offset_addr, offset_var);

    LLVMBuildBr(c->builder, cond_block);

    // While the index is less than the size, serialise an element. The
    // initial index when coming from the entry block is zero.
    LLVMPositionBuilderAtEnd(c->builder, cond_block);
    LLVMValueRef phi = LLVMBuildPhi(c->builder, c->intptr, "");
    LLVMValueRef zero = LLVMConstInt(c->intptr, 0, false);
    LLVMAddIncoming(phi, &zero, &entry_block, 1);
    LLVMValueRef test = LLVMBuildICmp(c->builder, LLVMIntULT, phi, size, "");
    LLVMBuildCondBr(c->builder, test, body_block, post_block);

    // The phi node is the index. Get the element and serialise it.
    LLVMPositionBuilderAtEnd(c->builder, body_block);
    LLVMValueRef elem_ptr = LLVMBuildGEP(c->builder, ptr, &phi, 1, "");

    ptr_offset_addr = LLVMBuildLoad(c->builder, offset_var, "");
    genserialise_element(c, t_elem, false, ctx, elem_ptr, ptr_offset_addr);
    ptr_offset_addr = LLVMBuildAdd(c->builder, ptr_offset_addr, l_size, "");
    LLVMBuildStore(c->builder, ptr_offset_addr, offset_var);

    // Add one to the phi node and branch back to the cond block.
    LLVMValueRef one = LLVMConstInt(c->intptr, 1, false);
    LLVMValueRef inc = LLVMBuildAdd(c->builder, phi, one, "");
    body_block = LLVMGetInsertBlock(c->builder);
    LLVMAddIncoming(phi, &inc, &body_block, 1);
    LLVMBuildBr(c->builder, cond_block);

    LLVMPositionBuilderAtEnd(c->builder, post_block);
  }

  LLVMBuildBr(c->builder, post_block);
  LLVMPositionBuilderAtEnd(c->builder, post_block);
  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}