Mercurial > projects > ldc
comparison gen/arrays.cpp @ 1328:c78fd2d30da1
Changed array slice copying to call a runtime function when assertions or array bound checks are enabled instead of just doing a memcpy. This makes sure an exception is thrown if the copy is invalid (ie. different lengths or overlap). Fixes ticket #283 . Rebuilding the runtime is necessary.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail com> |
---|---|
date | Sun, 10 May 2009 02:23:05 +0200 |
parents | ad41053c336e |
children | 16d9afa22df4 |
comparison
equal
deleted
inserted
replaced
1327:49fd0c8040e6 | 1328:c78fd2d30da1 |
---|---|
13 #include "gen/arrays.h" | 13 #include "gen/arrays.h" |
14 #include "gen/runtime.h" | 14 #include "gen/runtime.h" |
15 #include "gen/logger.h" | 15 #include "gen/logger.h" |
16 #include "gen/dvalue.h" | 16 #include "gen/dvalue.h" |
17 #include "ir/irmodule.h" | 17 #include "ir/irmodule.h" |
18 | |
19 #include "gen/cl_options.h" | |
18 | 20 |
19 ////////////////////////////////////////////////////////////////////////////////////////// | 21 ////////////////////////////////////////////////////////////////////////////////////////// |
20 | 22 |
21 const LLStructType* DtoArrayType(Type* arrayTy) | 23 const LLStructType* DtoArrayType(Type* arrayTy) |
22 { | 24 { |
332 static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz) | 334 static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz) |
333 { | 335 { |
334 assert(e->len != 0); | 336 assert(e->len != 0); |
335 const LLType* t = e->ptr->getType()->getContainedType(0); | 337 const LLType* t = e->ptr->getType()->getContainedType(0); |
336 sz = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(t)), e->len, "tmp"); | 338 sz = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(t)), e->len, "tmp"); |
337 return e->ptr; | 339 return DtoBitCast(e->ptr, getVoidPtrType()); |
338 } | 340 } |
339 | 341 |
340 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src) | 342 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src) |
341 { | 343 { |
342 Logger::println("ArrayCopySlices"); | 344 Logger::println("ArrayCopySlices"); |
343 | 345 |
344 LLValue *sz1,*sz2; | 346 LLValue *sz1,*sz2; |
345 LLValue* dstarr = get_slice_ptr(dst,sz1); | 347 LLValue* dstarr = get_slice_ptr(dst,sz1); |
346 LLValue* srcarr = get_slice_ptr(src,sz2); | 348 LLValue* srcarr = get_slice_ptr(src,sz2); |
347 | 349 |
348 DtoMemCpy(dstarr, srcarr, sz1); | 350 if (global.params.useAssert || global.params.useArrayBounds) |
351 { | |
352 LLValue* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_slice_copy"); | |
353 gIR->CreateCallOrInvoke4(fn, dstarr, sz1, srcarr, sz2); | |
354 } | |
355 else | |
356 { | |
357 DtoMemCpy(dstarr, srcarr, sz1); | |
358 } | |
349 } | 359 } |
350 | 360 |
351 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) | 361 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) |
352 { | 362 { |
353 Logger::println("ArrayCopyToSlice"); | 363 Logger::println("ArrayCopyToSlice"); |
354 | 364 |
355 LLValue* sz1; | 365 LLValue* sz1; |
356 LLValue* dstarr = get_slice_ptr(dst,sz1); | 366 LLValue* dstarr = get_slice_ptr(dst,sz1); |
357 LLValue* srcarr = DtoArrayPtr(src); | 367 LLValue* srcarr = DtoBitCast(DtoArrayPtr(src), getVoidPtrType()); |
358 | 368 |
359 DtoMemCpy(dstarr, srcarr, sz1); | 369 if (global.params.useAssert || global.params.useArrayBounds) |
370 { | |
371 LLValue* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_slice_copy"); | |
372 gIR->CreateCallOrInvoke4(fn, dstarr, sz1, srcarr, DtoArrayLen(src)); | |
373 } | |
374 else | |
375 { | |
376 DtoMemCpy(dstarr, srcarr, sz1); | |
377 } | |
360 } | 378 } |
361 | 379 |
362 ////////////////////////////////////////////////////////////////////////////////////////// | 380 ////////////////////////////////////////////////////////////////////////////////////////// |
363 void DtoStaticArrayCopy(LLValue* dst, LLValue* src) | 381 void DtoStaticArrayCopy(LLValue* dst, LLValue* src) |
364 { | 382 { |