Beispiel #1
0
value hx_zmq_setint64sockopt(value socket_handle_,value option_, value hi_optval_, value lo_optval_) {

	val_check_kind(socket_handle_, k_zmq_socket_handle);

	if (!val_is_int(option_)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
	
	if (!val_is_int(hi_optval_) || !val_is_int(lo_optval_)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
	
	uint64_t _optval64 = val_int(hi_optval_);
	_optval64 <<= 32;	// Shift the hi int into the top half of the uint64_t value
	_optval64 += val_int(lo_optval_);
	
	int rc = 0;
	int err = 0;
	int option = val_int(option_);
	size_t optvallen = sizeof(_optval64);
	
	rc = zmq_setsockopt (val_data(socket_handle_), option, &_optval64, optvallen);
    err = zmq_errno();
	if (rc != 0) {
		val_throw(alloc_int(err));
		return alloc_null();
	}		
	return alloc_int(rc);
	
}
Beispiel #2
0
/*
See Socket.cpp from jzmq library
*/
value hx_zmq_setintsockopt(value socket_handle_,value option_, value optval_) {

	val_check_kind(socket_handle_, k_zmq_socket_handle);

	if (!val_is_int(option_)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
	
	if (!val_is_int(optval_)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}

	int rc = 0;
	int err = 0;
	int ival = val_int(optval_);
	int option = val_int(option_);
	size_t optvallen = sizeof(ival);
	
	rc = zmq_setsockopt (val_data(socket_handle_), option, &ival, optvallen);
    err = zmq_errno();
	if (rc != 0) {
		val_throw(alloc_int(err));
		return alloc_null();
	}		
	return alloc_int(rc);
}
Beispiel #3
0
value hx_zmq_getbytessockopt(value socket_handle_,value option_) {

	val_check_kind(socket_handle_, k_zmq_socket_handle);

	if (!val_is_int(option_)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}

	int rc = 0;
	int err = 0;
	char optval [255];
	size_t optvallen = 255;
	rc = zmq_getsockopt(val_data(socket_handle_),val_int(option_),&optval, &optvallen);
	err = zmq_errno();
	if (rc != 0) {
		val_throw(alloc_int(err));
		return alloc_int(0);
	}	
	
	// Return data to Haxe

	// Create a return buffer byte array, by memcopying the message data, then discard the ZMQ message
	buffer b = alloc_buffer(NULL);
	buffer_append_sub(b,optval,optvallen);
	err = zmq_errno();
	if (rc != 0) {
		val_throw(alloc_int(err));
		return alloc_null();
	}
	
	return buffer_val(b);
}
Beispiel #4
0
value hx_zmq_getint64sockopt(value socket_handle_,value option_) {

	val_check_kind(socket_handle_, k_zmq_socket_handle);

	if (!val_is_int(option_)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}

	int rc = 0;
	int err = 0;
	uint64_t optval = 0;
	size_t optvallen = sizeof(optval);
	rc = zmq_getsockopt(val_data(socket_handle_),val_int(option_),&optval, &optvallen);
	err = zmq_errno();
	if (rc != 0) {
		val_throw(alloc_int(err));
		return alloc_int(0);
	}	
	value ret = alloc_empty_object();
	alloc_field(ret, val_id("hi"),alloc_int(optval >> 32));
	alloc_field(ret, val_id("lo"),alloc_int(optval & 0xFFFFFFFF));
	
	return ret;
}
Beispiel #5
0
value hx_zmq_construct (value io_threads)
{
	if (!val_is_int(io_threads))
		return alloc_null();
		
	int _io_threads = val_int(io_threads);
	if (_io_threads <= 0) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
	
	void *c = zmq_init (_io_threads);
	int err = zmq_errno();
	
	if (c == NULL) {
		val_throw (alloc_int(err));
		return alloc_null();
	}
	
	// See: http://nekovm.org/doc/ffi#abstracts_and_kinds
	value v =  alloc_abstract(k_zmq_context_handle,c);
	val_gc(v,finalize_context);		// finalize_context is called when the abstract value is garbage collected
	return v;
	
}
Beispiel #6
0
//Be very careful with this, it does not support offsets into buffers yet
value vertexAttribPointer( value *args, int count )
{
	enum {index,size,type,normalized,stride,pointer};
	if (count != 6) 
	{
		throw "vertexAttribPointer invalid parameter length";
	}

	char *ptr = NULL;
	if (val_is_buffer (args[pointer]))
	{
		std::cout << "vertexAttribPointer does not accept data for pointer arg" << std::endl;
		//ptr = buffer_data( val_to_buffer ( args[pointer] ) );
	}
	else if (val_is_int (args[pointer]))
	{
		ptr = ((char *)NULL + val_int(args[pointer]));
	}
	glVertexAttribPointer(
		(GLuint)val_int( args[index] ),
		(GLint)val_int( args[size] ),
		(GLenum)val_int( args[type] ),
		(GLboolean)val_bool( args[normalized] ),
		(GLsizei)val_int( args[stride] ),
		(const GLvoid *)ptr );
	return alloc_null( );
}
Beispiel #7
0
EXTERN int val_compare( value a, value b ) {
	char tmp_buf[32];
	switch( C(val_type(a),val_type(b)) ) {
	case C(VAL_INT,VAL_INT):
		return icmp(val_int(a),val_int(b));
	case C(VAL_INT32,VAL_INT):
		return icmp(val_int32(a),val_int(b));
	case C(VAL_INT,VAL_INT32):
		return icmp(val_int(a),val_int32(b));
	case C(VAL_INT32,VAL_INT32):
		return icmp(val_int32(a),val_int32(b));
	case C(VAL_INT,VAL_FLOAT):
		return fcmp(val_int(a),val_float(b));
	case C(VAL_INT32,VAL_FLOAT):
		return fcmp(val_int32(a),val_float(b));
	case C(VAL_INT,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int(a)),val_string(b),val_strlen(b));
	case C(VAL_INT32,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int32(a)),val_string(b),val_strlen(b));
	case C(VAL_FLOAT,VAL_INT):
		return fcmp(val_float(a),val_int(b));
	case C(VAL_FLOAT,VAL_INT32):
		return fcmp(val_float(a),val_int32(b));
	case C(VAL_FLOAT,VAL_FLOAT):
		return fcmp(val_float(a),val_float(b));
	case C(VAL_FLOAT,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(a)),val_string(b),val_strlen(b));
	case C(VAL_STRING,VAL_INT):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int(b)));
	case C(VAL_STRING,VAL_INT32):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int32(b)));
	case C(VAL_STRING,VAL_FLOAT):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(b)));
	case C(VAL_STRING,VAL_BOOL):
		return scmp(val_string(a),val_strlen(a),val_bool(b)?"true":"false",val_bool(b)?4:5);
	case C(VAL_BOOL,VAL_STRING):
		return scmp(val_bool(a)?"true":"false",val_bool(a)?4:5,val_string(b),val_strlen(b));
	case C(VAL_STRING,VAL_STRING):
		return scmp(val_string(a),val_strlen(a),val_string(b),val_strlen(b));
	case C(VAL_BOOL,VAL_BOOL):
		return (a == b) ? 0 : (val_bool(a) ? 1 : -1);
	case C(VAL_OBJECT,VAL_OBJECT):
		if( a == b )
			return 0;
		{
			value tmp = val_field(a,id_compare);
			if( tmp == val_null )
				return invalid_comparison;
			a = val_callEx(a,tmp,&b,1,NULL);
		}
		if( val_is_int(a) )
			return val_int(a);
		return invalid_comparison;
	default:
		if( a == b )
			return 0;
		return invalid_comparison;
	}
}
Beispiel #8
0
/**
	result_set_conv_date : 'result -> function:1 -> void
	<doc>Set the function that will convert a Date or DateTime string
	to the corresponding value.</doc>
**/
static value result_set_conv_date( value o, value c ) {
	val_check_function(c,1);
	if( val_is_int(o) )
		return val_true;
	val_check_kind(o,k_result);
	RESULT(o)->conv_date = c;
	return val_true;
}
Beispiel #9
0
// String access
int api_val_strlen(value  arg1)
{
	if (val_is_string(arg1))
	   return val_strlen(arg1);
	value l =  val_field(arg1,length_id);
	if (val_is_int(l))
		return val_int(l);
	return 0;
}
Beispiel #10
0
value hx_zmq_setbytessockopt(value socket_handle_, value option_, value bytes_optval_) {

	val_check_kind(socket_handle_, k_zmq_socket_handle);

	if (!val_is_int(option_)) {
		printf("option_ is not int");
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}

	size_t size = 0;
	uint8_t *data = 0;
	
	// If data from neko
	if (val_is_string(bytes_optval_))
	{
		size = val_strlen(bytes_optval_);
		data = (uint8_t *)val_string(bytes_optval_);		
	} // else from C++
	else if (val_is_buffer(bytes_optval_))
	{
		buffer buf = val_to_buffer(bytes_optval_);
		size = buffer_size(buf);
		data = (uint8_t *)buffer_data(buf);		
	} else {
		printf("bytes_optval_ not string or buffer");
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
		
	int rc = 0;
	int err = 0;
	int option = val_int(option_);

	rc = zmq_setsockopt (val_data(socket_handle_), option, data, size);
	
    err = zmq_errno();
	if (rc != 0) {
		printf("err:%d",err);
		val_throw(alloc_int(err));
		return alloc_null();
	}		
	return alloc_int(rc);
	
}
Beispiel #11
0
static int read_proxy( readp p, void *buf, int size ) {
	value fread = val_array_ptr(p)[0];
	value vbuf = val_array_ptr(p)[1];
	value ret;
	int len;
	if( size < 0 )
		return -1;
	if( size > READ_BUFSIZE )
		vbuf = alloc_empty_string(size);
	ret = val_call3(fread,vbuf,alloc_int(0),alloc_int(size));
	if( !val_is_int(ret) )
		return -1;
	len = val_int(ret);
	if( len < 0 || len > size )
		return -1;
	memcpy(buf,val_string(vbuf),len);
	return len;
}
Beispiel #12
0
//FIXME indices and bytearrays do not particularly mix
//Does val_to_buffer throw an error on null?
value drawElements( value mode, value count, value type, value indices )
{
	char *ptr = NULL;
	if (val_is_buffer(indices))
	{
		ptr = buffer_data( val_to_buffer ( indices ) );
	}
	else if (val_is_int(indices))
	{
		ptr = ((char *)NULL+val_int(indices));
	}
	glDrawElements(
		(GLenum)val_int( mode ),
		(GLsizei)val_int( count ),
		(GLenum)val_int( type ),
		(const GLvoid *)ptr );
	return alloc_null( );
}
Beispiel #13
0
value hx_zmq_construct_socket (value context_handle,value type)
{
	val_is_kind(context_handle,k_zmq_context_handle);
	if (!val_is_int(type)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
		
	void *s = zmq_socket (val_data(context_handle),val_int(type));
	int err = zmq_errno();
	
	if (s == NULL) {
		val_throw (alloc_int(err));
		return alloc_null();
	}
	
	// See: http://nekovm.org/doc/ffi#abstracts_and_kinds
	value v =  alloc_abstract(k_zmq_socket_handle,s);
	val_gc(v,finalize_socket);		// finalize_socket is called when the abstract value is garbage collected
	return v;
	
}
Beispiel #14
0
/**
	result_get_length : 'result -> int
	<doc>Return the number of rows returned or affected</doc>
**/
static value result_get_length( value o ) {
	if( val_is_int(o) )
		return o;
	val_check_kind(o,k_result);
	return alloc_int( (int)mysql_num_rows(RESULT(o)->r) );
}
Beispiel #15
0
static void report( neko_vm *vm, value exc ) {
#if OSX
	CFStringRef title = CFSTR("Uncaught exception");
	CFStringRef message;
#endif
	int i = 0;
	buffer b = alloc_buffer(NULL);
	value st = neko_exc_stack(vm);
	if( val_array_size(st) > 20 ) {
		i = val_array_size(st) - 20;
		buffer_append(b,"...\n");
	}
	for(i;i<val_array_size(st);i++) {
		value s = val_array_ptr(st)[i];
		if( val_is_null(s) )
			buffer_append(b,"Called from a C function\n");
		else if( val_is_string(s) ) {
			buffer_append(b,"Called from ");
			buffer_append(b,val_string(s));
			buffer_append(b," (no debug available)\n");
		} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) {
			buffer_append(b,"Called from ");
			buffer_append(b,val_string(val_array_ptr(s)[0]));
			buffer_append(b," line ");
			val_buffer(b,val_array_ptr(s)[1]);
			buffer_append(b,"\n");
		} else {
			buffer_append(b,"Called from ");
			val_buffer(b,s);
			buffer_append(b,"\n");
		}
	}
	val_buffer(b,exc);
#if _WIN32
	MessageBox(NULL,val_string(buffer_to_string(b)),"Uncaught exception",MB_OK | MB_ICONERROR);
#elif OSX
	message = CFStringCreateWithCString(NULL,val_string(buffer_to_string(b)), kCFStringEncodingUTF8);
	CFUserNotificationDisplayNotice(0,0,NULL,NULL,NULL,title,message,NULL);
#elif LINUX
	fprintf(stderr,"Uncaught Exception: %s\n",val_string(buffer_to_string(b)));
#endif
}
Beispiel #16
0
/**
	$not : any -> bool
	<doc>Return true if [v] is [false] or [null] or [0]</doc>
**/
static value builtin_not( value f ) {
	return alloc_bool(f == val_false || f == val_null || f == alloc_int(0) || (!val_is_int(f) && val_tag(f) == VAL_INT32 && val_int32(f) == 0));
}
Beispiel #17
0
static void report( neko_vm *vm, value exc, int isexc ) {
	int i;
	buffer b = alloc_buffer(NULL);
	value st = neko_exc_stack(vm);
	for(i=0;i<val_array_size(st);i++) {
		value s = val_array_ptr(st)[i];
		buffer_append(b,"Called from ");
		if( val_is_null(s) )
			buffer_append(b,"a C function");
		else if( val_is_string(s) ) {
			buffer_append(b,val_string(s));
			buffer_append(b," (no debug available)");
		} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) {
			val_buffer(b,val_array_ptr(s)[0]);
			buffer_append(b," line ");
			val_buffer(b,val_array_ptr(s)[1]);
		} else
			val_buffer(b,s);
		buffer_append_char(b,'\n');
	}
	if( isexc )
		buffer_append(b,"Uncaught exception - ");
	val_buffer(b,exc);
#	ifdef NEKO_STANDALONE
	neko_standalone_error(val_string(buffer_to_string(b)));
#	else
	fprintf(stderr,"%s\n",val_string(buffer_to_string(b)));
#	endif
}
Beispiel #18
0
static int ms_compare( m_sort *m, int a, int b ) {
	value v = val_call2(m->cmp,m->arr[a],m->arr[b]);
	if( !val_is_int(v) ) return -1;
	return val_int(v);
}
    DEFINE_FUNC_5(webp_encode_argb, data_buffer_value, width_value, height_value, lossless_value, quality_factor_value) {
        int width = 0;
        int height = 0;
        float quality_factor = 100;
        int lossless = 1;
        int stride = 0;
        uint8_t* abgr = NULL;
        uint8_t* rgba = NULL;
        uint8_t* output = NULL;
        int output_size = 0;
        int pixels_size;
        int bytes_size;
        buffer data_buffer;

        if (val_is_int(width_value)) width = val_int(width_value);
        if (val_is_int(height_value)) height = val_int(height_value);
        if (val_is_bool(lossless_value)) lossless = val_bool(lossless_value);
        if (val_is_float(quality_factor_value)) quality_factor = val_float(quality_factor_value);

        stride = width * 4;
        pixels_size = width * height;
        bytes_size = pixels_size * 4;

        if (!val_is_buffer(data_buffer_value)) {
            val_throw(alloc_string("webp_encode_argb: Expected to be a buffer"));
            return alloc_null();
        }

        data_buffer = val_to_buffer(data_buffer_value);

        if (bytes_size != buffer_size(data_buffer)) {
            val_throw(alloc_string("webp_encode_argb: Invalid buffer size"));
            return alloc_null();
        }

        //if ()

        abgr = (uint8_t *)buffer_data(data_buffer);
        rgba = (uint8_t *)malloc(bytes_size);

        uint8_t* _abgr = abgr;
        uint8_t* _rgba = rgba;
        int _pixels_size = pixels_size;

        while (_pixels_size-- > 0) {
            //_rgba[0] = _abgr[3];
            _rgba[0] = _abgr[1];
            _rgba[1] = _abgr[2];
            _rgba[2] = _abgr[3];
            _rgba[3] = _abgr[0];
            _abgr += 4;
            _rgba += 4;
        }

        if (lossless) {
            output_size = WebPEncodeLosslessRGBA(
                              rgba,
                              //abgr,
                              width, height, stride,
                              &output
                          );
        } else {
            output_size = WebPEncodeRGBA(
                              rgba,
                              //abgr,
                              width, height, stride,
                              quality_factor,
                              &output
                          );
        }

        printf("output_size: (%d, %d, %d) : %d\n", width, height, stride, output_size);

        buffer output_buffer = alloc_buffer_len(0);
        buffer_append_sub(output_buffer, (char *)output, output_size);
        buffer_set_size(output_buffer, output_size);

        if (output != NULL) free(output);
        if (rgba != NULL) free(rgba);

        return buffer_val(output_buffer);
    }
