compiler, runtime: More steps toward separating int and intgo.
From-SVN: r193059
This commit is contained in:
parent
79e0221796
commit
776f27a67f
@ -1832,11 +1832,9 @@ Integer_expression::do_get_tree(Translate_context* context)
|
||||
// some reason. Use a type which will fit the value. We use <,
|
||||
// not <=, because we need an extra bit for the sign bit.
|
||||
int bits = mpz_sizeinbase(this->val_, 2);
|
||||
if (bits < INT_TYPE_SIZE)
|
||||
{
|
||||
Type* t = Type::lookup_integer_type("int");
|
||||
type = type_to_tree(t->get_backend(gogo));
|
||||
}
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
if (bits < int_type->integer_type()->bits())
|
||||
type = type_to_tree(int_type->get_backend(gogo));
|
||||
else if (bits < 64)
|
||||
{
|
||||
Type* t = Type::lookup_integer_type("int64");
|
||||
@ -3146,7 +3144,10 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
|
||||
else if (type->is_string_type()
|
||||
&& expr_type->integer_type() != NULL)
|
||||
{
|
||||
expr_tree = fold_convert(integer_type_node, expr_tree);
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
|
||||
|
||||
expr_tree = fold_convert(int_type_tree, expr_tree);
|
||||
if (host_integerp(expr_tree, 0))
|
||||
{
|
||||
HOST_WIDE_INT intval = tree_low_cst(expr_tree, 0);
|
||||
@ -3162,20 +3163,24 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
|
||||
"__go_int_to_string",
|
||||
1,
|
||||
type_tree,
|
||||
integer_type_node,
|
||||
fold_convert(integer_type_node, expr_tree));
|
||||
int_type_tree,
|
||||
expr_tree);
|
||||
}
|
||||
else if (type->is_string_type() && expr_type->is_slice_type())
|
||||
{
|
||||
if (!DECL_P(expr_tree))
|
||||
expr_tree = save_expr(expr_tree);
|
||||
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
|
||||
|
||||
Array_type* a = expr_type->array_type();
|
||||
Type* e = a->element_type()->forwarded();
|
||||
go_assert(e->integer_type() != NULL);
|
||||
tree valptr = fold_convert(const_ptr_type_node,
|
||||
a->value_pointer_tree(gogo, expr_tree));
|
||||
tree len = a->length_tree(gogo, expr_tree);
|
||||
len = fold_convert_loc(this->location().gcc_location(), integer_type_node,
|
||||
len = fold_convert_loc(this->location().gcc_location(), int_type_tree,
|
||||
len);
|
||||
if (e->integer_type()->is_byte())
|
||||
{
|
||||
@ -3187,7 +3192,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
|
||||
type_tree,
|
||||
const_ptr_type_node,
|
||||
valptr,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
len);
|
||||
}
|
||||
else
|
||||
@ -3201,7 +3206,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
|
||||
type_tree,
|
||||
const_ptr_type_node,
|
||||
valptr,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
len);
|
||||
}
|
||||
}
|
||||
@ -3939,6 +3944,7 @@ Unary_expression::do_check_types(Gogo*)
|
||||
tree
|
||||
Unary_expression::do_get_tree(Translate_context* context)
|
||||
{
|
||||
Gogo* gogo = context->gogo();
|
||||
Location loc = this->location();
|
||||
|
||||
// Taking the address of a set-and-use-temporary expression requires
|
||||
@ -4103,7 +4109,7 @@ Unary_expression::do_get_tree(Translate_context* context)
|
||||
expr,
|
||||
fold_convert(TREE_TYPE(expr),
|
||||
null_pointer_node));
|
||||
tree crash = Gogo::runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
|
||||
tree crash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
|
||||
loc);
|
||||
expr = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR,
|
||||
TREE_TYPE(expr), build3(COND_EXPR,
|
||||
@ -4119,7 +4125,7 @@ Unary_expression::do_get_tree(Translate_context* context)
|
||||
if (VOID_TYPE_P(target_type_tree))
|
||||
{
|
||||
Type* pt = this->expr_->type()->points_to();
|
||||
tree ind = type_to_tree(pt->get_backend(context->gogo()));
|
||||
tree ind = type_to_tree(pt->get_backend(gogo));
|
||||
expr = fold_convert_loc(loc.gcc_location(),
|
||||
build_pointer_type(ind), expr);
|
||||
}
|
||||
@ -5668,6 +5674,8 @@ Binary_expression::do_check_types(Gogo*)
|
||||
tree
|
||||
Binary_expression::do_get_tree(Translate_context* context)
|
||||
{
|
||||
Gogo* gogo = context->gogo();
|
||||
|
||||
tree left = this->left_->get_tree(context);
|
||||
tree right = this->right_->get_tree(context);
|
||||
|
||||
@ -5756,7 +5764,7 @@ Binary_expression::do_get_tree(Translate_context* context)
|
||||
{
|
||||
go_assert(this->op_ == OPERATOR_PLUS);
|
||||
Type* st = Type::make_string_type();
|
||||
tree string_type = type_to_tree(st->get_backend(context->gogo()));
|
||||
tree string_type = type_to_tree(st->get_backend(gogo));
|
||||
static tree string_plus_decl;
|
||||
return Gogo::call_builtin(&string_plus_decl,
|
||||
this->location(),
|
||||
@ -5859,7 +5867,7 @@ Binary_expression::do_get_tree(Translate_context* context)
|
||||
// __go_runtime_error(RUNTIME_ERROR_DIVISION_BY_ZERO), 0
|
||||
int errcode = RUNTIME_ERROR_DIVISION_BY_ZERO;
|
||||
tree panic = fold_build2_loc(gccloc, COMPOUND_EXPR, TREE_TYPE(ret),
|
||||
Gogo::runtime_error(errcode,
|
||||
gogo->runtime_error(errcode,
|
||||
this->location()),
|
||||
fold_convert_loc(gccloc, TREE_TYPE(ret),
|
||||
integer_zero_node));
|
||||
@ -6152,6 +6160,9 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
Type* right_type, tree right_tree,
|
||||
Location location)
|
||||
{
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
tree int_type_tree = type_to_tree(int_type->get_backend(context->gogo()));
|
||||
|
||||
enum tree_code code;
|
||||
switch (op)
|
||||
{
|
||||
@ -6186,12 +6197,12 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
location,
|
||||
"__go_strcmp",
|
||||
2,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
string_type,
|
||||
left_tree,
|
||||
string_type,
|
||||
right_tree);
|
||||
right_tree = build_int_cst_type(integer_type_node, 0);
|
||||
right_tree = build_int_cst_type(int_type_tree, 0);
|
||||
}
|
||||
else if ((left_type->interface_type() != NULL
|
||||
&& right_type->interface_type() == NULL
|
||||
@ -6248,7 +6259,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
location,
|
||||
"__go_empty_interface_value_compare",
|
||||
3,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
TREE_TYPE(left_tree),
|
||||
left_tree,
|
||||
TREE_TYPE(descriptor),
|
||||
@ -6267,7 +6278,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
location,
|
||||
"__go_interface_value_compare",
|
||||
3,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
TREE_TYPE(left_tree),
|
||||
left_tree,
|
||||
TREE_TYPE(descriptor),
|
||||
@ -6279,7 +6290,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
// This can panic if the type is not comparable.
|
||||
TREE_NOTHROW(interface_value_compare_decl) = 0;
|
||||
}
|
||||
right_tree = build_int_cst_type(integer_type_node, 0);
|
||||
right_tree = build_int_cst_type(int_type_tree, 0);
|
||||
|
||||
if (make_tmp != NULL_TREE)
|
||||
left_tree = build2(COMPOUND_EXPR, TREE_TYPE(left_tree), make_tmp,
|
||||
@ -6296,7 +6307,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
location,
|
||||
"__go_empty_interface_compare",
|
||||
2,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
TREE_TYPE(left_tree),
|
||||
left_tree,
|
||||
TREE_TYPE(right_tree),
|
||||
@ -6314,7 +6325,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
location,
|
||||
"__go_interface_compare",
|
||||
2,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
TREE_TYPE(left_tree),
|
||||
left_tree,
|
||||
TREE_TYPE(right_tree),
|
||||
@ -6339,7 +6350,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
location,
|
||||
"__go_interface_empty_compare",
|
||||
2,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
TREE_TYPE(left_tree),
|
||||
left_tree,
|
||||
TREE_TYPE(right_tree),
|
||||
@ -6350,7 +6361,7 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
|
||||
TREE_NOTHROW(interface_empty_compare_decl) = 0;
|
||||
}
|
||||
|
||||
right_tree = build_int_cst_type(integer_type_node, 0);
|
||||
right_tree = build_int_cst_type(int_type_tree, 0);
|
||||
}
|
||||
|
||||
if (left_type->is_nil_type()
|
||||
@ -7869,6 +7880,9 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
|
||||
arg_tree = build_fold_indirect_ref(arg_tree);
|
||||
}
|
||||
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
|
||||
|
||||
tree val_tree;
|
||||
if (this->code_ == BUILTIN_LEN)
|
||||
{
|
||||
@ -7893,7 +7907,7 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
|
||||
location,
|
||||
"__go_map_len",
|
||||
1,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
arg_type_tree,
|
||||
arg_tree);
|
||||
}
|
||||
@ -7905,7 +7919,7 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
|
||||
location,
|
||||
"__go_chan_len",
|
||||
1,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
arg_type_tree,
|
||||
arg_tree);
|
||||
}
|
||||
@ -7934,7 +7948,7 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
|
||||
location,
|
||||
"__go_chan_cap",
|
||||
1,
|
||||
integer_type_node,
|
||||
int_type_tree,
|
||||
arg_type_tree,
|
||||
arg_tree);
|
||||
}
|
||||
@ -7942,15 +7956,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
|
||||
go_unreachable();
|
||||
}
|
||||
|
||||
if (val_tree == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
tree type_tree = type_to_tree(int_type->get_backend(gogo));
|
||||
if (type_tree == TREE_TYPE(val_tree))
|
||||
return val_tree;
|
||||
else
|
||||
return fold(convert_to_integer(type_tree, val_tree));
|
||||
return fold_convert_loc(location.gcc_location(), int_type_tree,
|
||||
val_tree);
|
||||
}
|
||||
|
||||
case BUILTIN_PRINT:
|
||||
@ -9872,7 +9879,7 @@ Array_index_expression::do_get_tree(Translate_context* context)
|
||||
: (this->end_ == NULL
|
||||
? RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS
|
||||
: RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS));
|
||||
tree crash = Gogo::runtime_error(code, loc);
|
||||
tree crash = gogo->runtime_error(code, loc);
|
||||
|
||||
if (this->end_ == NULL)
|
||||
{
|
||||
@ -10185,7 +10192,9 @@ String_index_expression::do_get_tree(Translate_context* context)
|
||||
|
||||
tree length_tree = String_type::length_tree(context->gogo(), string_tree);
|
||||
length_tree = save_expr(length_tree);
|
||||
tree length_type = TREE_TYPE(length_tree);
|
||||
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
tree length_type = type_to_tree(int_type->get_backend(context->gogo()));
|
||||
|
||||
tree bad_index = boolean_false_node;
|
||||
|
||||
@ -10205,7 +10214,7 @@ String_index_expression::do_get_tree(Translate_context* context)
|
||||
int code = (this->end_ == NULL
|
||||
? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS
|
||||
: RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS);
|
||||
tree crash = Gogo::runtime_error(code, loc);
|
||||
tree crash = context->gogo()->runtime_error(code, loc);
|
||||
|
||||
if (this->end_ == NULL)
|
||||
{
|
||||
|
@ -2331,14 +2331,17 @@ Gogo::call_builtin(tree* pdecl, Location location, const char* name,
|
||||
tree
|
||||
Gogo::runtime_error(int code, Location location)
|
||||
{
|
||||
Type* int32_type = Type::lookup_integer_type("int32");
|
||||
tree int32_type_tree = type_to_tree(int32_type->get_backend(this));
|
||||
|
||||
static tree runtime_error_fndecl;
|
||||
tree ret = Gogo::call_builtin(&runtime_error_fndecl,
|
||||
location,
|
||||
"__go_runtime_error",
|
||||
1,
|
||||
void_type_node,
|
||||
integer_type_node,
|
||||
build_int_cst(integer_type_node, code));
|
||||
int32_type_tree,
|
||||
build_int_cst(int32_type_tree, code));
|
||||
if (ret == error_mark_node)
|
||||
return error_mark_node;
|
||||
// The runtime error function panics and does not return.
|
||||
|
@ -558,7 +558,7 @@ class Gogo
|
||||
tree rettype, ...);
|
||||
|
||||
// Build a call to the runtime error function.
|
||||
static tree
|
||||
tree
|
||||
runtime_error(int code, Location);
|
||||
|
||||
// Build a builtin struct with a list of fields.
|
||||
|
@ -30,7 +30,7 @@ enum Runtime_function_type
|
||||
RFT_BOOL,
|
||||
// Go type *bool, C type _Bool*.
|
||||
RFT_BOOLPTR,
|
||||
// Go type int, C type int.
|
||||
// Go type int, C type intgo.
|
||||
RFT_INT,
|
||||
// Go type int32, C type int32_t.
|
||||
RFT_INT32,
|
||||
|
@ -198,7 +198,7 @@ DEF_GO_RUNTIME(CHECK_DEFER, "__go_check_defer", P1(BOOLPTR), R0())
|
||||
DEF_GO_RUNTIME(UNDEFER, "__go_undefer", P1(BOOLPTR), R0())
|
||||
|
||||
// Panic with a runtime error.
|
||||
DEF_GO_RUNTIME(RUNTIME_ERROR, "__go_runtime_error", P1(INT), R0())
|
||||
DEF_GO_RUNTIME(RUNTIME_ERROR, "__go_runtime_error", P1(INT32), R0())
|
||||
|
||||
|
||||
// Close.
|
||||
|
@ -2985,7 +2985,7 @@ String_type::length_tree(Gogo*, tree string)
|
||||
tree length_field = DECL_CHAIN(TYPE_FIELDS(string_type));
|
||||
go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(length_field)),
|
||||
"__length") == 0);
|
||||
return fold_build3(COMPONENT_REF, integer_type_node, string,
|
||||
return fold_build3(COMPONENT_REF, TREE_TYPE(length_field), string,
|
||||
length_field, NULL_TREE);
|
||||
}
|
||||
|
||||
@ -5524,7 +5524,9 @@ Array_type::get_length_tree(Gogo* gogo)
|
||||
tree len = this->length_->get_tree(&context);
|
||||
if (len != error_mark_node)
|
||||
{
|
||||
len = convert_to_integer(integer_type_node, len);
|
||||
Type* int_type = Type::lookup_integer_type("int");
|
||||
tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
|
||||
len = convert_to_integer(int_type_tree, len);
|
||||
len = save_expr(len);
|
||||
}
|
||||
this->length_tree_ = len;
|
||||
@ -5663,10 +5665,12 @@ Array_type::length_tree(Gogo* gogo, tree array)
|
||||
if (this->length_ != NULL)
|
||||
{
|
||||
if (TREE_CODE(array) == SAVE_EXPR)
|
||||
return fold_convert(integer_type_node, this->get_length_tree(gogo));
|
||||
return this->get_length_tree(gogo);
|
||||
else
|
||||
return omit_one_operand(integer_type_node,
|
||||
this->get_length_tree(gogo), array);
|
||||
{
|
||||
tree len = this->get_length_tree(gogo);
|
||||
return omit_one_operand(TREE_TYPE(len), len, array);
|
||||
}
|
||||
}
|
||||
|
||||
// This is an open array. We need to read the length field.
|
||||
@ -5690,8 +5694,10 @@ tree
|
||||
Array_type::capacity_tree(Gogo* gogo, tree array)
|
||||
{
|
||||
if (this->length_ != NULL)
|
||||
return omit_one_operand(integer_type_node, this->get_length_tree(gogo),
|
||||
array);
|
||||
{
|
||||
tree len = this->get_length_tree(gogo);
|
||||
return omit_one_operand(TREE_TYPE(len), len, array);
|
||||
}
|
||||
|
||||
// This is an open array. We need to read the capacity field.
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "array.h"
|
||||
|
||||
/* This is in C so that the compiler can optimize it appropriately.
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
@ -19,7 +18,7 @@ Signame (int sig)
|
||||
const char* s = NULL;
|
||||
char buf[100];
|
||||
size_t len;
|
||||
unsigned char *data;
|
||||
byte *data;
|
||||
String ret;
|
||||
|
||||
#if defined(HAVE_STRSIGNAL)
|
||||
@ -34,7 +33,7 @@ Signame (int sig)
|
||||
len = __builtin_strlen (s);
|
||||
data = runtime_mallocgc (len, FlagNoPointers, 0, 0);
|
||||
__builtin_memcpy (data, s, len);
|
||||
ret.__data = data;
|
||||
ret.__length = len;
|
||||
ret.str = data;
|
||||
ret.len = len;
|
||||
return ret;
|
||||
}
|
||||
|
@ -19,10 +19,10 @@ struct __go_open_array
|
||||
enough to hold the size of any allocated object. Using "int"
|
||||
saves 8 bytes per slice header on a 64-bit system with 32-bit
|
||||
ints. */
|
||||
int __count;
|
||||
intgo __count;
|
||||
/* The capacity of the array--the number of elements that can fit in
|
||||
the __VALUES field. */
|
||||
int __capacity;
|
||||
intgo __capacity;
|
||||
};
|
||||
|
||||
#endif /* !defined(LIBGO_ARRAY_H) */
|
||||
|
@ -4,10 +4,10 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-type.h"
|
||||
#include "go-panic.h"
|
||||
#include "array.h"
|
||||
#include "runtime.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-type.h"
|
||||
#include "array.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
|
@ -4,11 +4,12 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-alloc.h"
|
||||
#include "go-assert.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
#include "runtime.h"
|
||||
|
||||
/* This is called by the compiler to implement a type assertion from
|
||||
one interface type to another. This returns the value that should
|
||||
|
@ -4,22 +4,21 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
struct __go_string
|
||||
__go_byte_array_to_string (const void* p, int len)
|
||||
String
|
||||
__go_byte_array_to_string (const void* p, intgo len)
|
||||
{
|
||||
const unsigned char *bytes;
|
||||
unsigned char *retdata;
|
||||
struct __go_string ret;
|
||||
String ret;
|
||||
|
||||
bytes = (const unsigned char *) p;
|
||||
retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
|
||||
retdata = runtime_mallocgc ((uintptr) len, FlagNoPointers, 1, 0);
|
||||
__builtin_memcpy (retdata, bytes, len);
|
||||
ret.__data = retdata;
|
||||
ret.__length = len;
|
||||
ret.str = retdata;
|
||||
ret.len = len;
|
||||
return ret;
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "backtrace.h"
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-string.h"
|
||||
|
||||
/* Get the function name, file name, and line number for a PC value.
|
||||
We use the backtrace library to get this. */
|
||||
@ -20,9 +19,9 @@
|
||||
|
||||
struct caller
|
||||
{
|
||||
struct __go_string fn;
|
||||
struct __go_string file;
|
||||
int line;
|
||||
String fn;
|
||||
String file;
|
||||
intgo line;
|
||||
};
|
||||
|
||||
/* Collect file/line information for a PC value. If this is called
|
||||
@ -37,32 +36,32 @@ callback (void *data, uintptr_t pc __attribute__ ((unused)),
|
||||
|
||||
if (function == NULL)
|
||||
{
|
||||
c->fn.__data = NULL;
|
||||
c->fn.__length = 0;
|
||||
c->fn.str = NULL;
|
||||
c->fn.len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *s;
|
||||
byte *s;
|
||||
|
||||
c->fn.__length = __builtin_strlen (function);
|
||||
s = runtime_malloc (c->fn.__length);
|
||||
__builtin_memcpy (s, function, c->fn.__length);
|
||||
c->fn.__data = (unsigned char *) s;
|
||||
c->fn.len = __builtin_strlen (function);
|
||||
s = runtime_malloc (c->fn.len);
|
||||
__builtin_memcpy (s, function, c->fn.len);
|
||||
c->fn.str = s;
|
||||
}
|
||||
|
||||
if (filename == NULL)
|
||||
{
|
||||
c->file.__data = NULL;
|
||||
c->file.__length = 0;
|
||||
c->file.str = NULL;
|
||||
c->file.len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *s;
|
||||
byte *s;
|
||||
|
||||
c->file.__length = __builtin_strlen (filename);
|
||||
s = runtime_malloc (c->file.__length);
|
||||
__builtin_memcpy (s, filename, c->file.__length);
|
||||
c->file.__data = (unsigned char *) s;
|
||||
c->file.len = __builtin_strlen (filename);
|
||||
s = runtime_malloc (c->file.len);
|
||||
__builtin_memcpy (s, filename, c->file.len);
|
||||
c->file.str = s;
|
||||
}
|
||||
|
||||
c->line = lineno;
|
||||
@ -111,8 +110,7 @@ __go_get_backtrace_state ()
|
||||
/* Return function/file/line information for PC. */
|
||||
|
||||
_Bool
|
||||
__go_file_line (uintptr pc, struct __go_string *fn, struct __go_string *file,
|
||||
int *line)
|
||||
__go_file_line (uintptr pc, String *fn, String *file, intgo *line)
|
||||
{
|
||||
struct caller c;
|
||||
|
||||
@ -122,7 +120,7 @@ __go_file_line (uintptr pc, struct __go_string *fn, struct __go_string *file,
|
||||
*fn = c.fn;
|
||||
*file = c.file;
|
||||
*line = c.line;
|
||||
return c.file.__length > 0;
|
||||
return c.file.len > 0;
|
||||
}
|
||||
|
||||
/* Collect symbol information. */
|
||||
@ -153,8 +151,8 @@ __go_symbol_value (uintptr_t pc, uintptr_t *val)
|
||||
struct caller_ret
|
||||
{
|
||||
uintptr_t pc;
|
||||
struct __go_string file;
|
||||
int line;
|
||||
String file;
|
||||
intgo line;
|
||||
_Bool ok;
|
||||
};
|
||||
|
||||
@ -170,7 +168,7 @@ Caller (int skip)
|
||||
struct caller_ret ret;
|
||||
uintptr pc;
|
||||
int32 n;
|
||||
struct __go_string fn;
|
||||
String fn;
|
||||
|
||||
runtime_memclr (&ret, sizeof ret);
|
||||
n = runtime_callers (skip + 1, &pc, 1);
|
||||
@ -188,9 +186,9 @@ Func *
|
||||
FuncForPC (uintptr_t pc)
|
||||
{
|
||||
Func *ret;
|
||||
struct __go_string fn;
|
||||
struct __go_string file;
|
||||
int line;
|
||||
String fn;
|
||||
String file;
|
||||
intgo line;
|
||||
uintptr_t val;
|
||||
|
||||
if (!__go_file_line (pc, &fn, &file, &line))
|
||||
@ -212,8 +210,8 @@ FuncForPC (uintptr_t pc)
|
||||
|
||||
struct funcline_go_return
|
||||
{
|
||||
struct __go_string retfile;
|
||||
int retline;
|
||||
String retfile;
|
||||
intgo retline;
|
||||
};
|
||||
|
||||
struct funcline_go_return
|
||||
@ -224,7 +222,7 @@ struct funcline_go_return
|
||||
runtime_funcline_go (Func *f __attribute__((unused)), uintptr targetpc)
|
||||
{
|
||||
struct funcline_go_return ret;
|
||||
struct __go_string fn;
|
||||
String fn;
|
||||
|
||||
if (!__go_file_line (targetpc, &fn, &ret.retfile, &ret.retline))
|
||||
runtime_memclr (&ret, sizeof ret);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "backtrace.h"
|
||||
|
||||
#include "runtime.h"
|
||||
#include "array.h"
|
||||
|
||||
/* Argument passed to callback function. */
|
||||
|
||||
|
@ -4,7 +4,9 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-assert.h"
|
||||
#include "go-string.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "go-alloc.h"
|
||||
#include "interface.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-string.h"
|
||||
|
||||
/* Go memory allocated by code not written in Go. We keep a linked
|
||||
list of these allocations so that the garbage collector can see
|
||||
@ -135,9 +134,9 @@ extern const struct __go_type_descriptor string_type_descriptor
|
||||
void
|
||||
_cgo_panic (const char *p)
|
||||
{
|
||||
int len;
|
||||
intgo len;
|
||||
unsigned char *data;
|
||||
struct __go_string *ps;
|
||||
String *ps;
|
||||
struct __go_empty_interface e;
|
||||
|
||||
runtime_exitsyscall ();
|
||||
@ -145,8 +144,8 @@ _cgo_panic (const char *p)
|
||||
data = alloc_saved (len);
|
||||
__builtin_memcpy (data, p, len);
|
||||
ps = alloc_saved (sizeof *ps);
|
||||
ps->__data = data;
|
||||
ps->__length = len;
|
||||
ps->str = data;
|
||||
ps->len = len;
|
||||
e.__type_descriptor = &string_type_descriptor;
|
||||
e.__object = ps;
|
||||
|
||||
|
@ -4,9 +4,10 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-panic.h"
|
||||
#include "interface.h"
|
||||
#include "runtime.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
|
||||
/* Check that an interface type matches for a conversion to a
|
||||
non-interface type. This panics if the types are bad. The actual
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "map.h"
|
||||
|
||||
struct __go_map *
|
||||
|
@ -4,11 +4,13 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-alloc.h"
|
||||
#include "go-assert.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-string.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
#include "runtime.h"
|
||||
|
||||
/* This is called when converting one interface type into another
|
||||
interface type. LHS_DESCRIPTOR is the type descriptor of the
|
||||
|
@ -5,12 +5,13 @@
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
|
||||
/* Compare two interface values. Return 0 for equal, not zero for not
|
||||
equal (return value is like strcmp). */
|
||||
|
||||
int
|
||||
intgo
|
||||
__go_empty_interface_compare (struct __go_empty_interface left,
|
||||
struct __go_empty_interface right)
|
||||
{
|
||||
|
@ -11,7 +11,7 @@
|
||||
/* Compare an empty interface with a value. Return 0 for equal, not
|
||||
zero for not equal (return value is like strcmp). */
|
||||
|
||||
int
|
||||
intgo
|
||||
__go_empty_interface_value_compare (
|
||||
struct __go_empty_interface left,
|
||||
const struct __go_type_descriptor *right_descriptor,
|
||||
|
@ -6,21 +6,21 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
|
||||
struct __go_string getgoroot (void) asm ("runtime.getgoroot");
|
||||
String getgoroot (void) asm ("runtime.getgoroot");
|
||||
|
||||
struct __go_string
|
||||
String
|
||||
getgoroot ()
|
||||
{
|
||||
const char *p;
|
||||
struct __go_string ret;
|
||||
String ret;
|
||||
|
||||
p = getenv ("GOROOT");
|
||||
ret.__data = (const unsigned char *) p;
|
||||
if (ret.__data == NULL)
|
||||
ret.__length = 0;
|
||||
ret.str = (const byte *) p;
|
||||
if (ret.str == NULL)
|
||||
ret.len = 0;
|
||||
else
|
||||
ret.__length = __builtin_strlen (p);
|
||||
ret.len = __builtin_strlen (p);
|
||||
return ret;
|
||||
}
|
||||
|
@ -5,31 +5,30 @@
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-assert.h"
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
struct __go_string
|
||||
__go_int_array_to_string (const void* p, int len)
|
||||
String
|
||||
__go_int_array_to_string (const void* p, intgo len)
|
||||
{
|
||||
const int *ints;
|
||||
int slen;
|
||||
int i;
|
||||
const int32 *ints;
|
||||
intgo slen;
|
||||
intgo i;
|
||||
unsigned char *retdata;
|
||||
struct __go_string ret;
|
||||
String ret;
|
||||
unsigned char *s;
|
||||
|
||||
ints = (const int *) p;
|
||||
ints = (const int32 *) p;
|
||||
|
||||
slen = 0;
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
int v;
|
||||
int32 v;
|
||||
|
||||
v = ints[i];
|
||||
|
||||
if (v > 0x10ffff)
|
||||
if (v < 0 || v > 0x10ffff)
|
||||
v = 0xfffd;
|
||||
|
||||
if (v <= 0x7f)
|
||||
@ -42,20 +41,20 @@ __go_int_array_to_string (const void* p, int len)
|
||||
slen += 4;
|
||||
}
|
||||
|
||||
retdata = runtime_mallocgc (slen, FlagNoPointers, 1, 0);
|
||||
ret.__data = retdata;
|
||||
ret.__length = slen;
|
||||
retdata = runtime_mallocgc ((uintptr) slen, FlagNoPointers, 1, 0);
|
||||
ret.str = retdata;
|
||||
ret.len = slen;
|
||||
|
||||
s = retdata;
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
int v;
|
||||
int32 v;
|
||||
|
||||
v = ints[i];
|
||||
|
||||
/* If V is out of range for UTF-8, substitute the replacement
|
||||
character. */
|
||||
if (v > 0x10ffff)
|
||||
if (v < 0 || v > 0x10ffff)
|
||||
v = 0xfffd;
|
||||
|
||||
if (v <= 0x7f)
|
||||
|
@ -4,18 +4,17 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
struct __go_string
|
||||
__go_int_to_string (int v)
|
||||
String
|
||||
__go_int_to_string (intgo v)
|
||||
{
|
||||
char buf[4];
|
||||
int len;
|
||||
unsigned char *retdata;
|
||||
struct __go_string ret;
|
||||
String ret;
|
||||
|
||||
/* A negative value is not valid UTF-8; turn it into the replacement
|
||||
character. */
|
||||
@ -63,8 +62,8 @@ __go_int_to_string (int v)
|
||||
|
||||
retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
|
||||
__builtin_memcpy (retdata, buf, len);
|
||||
ret.__data = retdata;
|
||||
ret.__length = len;
|
||||
ret.str = retdata;
|
||||
ret.len = len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -4,6 +4,10 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
|
||||
/* Compare two interface values. Return 0 for equal, not zero for not
|
||||
|
@ -5,13 +5,14 @@
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
|
||||
/* Compare a non-empty interface value with an empty interface value.
|
||||
Return 0 for equal, not zero for not equal (return value is like
|
||||
strcmp). */
|
||||
|
||||
int
|
||||
intgo
|
||||
__go_interface_empty_compare (struct __go_interface left,
|
||||
struct __go_empty_interface right)
|
||||
{
|
||||
|
@ -4,13 +4,14 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
|
||||
/* Compare two interface values. Return 0 for equal, not zero for not
|
||||
equal (return value is like strcmp). */
|
||||
|
||||
int
|
||||
intgo
|
||||
__go_interface_value_compare (
|
||||
struct __go_interface left,
|
||||
const struct __go_type_descriptor *right_descriptor,
|
||||
|
@ -14,11 +14,9 @@
|
||||
#include <fpu_control.h>
|
||||
#endif
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-alloc.h"
|
||||
#include "array.h"
|
||||
#include "go-string.h"
|
||||
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
|
@ -6,12 +6,12 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-alloc.h"
|
||||
#include "go-assert.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-type.h"
|
||||
#include "array.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
@ -20,8 +20,8 @@ __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len,
|
||||
uintptr_t cap)
|
||||
{
|
||||
const struct __go_slice_type* std;
|
||||
int ilen;
|
||||
int icap;
|
||||
intgo ilen;
|
||||
intgo icap;
|
||||
uintptr_t size;
|
||||
struct __go_open_array ret;
|
||||
unsigned int flag;
|
||||
@ -29,11 +29,11 @@ __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len,
|
||||
__go_assert (td->__code == GO_SLICE);
|
||||
std = (const struct __go_slice_type *) td;
|
||||
|
||||
ilen = (int) len;
|
||||
ilen = (intgo) len;
|
||||
if (ilen < 0 || (uintptr_t) ilen != len)
|
||||
runtime_panicstring ("makeslice: len out of range");
|
||||
|
||||
icap = (int) cap;
|
||||
icap = (intgo) cap;
|
||||
if (cap < len
|
||||
|| (uintptr_t) icap != cap
|
||||
|| (std->__element_type->__size > 0
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-assert.h"
|
||||
#include "map.h"
|
||||
|
||||
@ -13,11 +14,12 @@
|
||||
but I'm doing it as a function for now to make it easy to change
|
||||
the map structure. */
|
||||
|
||||
int
|
||||
intgo
|
||||
__go_map_len (struct __go_map *map)
|
||||
{
|
||||
if (map == NULL)
|
||||
return 0;
|
||||
__go_assert (map->__element_count == (uintptr_t) (int) map->__element_count);
|
||||
__go_assert (map->__element_count
|
||||
== (uintptr_t) (intgo) map->__element_count);
|
||||
return map->__element_count;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-assert.h"
|
||||
#include "map.h"
|
||||
|
||||
|
@ -106,10 +106,10 @@ __go_map_next_prime (uintptr_t n)
|
||||
struct __go_map *
|
||||
__go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries)
|
||||
{
|
||||
int ientries;
|
||||
intgo ientries;
|
||||
struct __go_map *ret;
|
||||
|
||||
ientries = (int) entries;
|
||||
ientries = (intgo) entries;
|
||||
if (ientries < 0 || (uintptr_t) ientries != entries)
|
||||
runtime_panicstring ("map size out of range");
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "go-alloc.h"
|
||||
#include "go-defer.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-string.h"
|
||||
#include "interface.h"
|
||||
|
||||
/* Print the panic stack. This is used when there is no recover. */
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
struct __go_string;
|
||||
struct String;
|
||||
struct __go_type_descriptor;
|
||||
struct __go_defer_stack;
|
||||
|
||||
@ -34,7 +34,7 @@ struct __go_panic_stack
|
||||
extern void __go_panic (struct __go_empty_interface)
|
||||
__attribute__ ((noreturn));
|
||||
|
||||
extern void __go_print_string (struct __go_string);
|
||||
extern void __go_print_string (struct String);
|
||||
|
||||
extern struct __go_empty_interface __go_recover (void);
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "runtime.h"
|
||||
#include "array.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-string.h"
|
||||
#include "interface.h"
|
||||
|
||||
/* This implements the various little functions which are called by
|
||||
|
@ -8,12 +8,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-alloc.h"
|
||||
#include "go-assert.h"
|
||||
#include "go-type.h"
|
||||
#include "runtime.h"
|
||||
|
||||
#ifdef USE_LIBFFI
|
||||
|
||||
@ -77,13 +75,15 @@ go_slice_to_ffi (
|
||||
const struct __go_slice_type *descriptor __attribute__ ((unused)))
|
||||
{
|
||||
ffi_type *ret;
|
||||
ffi_type *intgo;
|
||||
|
||||
ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
|
||||
ret->type = FFI_TYPE_STRUCT;
|
||||
ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
|
||||
ret->elements[0] = &ffi_type_pointer;
|
||||
ret->elements[1] = &ffi_type_sint;
|
||||
ret->elements[2] = &ffi_type_sint;
|
||||
intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
|
||||
ret->elements[1] = intgo;
|
||||
ret->elements[2] = intgo;
|
||||
ret->elements[3] = NULL;
|
||||
return ret;
|
||||
}
|
||||
@ -110,19 +110,21 @@ go_struct_to_ffi (const struct __go_struct_type *descriptor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return an ffi_type for a Go string type. This describes the
|
||||
__go_string struct. */
|
||||
/* Return an ffi_type for a Go string type. This describes the String
|
||||
struct. */
|
||||
|
||||
static ffi_type *
|
||||
go_string_to_ffi (void)
|
||||
{
|
||||
ffi_type *ret;
|
||||
ffi_type *intgo;
|
||||
|
||||
ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
|
||||
ret->type = FFI_TYPE_STRUCT;
|
||||
ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
|
||||
ret->elements[0] = &ffi_type_pointer;
|
||||
ret->elements[1] = &ffi_type_sint;
|
||||
intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
|
||||
ret->elements[1] = intgo;
|
||||
ret->elements[2] = NULL;
|
||||
return ret;
|
||||
}
|
||||
@ -199,7 +201,7 @@ go_type_to_ffi (const struct __go_type_descriptor *descriptor)
|
||||
case GO_INT8:
|
||||
return &ffi_type_sint8;
|
||||
case GO_INT:
|
||||
return &ffi_type_sint;
|
||||
return sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
|
||||
case GO_UINT16:
|
||||
return &ffi_type_uint16;
|
||||
case GO_UINT32:
|
||||
@ -209,7 +211,7 @@ go_type_to_ffi (const struct __go_type_descriptor *descriptor)
|
||||
case GO_UINT8:
|
||||
return &ffi_type_uint8;
|
||||
case GO_UINT:
|
||||
return &ffi_type_uint;
|
||||
return sizeof (uintgo) == 4 ? &ffi_type_uint32 : &ffi_type_uint64;
|
||||
case GO_UINTPTR:
|
||||
if (sizeof (void *) == 2)
|
||||
return &ffi_type_uint16;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-string.h"
|
||||
|
||||
/* Get a character from the UTF-8 string STR, of length LEN. Store
|
||||
|
@ -55,7 +55,7 @@ enum
|
||||
extern void __go_runtime_error () __attribute__ ((noreturn));
|
||||
|
||||
void
|
||||
__go_runtime_error (int i)
|
||||
__go_runtime_error (int32 i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
|
@ -10,39 +10,38 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "go-alloc.h"
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
|
||||
/* Set the C environment from Go. This is called by syscall.Setenv. */
|
||||
|
||||
void setenv_c (struct __go_string, struct __go_string)
|
||||
__asm__ ("syscall.setenv_c");
|
||||
void setenv_c (String, String) __asm__ ("syscall.setenv_c");
|
||||
|
||||
void
|
||||
setenv_c (struct __go_string k, struct __go_string v)
|
||||
setenv_c (String k, String v)
|
||||
{
|
||||
const unsigned char *ks;
|
||||
const byte *ks;
|
||||
unsigned char *kn;
|
||||
const unsigned char *vs;
|
||||
const byte *vs;
|
||||
unsigned char *vn;
|
||||
|
||||
ks = k.__data;
|
||||
ks = k.str;
|
||||
kn = NULL;
|
||||
vs = v.__data;
|
||||
vs = v.str;
|
||||
vn = NULL;
|
||||
|
||||
#ifdef HAVE_SETENV
|
||||
|
||||
if (ks[k.__length] != 0)
|
||||
if (ks[k.len] != 0)
|
||||
{
|
||||
kn = __go_alloc (k.__length + 1);
|
||||
__builtin_memcpy (kn, ks, k.__length);
|
||||
kn = __go_alloc (k.len + 1);
|
||||
__builtin_memcpy (kn, ks, k.len);
|
||||
ks = kn;
|
||||
}
|
||||
|
||||
if (vs[v.__length] != 0)
|
||||
if (vs[v.len] != 0)
|
||||
{
|
||||
vn = __go_alloc (v.__length + 1);
|
||||
__builtin_memcpy (vn, vs, v.__length);
|
||||
vn = __go_alloc (v.len + 1);
|
||||
__builtin_memcpy (vn, vs, v.len);
|
||||
vs = vn;
|
||||
}
|
||||
|
||||
@ -50,11 +49,11 @@ setenv_c (struct __go_string k, struct __go_string v)
|
||||
|
||||
#else /* !defined(HAVE_SETENV) */
|
||||
|
||||
kn = __go_alloc (k.__length + v.__length + 2);
|
||||
__builtin_memcpy (kn, ks, k.__length);
|
||||
kn[k.__length] = '=';
|
||||
__builtin_memcpy (kn + k.__length + 1, vs, v.__length);
|
||||
kn[k.__length + v.__length + 1] = '\0';
|
||||
kn = __go_alloc (k.len + v.len + 2);
|
||||
__builtin_memcpy (kn, ks, k.len);
|
||||
kn[k.len] = '=';
|
||||
__builtin_memcpy (kn + k.len + 1, vs, v.len);
|
||||
kn[k.len + v.len + 1] = '\0';
|
||||
putenv ((char *) kn);
|
||||
|
||||
#endif /* !defined(HAVE_SETENV) */
|
||||
|
@ -4,23 +4,21 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
|
||||
int
|
||||
__go_strcmp(struct __go_string s1, struct __go_string s2)
|
||||
intgo
|
||||
__go_strcmp(String s1, String s2)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = __builtin_memcmp(s1.__data, s2.__data,
|
||||
(s1.__length < s2.__length
|
||||
? s1.__length
|
||||
: s2.__length));
|
||||
i = __builtin_memcmp(s1.str, s2.str,
|
||||
(s1.len < s2.len ? s1.len : s2.len));
|
||||
if (i != 0)
|
||||
return i;
|
||||
|
||||
if (s1.__length < s2.__length)
|
||||
if (s1.len < s2.len)
|
||||
return -1;
|
||||
else if (s1.__length > s2.__length)
|
||||
else if (s1.len > s2.len)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
@ -4,22 +4,21 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-string.h"
|
||||
#include "array.h"
|
||||
#include "runtime.h"
|
||||
#include "array.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
struct __go_open_array
|
||||
__go_string_to_byte_array (struct __go_string str)
|
||||
__go_string_to_byte_array (String str)
|
||||
{
|
||||
unsigned char *data;
|
||||
struct __go_open_array ret;
|
||||
|
||||
data = (unsigned char *) runtime_mallocgc (str.__length, FlagNoPointers, 1, 0);
|
||||
__builtin_memcpy (data, str.__data, str.__length);
|
||||
data = (unsigned char *) runtime_mallocgc (str.len, FlagNoPointers, 1, 0);
|
||||
__builtin_memcpy (data, str.str, str.len);
|
||||
ret.__values = (void *) data;
|
||||
ret.__count = str.__length;
|
||||
ret.__capacity = str.__length;
|
||||
ret.__count = str.len;
|
||||
ret.__capacity = str.len;
|
||||
return ret;
|
||||
}
|
||||
|
@ -4,15 +4,15 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-alloc.h"
|
||||
#include "go-string.h"
|
||||
#include "array.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
struct __go_open_array
|
||||
__go_string_to_int_array (struct __go_string str)
|
||||
__go_string_to_int_array (String str)
|
||||
{
|
||||
size_t c;
|
||||
const unsigned char *p;
|
||||
@ -22,8 +22,8 @@ __go_string_to_int_array (struct __go_string str)
|
||||
struct __go_open_array ret;
|
||||
|
||||
c = 0;
|
||||
p = str.__data;
|
||||
pend = p + str.__length;
|
||||
p = str.str;
|
||||
pend = p + str.len;
|
||||
while (p < pend)
|
||||
{
|
||||
int rune;
|
||||
@ -34,7 +34,7 @@ __go_string_to_int_array (struct __go_string str)
|
||||
|
||||
data = (uint32_t *) runtime_mallocgc (c * sizeof (uint32_t), FlagNoPointers,
|
||||
1, 0);
|
||||
p = str.__data;
|
||||
p = str.str;
|
||||
pd = data;
|
||||
while (p < pend)
|
||||
{
|
||||
|
@ -9,26 +9,15 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* A string is an instance of this structure. */
|
||||
|
||||
struct __go_string
|
||||
{
|
||||
/* The bytes. */
|
||||
const unsigned char *__data;
|
||||
/* The length. */
|
||||
int __length;
|
||||
};
|
||||
|
||||
static inline _Bool
|
||||
__go_strings_equal (struct __go_string s1, struct __go_string s2)
|
||||
__go_strings_equal (String s1, String s2)
|
||||
{
|
||||
return (s1.__length == s2.__length
|
||||
&& __builtin_memcmp (s1.__data, s2.__data, s1.__length) == 0);
|
||||
return (s1.len == s2.len
|
||||
&& __builtin_memcmp (s1.str, s2.str, s1.len) == 0);
|
||||
}
|
||||
|
||||
static inline _Bool
|
||||
__go_ptr_strings_equal (const struct __go_string *ps1,
|
||||
const struct __go_string *ps2)
|
||||
__go_ptr_strings_equal (const String *ps1, const String *ps2)
|
||||
{
|
||||
if (ps1 == NULL)
|
||||
return ps2 == NULL;
|
||||
|
@ -4,28 +4,27 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
struct __go_string
|
||||
__go_string_plus (struct __go_string s1, struct __go_string s2)
|
||||
String
|
||||
__go_string_plus (String s1, String s2)
|
||||
{
|
||||
int len;
|
||||
unsigned char *retdata;
|
||||
struct __go_string ret;
|
||||
byte *retdata;
|
||||
String ret;
|
||||
|
||||
if (s1.__length == 0)
|
||||
if (s1.len == 0)
|
||||
return s2;
|
||||
else if (s2.__length == 0)
|
||||
else if (s2.len == 0)
|
||||
return s1;
|
||||
|
||||
len = s1.__length + s2.__length;
|
||||
len = s1.len + s2.len;
|
||||
retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
|
||||
__builtin_memcpy (retdata, s1.__data, s1.__length);
|
||||
__builtin_memcpy (retdata + s1.__length, s2.__data, s2.__length);
|
||||
ret.__data = retdata;
|
||||
ret.__length = len;
|
||||
__builtin_memcpy (retdata, s1.str, s1.len);
|
||||
__builtin_memcpy (retdata + s1.len, s2.str, s2.len);
|
||||
ret.str = retdata;
|
||||
ret.len = len;
|
||||
return ret;
|
||||
}
|
||||
|
@ -4,24 +4,23 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "go-string.h"
|
||||
#include "go-panic.h"
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
struct __go_string
|
||||
__go_string_slice (struct __go_string s, int start, int end)
|
||||
String
|
||||
__go_string_slice (String s, intgo start, intgo end)
|
||||
{
|
||||
int len;
|
||||
struct __go_string ret;
|
||||
intgo len;
|
||||
String ret;
|
||||
|
||||
len = s.__length;
|
||||
len = s.len;
|
||||
if (end == -1)
|
||||
end = len;
|
||||
if (start > len || end < start || end > len)
|
||||
runtime_panicstring ("string index out of bounds");
|
||||
ret.__data = s.__data + start;
|
||||
ret.__length = end - start;
|
||||
ret.str = s.str + start;
|
||||
ret.len = end - start;
|
||||
return ret;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-string.h"
|
||||
|
||||
/* Print a stack trace for the current goroutine. */
|
||||
|
||||
@ -28,12 +27,12 @@ runtime_printtrace (uintptr *pcbuf, int32 c)
|
||||
|
||||
for (i = 0; i < c; ++i)
|
||||
{
|
||||
struct __go_string fn;
|
||||
struct __go_string file;
|
||||
String fn;
|
||||
String file;
|
||||
int line;
|
||||
|
||||
if (__go_file_line (pcbuf[i], &fn, &file, &line)
|
||||
&& runtime_showframe (fn.__data))
|
||||
&& runtime_showframe (fn.str))
|
||||
{
|
||||
runtime_printf ("%S\n", fn);
|
||||
runtime_printf ("\t%S:%d\n", file, line);
|
||||
|
@ -6,13 +6,9 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
|
||||
/* The 64-bit type. */
|
||||
|
||||
typedef unsigned int DItype __attribute__ ((mode (DI)));
|
||||
|
||||
/* An identity hash function for a type. This is used for types where
|
||||
we can simply use the type value itself as a hash code. This is
|
||||
true of, e.g., integers and pointers. */
|
||||
@ -28,7 +24,7 @@ __go_type_hash_identity (const void *key, uintptr_t key_size)
|
||||
{
|
||||
union
|
||||
{
|
||||
DItype v;
|
||||
uint64 v;
|
||||
unsigned char a[8];
|
||||
} u;
|
||||
u.v = 0;
|
||||
|
@ -4,6 +4,7 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "interface.h"
|
||||
#include "go-type.h"
|
||||
|
||||
|
@ -4,10 +4,9 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
#include "go-string.h"
|
||||
|
||||
/* A string hash function for a map. */
|
||||
|
||||
@ -16,15 +15,15 @@ __go_type_hash_string (const void *vkey,
|
||||
uintptr_t key_size __attribute__ ((unused)))
|
||||
{
|
||||
uintptr_t ret;
|
||||
const struct __go_string *key;
|
||||
int len;
|
||||
int i;
|
||||
const unsigned char *p;
|
||||
const String *key;
|
||||
intgo len;
|
||||
intgo i;
|
||||
const byte *p;
|
||||
|
||||
ret = 5381;
|
||||
key = (const struct __go_string *) vkey;
|
||||
len = key->__length;
|
||||
for (i = 0, p = key->__data; i < len; i++, p++)
|
||||
key = (const String *) vkey;
|
||||
len = key->len;
|
||||
for (i = 0, p = key->str; i < len; i++, p++)
|
||||
ret = ret * 33 + *p;
|
||||
return ret;
|
||||
}
|
||||
@ -35,11 +34,10 @@ _Bool
|
||||
__go_type_equal_string (const void *vk1, const void *vk2,
|
||||
uintptr_t key_size __attribute__ ((unused)))
|
||||
{
|
||||
const struct __go_string *k1;
|
||||
const struct __go_string *k2;
|
||||
const String *k1;
|
||||
const String *k2;
|
||||
|
||||
k1 = (const struct __go_string *) vk1;
|
||||
k2 = (const struct __go_string *) vk2;
|
||||
return (k1->__length == k2->__length
|
||||
&& __builtin_memcmp (k1->__data, k2->__data, k1->__length) == 0);
|
||||
k1 = (const String *) vk1;
|
||||
k2 = (const String *) vk2;
|
||||
return __go_ptr_strings_equal (k1, k2);
|
||||
}
|
||||
|
@ -10,9 +10,10 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "go-string.h"
|
||||
#include "array.h"
|
||||
|
||||
struct String;
|
||||
|
||||
/* Many of the types in this file must match the data structures
|
||||
generated by the compiler, and must also match the Go types which
|
||||
appear in go/runtime/type.go and go/reflect/type.go. */
|
||||
@ -94,7 +95,7 @@ struct __go_type_descriptor
|
||||
|
||||
/* A string describing this type. This is only used for
|
||||
debugging. */
|
||||
const struct __go_string *__reflection;
|
||||
const struct String *__reflection;
|
||||
|
||||
/* A pointer to fields which are only used for some types. */
|
||||
const struct __go_uncommon_type *__uncommon;
|
||||
@ -109,11 +110,11 @@ struct __go_type_descriptor
|
||||
struct __go_method
|
||||
{
|
||||
/* The name of the method. */
|
||||
const struct __go_string *__name;
|
||||
const struct String *__name;
|
||||
|
||||
/* This is NULL for an exported method, or the name of the package
|
||||
where it lives. */
|
||||
const struct __go_string *__pkg_path;
|
||||
const struct String *__pkg_path;
|
||||
|
||||
/* The type of the method, without the receiver. This will be a
|
||||
function type. */
|
||||
@ -134,10 +135,10 @@ struct __go_method
|
||||
struct __go_uncommon_type
|
||||
{
|
||||
/* The name of the type. */
|
||||
const struct __go_string *__name;
|
||||
const struct String *__name;
|
||||
|
||||
/* The type's package. This is NULL for builtin types. */
|
||||
const struct __go_string *__pkg_path;
|
||||
const struct String *__pkg_path;
|
||||
|
||||
/* The type's methods. This is an array of struct __go_method. */
|
||||
struct __go_open_array __methods;
|
||||
@ -216,11 +217,11 @@ struct __go_func_type
|
||||
struct __go_interface_method
|
||||
{
|
||||
/* The name of the method. */
|
||||
const struct __go_string *__name;
|
||||
const struct String *__name;
|
||||
|
||||
/* This is NULL for an exported method, or the name of the package
|
||||
where it lives. */
|
||||
const struct __go_string *__pkg_path;
|
||||
const struct String *__pkg_path;
|
||||
|
||||
/* The real type of the method. */
|
||||
struct __go_type_descriptor *__type;
|
||||
@ -269,17 +270,17 @@ struct __go_ptr_type
|
||||
struct __go_struct_field
|
||||
{
|
||||
/* The name of the field--NULL for an anonymous field. */
|
||||
const struct __go_string *__name;
|
||||
const struct String *__name;
|
||||
|
||||
/* This is NULL for an exported method, or the name of the package
|
||||
where it lives. */
|
||||
const struct __go_string *__pkg_path;
|
||||
const struct String *__pkg_path;
|
||||
|
||||
/* The type of the field. */
|
||||
const struct __go_type_descriptor *__type;
|
||||
|
||||
/* The field tag, or NULL. */
|
||||
const struct __go_string *__tag;
|
||||
const struct String *__tag;
|
||||
|
||||
/* The offset of the field in the struct. */
|
||||
uintptr_t __offset;
|
||||
|
@ -4,6 +4,7 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-string.h"
|
||||
#include "go-type.h"
|
||||
|
||||
|
@ -4,14 +4,13 @@
|
||||
Use of this source code is governed by a BSD-style
|
||||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include "runtime.h"
|
||||
#include "interface.h"
|
||||
#include "go-type.h"
|
||||
#include "go-string.h"
|
||||
|
||||
struct __go_string typestring(struct __go_empty_interface)
|
||||
asm ("runtime.typestring");
|
||||
String typestring(struct __go_empty_interface) asm ("runtime.typestring");
|
||||
|
||||
struct __go_string
|
||||
String
|
||||
typestring (struct __go_empty_interface e)
|
||||
{
|
||||
return *e.__type_descriptor->__reflection;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "go-string.h"
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
|
||||
/* This file provides the type descriptor for the unsafe.Pointer type.
|
||||
@ -26,9 +26,9 @@ struct field_align
|
||||
|
||||
/* The reflection string. */
|
||||
#define REFLECTION "unsafe.Pointer"
|
||||
static const struct __go_string reflection_string =
|
||||
static const String reflection_string =
|
||||
{
|
||||
(const unsigned char *) REFLECTION,
|
||||
(const byte *) REFLECTION,
|
||||
sizeof REFLECTION - 1
|
||||
};
|
||||
|
||||
@ -65,9 +65,9 @@ extern const struct __go_ptr_type pointer_unsafe_Pointer
|
||||
|
||||
/* The reflection string. */
|
||||
#define PREFLECTION "*unsafe.Pointer"
|
||||
static const struct __go_string preflection_string =
|
||||
static const String preflection_string =
|
||||
{
|
||||
(const unsigned char *) PREFLECTION,
|
||||
(const byte *) PREFLECTION,
|
||||
sizeof PREFLECTION - 1,
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#ifndef LIBGO_INTERFACE_H
|
||||
#define LIBGO_INTERFACE_H
|
||||
|
||||
#include "go-type.h"
|
||||
struct __go_type_descriptor;
|
||||
|
||||
/* A variable of interface type is an instance of this struct, if the
|
||||
interface has any methods. */
|
||||
|
@ -14,7 +14,6 @@ package runtime
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
#include "go-string.h"
|
||||
#include "interface.h"
|
||||
#include "go-type.h"
|
||||
#include "race.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-defer.h"
|
||||
#include "go-panic.h"
|
||||
|
||||
// Code related to defer, panic and recover.
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "runtime.h"
|
||||
#include "array.h"
|
||||
|
||||
//static Lock debuglock;
|
||||
|
||||
@ -294,8 +295,8 @@ runtime_printstring(String v)
|
||||
// gwrite("[string too long]", 17);
|
||||
// return;
|
||||
// }
|
||||
if(v.__length > 0)
|
||||
gwrite(v.__data, v.__length);
|
||||
if(v.len > 0)
|
||||
gwrite(v.str, v.len);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -586,13 +586,13 @@ void
|
||||
runtime_goroutinetrailer(G *g)
|
||||
{
|
||||
if(g != nil && g->gopc != 0 && g->goid != 1) {
|
||||
struct __go_string fn;
|
||||
struct __go_string file;
|
||||
String fn;
|
||||
String file;
|
||||
int line;
|
||||
|
||||
if(__go_file_line(g->gopc - 1, &fn, &file, &line)) {
|
||||
runtime_printf("created by %s\n", fn.__data);
|
||||
runtime_printf("\t%s:%d\n", file.__data, line);
|
||||
runtime_printf("created by %S\n", fn);
|
||||
runtime_printf("\t%S:%d\n", file, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,9 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package reflect
|
||||
#include "runtime.h"
|
||||
#include "go-type.h"
|
||||
#include "interface.h"
|
||||
#include "runtime.h"
|
||||
#include "go-panic.h"
|
||||
|
||||
func ifaceE2I(inter *Type, e Eface, ret *Iface) {
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "runtime.h"
|
||||
#include "array.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-string.h"
|
||||
|
||||
int32
|
||||
runtime_gotraceback(void)
|
||||
@ -93,9 +92,9 @@ runtime_getenv(const char *s)
|
||||
envv = (String*)syscall_Envs.__values;
|
||||
envc = syscall_Envs.__count;
|
||||
for(i=0; i<envc; i++){
|
||||
if(envv[i].__length <= len)
|
||||
if(envv[i].len <= len)
|
||||
continue;
|
||||
v = (const byte*)envv[i].__data;
|
||||
v = (const byte*)envv[i].str;
|
||||
for(j=0; j<len; j++)
|
||||
if(bs[j] != v[j])
|
||||
goto nomatch;
|
||||
|
@ -21,10 +21,8 @@
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "array.h"
|
||||
#include "interface.h"
|
||||
#include "go-alloc.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-string.h"
|
||||
|
||||
/* This file supports C files copied from the 6g runtime library.
|
||||
This is a version of the 6g runtime.h rewritten for gccgo's version
|
||||
@ -67,7 +65,7 @@ typedef struct ParFor ParFor;
|
||||
typedef struct ParForThread ParForThread;
|
||||
|
||||
typedef struct __go_open_array Slice;
|
||||
typedef struct __go_string String;
|
||||
typedef struct String String;
|
||||
typedef struct __go_interface Iface;
|
||||
typedef struct __go_empty_interface Eface;
|
||||
typedef struct __go_type_descriptor Type;
|
||||
@ -129,6 +127,11 @@ union Note
|
||||
uint32 key; // futex-based impl
|
||||
M* waitm; // waiting M (sema-based impl)
|
||||
};
|
||||
struct String
|
||||
{
|
||||
const byte* str;
|
||||
intgo len;
|
||||
};
|
||||
struct GCStats
|
||||
{
|
||||
// the struct must consist of only uint64's,
|
||||
|
@ -6,10 +6,11 @@ package runtime
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
#include "go-string.h"
|
||||
|
||||
#define charntorune(pv, str, len) __go_get_rune(str, len, pv)
|
||||
|
||||
int32
|
||||
intgo
|
||||
runtime_findnull(const byte *s)
|
||||
{
|
||||
if(s == nil)
|
||||
@ -22,8 +23,8 @@ runtime_gostringnocopy(const byte *str)
|
||||
{
|
||||
String s;
|
||||
|
||||
s.__data = (const unsigned char *) str;
|
||||
s.__length = runtime_findnull(str);
|
||||
s.str = str;
|
||||
s.len = runtime_findnull(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -35,40 +36,40 @@ enum
|
||||
func stringiter(s String, k int) (retk int) {
|
||||
int32 l;
|
||||
|
||||
if(k >= s.__length) {
|
||||
if(k >= s.len) {
|
||||
// retk=0 is end of iteration
|
||||
retk = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
l = s.__data[k];
|
||||
l = s.str[k];
|
||||
if(l < Runeself) {
|
||||
retk = k+1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// multi-char rune
|
||||
retk = k + charntorune(&l, s.__data+k, s.__length-k);
|
||||
retk = k + charntorune(&l, s.str+k, s.len-k);
|
||||
|
||||
out:
|
||||
}
|
||||
|
||||
func stringiter2(s String, k int) (retk int, retv int) {
|
||||
if(k >= s.__length) {
|
||||
if(k >= s.len) {
|
||||
// retk=0 is end of iteration
|
||||
retk = 0;
|
||||
retv = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
retv = s.__data[k];
|
||||
retv = s.str[k];
|
||||
if(retv < Runeself) {
|
||||
retk = k+1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// multi-char rune
|
||||
retk = k + charntorune(&retv, s.__data+k, s.__length-k);
|
||||
retk = k + charntorune(&retv, s.str+k, s.len-k);
|
||||
|
||||
out:
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user