method_prims.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.21 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_method_prims.cpp.incl"
00026 
00027 TRACE_FUNC(TraceMethodPrims, "method")
00028 
00029 int methodOopPrimitives::number_of_calls;
00030 
00031 #define ASSERT_RECEIVER assert(receiver->is_method(), "receiver must be method")
00032 
00033 PRIM_DECL_1(methodOopPrimitives::selector, oop receiver) {
00034   PROLOGUE_1("selector", receiver);
00035   ASSERT_RECEIVER;
00036   return methodOop(receiver)->selector();
00037 }
00038 
00039 PRIM_DECL_1(methodOopPrimitives::debug_info, oop receiver) {
00040   PROLOGUE_1("debug_info", receiver);
00041   ASSERT_RECEIVER;
00042   return methodOop(receiver)->debugInfo();
00043 }
00044 
00045 PRIM_DECL_1(methodOopPrimitives::size_and_flags, oop receiver) {
00046   PROLOGUE_1("size_and_flags", receiver);
00047   ASSERT_RECEIVER;
00048   return methodOop(receiver)->size_and_flags();
00049 }
00050 
00051 PRIM_DECL_1(methodOopPrimitives::fileout_body, oop receiver) {
00052   PROLOGUE_1("fileout_body", receiver);
00053   ASSERT_RECEIVER;
00054   return methodOop(receiver)->fileout_body();
00055 }
00056 
00057 PRIM_DECL_2(methodOopPrimitives::setSelector, oop receiver, oop name) {
00058   PROLOGUE_2("setSelector", receiver, name);
00059   ASSERT_RECEIVER;
00060   if (!name->is_symbol())
00061     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00062   methodOop(receiver)->set_selector_or_method(oop(name));
00063   return receiver;
00064 }
00065 
00066 PRIM_DECL_1(methodOopPrimitives::numberOfArguments, oop receiver) {
00067   PROLOGUE_1("numberOfArguments", receiver);
00068   ASSERT_RECEIVER;
00069   return as_smiOop(methodOop(receiver)->number_of_arguments());
00070 }
00071 
00072 PRIM_DECL_1(methodOopPrimitives::outer, oop receiver) {
00073   PROLOGUE_1("outer", receiver);
00074   ASSERT_RECEIVER;
00075   return methodOop(receiver)->selector_or_method();
00076 }
00077 
00078 PRIM_DECL_2(methodOopPrimitives::setOuter, oop receiver, oop method) {
00079   PROLOGUE_2("setOuter", receiver, method);
00080   ASSERT_RECEIVER;
00081   methodOop(receiver)->set_selector_or_method(oop(method));
00082   return receiver;
00083 }
00084 
00085 PRIM_DECL_2(methodOopPrimitives::referenced_instance_variable_names, oop receiver, oop mixin) {
00086   PROLOGUE_2("referenced_instance_variable_names", receiver, mixin);
00087   ASSERT_RECEIVER;
00088   if (!mixin->is_mixin())
00089     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00090 
00091   return methodOop(receiver)->referenced_instance_variable_names(mixinOop(mixin));
00092 }
00093 
00094 PRIM_DECL_1(methodOopPrimitives::referenced_class_variable_names, oop receiver) {
00095   PROLOGUE_1("referenced_class_variable_names", receiver);
00096   ASSERT_RECEIVER;
00097   return methodOop(receiver)->referenced_class_variable_names();
00098 }
00099 
00100 PRIM_DECL_1(methodOopPrimitives::referenced_global_names, oop receiver) {
00101   PROLOGUE_1("referenced_global_names", receiver);
00102   ASSERT_RECEIVER;
00103   return methodOop(receiver)->referenced_global_names();
00104 }
00105 
00106 PRIM_DECL_1(methodOopPrimitives::senders, oop receiver) {
00107   PROLOGUE_1("senders", receiver);
00108   ASSERT_RECEIVER;
00109   return methodOop(receiver)->senders();
00110 }
00111 
00112 PRIM_DECL_2(methodOopPrimitives::prettyPrint, oop receiver, oop klass) {
00113   PROLOGUE_2("prettyPrint", receiver, klass);
00114   ASSERT_RECEIVER;
00115   if (klass == nilObj) {
00116     prettyPrinter::print(methodOop(receiver));
00117   } else {
00118     if (!klass->is_klass())
00119       return markSymbol(vmSymbols::first_argument_has_wrong_type());
00120     prettyPrinter::print(methodOop(receiver), klassOop(klass));
00121   }
00122   return receiver;
00123 }
00124 
00125 PRIM_DECL_2(methodOopPrimitives::prettyPrintSource, oop receiver, oop klass) {
00126   PROLOGUE_2("prettyPrintSource", receiver, klass);
00127   ASSERT_RECEIVER;
00128   byteArrayOop a;
00129   if (klass == nilObj) {
00130     a = prettyPrinter::print_in_byteArray(methodOop(receiver));
00131   } else {
00132     if (!klass->is_klass())
00133       return markSymbol(vmSymbols::first_argument_has_wrong_type());
00134     a = prettyPrinter::print_in_byteArray(methodOop(receiver), klassOop(klass));
00135   }
00136   return a;
00137 }
00138 
00139 PRIM_DECL_1(methodOopPrimitives::printCodes, oop receiver) {
00140   PROLOGUE_1("printCodes", receiver);
00141   ASSERT_RECEIVER;
00142   #ifndef PRODUCT
00143   { ResourceMark rm;
00144     methodOop(receiver)->print_codes();
00145   }
00146   #endif
00147   return receiver;
00148 }
00149 
00150 
00151 PRIM_DECL_6(methodOopPrimitives::constructMethod, oop selector_or_method, oop flags, oop nofArgs, oop debugInfo, oop bytes, oop oops) {
00152   PROLOGUE_6("constructMethod", selector_or_method, flags, nofArgs, debugInfo, bytes, oops);
00153   if (!selector_or_method->is_symbol() && (selector_or_method != nilObj))
00154     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00155   if (!flags->is_smi())
00156     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00157   if (!nofArgs->is_smi())
00158     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00159   if (!debugInfo->is_objArray())
00160     return markSymbol(vmSymbols::fourth_argument_has_wrong_type());
00161   if (!bytes->is_byteArray())
00162     return markSymbol(vmSymbols::fifth_argument_has_wrong_type());
00163   if (!oops->is_objArray())
00164     return markSymbol(vmSymbols::sixth_argument_has_wrong_type());
00165 
00166   if (objArrayOop(oops)->length() * oopSize != byteArrayOop(bytes)->length()) {
00167         return markSymbol(vmSymbols::method_construction_failed());
00168   }
00169 
00170   methodKlass* k = (methodKlass*) Universe::methodKlassObj()->klass_part();
00171   methodOop result = k->constructMethod(selector_or_method,
00172                                         smiOop(flags)->value(),
00173                                         smiOop(nofArgs)->value(),
00174                                         objArrayOop(debugInfo),
00175                                                             byteArrayOop(bytes),
00176                                                             objArrayOop(oops));
00177   if (result) return result;
00178   return markSymbol(vmSymbols::method_construction_failed());
00179 }
00180 
00181 extern "C" blockClosureOop allocateBlock(smiOop nof);
00182 
00183 static oop allocate_block_for(methodOop method, oop self) {
00184   BlockScavenge bs;
00185 
00186   if (!method->is_customized()) {
00187     method->customize_for(self->klass(), self->blueprint()->mixin());
00188   }
00189 
00190   // allocate the context for the block (make room for the self)
00191   contextKlass* ok = (contextKlass*) contextKlassObj->klass_part();
00192   contextOop con = contextOop(ok->allocateObjectSize(1));
00193   con->kill();
00194   con->obj_at_put(0, self);
00195 
00196   // allocate the resulting block
00197   blockClosureOop blk = allocateBlock(as_smiOop(method->number_of_arguments()));
00198   blk->set_method(method);
00199   blk->set_lexical_scope(con);
00200 
00201   return blk;
00202 }
00203 
00204 PRIM_DECL_1(methodOopPrimitives::allocate_block, oop receiver) {
00205   PROLOGUE_1("allocate_block", receiver);
00206   ASSERT_RECEIVER;
00207 
00208   if (!methodOop(receiver)->is_blockMethod())
00209     return markSymbol(vmSymbols::conversion_failed());
00210 
00211   return allocate_block_for(methodOop(receiver), nilObj);
00212 }
00213 
00214 PRIM_DECL_2(methodOopPrimitives::allocate_block_self, oop receiver, oop self) {
00215   PROLOGUE_2("allocate_block_self", receiver, self);
00216   ASSERT_RECEIVER;
00217 
00218   if (!methodOop(receiver)->is_blockMethod())
00219     return markSymbol(vmSymbols::conversion_failed());
00220 
00221   return allocate_block_for(methodOop(receiver), self);
00222 }
00223 
00224 static symbolOop symbol_from_method_inlining_info(methodOopDesc::Method_Inlining_Info info) { 
00225   if (info == methodOopDesc::normal_inline)  return oopFactory::new_symbol("Normal");
00226   if (info == methodOopDesc::never_inline)   return oopFactory::new_symbol("Never");
00227   if (info == methodOopDesc::always_inline)  return oopFactory::new_symbol("Always");
00228   ShouldNotReachHere();
00229   return NULL;
00230 }
00231 
00232 PRIM_DECL_2(methodOopPrimitives::set_inlining_info, oop receiver, oop info) {
00233   PROLOGUE_2("set_inlining_info", receiver, info);
00234   ASSERT_RECEIVER;
00235   if (!info->is_symbol())
00236     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00237 
00238   // Check argument value
00239   methodOopDesc::Method_Inlining_Info in;
00240   if (symbolOop(info)->equals("Never")) {
00241     in = methodOopDesc::never_inline;
00242   } else if(symbolOop(info)->equals("Always")) {
00243     in = methodOopDesc::always_inline;
00244   } else if(symbolOop(info)->equals("Normal")) {
00245     in = methodOopDesc::normal_inline;
00246   } else {
00247     return markSymbol(vmSymbols::argument_is_invalid());
00248   }
00249   methodOopDesc::Method_Inlining_Info old = methodOop(receiver)->method_inlining_info();
00250   methodOop(receiver)->set_method_inlining_info(in);
00251   return symbol_from_method_inlining_info(old);
00252 }
00253 
00254 PRIM_DECL_1(methodOopPrimitives::inlining_info, oop receiver) {
00255   PROLOGUE_1("inlining_info", receiver);
00256   ASSERT_RECEIVER;
00257   return symbol_from_method_inlining_info(methodOop(receiver)->method_inlining_info());
00258 }

Generated on Mon Oct 9 13:37:14 2006 for Strongtalk VM by  doxygen 1.4.7