value_t builtin_implementation_validate(value_t self) { VALIDATE_FAMILY(ofBuiltinImplementation, self); VALIDATE_FAMILY(ofUtf8, get_builtin_implementation_name(self)); VALIDATE_FAMILY(ofCodeBlock, get_builtin_implementation_code(self)); VALIDATE_PHYLUM(tpFlagSet, get_builtin_implementation_method_flags(self)); return success(); }
// Executes a method declaration on the given fragment. static value_t apply_method_declaration(value_t ambience, value_t decl, value_t fragment) { CHECK_FAMILY(ofMethodDeclarationAst, decl); CHECK_FAMILY(ofModuleFragment, fragment); runtime_t *runtime = get_ambience_runtime(ambience); // Look for the :builtin annotation on this method. value_t annots = get_method_declaration_ast_annotations(decl); value_t builtin_name = new_not_found_condition(); for (size_t i = 0; i < get_array_length(annots); i++) { value_t annot = get_array_at(annots, i); TRY_DEF(value, run_expression_until_condition(ambience, fragment, annot)); if (in_family(ofBuiltinMarker, value)) builtin_name = get_builtin_marker_name(value); } // Compile the method whether it's a builtin or not. This way we can reuse // the compilation code for both cases and just patch up the result after // the fact if it's a builtin. value_t method_ast = get_method_declaration_ast_method(decl); TRY_DEF(method, compile_method_ast_to_method(runtime, method_ast, fragment)); if (!in_condition_cause(ccNotFound, builtin_name)) { // This is a builtin so patch the method with the builtin implementation. TRY_DEF(impl, runtime_get_builtin_implementation(runtime, builtin_name)); value_t impl_code = get_builtin_implementation_code(impl); TRY(validate_builtin_method_binding(method, impl)); set_method_code(method, impl_code); value_t impl_flags = get_builtin_implementation_method_flags(impl); set_method_flags(method, impl_flags); } value_t methodspace = get_module_fragment_methodspace(fragment); TRY(add_methodspace_method(runtime, methodspace, method)); return success(); }