little confused with reflect pkg
all of the examples us reflect.NewValue() to get the reflect.Value of a var, but
func NewValue is not documented in http://golang.org/pkg/reflect/
the 8g compiler returns "undefined: reflect.NewValue"
is NewValue() still supported? if not, how does one get reflect.Value from a var?
the Typeof and NewValue functions have been renamed to TypeOf and ValueOf.
The Go reflect package was substantially revised for the weekly.2011-04-13 and subsequent releases. For details, see revision 843855f3c026.
Related
I am updating some old code and I am now getting errors: ERROR: setfield! immutable struct cannot be changed in Julia when I try to change the values of an immutable struct. Is there a common workaround for how I can edit/mutate those values (this may be a rather silly question given that the type is explicitly immutable so it's not a good idea generally to try and change it).
As far as I remember immutables can not be safely manipulated even if you get a memory pointer to them and try to use ccal.
However, as an imperfect workaround you can consider using Setfield package as in the example below.
using Setfield
struct S
a::Int
b::String
end
Using:
julia> s = S(2, "hello")
S(2, "hello")
julia> s = #set s.a = 5
S(5, "hello")
Note that in many scenarios this might be faster than actually changing type of S to mutable.
I use an object based on a base package roughly defined as:
package Base is
type T_Base is abstract tagged null record;
-- This performs a deep copy. Shallow copies may lead to STORAGE_ERROR.
-- This shall be implemented by every derived type.
function Copy (From : in T_Base) return T_Base'Class is abstract;
end package Base;
This package is derived by several packages which are further derived
package Foo is
type T_Foo is new T_Base with record
A_Data : Natural; -- Of course, in the real code, these are types by far more complex.
end record;
procedure do_something (Foo_Object : in T_Foo);
-- This implements the deep copy
function Copy (From : in T_Foo) return T_Base'Class is abstract;
end package Foo;
On calling the procedure do_something, I do get a storage_error:
procedure handle_received_foo (Foo_In: in Foo.T_Foo) is
begin
Foo.do_something (Foo_Object => Foo_In); -- The storage error does happen here.
end main;
When running the code with gdb, I get a segfault on entering the function and I get:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 39 (LWP 39)]
0x033c9828 in foo.do_something (foo_object=...) at ./foo.adb:67
67 procedure do_something (Foo_Object : in T_Foo);
(gdb) p foo_object
$1 (null)
So I guess I get a storage_error when doing the shallow copy of the argument Foo_Object.
I am aware that this is no MWE and that there might be a mistake in one of the types present used in the derived types.
I can't find any good option:
Making T_Foo a Controlled type to call Copy in Adjust seems not to be possible without greatly changing its definition as I can't derive T_Foo both from T_Base and Ada.Finalization.Controlled since none of them is an interface types
Defining T_Base as
type T_Base is abstract new Ada.Finalization.Controlled with null record;
and override Adjust here seems to induce a hell lot too much modifications on the existing code base as gnat yields in multiple places
type of aggregate has private ancestor "Controlled" must use extension aggregate.
So I'm low on solutions to either investigate the problem further or to solve it with a hammer.
The problem was not in the Copy function. The comments I saw in the code base were misleading.
The fact that introducing new variables changed the location of the exception made me consider some stack overflow problems.
Indeed the Storage_Size allocated for the task was not sufficient. Increasing the pragma Storage_Size(<value>) solved the problem.
Since the code base is compiled with -fstack-check, this led to the aforementioned STORAGE_ERROR.
More infos on Adacore's documentation.
This could probably have been seen with Gem #95: Dynamic Stack Analysis in GNAT but I am not currently able to see any result with the binding option suggested therein.
I want to create a 2D array of Uint64s in Julia 0.4. This worked in 0.3:
s = 128
a = zeros(Uint64, s, s)::Array{Uint64,2}
It continues to compile but gives me the notice
WARNING: Base.Uint64 is deprecated, use UInt64 instead.
I don't know what this message means. I've tried googling the error message but haven't found anything helpful. What is an equivalent line of code that will not produce any warnings?
s = 128
a = zeros(UInt64, s, s)::Array{UInt64,2}
Watch out for capitals!
Doug's answer is correct, except that you can simplify it to
s = 128
a = zeros(UInt64, s, s)
You don't need the type annotation ::Array{UInt64,2}. Defining a = zeros(UInt64, s, s) will create a variable which knows its type.
Note that the Julia error message was telling you what you had to do -- replace Uint64 by UInt64. If you can think of a better way of rephrasing the message to be clearer, that would be useful to hear.
In general, type annotations are at best redundant when defining variables in Julia -- the type is automatically inferred from the type of the right-hand side, and this will be the type assigned to the variable being created.
Type annotations are used in Julia in two circumstances:
1. to define the type of variables inside a composite type
2. for multiple dispatch in function definitions, to specify which types a given method applies to.
I am using custom LLVM pass where if I encounter a store to
where the compiler converts the value to a Constant; e.g. there is an explicit store:
X[gidx] = 10;
Then LLVM will generate this error:
aoc: ../../../Instructions.cpp:1056: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
The inheritance order goes as: Value<-User<-Constant, so this shouldn't be an issue, but it is. Using an a cast on the ConstantInt or ConstantFP has no effect on this error.
So I've tried this bloated solution:
Value *new_value;
if(isa<ConstantInt>(old_value) || isa<ConstantFP>(old_value)){
Instruction *allocInst = builder.CreateAlloca(old_value->getType());
builder.CreateStore(old_value, allocInst);
new_value = builder.CreateLoad(allocResultInst);
}
However this solution creates its own register errors when different type are involved, so I'd like to avoid it.
Does anyone know how to convert a Constant to a Value? It must be a simple issue that I'm not seeing. I'm developing on Ubuntu 12.04, LLVM 3, AMD gpu, OpenCL kernels.
Thanks ahead of time.
EDIT:
The original code that produces the first error listed is simply:
builder.CreateStore(old_value, store_addr);
EDIT2:
This old_value is declared as
Value *old_value = current_instruction->getOperand(0);
So I'm grabbing the value to be stored, in this case "10" from the first code line.
You didn't provide the code that caused this first assertion, but its wording is pretty clear: you are trying to create a store where the value operand and the pointer operand do not agree on their types. It would be useful for the question if you'd provide the code that generated that error.
Your second, so-called "bloated" solution, is the correct way to store old_value into the stack and then load it again. You write:
However this solution creates its own register errors when different type are involved
These "register errors" are the real issue you should be addressing.
In any case, the whole premise of "converting a constant to a value" is flawed - as you have correctly observed, all constants are values. There's no point storing a value into the stack with the sole purpose of loading it again, and indeed the standard LLVM pass "mem2reg" will completely remove such a sequence, replacing all uses of the load with the original value.
What is a purpose in Pascal to declare variable that is pointer to a pointer? I have a code in Mac Think Pascal. Here is some parts from the code that I don't understand:
type
my_array = array[1..100] of integer;
my_array_pointer = ^my_array;
my_array_handle = ^my_array_pointer;
...
var
xx : my_array_handle;
...
begin
xx:= my_array_handle(NewHandle( sizeof(my_array)) );
As you see, the last line is an assignment of a type my_array_handle to variable xx. What does it mean? What does NewHandle function do? (This is an internal function of Think Pascal). Actually, I need to convert a Think Pascal program to Windows Pascal. However I cannot find the description of NewHandle function, and don't know how to implement this function using the standard (New(), GetMem() etc) pointer functions.
This is a classic macos feature, not typically something of Pascal.
I don't know exactly, but it had something to do with relocatability of the loaded program in a non PM environment.
Note that the indirect pointer is allocated via an OS function, which probably means that it is allocated in some table that is maintained by the OS. (so that the OS can move/relocate the program?)
In modern Mac (and other) programming this whole principle is alien. Just clean it up.
(added)
If you want to keep these redirections, you could try your luck with something like:
function newhandle( nrbytes:integer):ppointer;
var xx : ppointer;
begin
new(xx);
getmem(xx^,nrbytes);
newhandle:=xx;
end;
I didn't add this originally, but I recommend you simply clean up these anachronistic indirect references and use my_array_pointer based pointers and getmem or new directly.
The meaning of these indirect references has no use on non m68k Classic Mac OS systems, though afaik later PPC versions still somewhat support them. (PPC is always protected mode)
If you really want the gritty details, you probably want to subscribe to the mac-pascal list.