Beispiel #1
0
bool objCMethodDeclHasActionAttributeImpl(
    const clang::ObjCMethodDecl *decl,
    const std::string& action,
    const CAPA::RuleBase& rule,
    std::string* comment) {
    if(decl == nullptr) {
        return false;
    }

    // Check the method directly
    if(baseDeclHasActionAttributeImpl(decl, action, rule, comment)) {
        return true;
    }

    // That failed, check if it has a property declaration and use that
    if(decl->isPropertyAccessor() &&
       baseDeclHasActionAttributeImpl(decl->findPropertyDecl(), action, rule, comment)) {
        return true;
    }
  
    // Check if the method comes from a protocol, because then it doesn't have a class
    // interface
    const auto protocol = clang::dyn_cast<clang::ObjCProtocolDecl>(decl->getDeclContext());
    if(protocol) {
       const auto method = protocol->lookupMethod(decl->getSelector(), decl->isInstanceMethod());
       return baseDeclHasActionAttributeImpl(method, action, rule, comment);
    }
 
    return objCMethodDeclHasAttributeFromCategory(decl, action, rule, comment);

}
Beispiel #2
0
	bool methodCallPrologue(Thread* t, AbsStack slot, Value self, String* methodName, word numReturns, uword numParams,
		bool isTailcall)
	{
		auto method = lookupMethod(t, self, methodName);

		// Idea is like this:

		// If we're calling the real method, the object is moved to the 'this' slot and the method takes its place.

		// If we're calling opMethod, the object is left where it is (or the custom context is moved to its place),
		// the method name goes where the context was, and we use callPrologue2 with a closure that's not on the stack.

		if(method.type != CrocType_Null)
		{
			t->stack[slot] = method;
			t->stack[slot + 1] = self;
			return callPrologue(t, slot, numReturns, numParams, isTailcall);
		}
		else
		{
			if(auto mm = getMM(t, self, MM_Method))
			{
				t->stack[slot] = self;
				t->stack[slot + 1] = Value::from(methodName);
				return funcCallPrologue(t, mm, slot, numReturns, slot, numParams + 1, isTailcall);
			}
			else
			{
				pushTypeStringImpl(t, self);
				return croc_eh_throwStd(*t, "MethodError", "No implementation of method '%s' or %s for type '%s'",
					methodName->toCString(), MetaNames[MM_Method], croc_getString(*t, -1));
			}
		}
	}
