static bool dynamic_value_ptr(compile_t* c, LLVMValueRef ptr, LLVMValueRef desc, ast_t* pattern, LLVMBasicBlockRef next_block) { // Get the type of the right-hand side of the pattern's eq() function. ast_t* param_type = eq_param_type(pattern); // Check the runtime type. We pass a pointer to the fields because we may // still need to match a tuple type inside a type expression. if(!check_type(c, ptr, desc, param_type, next_block)) return false; // We now know that ptr points to something of type pattern_type, and that // it isn't a boxed primitive, as that would go through the other path, ie // dynamic_match_object(). We also know it isn't an unboxed tuple. We can // load from ptr with a type based on the static type of the pattern. gentype_t g; if(!gentype(c, param_type, &g)) return false; LLVMTypeRef ptr_type = LLVMPointerType(g.use_type, 0); ptr = LLVMBuildIntToPtr(c->builder, ptr, ptr_type, ""); LLVMValueRef value = LLVMBuildLoad(c->builder, ptr, ""); return check_value(c, pattern, param_type, value, next_block); }
static bool static_value(compile_t* c, LLVMValueRef value, ast_t* type, ast_t* pattern, LLVMBasicBlockRef next_block) { // Get the type of the right-hand side of the pattern's eq() function. ast_t* param_type = eq_param_type(c, pattern); if(!is_subtype(type, param_type, NULL, c->opt)) { // Switch to dynamic value checking. assert(LLVMTypeOf(value) == c->object_ptr); LLVMValueRef desc = gendesc_fetch(c, value); return dynamic_value_object(c, value, desc, pattern, next_block); } return check_value(c, pattern, param_type, value, next_block); }
static bool dynamic_value_object(compile_t* c, LLVMValueRef object, LLVMValueRef desc, ast_t* pattern, LLVMBasicBlockRef next_block) { // Get the type of the right-hand side of the pattern's eq() function. ast_t* param_type = eq_param_type(c, pattern); // Build a base pointer that skips the object header. LLVMValueRef ptr = gendesc_ptr_to_fields(c, object, desc); // Check the runtime type. We pass a pointer to the fields because we may // still need to match a tuple type inside a type expression. if(!check_type(c, ptr, desc, param_type, next_block)) return false; return check_value(c, pattern, param_type, object, next_block); }