@@ -693,6 +693,13 @@ static const auto jlundefvarerror_func = new JuliaFunction{
693693            {PointerType::get (JuliaType::get_jlvalue_ty (C), AddressSpace::CalleeRooted)}, false ); },
694694    get_attrs_noreturn,
695695};
696+ static  const  auto  jlhasnofield_func = new  JuliaFunction{
697+     XSTR (jl_has_no_field_error),
698+     [](LLVMContext &C) { return  FunctionType::get (getVoidTy (C),
699+             {PointerType::get (JuliaType::get_jlvalue_ty (C), AddressSpace::CalleeRooted),
700+              PointerType::get (JuliaType::get_jlvalue_ty (C), AddressSpace::CalleeRooted)}, false ); },
701+     get_attrs_noreturn,
702+ };
696703static  const  auto  jlboundserrorv_func = new  JuliaFunction{
697704    XSTR (jl_bounds_error_ints),
698705    [](LLVMContext &C) { return  FunctionType::get (getVoidTy (C),
@@ -3236,6 +3243,8 @@ static jl_llvm_functions_t
32363243        jl_value_t  *jlrettype,
32373244        jl_codegen_params_t  ¶ms);
32383245
3246+ static  void  emit_hasnofield_error_ifnot (jl_codectx_t  &ctx, Value *ok, jl_sym_t  *type, jl_cgval_t  name);
3247+ 
32393248static  bool  emit_builtin_call (jl_codectx_t  &ctx, jl_cgval_t  *ret, jl_value_t  *f,
32403249                              const  jl_cgval_t  *argv, size_t  nargs, jl_value_t  *rt,
32413250                              jl_expr_t  *ex, bool  is_promotable)
@@ -3706,6 +3715,18 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
37063715                *ret = mark_julia_type (ctx, fld_val, true , jl_any_type);
37073716                return  true ;
37083717            }
3718+         } else  if  (fld.typ  == (jl_value_t *)jl_symbol_type) {
3719+             if  (jl_is_datatype (utt) && !jl_is_namedtuple_type (utt)) { //  TODO: Look into this for NamedTuple
3720+                 if  (jl_struct_try_layout (utt) && (jl_datatype_nfields (utt) == 1 )) {
3721+                     jl_svec_t  *fn = jl_field_names (utt);
3722+                     assert (jl_svec_len (fn) == 1 );
3723+                     Value *typ_sym = literal_pointer_val (ctx, jl_svecref (fn, 0 ));
3724+                     Value *cond = ctx.builder .CreateICmpEQ (mark_callee_rooted (ctx, typ_sym), mark_callee_rooted (ctx, boxed (ctx, fld)));
3725+                     emit_hasnofield_error_ifnot (ctx, cond, utt->name ->name , fld);
3726+                     *ret = emit_getfield_knownidx (ctx, obj, 0 , utt, order);
3727+                     return  true ;
3728+                 }
3729+             }
37093730        }
37103731        //  TODO: generic getfield func with more efficient calling convention
37113732        return  false ;
@@ -4426,6 +4447,22 @@ static void undef_var_error_ifnot(jl_codectx_t &ctx, Value *ok, jl_sym_t *name)
44264447    ctx.builder .SetInsertPoint (ifok);
44274448}
44284449
4450+ static  void  emit_hasnofield_error_ifnot (jl_codectx_t  &ctx, Value *ok, jl_sym_t  *type, jl_cgval_t  name)
4451+ {
4452+     ++EmittedUndefVarErrors;
4453+     assert (name.typ  == (jl_value_t *)jl_symbol_type);
4454+     BasicBlock *err = BasicBlock::Create (ctx.builder .getContext (), " err" f );
4455+     BasicBlock *ifok = BasicBlock::Create (ctx.builder .getContext (), " ok" 
4456+     ctx.builder .CreateCondBr (ok, ifok, err);
4457+     ctx.builder .SetInsertPoint (err);
4458+     ctx.builder .CreateCall (prepare_call (jlhasnofield_func),
4459+                           {mark_callee_rooted (ctx, literal_pointer_val (ctx, (jl_value_t *)type)),
4460+                            mark_callee_rooted (ctx, boxed (ctx, name))});
4461+     ctx.builder .CreateUnreachable ();
4462+     ctx.f ->getBasicBlockList ().push_back (ifok);
4463+     ctx.builder .SetInsertPoint (ifok);
4464+ }
4465+ 
44294466//  returns a jl_ppvalue_t location for the global variable m.s
44304467//  if the reference currently bound or assign == true,
44314468//    pbnd will also be assigned with the binding address
@@ -8692,6 +8729,7 @@ static void init_jit_functions(void)
86928729    add_named_global (jlatomicerror_func, &jl_atomic_error);
86938730    add_named_global (jlthrow_func, &jl_throw);
86948731    add_named_global (jlundefvarerror_func, &jl_undefined_var_error);
8732+     add_named_global (jlhasnofield_func, &jl_has_no_field_error);
86958733    add_named_global (jlboundserrorv_func, &jl_bounds_error_ints);
86968734    add_named_global (jlboundserror_func, &jl_bounds_error_int);
86978735    add_named_global (jlvboundserror_func, &jl_bounds_error_tuple_int);
0 commit comments