void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { __ emit_fd(); // generate code to handle arguments iterate(fingerprint); pass_prev(-BytesPerWord); // return result handler __ movl(GR_RET, (uint64_t)AbstractInterpreter::result_handler(method()->result_type())); __ ret(); __ flush(); }
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { pass_prev(0); pass_curr(Argument::float_sig); }
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { pass_prev(BytesPerWord); pass_curr(Argument::double_sig); }
ast_t* package_load(ast_t* from, const char* path, pass_opt_t* options) { const char* magic = find_magic_package(path); const char* full_path = path; const char* qualified_name = path; ast_t* program = ast_nearest(from, TK_PROGRAM); if(magic == NULL) { // Lookup (and hence normalise) path bool is_relative = false; full_path = find_path(from, path, &is_relative); if(full_path == NULL) return NULL; if((from != NULL) && is_relative) { // Package to load is relative to from, build the qualified name // The qualified name should be relative to the program being built package_t* from_pkg = (package_t*)ast_data(ast_child(program)); if(from_pkg != NULL) { const char* base_name = from_pkg->qualified_name; size_t base_name_len = strlen(base_name); size_t path_len = strlen(path); size_t len = base_name_len + path_len + 2; char* q_name = (char*)pool_alloc_size(len); memcpy(q_name, base_name, base_name_len); q_name[base_name_len] = '/'; memcpy(q_name + base_name_len + 1, path, path_len); q_name[len - 1] = '\0'; qualified_name = stringtab_consume(q_name, len); } } } ast_t* package = ast_get(program, full_path, NULL); // Package already loaded if(package != NULL) return package; package = create_package(program, full_path, qualified_name); if(report_build) printf("Building %s -> %s\n", path, full_path); if(magic != NULL) { if(!parse_source_code(package, magic, options)) return NULL; } else { if(!parse_files_in_dir(package, full_path, options)) return NULL; } if(ast_child(package) == NULL) { ast_error(package, "no source files in package '%s'", path); return NULL; } // We add new packages to the end of the program, so they will be reached by // the current pass processing. This means we need to catch up the new // package to the previous pass if(!ast_passes_subtree(&package, options, pass_prev(options->type_catchup_pass))) return NULL; return package; }