* Method: allocation for DF object references. */
| 680 | * Method: allocation for DF object references. |
| 681 | */ |
| 682 | static int meta_new(lua_State *state) |
| 683 | { |
| 684 | int argc = lua_gettop(state); |
| 685 | |
| 686 | if (argc != 1 && argc != 2) |
| 687 | luaL_error(state, "Usage: object:new() or df.new(object) or df.new(ptype,count)"); |
| 688 | |
| 689 | const type_identity *id = get_object_identity(state, 1, "df.new()", true); |
| 690 | |
| 691 | void *ptr = nullptr; |
| 692 | std::string err_context; |
| 693 | |
| 694 | // Support arrays of primitive types |
| 695 | if (argc == 2) |
| 696 | { |
| 697 | int cnt = luaL_checkint(state, 2); |
| 698 | if (cnt <= 0) |
| 699 | luaL_error(state, "Invalid array size in df.new()"); |
| 700 | if (id->type() != IDTYPE_PRIMITIVE) |
| 701 | luaL_error(state, "Cannot allocate arrays of non-primitive types."); |
| 702 | |
| 703 | size_t sz = id->byte_size() * cnt; |
| 704 | ptr = malloc(sz); |
| 705 | if (ptr) |
| 706 | memset(ptr, 0, sz); |
| 707 | } |
| 708 | else |
| 709 | { |
| 710 | try { |
| 711 | ptr = id->allocate(); |
| 712 | } |
| 713 | catch (std::exception &e) { |
| 714 | if (e.what()) { |
| 715 | err_context = e.what(); |
| 716 | } |
| 717 | } |
| 718 | } |
| 719 | |
| 720 | if (!ptr) |
| 721 | luaL_error(state, "Cannot allocate %s%s%s", |
| 722 | id->getFullName().c_str(), |
| 723 | err_context.empty() ? "" : ": ", |
| 724 | err_context.c_str() |
| 725 | ); |
| 726 | |
| 727 | if (lua_isuserdata(state, 1)) |
| 728 | { |
| 729 | lua_getmetatable(state, 1); |
| 730 | push_object_ref(state, ptr); |
| 731 | |
| 732 | id->copy(ptr, get_object_ref(state, 1)); |
| 733 | } |
| 734 | else |
| 735 | push_object_internal(state, id, ptr); |
| 736 | |
| 737 | return 1; |
| 738 | } |
| 739 |
nothing calls this directly
no test coverage detected