Beispiel #20
0
/**
 * Receive data from socket
 * Based on code in  https://github.com/zeromq/jzmq/blob/master/src/Socket.cpp
 */
value hx_zmq_send(value socket_handle_, value msg_data, value flags) {
	
	val_check_kind(socket_handle_, k_zmq_socket_handle);
	
	if (!val_is_null(flags) && !val_is_int(flags)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
	
	size_t size = 0;
	uint8_t *data = 0;
	
	
	zmq_msg_t message;

	// Extract byte data from either Neko string or C++ buffer
	// see: http://waxe.googlecode.com/svn-history/r32/trunk/src/waxe/HaxeAPI.cpp "Val2ByteData"
	if (val_is_string(msg_data))
	{
		// Neko
		size = val_strlen(msg_data);
		data = (uint8_t *)val_string(msg_data);
	}
	else if (val_is_buffer(msg_data))
	{
		// CPP
		buffer buf = val_to_buffer(msg_data);
		size = buffer_size(buf);
		data = (uint8_t *)buffer_data(buf);
	} else {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
		
	
	// Set up send message buffer by referencing the provided bytes data
    //zero copy version: int rc = zmq_msg_init_data (&message, data, size,NULL,NULL);
	int rc = zmq_msg_init_size(&message, size);
	memcpy (zmq_msg_data(&message), data, size);
	
    int err = zmq_errno();
    if (rc != 0) {
        val_throw(alloc_int(err));
        return alloc_null();
    }

	gc_enter_blocking();
	// Send
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)	
    rc = zmq_sendmsg (val_data(socket_handle_), &message, val_int(flags));
#else
    rc = zmq_send (val_data(socket_handle_), &message, val_int(flags));
#endif
    err = zmq_errno();
	
	gc_exit_blocking();
	
	// If NOBLOCK, but cant send message now, close message first before quitting
    if (rc == -1 && err == EAGAIN) {
        rc = zmq_msg_close (&message);
        err = zmq_errno();
        if (rc != 0) {
			val_throw(alloc_int(err));
			return alloc_null();
        }
        return alloc_null();
    }
    
    if (rc == -1) {
        val_throw(alloc_int(err));
        rc = zmq_msg_close (&message);
        err = zmq_errno();
        if (rc != 0) {
			val_throw(alloc_int(err));
			return alloc_null();
        }
        return alloc_null();
    }

    rc = zmq_msg_close (&message);
    err = zmq_errno();
    if (rc != 0) {
			val_throw(alloc_int(err));
			return alloc_null();
    }
	return alloc_null();
}
void NekoCodeChunk::neko_dump(std::string const & indent) const {
	for (const_iterator it = begin();
		 it != end();
		 ++it)
		{
			std::cout << indent << it->first << ": ";
			print_neko_instruction((OPCODE) it->second.first, it->second.second, parameter_table[it->second.first]);

			std::cout << "; // ";
			{
				int ppc = (int)((int_val *)it->first - m->code);
				int idx = m->dbgidxs[ppc>>5].base + bitcount(m->dbgidxs[ppc>>5].bits >> (31 - (ppc & 31)));
				value s = val_array_ptr(m->dbgtbl)[idx];
				if( val_is_string(s) )
					printf("%s",val_string(s));
				else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) )
					printf("file %s line %d",val_string(val_array_ptr(s)[0]),val_int(val_array_ptr(s)[1]));
				else
					printf("???");
			}
			std::cout << std::endl;
		}
}
Beispiel #22
0
/**
 * Receive data from socket
 * Based on code in  https://github.com/zeromq/jzmq/blob/master/src/Socket.cpp
 */
