enum crest_method crest_req_get_method(struct crest_req *req) { if (is_method(req->method, "GET")) return crest_get; if (is_method(req->method, "POST")) return crest_post; if (is_method(req->method, "PUT")) return crest_put; if (is_method(req->method, "DELETE")) return crest_delete; return crest_unsupported; }
void get_print_string(oop_t x, char* s, int size) { // toto unimplemented incomplete -- dmu 1/06 switch (tag(x)) { default: fatal("???"); case float_tag: sprintf(s, "a float 0x%x", x); return; case smi_tag: sprintf(s, "a smi %d", value_of_smiOop(x)); return; case mark_tag: sprintf(s, "a markOop 0x%x", x); return; case mem_tag: break; } if (size < length_of_C_string(s)) fatal("string overflow"); size -= length_of_C_string(s); if (is_byteVector(x)) { ByteVectorObj::from(x)->copy_to_C_string(s, size); } else if (is_method(x)) { printf_and_flush("object vector printing not implemented\n"); // }else if (is_blockMethod(x)) { // printf_and_flush("block method printing not implemented\n"); } else if (is_block(x)) { printf_and_flush("block printing not implemented\n"); } else if (is_objVector(x)) { smi id = Object_Table::index_for_oop(x); ObjVectorObj* x_ov = ObjVectorObj::from(x); printf_and_flush("object vector [ID: %d, size: %d], contents:\n", id , x_ov->indexableSize()); //x_ov->print(); printf_and_flush("done contents [ID: %d].\n", id); } else { printf_and_flush("printing not implemented for ??? object type\n"); } if (size < length_of_C_string(s)) fatal("string overflow"); }
// a constant pool cache entry should never contain old or obsolete methods bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { if (is_vfinal()) { // virtual and final so _f2 contains method ptr instead of vtable index Metadata* f2 = (Metadata*)_f2; // Return false if _f2 refers to an old or an obsolete method. // _f2 == NULL || !_f2->is_method() are just as unexpected here. return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() && !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete()); } else if (_f1 == NULL ||
// Process the method provided to the given entity. // Stage 2. static bool provided_methods(ast_t* entity) { assert(entity != NULL); ast_t* provides = ast_childidx(entity, 3); ast_t* entity_members = ast_childidx(entity, 4); ast_t* last_member = ast_childlast(entity_members); bool r = true; // Run through our provides list for(ast_t* p = ast_child(provides); p != NULL; p = ast_sibling(p)) { ast_t* trait_def = (ast_t*)ast_data(p); assert(trait_def != NULL); ast_t* type_args = ast_childidx(p, 2); ast_t* type_params = ast_childidx(trait_def, 1); ast_t* members = ast_childidx(trait_def, 4); // Run through the methods of each provided type for(ast_t* m = ast_child(members); m != NULL; m = ast_sibling(m)) { // Check behaviour compatability if(ast_id(m) == TK_BE) { if(ast_id(entity) == TK_PRIMITIVE || ast_id(entity) == TK_CLASS) { ast_error(entity, "%s can't provide traits that have behaviours", (ast_id(entity) == TK_CLASS) ? "classes" : "primitives"); r = false; continue; } } if(is_method(m)) { // We have a provided method // Reify the method with the type parameters from trait definition and type // arguments from trait reference ast_t* reified = reify(type_args, m, type_params, type_args); if(reified == NULL) // Reification error, already reported return false; if(!provided_method(entity, reified, m, &last_member)) r = false; } } } return r; }
// Setup a method_t structure for each method in the given type static void setup_local_methods(ast_t* ast) { assert(ast != NULL); ast_t* members = ast_childidx(ast, 4); assert(members != NULL); for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { if(is_method(p)) attach_method_t(p, ast, true); } }
// Find the method with the specified name in the given entity. // Find only methods, ignore fields. // Return the method with the specified name or NULL if not found. static ast_t* find_method(ast_t* entity, const char* name) { assert(entity != NULL); assert(name != NULL); ast_t* method = ast_get(entity, name, NULL); if(method == NULL) return NULL; if(is_method(method)) return method; return NULL; }
// Resolve all methods in the given type. // Stage 4. static bool resolve_methods(ast_t* ast, pass_opt_t* options) { assert(ast != NULL); ast_t* members = ast_childidx(ast, 4); assert(members != NULL); bool r = true; for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { if(is_method(p) && !resolve_body(ast, p, options)) r = false; } return r; }
// Check that the given entity, if concrete, has bodies for all methods. static bool check_concrete_bodies(ast_t* entity, pass_opt_t* opt) { assert(entity != NULL); token_id variety = ast_id(entity); if((variety != TK_PRIMITIVE) && (variety != TK_STRUCT) && (variety != TK_CLASS) && (variety != TK_ACTOR)) return true; bool r = true; ast_t* members = ast_childidx(entity, 4); assert(members != NULL); for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { if(is_method(p)) { method_t* info = (method_t*)ast_data(p); assert(info != NULL); if(!info->failed) { const char* name = ast_name(ast_childidx(p, 1)); if(ast_checkflag(p, AST_FLAG_AMBIGUOUS)) { // Concrete types must not have ambiguous bodies. ast_error(opt->check.errors, entity, "multiple possible bodies for " "method %s, local disambiguation required", name); r = false; } else if(info->body_donor == NULL) { // Concrete types must have method bodies. assert(info->trait_ref != NULL); ast_error(opt->check.errors, info->trait_ref, "no body found for method %s", name); r = false; } } } } return r; }
// Process the methods provided to the given entity from all traits in its // provides list. static bool provided_methods(ast_t* entity, pass_opt_t* opt) { assert(entity != NULL); ast_t* provides = ast_childidx(entity, 3); bool r = true; // Run through our provides list for(ast_t* trait_ref = ast_child(provides); trait_ref != NULL; trait_ref = ast_sibling(trait_ref)) { ast_t* trait = (ast_t*)ast_data(trait_ref); assert(trait != NULL); if(!trait_entity(trait, opt)) return false; ast_t* members = ast_childidx(trait, 4); // Run through the methods of each provided type. for(ast_t* method = ast_child(members); method != NULL; method = ast_sibling(method)) { assert(is_method(method)); ast_t* reified = reify_provides_type(method, trait_ref, opt); if(reified == NULL) { // Reification error, already reported. r = false; } else { if(!add_method_from_trait(entity, reified, trait_ref, opt)) r = false; ast_free_unattached(reified); } } } return r; }
// Setup a method_t structure for each method in the given type. static void setup_local_methods(ast_t* ast) { assert(ast != NULL); ast_t* members = ast_childidx(ast, 4); assert(members != NULL); for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { if(is_method(p)) { method_t* info = attach_method_t(p); info->local_define = true; if(ast_id(ast_childidx(p, 6)) != TK_NONE) info->body_donor = ast; } } }
// Tidy up the method_t structures in the given type static void tidy_up(ast_t* ast) { assert(ast != NULL); ast_t* members = ast_childidx(ast, 4); assert(members != NULL); for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { if(is_method(p)) { method_t* info = (method_t*)ast_data(p); assert(info != NULL); ast_t* body_donor = info->body_donor; ast_free_unattached(info->reified_default); POOL_FREE(method_t, info); ast_setdata(p, body_donor); } } }
// Tidy up the method_t structures in the given entity. static void tidy_up(ast_t* entity) { assert(entity != NULL); ast_t* members = ast_childidx(entity, 4); assert(members != NULL); for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { if(is_method(p)) { method_t* info = (method_t*)ast_data(p); assert(info != NULL); ast_t* body_donor = info->body_donor; POOL_FREE(method_t, info); if(body_donor == NULL) // No body, donor should indicate containing type. body_donor = entity; ast_setdata(p, body_donor); } } }
bool Function::is_static() { return class_context() != NULL && !is_method(); }
ciMethod* as_method() { assert(is_method(), "bad cast"); return (ciMethod*)this; }
// The Method vtable is restored by this call when the Method is in the // shared archive. See patch_klass_vtables() in metaspaceShared.cpp for // all the gory details. SA, dtrace and pstack helpers distinguish metadata // by their vtable. void restore_vtable() { guarantee(is_method(), "vtable restored by this call"); }
// Process all field delegations in the given type. // Stage 3. static bool field_delegations(ast_t* entity) { assert(entity != NULL); ast_t* members = ast_childidx(entity, 4); assert(members != NULL); bool r = true; // Check all fields for(ast_t* f = ast_child(members); f != NULL; f = ast_sibling(f)) { if(is_field(f)) { AST_GET_CHILDREN(f, id, f_type, value, delegates); // Check all delegates for field for(ast_t* d = ast_child(delegates); d != NULL; d = ast_sibling(d)) { if(!check_delegate(entity, f_type, d)) { r = false; continue; } // Mark all methods in delegate trait as targets for this field ast_t* trait = (ast_t*)ast_data(d); assert(trait != NULL); ast_t* t_members = ast_childidx(trait, 4); for(ast_t* m = ast_child(t_members); m != NULL; m = ast_sibling(m)) { if(is_method(m)) { // Mark method as delegate target for this field const char* method_name = ast_name(ast_childidx(m, 1)); assert(method_name != NULL); ast_t* local_method = ast_get(entity, method_name, NULL); assert(local_method != NULL); method_t* info = (method_t*)ast_data(local_method); assert(info != NULL); if(info->delegate_field_1 == NULL) { // First delegate field for this method info->delegate_field_1 = f; info->delegate_target_1 = d; } else if(info->delegate_field_2 == NULL && info->delegate_field_1 != f) { // We already have one delegate field, record second info->delegate_field_2 = f; info->delegate_target_2 = d; } } } } } } return r; }
// Combine the given delegated method with the existing one, if any, in the // given entity. // The trait_ref is the entry in the delegates list that causes this method // inclusion. Needed for error reporting. // Returns true on success, false on failure in which case an error will have // been reported. static bool delegated_method(ast_t* entity, ast_t* method, ast_t* field, ast_t* trait_ref, pass_opt_t* opt) { assert(entity != NULL); assert(method != NULL); assert(is_method(method)); assert(field != NULL); assert(trait_ref != NULL); if(ast_id(method) == TK_NEW) // Don't delegate constructors. return true; // Check for existing method of the same name. const char* name = ast_name(ast_childidx(method, 1)); assert(name != NULL); ast_t* existing = find_method(entity, name); if(existing != NULL) { // We already have a method with this name. method_t* info = (method_t*)ast_data(existing); assert(info != NULL); // Nothing new to add. if(info->local_define || info->delegated_field == field) return true; assert(info->trait_ref != NULL); ast_error(opt->check.errors, trait_ref, "clashing delegates for method %s, local disambiguation required", name); ast_error_continue(opt->check.errors, trait_ref, "field %s delegates to %s here", ast_name(ast_child(field)), name); ast_error_continue(opt->check.errors, info->trait_ref, "field %s delegates to %s here", ast_name(ast_child(info->delegated_field)), name); info->failed = true; info->delegated_field = NULL; return false; } // This is a new method, reify and add it. ast_t* reified = reify_provides_type(method, trait_ref, opt); // Reification error, already reported if(reified == NULL) return false; ast_t* new_method = add_method(entity, trait_ref, reified, "delegate", opt); if(new_method == NULL) { ast_free_unattached(reified); return false; } // Convert the newly added method into a delegation redirection. make_delegation(new_method, field, trait_ref, entity); return true; }
bool is_entry() const { return !is_method(); }