bool LuaInterface::callMethod(void *o, const char *func, float a, float b)
{
    lookupMethod(o, func);
	lua_pushnumber(_lua, a);
	lua_pushnumber(_lua, b);
    return doCall(2+1); // first parameter is self (aka o)
}
Beispiel #4
0
int main(int argc, char *argv[]) {
    Class *array_class, *main_class;
    Object *system_loader, *array;
    MethodBlock *mb;
    InitArgs args;
    int class_arg;
    char *cpntr;
    int status;
    int i;

    setDefaultInitArgs(&args);
    class_arg = parseCommandLine(argc, argv, &args);

    args.main_stack_base = &array_class;

    if(!initVM(&args)) {
        printf("Could not initialise VM.  Aborting.\n");
        exit(1);
    }

   if((system_loader = getSystemClassLoader()) == NULL)
        goto error;

    mainThreadSetContextClassLoader(system_loader);

    for(cpntr = argv[class_arg]; *cpntr; cpntr++)
        if(*cpntr == '.')
            *cpntr = '/';

    main_class = findClassFromClassLoader(argv[class_arg], system_loader);
    if(main_class != NULL)
        initClass(main_class);

    if(exceptionOccurred())
        goto error;

    mb = lookupMethod(main_class, SYMBOL(main),
                                  SYMBOL(_array_java_lang_String__V));

    if(mb == NULL || !(mb->access_flags & ACC_STATIC)) {
        signalException(java_lang_NoSuchMethodError, "main");
        goto error;
    }

    /* Create the String array holding the command line args */

    i = class_arg + 1;
    if((array_class = findArrayClass(SYMBOL(array_java_lang_String))) &&
           (array = allocArray(array_class, argc - i, sizeof(Object*))))  {
        Object **args = ARRAY_DATA(array, Object*) - i;

        for(; i < argc; i++)
            if(!(args[i] = Cstr2String(argv[i])))
                break;

        /* Call the main method */
        if(i == argc)
            executeStaticMethod(main_class, mb, array);
    }
Beispiel #5
0
void signalChainedExceptionClass(Class *exception, char *message, Object *cause) {
    Object *exp = allocObject(exception);
    Object *str = message == NULL ? NULL : Cstr2String(message);
    MethodBlock *init = lookupMethod(exception, SYMBOL(object_init),
                                                SYMBOL(_java_lang_String__V));
    if(exp && init) {
        executeMethod(exp, init, str);

        if(cause && !exceptionOccurred()) {
            MethodBlock *mb = lookupMethod(exception, SYMBOL(initCause),
                                           SYMBOL(_java_lang_Throwable__java_lang_Throwable));
            if(mb)
                executeMethod(exp, mb, cause);
        }
        setException(exp);
    }
}
Beispiel #6
0
/*
 * The CreateCl opcode is specified as not being allowed before the
 * class it creates exists, and closure classes are always unique.
 *
 * This means even if we're not in RepoAuthoritative mode, as long as
 * this code is reachable it will always use the same closure Class*,
 * so we can just burn it into the TC without using RDS.
 */
void emitCreateCl(HTS& env, int32_t numParams, const StringData* clsName) {
  auto const cls = Unit::lookupClassOrUniqueClass(clsName);
  auto const invokeFunc = cls->lookupMethod(s_uuinvoke.get());
  auto const clonedFunc = invokeFunc->cloneAndSetClass(
    const_cast<Class*>(curClass(env))
  );
  assert(cls && (cls->attrs() & AttrUnique));

  auto const closure = allocObjFast(env, cls);
  gen(env, IncRef, closure);

  auto const ctx = [&]{
    if (!curClass(env)) return cns(env, nullptr);
    auto const ldctx = gen(env, LdCtx, fp(env));
    if (invokeFunc->attrs() & AttrStatic) {
      return gen(env, ConvClsToCctx, gen(env, LdClsCtx, ldctx));
    }
    gen(env, IncRefCtx, ldctx);
    return ldctx;
  }();
  gen(env, StClosureCtx, closure, ctx);
  gen(env, StClosureFunc, FuncData(clonedFunc), closure);

  SSATmp* args[numParams];
  for (int32_t i = 0; i < numParams; ++i) {
    args[numParams - i - 1] = popF(env);
  }

  int32_t propId = 0;
  for (; propId < numParams; ++propId) {
    gen(
      env,
      StClosureArg,
      PropByteOffset(cls->declPropOffset(propId)),
      closure,
      args[propId]
    );
  }

  // Closure static variables are per instance, and need to start
  // uninitialized.  After numParams use vars, the remaining instance
  // properties hold any static locals.
  assert(cls->numDeclProperties() ==
         clonedFunc->numStaticLocals() + numParams);
  for (int32_t numDeclProperties = cls->numDeclProperties();
      propId < numDeclProperties;
      ++propId) {
    gen(
      env,
      StClosureArg,
      PropByteOffset(cls->declPropOffset(propId)),
      closure,
      cns(env, Type::Uninit)
    );
  }

  push(env, closure);
}
bool LuaInterface::callMethod(void *o, const char *func, void* other)
{
    lookupMethod(o, func);
	int lty = lua_rawgetp(_lua, LUA_REGISTRYINDEX, other);
#ifdef _DEBUG
	assert(lty == LUA_TUSERDATA);
#endif
    return doCall(1+1); // first parameter is self (aka o)
}
Beispiel #8
0
/**
 * Recursively searches the scope hierarchy for the instance of
 * a method having the given name.
 */
Method* CodeParser::lookupMethod( Scope* scope, const char* signature ) {
	// is the scope a class scope?
	if( scope->getScopeType() == CLASS_SCOPE ) {
		ScopeContainer* container = (ScopeContainer*)scope;
		Method* method = container->lookupMethod( signature );
		if( method != NULL ) {
			return method;
		}
	}

	// look for the method via the parent scope
	Scope* parentScope = scope->getParentSope();
	return ( parentScope != NULL ) ? lookupMethod( parentScope, signature ) : NULL;
}
Beispiel #9
0
void Java_java_lang_Class_newInstance(void)
{
    INSTANCE_CLASS currentClass = getFP()->thisMethod->ofClass;
    CLASS clazz = topStackAsType(CLASS);

    if (IS_ARRAY_CLASS(clazz)
        || ((clazz->accessFlags & (ACC_INTERFACE | ACC_ABSTRACT)) != 0)) {
        raiseException("java/lang/InstantiationException");
        return;
    }

    if (classHasAccessToClass(currentClass, clazz)) {
        METHOD method = lookupMethod(clazz, initNameAndType, currentClass);
        if (   (method != NULL)
            && (method->ofClass == (INSTANCE_CLASS)clazz)
               /* I don't understand why, but we're not allowed access to
                * a protected <init> method of a superclass. */
            && classHasAccessToMember(currentClass, 
                   (method->accessFlags & ~ACC_PROTECTED),
                   (INSTANCE_CLASS)clazz, (INSTANCE_CLASS)clazz)

            )
        {
            START_TEMPORARY_ROOTS
                DECLARE_TEMPORARY_ROOT(INSTANCE, object,
                                       instantiate((INSTANCE_CLASS)clazz));
                if (object != NULL) {
                    /*  Put the result back on the stack */
                    topStackAsType(INSTANCE) = object; /* Will get the result */
                    /* We now need to call the initializer.  We'd like to just
                     * push a second copy of the object onto the stack, and then
                     * do pushFrame(method).  But we can't, because that would
                     * not necessarily coincide with the stack map of the
                     * current method.
                     */
                    pushFrame(RunCustomCodeMethod);
                    pushStackAsType(CustomCodeCallbackFunction,
                                    newInstanceReturnObject);
                    pushStackAsType(INSTANCE, object);
                    /* pushFrame may signal a stack overflow.  */
                    pushFrame(method);
                } else {
                    /* We will already have thrown an appropriate error */
                }
            END_TEMPORARY_ROOTS
            return;
        }
    }
Beispiel #10
0
UserFSNode::UserFSNode(Class* cls, const Variant& context /*= null */) {
  VMRegAnchor _;
  const Func* ctor;
  m_cls = cls;
  if (LookupResult::MethodFoundWithThis !=
      g_context->lookupCtorMethod(ctor, m_cls)) {
    raise_error("Unable to call %s'n constructor", m_cls->name()->data());
  }

  m_obj = ObjectData::newInstance(m_cls);
  m_obj.o_set("context", context);
  Variant ret;
  g_context->invokeFuncFew(ret.asTypedValue(), ctor, m_obj.get());

  m_Call = lookupMethod(s_call.get());
}
Beispiel #11
0
/**
 * Parses the method call within an expression
 */
int CodeParser::parseExpression_MethodCall( const char* methodName, Scope* scope, TokenStack* stack ) {
	int errorCode = 0;
	list<Parameter*> params;

	// parse the method parameters
	if( ( errorCode = parseMethodParameters( scope, stack, params ) ) ) {
		return errorCode;
	}

	// generate the method signature
	const char* signature = generateSignature( methodName, params );

	// lookup the method
	Method* method = lookupMethod( scope, signature );
	if( method == NULL ) {
		// generate the error message
		char* errorMessage = new char[256];
		sprintf( errorMessage, "Method '%s' could not be found", signature );

		// display the error message
		SYNTAX_ERROR( errorMessage, stack->last() );
		delete errorMessage;
		return -1;
	}
	else {
		printf( "CodeParser::parseExpression: Method call - [%s]\n", signature );

		// get the code buffer
		CodeBuffer* cb = scope->getCodeBuffer();

		// parse the method parameter


		// setup the method call
		// instruction: PARAMS methodParams
		// instruction: INVOKE methodSig
		OFFSET_T offset1 = cb->putInstruction( PARAMS << A_OP );
		OFFSET_T offset2 = cb->putInstruction( INVOKE << A_OP );

		// add the parameter and reference data
		scope->addParameterData( new ParameterData( state->nextParamId(), params, offset1 ) );
		scope->addReferenceData( new ReferenceData( state->nextDataRefId(), signature, offset2 ) );
		return 0;
	}
}
Beispiel #12
0
bool objOffsetIsset(
  ObjectData* base,
  TypedValue offset,
  bool validate /* = true */
) {
  auto exists = objOffsetExists(base, offset);

  // Unless we called ArrayObject::offsetExists, there's nothing more to do.
  if (exists != OffsetExistsResult::IssetIfNonNull) {
    return (int)exists;
  }

  // For ArrayObject::offsetExists, we need to check the value at `offset`.  If
  // it's null, then we return false.  We can't call the offsetGet method on
  // `base` because users aren't expecting offsetGet to be called for
  // `isset(...)` expressions, so call the method on the base ArrayObject class.
  auto const cls = SystemLib::s_ArrayObjectClass;
  auto const method = cls->lookupMethod(s_offsetGet.get());
  assert(method != nullptr);

  auto result = g_context->invokeMethodV(base, method, InvokeArgs(&offset, 1));
  return !result.isNull();
}
Beispiel #13
0
void SmalltalkVM::setupVarsForDoesNotUnderstand(hptr<TMethod>& method, hptr<TObjectArray>& arguments, TSymbol* selector, TClass* receiverClass) {
    // Looking up the #doesNotUnderstand: method:
    method = newPointer(lookupMethod(globals.badMethodSymbol, receiverClass));
    if (method == 0) {
        // Something goes really wrong.
        // We could not continue the execution
        std::fprintf(stderr, "Could not locate #doesNotUnderstand:\n");
        //exit(1);
    }

    // Protecting the selector pointer because it may be invalidated later
    hptr<TSymbol> failedSelector = newPointer(selector);

    // We're replacing the original call arguments with custom one
    hptr<TObjectArray> errorArguments = newObject<TObjectArray>(2);

    // Filling in the failed call context information
    errorArguments[0] = arguments[0];   // receiver object
    errorArguments[1] = failedSelector; // message selector that failed

    // Replacing the arguments with newly created one
    arguments = errorArguments;
}
Beispiel #14
0
void c_Closure::init(int numArgs, ActRec* ar, TypedValue* sp) {
  auto const cls = getVMClass();
  auto const invokeFunc = cls->lookupMethod(s_uuinvoke.get());

  if (ar->hasThis()) {
    if (invokeFunc->isStatic()) {
      // Only set the class for static closures.
      setClass(ar->getThis()->getVMClass());
    } else {
      setThis(ar->m_this);
      ar->getThis()->incRefCount();
    }
  } else if (ar->hasClass()) {
    setClass(ar->getClass());
  } else {
    m_ctx = nullptr;
  }

  /*
   * Copy the use vars to instance variables, and initialize any
   * instance properties that are for static locals to KindOfUninit.
   */
  auto const numDeclProperties = cls->numDeclProperties();
  assertx(numDeclProperties - numArgs == getInvokeFunc()->numStaticLocals());
  auto beforeCurUseVar = sp + numArgs;
  auto curProperty = getUseVars();
  int i = 0;
  assertx(numArgs <= numDeclProperties);
  for (; i < numArgs; i++) {
    // teleport the references in here so we don't incref
    tvCopy(*--beforeCurUseVar, *curProperty++);
  }
  for (; i < numDeclProperties; ++i) {
    tvWriteUninit(curProperty++);
  }
}
Beispiel #15
0
void SmalltalkVM::doSendMessage(TVMExecutionContext& ec, TSymbol* selector, TObjectArray* arguments, TClass* receiverClass /*= 0*/ )
{
    hptr<TObjectArray> messageArguments = newPointer(arguments);

    if (!receiverClass) {
        TObject* receiver = messageArguments[0];
        assert(receiver != 0);
        receiverClass = isSmallInteger(receiver) ? globals.smallIntClass : receiver->getClass();
        assert(receiverClass != 0);
    }

    hptr<TMethod> receiverMethod = newPointer(lookupMethod(selector, receiverClass));

    // Checking whether we found a method
    if (receiverMethod == 0) {
        // Oops. Method was not found. In this case we should send #doesNotUnderstand: message to the receiver
        setupVarsForDoesNotUnderstand(receiverMethod, messageArguments, selector, receiverClass);
        // Continuing the execution just as if #doesNotUnderstand: was the actual selector that we wanted to call
    }

    // Save stack and opcode pointers
    ec.storePointers();

    // Create a new context for the giving method and arguments
    hptr<TContext>   newContext = newObject<TContext>();
    hptr<TObjectArray> newStack = newObject<TObjectArray>(receiverMethod->stackSize);
    hptr<TObjectArray> newTemps = newObject<TObjectArray>(receiverMethod->temporarySize);

    newContext->stack           = newStack;
    newContext->temporaries     = newTemps;
    newContext->arguments       = messageArguments;
    newContext->method          = receiverMethod;
    newContext->stackTop        = 0;
    newContext->bytePointer     = 0;

    // Suppose that current send message operation is last operation in the current context.
    // If it is true then next instruction will be either stackReturn or blockReturn.
    //
    // VM will switch to the newContext, perform it and then switch back to the current context
    // for the single one return instruction. This is pretty dumb to load the whole context
    // just to exit it immediately. Therefore, we looking one instruction ahead to see if it is
    // a return instruction. If it is, we may skip our context and set our previousContext as
    // previousContext for the newContext. In case of blockReturn it will be the previousContext
    // of the wrapping method context.

    uint8_t nextInstruction = ec.currentContext->method->byteCodes->getByte(ec.bytePointer);
    if (nextInstruction == (opcode::doSpecial * 16 + special::stackReturn)) {
        // Optimizing stack return
        newContext->previousContext = ec.currentContext->previousContext;
    } else if (nextInstruction == (opcode::doSpecial * 16 + special::blockReturn) &&
              (ec.currentContext->getClass() == globals.blockClass))
    {
        // Optimizing block return
        newContext->previousContext = ec.currentContext.cast<TBlock>()->creatingContext->previousContext;
    } else {
        newContext->previousContext = ec.currentContext;
    }
    // Replace current context with the new one. On the next iteration,
    // VM will start interpreting instructions from the new context.
    ec.currentContext = newContext;
    ec.loadPointers();

    m_messagesSent++;
}
Beispiel #16
0
APCHandle::Pair APCObject::Construct(ObjectData* objectData) {
  // This function assumes the object and object/array down the tree have no
  // internal references and do not implement the serializable interface.
  assert(!objectData->instanceof(SystemLib::s_SerializableClass));

  auto cls = objectData->getVMClass();
  auto clsOrName = make_class(cls);
  if (clsOrName.right()) return ConstructSlow(objectData, clsOrName);

  // We have a persistent Class. Build an array of APCHandle* to mirror the
  // declared properties in the object.
  auto const propInfo = cls->declProperties();
  auto const hasDynProps = objectData->hasDynProps();
  auto const numRealProps = propInfo.size();
  auto const numApcProps = numRealProps + hasDynProps;
  auto size = sizeof(APCObject) + sizeof(APCHandle*) * numApcProps;
  auto const apcObj = new (malloc_huge(size)) APCObject(clsOrName, numApcProps);
  apcObj->m_persistent = 1;

  // Set a few more flags for faster fetching: whether or not the object has a
  // wakeup method, and whether or not we can use a fast path that avoids
  // default-initializing properties before setting them to their APC values.
  if (!cls->lookupMethod(s___wakeup.get())) apcObj->m_no_wakeup = 1;
  if (!cls->instanceCtor()) {
    apcObj->m_fast_init = 1;
  }

  auto const apcPropVec = apcObj->persistentProps();
  auto const objPropVec = objectData->propVec();
  const TypedValueAux* propInit = nullptr;

  for (unsigned i = 0; i < numRealProps; ++i) {
    auto const attrs = propInfo[i].attrs;
    assert((attrs & AttrStatic) == 0);

    const TypedValue* objProp;
    if (attrs & AttrBuiltin) {
      // Special properties like the Memoize cache should be set to their
      // default value, not the current value.
      if (propInit == nullptr) {
        propInit = cls->pinitVec().empty() ? &cls->declPropInit()[0]
                                           : &(*cls->getPropData())[0];
      }

      objProp = propInit + i;
    } else {
      objProp = objPropVec + i;
    }

    auto val = APCHandle::Create(tvAsCVarRef(objProp), false,
                                 APCHandleLevel::Inner, true);
    size += val.size;
    apcPropVec[i] = val.handle;
  }

  if (UNLIKELY(hasDynProps)) {
    auto val = APCHandle::Create(objectData->dynPropArray(), false,
                                 APCHandleLevel::Inner, true);
    size += val.size;
    apcPropVec[numRealProps] = val.handle;
  }

  return {apcObj->getHandle(), size};
}
Beispiel #17
0
void detachThread(Thread *thread) {
    Object *group, *excep;
    //ExecEnv *ee = thread->ee;
    //Object *jThread = ee->thread;
    Object *jThread = thread->thread;
    Object *vmthread = (Object*)INST_DATA(jThread)[vmthread_offset];

    /* Get the thread's group */
    group = (Object *)INST_DATA(jThread)[group_offset];

    /* If there's an uncaught exception, call uncaughtException on the thread's
       exception handler, or the thread's group if this is unset */
    if((excep = exceptionOccurred())) {
        FieldBlock *fb = findField(thread_class, SYMBOL(exceptionHandler),
                                                 SYMBOL(sig_java_lang_Thread_UncaughtExceptionHandler));
        Object *thread_handler = fb == NULL ? NULL : (Object *)INST_DATA(jThread)[fb->offset];
        Object *handler = thread_handler == NULL ? group : thread_handler;

        MethodBlock *uncaught_exp = lookupMethod(handler->classobj, SYMBOL(uncaughtException),
                                                 SYMBOL(_java_lang_Thread_java_lang_Throwable__V));

        if(uncaught_exp) {
            clearException();
            DummyFrame dummy;
            executeMethod(&dummy, handler, uncaught_exp, jThread, excep);
        } else
            printException();
    }

    /* remove thread from thread group */
    DummyFrame dummy;
    executeMethod(&dummy, group, (CLASS_CB(group->classobj))->method_table[rmveThrd_mtbl_idx], jThread);

    /* set VMThread ref in Thread object to null - operations after this
       point will result in an IllegalThreadStateException */
    INST_DATA(jThread)[vmthread_offset] = 0;

    /* Remove thread from the ID map hash table */
    deleteThreadFromHash(thread);

    /* Disable suspend to protect lock operation */
    disableSuspend(thread);

    /* Grab global lock, and update thread structures protected by
       it (thread list, thread ID and number of daemon threads) */
    pthread_mutex_lock(&lock);

    /* remove from thread list... */
    if((thread->prev->next = thread->next))
        thread->next->prev = thread->prev;

    /* One less live thread */
    threads_count--;

    /* Recycle the thread's thread ID */
    freeThreadID(thread->id);

    /* Handle daemon thread status */
    if(!INST_DATA(jThread)[daemon_offset])
        non_daemon_thrds--;

    pthread_mutex_unlock(&lock);

    /* notify any threads waiting on VMThread object -
       these are joining this thread */
    objectLock(vmthread);
    objectNotifyAll(vmthread);
    objectUnlock(vmthread);

    /* It is safe to free the thread's ExecEnv and stack now as these are
       only used within the thread.  It is _not_ safe to free the native
       thread structure as another thread may be concurrently accessing it.
       However, they must have a reference to the VMThread -- therefore, it
       is safe to free during GC when the VMThread is determined to be no
       longer reachable. */
//    sysFree(ee->stack);
    //sysFree(ee);

    /* If no more daemon threads notify the main thread (which
       may be waiting to exit VM).  Note, this is not protected
       by lock, but main thread checks again */

    if(non_daemon_thrds == 0) {
        /* No need to bother with disabling suspension
         * around lock, as we're no longer on thread list */
        pthread_mutex_lock(&exit_lock);
        pthread_cond_signal(&exit_cv);
        pthread_mutex_unlock(&exit_lock);
    }

    TRACE("Thread 0x%x id: %d detached from VM\n", thread, thread->id);
}
Beispiel #18
0
int main(int argc, char *argv[]) {
    Class *array_class, *main_class;
    Object *system_loader, *array;
    MethodBlock *mb;
    InitArgs args;
    int class_arg;
    char *cpntr;
    int status;
    int i;

    setDefaultInitArgs(&args);
    class_arg = parseCommandLine(argc, argv, &args);

    args.main_stack_base = &array_class;
    initVM(&args);

   if((system_loader = getSystemClassLoader()) == NULL) {
        printf("Cannot create system class loader\n");
        printException();
        exitVM(1);
    }

    mainThreadSetContextClassLoader(system_loader);

    for(cpntr = argv[class_arg]; *cpntr; cpntr++)
        if(*cpntr == '.')
            *cpntr = '/';

    if((main_class = findClassFromClassLoader(argv[class_arg], system_loader)) != NULL)
        initClass(main_class);

    if(exceptionOccurred()) {
        printException();
        exitVM(1);
    }

    mb = lookupMethod(main_class, SYMBOL(main), SYMBOL(_array_java_lang_String__V));
    if(!mb || !(mb->access_flags & ACC_STATIC)) {
        printf("Static method \"main\" not found in %s\n", argv[class_arg]);
        exitVM(1);
    }

    /* Create the String array holding the command line args */

    i = class_arg + 1;
    if((array_class = findArrayClass(SYMBOL(array_java_lang_String))) &&
           (array = allocArray(array_class, argc - i, sizeof(Object*))))  {
        Object **args = (Object**)ARRAY_DATA(array) - i;

        for(; i < argc; i++)
            if(!(args[i] = Cstr2String(argv[i])))
                break;

        /* Call the main method */
        if(i == argc)
            executeStaticMethod(main_class, mb, array);
    }

    /* ExceptionOccurred returns the exception or NULL, which is OK
       for normal conditionals, but not here... */
    if((status = exceptionOccurred() ? 1 : 0))
        printException();

    /* Wait for all but daemon threads to die */
    mainThreadWaitToExitVM();
    exitVM(status);
}
Beispiel #19
0
bool LuaInterface::callMethod(ScriptObject *obj, const char *func, float f)
{
    lookupMethod(obj, func);
    lua_pushnumber(_lua, f);
    return doCall(2);
}
Beispiel #20
0
UserFile::UserFile(Class *cls, CVarRef context /*= null */) : UserFSNode(cls) {
  m_StreamOpen  = lookupMethod(s_stream_open.get());
  m_StreamClose = lookupMethod(s_stream_close.get());
  m_StreamRead  = lookupMethod(s_stream_read.get());
  m_StreamWrite = lookupMethod(s_stream_write.get());
  m_StreamSeek  = lookupMethod(s_stream_seek.get());
  m_StreamTell  = lookupMethod(s_stream_tell.get());
  m_StreamEof   = lookupMethod(s_stream_eof.get());
  m_StreamFlush = lookupMethod(s_stream_flush.get());
  m_StreamTruncate = lookupMethod(s_stream_truncate.get());
  m_StreamLock  = lookupMethod(s_stream_lock.get());
  m_StreamStat  = lookupMethod(s_stream_stat.get());
  m_UrlStat     = lookupMethod(s_url_stat.get());
  m_Unlink      = lookupMethod(s_unlink.get());
  m_Rename      = lookupMethod(s_rename.get());
  m_Mkdir       = lookupMethod(s_mkdir.get());
  m_Rmdir       = lookupMethod(s_rmdir.get());
  m_isLocal = true;

  // UserFile, to match Zend, should not call stream_close() unless it was ever
  // opened. This is a bit of a misuse of this field but the API doesn't allow
  // one direct access to an not-yet-opened stream resource so it should be
  // safe.
  m_closed = true;
}
bool LuaInterface::callMethod(void *o, const char *func)
{
    lookupMethod(o, func);
    return doCall(0+1); // first parameter is self (aka o)
}
Beispiel #22
0
UserFile::UserFile(Class *cls, CVarRef context /*= null */) :
                   UserFSNode(cls), m_opened(false) {
  m_StreamOpen  = lookupMethod(s_stream_open.get());
  m_StreamClose = lookupMethod(s_stream_close.get());
  m_StreamRead  = lookupMethod(s_stream_read.get());
  m_StreamWrite = lookupMethod(s_stream_write.get());
  m_StreamSeek  = lookupMethod(s_stream_seek.get());
  m_StreamTell  = lookupMethod(s_stream_tell.get());
  m_StreamEof   = lookupMethod(s_stream_eof.get());
  m_StreamFlush = lookupMethod(s_stream_flush.get());
  m_StreamTruncate = lookupMethod(s_stream_truncate.get());
  m_StreamLock  = lookupMethod(s_stream_lock.get());
  m_UrlStat     = lookupMethod(s_url_stat.get());
  m_isLocal = true;
}
Beispiel #23
0
UserDirectory::UserDirectory(Class* cls) : UserFSNode(cls) {
  m_DirOpen  = lookupMethod(s_dir_opendir.get());
  m_DirClose = lookupMethod(s_dir_closedir.get());
  m_DirRead  = lookupMethod(s_dir_readdir.get());
  m_DirRewind  = lookupMethod(s_dir_rewinddir.get());
}
Beispiel #24
0
bool LuaInterface::callMethod(ScriptObject *obj, const char *func)
{
    lookupMethod(obj, func);
    return doCall(1);
}