value hx_zmq_rcv(value socket_handle_, value flags) {
	
	val_check_kind(socket_handle_, k_zmq_socket_handle);
	
	if (!val_is_null(flags) && !val_is_int(flags)) {
		val_throw(alloc_int(EINVAL));
		return alloc_null();
	}
	
	zmq_msg_t message;

    int rc = zmq_msg_init (&message);
    int err = zmq_errno();
    if (rc != 0) {
        val_throw(alloc_int(err));
        return alloc_null();
    }
	
	gc_enter_blocking();
	
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)	
    rc = zmq_recvmsg (val_data(socket_handle_), &message, val_int(flags));
#else
    rc = zmq_recv (val_data(socket_handle_), &message, val_int(flags));
#endif
	gc_exit_blocking();

    err = zmq_errno();
    if (rc == -1 && err == EAGAIN) {
        rc = zmq_msg_close (&message);
        err = zmq_errno();
        if (rc != 0) {
			val_throw(alloc_int(err));
			return alloc_null();
        }
        return alloc_null();
    }

    if (rc == -1) {
        rc = zmq_msg_close (&message);
        int err1 = zmq_errno();
        if (rc != 0) {
			val_throw(alloc_int(err1));
			return alloc_null();
        }
        val_throw(alloc_int(err));
        return alloc_null();
    }
	
	// Return data to Haxe
	int sz = zmq_msg_size (&message);
    const char* pd = (char *)zmq_msg_data (&message);

	// Create a return buffer byte array, by memcopying the message data, then discard the ZMQ message
	buffer b = alloc_buffer(NULL);
	buffer_append_sub(b,pd,sz);
	rc = zmq_msg_close (&message);
	err = zmq_errno();
	if (rc != 0) {
		val_throw(alloc_int(err));
		return alloc_null();
	}
	return buffer_val(b);
}
Beispiel #23
0
EXTERN value val_callEx( value vthis, value f, value *args, int nargs, value *exc ) {
	neko_vm *vm = NEKO_VM();
	value old_this = vm->vthis;
	value old_env = vm->env;
	value ret = val_null;
	jmp_buf oldjmp;
	if( vthis != NULL )
		vm->vthis = vthis;
	if( exc ) {
		memcpy(&oldjmp,&vm->start,sizeof(jmp_buf));
		if( setjmp(vm->start) ) {
			*exc = vm->vthis;
			neko_process_trap(vm);
			vm->vthis = old_this;
			vm->env = old_env;
			memcpy(&vm->start,&oldjmp,sizeof(jmp_buf));
			return val_null;
		}
		neko_setup_trap(vm);
	}
	if( (uintptr_t)&vm < (uintptr_t)vm->c_stack_max )
		val_throw(alloc_string("C Stack Overflow"));
	if( val_is_int(f) )
		val_throw(alloc_string("Invalid call"));
	if( val_tag(f) == VAL_PRIMITIVE ) {
		vm->env = ((vfunction *)f)->env;
		if( nargs == ((vfunction*)f)->nargs ) {
			if( nargs > CALL_MAX_ARGS )
				failure("Too many arguments for a call");
			switch( nargs ) {
			case 0:
				ret = ((c_prim0)((vfunction*)f)->addr)();
				break;
			case 1:
				ret = ((c_prim1)((vfunction*)f)->addr)(args[0]);
				break;
			case 2:
				ret = ((c_prim2)((vfunction*)f)->addr)(args[0],args[1]);
				break;
			case 3:
				ret = ((c_prim3)((vfunction*)f)->addr)(args[0],args[1],args[2]);
				break;
			case 4:
				ret = ((c_prim4)((vfunction*)f)->addr)(args[0],args[1],args[2],args[3]);
				break;
			case 5:
				ret = ((c_prim5)((vfunction*)f)->addr)(args[0],args[1],args[2],args[3],args[4]);
				break;
			}
		} else if( ((vfunction*)f)->nargs == -1 )
			ret = (value)((c_primN)((vfunction*)f)->addr)(args,nargs);
		else
			val_throw(alloc_string("Invalid call"));		
		if( ret == NULL )
			val_throw( (value)((vfunction*)f)->module );		
	} else if( val_short_tag(f) == VAL_FUNCTION ) {
		if( nargs == ((vfunction*)f)->nargs )  {
			int n;
			if( vm->csp + 4 >= vm->sp - nargs && !neko_stack_expand(vm->sp,vm->csp,vm) ) {
				if( exc ) {
					neko_process_trap(vm);
					memcpy(&vm->start,&oldjmp,sizeof(jmp_buf));	
				}
				failure("Stack Overflow");
			} else {
				for(n=0;n<nargs;n++)
					*--vm->sp = (int_val)args[n];
				vm->env = ((vfunction*)f)->env;
				if( val_tag(f) == VAL_FUNCTION ) {
					*++vm->csp = (int_val)callback_return;
					*++vm->csp = 0;
					*++vm->csp = 0;
					*++vm->csp = 0;
					ret = neko_interp(vm,((vfunction*)f)->module,(int_val)val_null,(int_val*)((vfunction*)f)->addr);
				} else {
					neko_module *m = (neko_module*)((vfunction*)f)->module;
					ret = ((jit_prim)jit_boot_seq)(vm,((vfunction*)f)->addr,val_null,m);			
				}
			}
		}
		else
			val_throw(alloc_string("Invalid call"));
	} else
		val_throw(alloc_string("Invalid call"));
	if( exc ) {
		neko_process_trap(vm);
		memcpy(&vm->start,&oldjmp,sizeof(jmp_buf));	
	}
	vm->vthis = old_this;
	vm->env = old_env;
	return ret;
}
Beispiel #24
0
static int neko_handler_rec( request_rec *r ) {
	mcontext ctx;
	neko_vm *vm;
	const char *ctype;
	value exc = NULL;

/*
	Seems to crash on Windows. And on Linux, we rarely have libGC 7.x installed anyway

#	if defined(APACHE_2_X) || defined(NEKO_WINDOWS)
	// we are using threads, so let's make sure that the current thread is registered
	neko_thread_register(true);
#	endif
*/

	config.hits++;

	ctx.r = r;
	ctx.main = cache_find(r);
	ctx.post_data = val_null;
	ctx.headers_sent = false;
	ctx.content_type = alloc_string("text/html");
    r->content_type = val_string(ctx.content_type);

	if( ap_setup_client_block(r,REQUEST_CHUNKED_ERROR) != 0 ) {
		send_headers(&ctx);
		apache_error(APLOG_WARNING,r,"ap_setup_client_block failed");
		return OK;
	}

	ctype = ap_table_get(r->headers_in,"Content-Type");
	if( (!ctype || strstr(ctype,"multipart/form-data") == NULL) && ap_should_client_block(r) ) {
#		define MAXLEN 1024
		char buf[MAXLEN];
		int len;
		int tlen = 0;
		buffer b = alloc_buffer(NULL);
		while( (len = ap_get_client_block(r,buf,MAXLEN)) > 0 ) {
			if( tlen < config.max_post_size )
				buffer_append_sub(b,buf,len);
			tlen += len;
		}
		if( tlen >= config.max_post_size ) {
			send_headers(&ctx);
			apache_error(APLOG_WARNING,r,"Maximum POST data exceeded. Try using multipart encoding");
			return OK;
		}
		ctx.post_data = buffer_to_string(b);
	}

	vm = neko_vm_alloc(NULL);
	if( config.use_stats ) neko_vm_set_stats(vm,neko_stats_measure,config.use_prim_stats?neko_stats_measure:NULL);

	neko_vm_set_custom(vm,k_mod_neko,&ctx);
	if( config.use_jit && !neko_vm_jit(vm,1) ) {
		send_headers(&ctx);
		apache_error(APLOG_WARNING,r,"JIT required by env. var but not enabled in NekoVM");
		return OK;
	}

	neko_vm_redirect(vm,request_print,&ctx);
	neko_vm_select(vm);

	if( ctx.main != NULL ) {
		value old = ctx.main;
		if( config.use_stats ) neko_stats_measure(vm,r->filename,1);
		val_callEx(val_null,old,NULL,0,&exc);
		if( config.use_stats ) neko_stats_measure(vm,r->filename,0);
		if( old != ctx.main ) cache_module(r->filename,FTIME(r),ctx.main);
	} else {
		char *base_uri = request_base_uri(r);
		value mload = neko_default_loader(&base_uri,1);
		value args[] = { alloc_string(r->filename), mload };
		char *p = strrchr(val_string(args[0]),'.');
		if( p != NULL )
			*p = 0;
		val_callEx(mload,val_field(mload,val_id("loadmodule")),args,2,&exc);
		if( ctx.main != NULL && config.use_cache )
			cache_module(r->filename,FTIME(r),ctx.main);
	}

	if( exc != NULL ) {
		buffer b = alloc_buffer(NULL);
		value v;
		int i;
		const char *p, *start;
		value st = neko_exc_stack(vm);
		val_buffer(b,exc);
		config.exceptions++;
		ap_soft_timeout("Client Timeout",r);
		send_headers(&ctx);
		v = buffer_to_string(b);
		p = val_string(v);
		start = p;
		ap_rprintf(r,"Uncaught exception - ");
		while( *p ) {
			if( *p == '<' || *p == '>' ) {
				ap_rwrite(start,(int)(p - start),r);
				ap_rwrite((*p == '<')?"&lt;":"&gt;",4, r);
				start = p + 1;
			}
			p++;
		}
		ap_rwrite(start,(int)(p - start),r);
		ap_rprintf(r,"<br/><br/>");
		for(i=0;i<val_array_size(st);i++) {
			value s = val_array_ptr(st)[i];
			if( val_is_null(s) )
				ap_rprintf(r,"Called from a C function<br/>");
			else if( val_is_string(s) ) {
				ap_rprintf(r,"Called from %s (no debug available)<br/>",val_string(s));
			} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) )
				ap_rprintf(r,"Called from %s line %d<br/>",val_string(val_array_ptr(s)[0]),val_int(val_array_ptr(s)[1]));
			else {
				b = alloc_buffer(NULL);
				val_buffer(b,s);
				ap_rprintf(r,"Called from %s<br/>",val_string(buffer_to_string(b)));
			}
		}
		ap_kill_timeout(r);
		return OK;
	}

	send_headers(&ctx);
    return OK;
}
Beispiel #25
0
/**
	$istrue : v:any -> bool
	<doc>Return true if [v] is not [false], not [null] and not 0</doc>
**/
static value builtin_istrue( value f ) {
	return alloc_bool(f != val_false && f != val_null && f != alloc_int(0) && (val_is_int(f) || val_tag(f) != VAL_INT32 || val_int32(f) != 0));
}