Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

718 lines (652 sloc) 21.545 kb
/*
object constructors
*/
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include "julia.h"
#include "newobj_internal.h"
#include "builtin_proto.h"
jl_value_t *jl_true;
jl_value_t *jl_false;
jl_tag_type_t *jl_undef_type;
jl_tvar_t *jl_typetype_tvar;
jl_tag_type_t *jl_typetype_type;
jl_value_t *jl_ANY_flag;
jl_struct_type_t *jl_function_type;
jl_struct_type_t *jl_box_type;
jl_type_t *jl_box_any_type;
jl_typename_t *jl_box_typename;
jl_struct_type_t *jl_typector_type;
jl_struct_type_t *jl_array_type;
jl_typename_t *jl_array_typename;
jl_type_t *jl_array_uint8_type;
jl_type_t *jl_array_any_type;
jl_function_t *jl_bottom_func;
jl_struct_type_t *jl_weakref_type;
jl_struct_type_t *jl_ascii_string_type;
jl_struct_type_t *jl_utf8_string_type;
jl_struct_type_t *jl_expr_type;
jl_struct_type_t *jl_symbolnode_type;
jl_struct_type_t *jl_linenumbernode_type;
jl_struct_type_t *jl_labelnode_type;
jl_struct_type_t *jl_gotonode_type;
jl_struct_type_t *jl_quotenode_type;
jl_struct_type_t *jl_topnode_type;
jl_bits_type_t *jl_intrinsic_type;
jl_struct_type_t *jl_methtable_type;
jl_struct_type_t *jl_method_type;
jl_struct_type_t *jl_lambda_info_type;
jl_struct_type_t *jl_module_type;
jl_struct_type_t *jl_errorexception_type=NULL;
jl_struct_type_t *jl_typeerror_type;
jl_struct_type_t *jl_loaderror_type;
jl_struct_type_t *jl_backtrace_type;
jl_bits_type_t *jl_pointer_type;
jl_value_t *jl_an_empty_cell=NULL;
jl_value_t *jl_stackovf_exception;
jl_value_t *jl_divbyzero_exception;
jl_value_t *jl_domain_exception;
jl_value_t *jl_overflow_exception;
jl_value_t *jl_inexact_exception;
jl_value_t *jl_undefref_exception;
jl_value_t *jl_interrupt_exception;
jl_value_t *jl_memory_exception;
jl_sym_t *call_sym; jl_sym_t *dots_sym;
jl_sym_t *call1_sym; jl_sym_t *module_sym;
jl_sym_t *export_sym; jl_sym_t *import_sym;
jl_sym_t *importall_sym;
jl_sym_t *quote_sym; jl_sym_t *amp_sym;
jl_sym_t *top_sym; jl_sym_t *colons_sym;
jl_sym_t *line_sym; jl_sym_t *jl_continue_sym;
// head symbols for each expression type
jl_sym_t *goto_sym; jl_sym_t *goto_ifnot_sym;
jl_sym_t *label_sym; jl_sym_t *return_sym;
jl_sym_t *lambda_sym; jl_sym_t *assign_sym;
jl_sym_t *null_sym; jl_sym_t *body_sym;
jl_sym_t *macro_sym; jl_sym_t *method_sym;
jl_sym_t *enter_sym; jl_sym_t *leave_sym;
jl_sym_t *exc_sym; jl_sym_t *error_sym;
jl_sym_t *static_typeof_sym;
jl_sym_t *new_sym; jl_sym_t *multivalue_sym;
jl_sym_t *const_sym; jl_sym_t *thunk_sym;
jl_sym_t *anonymous_sym; jl_sym_t *underscore_sym;
jl_sym_t *abstracttype_sym; jl_sym_t *bitstype_sym;
jl_sym_t *compositetype_sym; jl_sym_t *type_goto_sym;
DLLEXPORT jl_value_t *jl_new_struct(jl_struct_type_t *type, ...)
{
if (type->instance != NULL) return type->instance;
va_list args;
size_t nf = jl_tuple_len(type->names);
size_t i;
va_start(args, type);
jl_value_t *jv = newobj((jl_type_t*)type, nf);
for(i=0; i < nf; i++) {
((jl_value_t**)jv)[i+1] = va_arg(args, jl_value_t*);
}
if (nf == 0) type->instance = jv;
va_end(args);
return jv;
}
DLLEXPORT jl_value_t *jl_new_struct_uninit(jl_struct_type_t *type)
{
if (type->instance != NULL) return type->instance;
size_t nf = jl_tuple_len(type->names);
size_t i;
jl_value_t *jv = newobj((jl_type_t*)type, nf);
for(i=0; i < nf; i++) {
((jl_value_t**)jv)[i+1] = NULL;
}
if (nf == 0) type->instance = jv;
return jv;
}
DLLEXPORT jl_value_t *jl_new_structt(jl_struct_type_t *type, jl_tuple_t *t)
{
assert(jl_tuple_len(type->names) == jl_tuple_len(t));
jl_value_t *jv = jl_new_struct_uninit(type);
for(size_t i=0; i < jl_tuple_len(t); i++) {
((jl_value_t**)jv)[i+1] = jl_tupleref(t, i);
}
return jv;
}
jl_tuple_t *jl_tuple(size_t n, ...)
{
va_list args;
size_t i;
if (n == 0) return jl_null;
va_start(args, n);
jl_tuple_t *jv = (jl_tuple_t*)newobj((jl_type_t*)jl_tuple_type, n+1);
jl_tuple_set_len_unsafe(jv, n);
for(i=0; i < n; i++) {
jl_tupleset(jv, i, va_arg(args, jl_value_t*));
}
va_end(args);
return jv;
}
jl_tuple_t *jl_tuple1(void *a)
{
jl_tuple_t *t = (jl_tuple_t*)alloc_3w();
t->type = (jl_type_t*)jl_tuple_type;
jl_tuple_set_len_unsafe(t, 1);
jl_tupleset(t, 0, a);
return t;
}
jl_tuple_t *jl_tuple2(void *a, void *b)
{
jl_tuple_t *t = (jl_tuple_t*)alloc_4w();
t->type = (jl_type_t*)jl_tuple_type;
jl_tuple_set_len_unsafe(t, 2);
jl_tupleset(t, 0, a);
jl_tupleset(t, 1, b);
return t;
}
jl_tuple_t *jl_alloc_tuple_uninit(size_t n)
{
if (n == 0) return jl_null;
jl_tuple_t *jv = (jl_tuple_t*)newobj((jl_type_t*)jl_tuple_type, n+1);
jl_tuple_set_len_unsafe(jv, n);
return jv;
}
jl_tuple_t *jl_alloc_tuple(size_t n)
{
if (n == 0) return jl_null;
jl_tuple_t *jv = jl_alloc_tuple_uninit(n);
size_t i;
for(i=0; i < n; i++) {
jl_tupleset(jv, i, NULL);
}
return jv;
}
jl_tuple_t *jl_tuple_append(jl_tuple_t *a, jl_tuple_t *b)
{
jl_tuple_t *c = jl_alloc_tuple_uninit(jl_tuple_len(a) + jl_tuple_len(b));
size_t i=0, j;
for(j=0; j < jl_tuple_len(a); j++) {
jl_tupleset(c, i, jl_tupleref(a,j));
i++;
}
for(j=0; j < jl_tuple_len(b); j++) {
jl_tupleset(c, i, jl_tupleref(b,j));
i++;
}
return c;
}
jl_tuple_t *jl_tuple_fill(size_t n, jl_value_t *v)
{
if (n==0) return jl_null;
jl_tuple_t *tup = jl_alloc_tuple_uninit(n);
size_t i;
for(i=0; i < n; i++) {
jl_tupleset(tup, i, v);
}
return tup;
}
DLLEXPORT jl_function_t *jl_new_closure(jl_fptr_t fptr, jl_value_t *env,
jl_lambda_info_t *linfo)
{
jl_function_t *f = (jl_function_t*)alloc_4w();
f->type = (jl_type_t*)jl_function_type;
f->fptr = (fptr!=NULL ? fptr : linfo->fptr);
f->env = env;
f->linfo = linfo;
return f;
}
DLLEXPORT
jl_lambda_info_t *jl_new_lambda_info(jl_value_t *ast, jl_tuple_t *sparams)
{
jl_lambda_info_t *li =
(jl_lambda_info_t*)newobj((jl_type_t*)jl_lambda_info_type,
LAMBDA_INFO_NW);
li->ast = ast;
li->file = (jl_value_t*)null_sym;
li->line = jl_box_long(0);
if (ast != NULL && jl_is_expr(ast)) {
jl_expr_t *body1 = (jl_expr_t*)jl_exprarg(jl_lam_body((jl_expr_t*)ast),0);
if (jl_is_expr(body1) && ((jl_expr_t*)body1)->head == line_sym) {
li->file = jl_exprarg(body1, 1);
li->line = jl_exprarg(body1, 0);
}
}
li->module = jl_current_module;
li->sparams = sparams;
li->tfunc = (jl_value_t*)jl_null;
li->fptr = &jl_trampoline;
li->roots = NULL;
li->functionObject = NULL;
li->specTypes = NULL;
li->inferred = jl_false;
li->inInference = 0;
li->inCompile = 0;
li->unspecialized = NULL;
li->specializations = NULL;
li->name = anonymous_sym;
return li;
}
// symbols --------------------------------------------------------------------
static jl_sym_t *symtab = NULL;
static jl_sym_t *mk_symbol(const char *str)
{
jl_sym_t *sym;
size_t len = strlen(str);
sym = (jl_sym_t*)malloc(sizeof(jl_sym_t)-sizeof(void*) + len + 1);
sym->type = (jl_type_t*)jl_sym_type;
sym->left = sym->right = NULL;
#ifdef __LP64__
sym->hash = memhash(str, len)^0xAAAAAAAAAAAAAAAAL;
#else
sym->hash = memhash32(str, len)^0xAAAAAAAA;
#endif
strcpy(&sym->name[0], str);
return sym;
}
static void unmark_symbols_(jl_sym_t *root)
{
while (root != NULL) {
root->type = (jl_type_t*)(((uptrint_t)root->type)&~1UL);
unmark_symbols_(root->left);
root = root->right;
}
}
void jl_unmark_symbols(void) { unmark_symbols_(symtab); }
static jl_sym_t **symtab_lookup(jl_sym_t **ptree, const char *str)
{
int x;
while(*ptree != NULL) {
x = strcmp(str, (*ptree)->name);
if (x == 0)
return ptree;
if (x < 0)
ptree = &(*ptree)->left;
else
ptree = &(*ptree)->right;
}
return ptree;
}
jl_sym_t *jl_symbol(const char *str)
{
jl_sym_t **pnode;
pnode = symtab_lookup(&symtab, str);
if (*pnode == NULL)
*pnode = mk_symbol(str);
return *pnode;
}
DLLEXPORT jl_sym_t *jl_symbol_n(const char *str, int32_t len)
{
char name[len+1];
memcpy(name, str, len);
name[len] = '\0';
return jl_symbol(name);
}
DLLEXPORT jl_sym_t *jl_get_root_symbol() { return symtab; }
static uint32_t gs_ctr = 0; // TODO: per-thread
uint32_t jl_get_gs_ctr(void) { return gs_ctr; }
void jl_set_gs_ctr(uint32_t ctr) { gs_ctr = ctr; }
DLLEXPORT jl_sym_t *jl_gensym(void)
{
static char name[16];
char *n;
n = uint2str(&name[2], sizeof(name)-2, gs_ctr, 10);
*(--n) = '#'; *(--n) = '#';
gs_ctr++;
return jl_symbol(n);
}
DLLEXPORT jl_sym_t *jl_tagged_gensym(const char* str, int32_t len)
{
static char gs_name[14];
char name[sizeof(gs_name)+len+3];
char *n;
name[0] = '#'; name[1] = '#'; name[2+len] = '#';
memcpy(name+2, str, len);
n = uint2str(gs_name, sizeof(gs_name), gs_ctr, 10);
memcpy(name+3+len, n, sizeof(gs_name)-(n-gs_name));
gs_ctr++;
return jl_symbol(name);
}
// allocating types -----------------------------------------------------------
jl_typename_t *jl_new_typename(jl_sym_t *name)
{
jl_typename_t *tn=(jl_typename_t*)newobj((jl_type_t*)jl_typename_type, 3);
tn->name = name;
tn->primary = NULL;
tn->cache = jl_null;
return tn;
}
jl_tag_type_t *jl_new_tagtype(jl_value_t *name, jl_tag_type_t *super,
jl_tuple_t *parameters)
{
jl_typename_t *tn=NULL;
JL_GC_PUSH(&tn);
if (jl_is_typename(name))
tn = (jl_typename_t*)name;
else
tn = jl_new_typename((jl_sym_t*)name);
jl_tag_type_t *t = (jl_tag_type_t*)newobj((jl_type_t*)jl_tag_kind,
TAG_TYPE_NW);
t->name = tn;
t->super = super;
t->parameters = parameters;
t->fptr = NULL;
t->env = NULL;
t->linfo = NULL;
if (t->name->primary == NULL)
t->name->primary = (jl_value_t*)t;
JL_GC_POP();
return t;
}
jl_function_t *jl_instantiate_method(jl_function_t *f, jl_tuple_t *sp);
void jl_add_constructors(jl_struct_type_t *t)
{
if (t->name == jl_array_typename) {
t->fptr = jl_f_no_function;
return;
}
jl_initialize_generic_function((jl_function_t*)t, t->name->name);
if (t->ctor_factory == (jl_value_t*)jl_nothing ||
t->ctor_factory == (jl_value_t*)jl_null) {
assert(jl_tuple_len(t->parameters) == 0);
}
else {
assert(jl_tuple_len(t->parameters) > 0);
if (t != (jl_struct_type_t*)t->name->primary) {
// instantiating
assert(jl_is_function(t->ctor_factory));
// add type's static parameters to the ctor factory
size_t np = jl_tuple_len(t->parameters);
jl_tuple_t *sparams = jl_alloc_tuple_uninit(np*2);
jl_function_t *cfactory = NULL;
JL_GC_PUSH(&sparams, &cfactory);
size_t i;
for(i=0; i < np; i++) {
jl_tupleset(sparams, i*2+0,
jl_tupleref(((jl_struct_type_t*)t->name->primary)->parameters, i));
jl_tupleset(sparams, i*2+1,
jl_tupleref(t->parameters, i));
}
cfactory = jl_instantiate_method((jl_function_t*)t->ctor_factory,
sparams);
cfactory->linfo->ast = jl_prepare_ast(cfactory->linfo,
cfactory->linfo->sparams);
// call user-defined constructor factory on (type,)
jl_value_t *cfargs[1] = { (jl_value_t*)t };
jl_apply(cfactory, cfargs, 1);
JL_GC_POP();
}
}
}
JL_CALLABLE(jl_f_ctor_trampoline)
{
jl_add_constructors((jl_struct_type_t*)F);
return jl_apply((jl_function_t*)F, args, nargs);
}
jl_struct_type_t *jl_new_struct_type(jl_sym_t *name, jl_tag_type_t *super,
jl_tuple_t *parameters,
jl_tuple_t *fnames, jl_tuple_t *ftypes)
{
jl_typename_t *tn = jl_new_typename(name);
JL_GC_PUSH(&tn);
jl_struct_type_t *t = (jl_struct_type_t*)newobj((jl_type_t*)jl_struct_kind,
STRUCT_TYPE_NW);
t->name = tn;
t->name->primary = (jl_value_t*)t;
t->super = super;
t->parameters = parameters;
t->names = fnames;
t->types = ftypes;
t->fptr = jl_f_ctor_trampoline;
t->env = (jl_value_t*)t;
t->linfo = NULL;
t->ctor_factory = (jl_value_t*)jl_null;
t->instance = NULL;
if (!jl_is_leaf_type((jl_value_t*)t))
t->uid = 0;
else
t->uid = jl_assign_type_uid();
JL_GC_POP();
return t;
}
extern int jl_boot_file_loaded;
jl_bits_type_t *jl_new_bitstype(jl_value_t *name, jl_tag_type_t *super,
jl_tuple_t *parameters, size_t nbits)
{
jl_bits_type_t *t=NULL;
jl_typename_t *tn=NULL;
JL_GC_PUSH(&t, &tn);
if (!jl_boot_file_loaded && jl_is_symbol(name)) {
// hack to avoid making two versions of basic types needed
// during bootstrapping
if (!strcmp(((jl_sym_t*)name)->name, "Int32"))
t = jl_int32_type;
else if (!strcmp(((jl_sym_t*)name)->name, "Int64"))
t = jl_int64_type;
else if (!strcmp(((jl_sym_t*)name)->name, "Bool"))
t = jl_bool_type;
}
int makenew = (t==NULL);
if (makenew) {
t = (jl_bits_type_t*)newobj((jl_type_t*)jl_bits_kind, BITS_TYPE_NW);
if (jl_is_typename(name))
tn = (jl_typename_t*)name;
else
tn = jl_new_typename((jl_sym_t*)name);
t->name = tn;
}
t->super = super;
t->parameters = parameters;
if (jl_int32_type != NULL)
t->bnbits = jl_box_int32(nbits);
else
t->bnbits = (jl_value_t*)jl_null;
t->nbits = nbits;
if (!jl_is_leaf_type((jl_value_t*)t))
t->uid = 0;
else if (makenew)
t->uid = jl_assign_type_uid();
t->fptr = NULL;
t->env = NULL;
t->linfo = NULL;
if (t->name->primary == NULL)
t->name->primary = (jl_value_t*)t;
JL_GC_POP();
return t;
}
jl_uniontype_t *jl_new_uniontype(jl_tuple_t *types)
{
jl_uniontype_t *t = (jl_uniontype_t*)newobj((jl_type_t*)jl_union_kind, 1);
// don't make unions of 1 type; Union(T)==T
assert(jl_tuple_len(types) != 1);
t->types = types;
return t;
}
// type constructor -----------------------------------------------------------
jl_typector_t *jl_new_type_ctor(jl_tuple_t *params, jl_type_t *body)
{
jl_typector_t *tc = (jl_typector_t*)newobj((jl_type_t*)jl_typector_type,2);
tc->parameters = params;
tc->body = body;
return (jl_typector_t*)tc;
}
// bits constructors ----------------------------------------------------------
#define BOXN_FUNC(nb,nw) \
jl_value_t *jl_box##nb(jl_bits_type_t *t, int##nb##_t x) \
{ \
assert(jl_is_bits_type(t)); \
assert(jl_bitstype_nbits(t)/8 == sizeof(x)); \
jl_value_t *v = alloc_##nw##w(); \
v->type = (jl_type_t*)t; \
*(int##nb##_t*)jl_bits_data(v) = x; \
return v; \
}
BOXN_FUNC(8, 2)
BOXN_FUNC(16, 2)
BOXN_FUNC(32, 2)
#ifdef __LP64__
BOXN_FUNC(64, 2)
#else
BOXN_FUNC(64, 3)
#endif
#define UNBOX_FUNC(j_type,c_type) \
c_type jl_unbox_##j_type(jl_value_t *v) \
{ \
assert(jl_is_bits_type(jl_typeof(v))); \
assert(jl_bitstype_nbits(jl_typeof(v))/8 == sizeof(c_type)); \
return *(c_type*)jl_bits_data(v); \
}
UNBOX_FUNC(int8, int8_t)
UNBOX_FUNC(uint8, uint8_t)
UNBOX_FUNC(int16, int16_t)
UNBOX_FUNC(uint16, uint16_t)
UNBOX_FUNC(int32, int32_t)
UNBOX_FUNC(uint32, uint32_t)
UNBOX_FUNC(int64, int64_t)
UNBOX_FUNC(uint64, uint64_t)
UNBOX_FUNC(bool, int8_t)
UNBOX_FUNC(float32, float)
UNBOX_FUNC(float64, double)
UNBOX_FUNC(pointer, void*)
#define BOX_FUNC(typ,c_type,pfx,nw) \
jl_value_t *pfx##_##typ(c_type x) \
{ \
jl_value_t *v = alloc_##nw##w(); \
v->type = (jl_type_t*)jl_##typ##_type; \
*(c_type*)jl_bits_data(v) = x; \
return v; \
}
BOX_FUNC(float32, float, jl_box, 2)
BOX_FUNC(pointer, void*, jl_box, 2) //2 pointers == two words on all platforms
#ifdef __LP64__
BOX_FUNC(float64, double, jl_box, 2)
#else
BOX_FUNC(float64, double, jl_box, 3)
#endif
#define NBOX_C 1024
#define SIBOX_FUNC(typ,c_type,nw) \
static jl_value_t *boxed_##typ##_cache[NBOX_C]; \
jl_value_t *jl_box_##typ(c_type x) \
{ \
c_type idx = x+NBOX_C/2; \
if ((u##c_type)idx < (u##c_type)NBOX_C) \
return boxed_##typ##_cache[idx]; \
jl_value_t *v = alloc_##nw##w(); \
v->type = (jl_type_t*)jl_##typ##_type; \
*(c_type*)jl_bits_data(v) = x; \
return v; \
}
#define UIBOX_FUNC(typ,c_type,nw) \
static jl_value_t *boxed_##typ##_cache[NBOX_C]; \
jl_value_t *jl_box_##typ(c_type x) \
{ \
if (x < NBOX_C) \
return boxed_##typ##_cache[x]; \
jl_value_t *v = alloc_##nw##w(); \
v->type = (jl_type_t*)jl_##typ##_type; \
*(c_type*)jl_bits_data(v) = x; \
return v; \
}
SIBOX_FUNC(int16, int16_t, 2)
SIBOX_FUNC(int32, int32_t, 2)
UIBOX_FUNC(uint16, uint16_t, 2)
UIBOX_FUNC(uint32, uint32_t, 2)
UIBOX_FUNC(char, uint32_t, 2)
#ifdef __LP64__
SIBOX_FUNC(int64, int64_t, 2)
UIBOX_FUNC(uint64, uint64_t, 2)
#else
SIBOX_FUNC(int64, int64_t, 3)
UIBOX_FUNC(uint64, uint64_t, 3)
#endif
static jl_value_t *boxed_int8_cache[256];
jl_value_t *jl_box_int8(int32_t x)
{
return boxed_int8_cache[(uint8_t)x];
}
static jl_value_t *boxed_uint8_cache[256];
jl_value_t *jl_box_uint8(uint32_t x)
{
return boxed_uint8_cache[(uint8_t)x];
}
void jl_init_int32_int64_cache(void)
{
int64_t i;
for(i=0; i < NBOX_C; i++) {
boxed_int32_cache[i] = jl_box32(jl_int32_type, i-NBOX_C/2);
boxed_int64_cache[i] = jl_box64(jl_int64_type, i-NBOX_C/2);
}
}
void jl_init_box_caches(void)
{
int64_t i;
for(i=0; i < 256; i++) {
boxed_int8_cache[i] = jl_box8(jl_int8_type, i);
boxed_uint8_cache[i] = jl_box8(jl_uint8_type, i);
}
for(i=0; i < NBOX_C; i++) {
boxed_int16_cache[i] = jl_box16(jl_int16_type, i-NBOX_C/2);
boxed_uint16_cache[i] = jl_box16(jl_uint16_type, i);
boxed_uint32_cache[i] = jl_box32(jl_uint32_type, i);
boxed_char_cache[i] = jl_box32(jl_char_type, i);
boxed_uint64_cache[i] = jl_box64(jl_uint64_type, i);
}
}
#ifdef JL_GC_MARKSWEEP
void jl_mark_box_caches(void)
{
int64_t i;
for(i=0; i < 256; i++) {
jl_gc_markval(boxed_int8_cache[i]);
jl_gc_markval(boxed_uint8_cache[i]);
}
for(i=0; i < NBOX_C; i++) {
jl_gc_markval(boxed_int16_cache[i]);
jl_gc_markval(boxed_int32_cache[i]);
jl_gc_markval(boxed_int64_cache[i]);
jl_gc_markval(boxed_uint16_cache[i]);
jl_gc_markval(boxed_uint32_cache[i]);
jl_gc_markval(boxed_char_cache[i]);
jl_gc_markval(boxed_uint64_cache[i]);
}
}
#endif
jl_value_t *jl_box_bool(int8_t x)
{
if (x)
return jl_true;
return jl_false;
}
// Expr constructor for internal use ------------------------------------------
jl_expr_t *jl_exprn(jl_sym_t *head, size_t n)
{
jl_array_t *ar = n==0 ? (jl_array_t*)jl_an_empty_cell : jl_alloc_cell_1d(n);
JL_GC_PUSH(&ar);
jl_expr_t *ex = (jl_expr_t*)alloc_4w();
ex->type = (jl_type_t*)jl_expr_type;
ex->head = head;
ex->args = ar;
ex->etype = (jl_value_t*)jl_any_type;
JL_GC_POP();
return ex;
}
// this constructor has to be built-in for bootstrapping, because we can't
// do anything without being able to make Exprs.
JL_CALLABLE(jl_f_new_expr)
{
JL_NARGS(Expr, 3, 3);
JL_TYPECHK(Expr, symbol, args[0]);
if (!jl_typeis(args[1], (jl_value_t*)jl_array_any_type)) {
jl_type_error("Expr", (jl_value_t*)jl_array_any_type, args[1]);
}
jl_expr_t *ex = (jl_expr_t*)alloc_4w();
ex->type = (jl_type_t*)jl_expr_type;
ex->head = (jl_sym_t*)args[0];
ex->args = (jl_array_t*)args[1];
ex->etype = args[2];
return (jl_value_t*)ex;
}
JL_CALLABLE(jl_f_new_box)
{
JL_NARGS(Box, 1, 1);
jl_value_t *box = (jl_value_t*)alloc_2w();
box->type = jl_box_any_type;
((jl_value_t**)box)[1] = args[0];
return box;
}
Jump to Line
Something went wrong with that request. Please try again.