Show Changes Show Changes
Edit Edit
Print Print
Recent Changes Recent Changes
Subscriptions Subscriptions
Lost and Found Lost and Found
Find References Find References
Rename Rename
Administration Page Administration Page
Topic Locks Topic Locks

Search

History

5/31/2011 3:39:39 AM
-173.16.151.55
4/27/2011 9:41:24 AM
-92.112.48.166
10/4/2007 9:51:01 PM
-82.148.98.34
7/10/2007 3:39:56 PM
ad-remover-84.49.122.139
5/30/2007 12:38:14 PM
-125.72.28.38
List all versions List all versions

RSS feed for the SquirrelWiki namespace

Sq Plus Create Construct Native Class Instance Bug
.

acsitdo

[Fix added to release 18, 5/28/06. jcs]

The following code produces an error:

#include <stdarg.h> 
#include <stdio.h> 

#include <squirrel.h> 
#include <sqstdio.h> 
#include <sqstdaux.h> 
#include <sqplus.h> 

#ifdef SQUNICODE 
#define scvprintf vwprintf 
#else 
#define scvprintf vprintf 
#endif 

class Point3
{
public:
  float x, y, z;
};

DECLARE_INSTANCE_TYPE(Point3);

class Entity
{
public:
  void test(Point3& p)
  {
    if (scriptTest.func.IsNull())
      printf("invalid function\n");
    else
    {
      printf("p = {%f, %f, %f}\n", p.x, p.y, p.z);
      scriptTest(p);
    }
  }

  static int construct(HSQUIRRELVM v)
  {
    printf("construct()\n");
    StackHandler sa(v);

    Entity *self = new Entity();
    self->scriptTest = SqPlus::SquirrelFunction<void>(sa.GetObjectHandle(1),_T("test"));

    self->scriptObjHandle = sa.GetObjectHandle(1);
    sq_addref(SquirrelVM::GetVMPtr(), &self->scriptObjHandle);

    return SqPlus::PostConstruct<Entity>(v, self, release);
  }
  SQ_DECLARE_RELEASE(Entity);

private:
  SqPlus::SquirrelFunction<void> scriptTest;
  HSQOBJECT scriptObjHandle;
};


DECLARE_INSTANCE_TYPE(Entity);

void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
{
  va_list arglist;
  va_start(arglist, s);
  vprintf(s, arglist);
  va_end(arglist);
}

int main()
{
  SquirrelVM::Init();

  sq_setprintfunc(SquirrelVM::GetVMPtr(), printfunc);

  HSQUIRRELVM v = SquirrelVM::GetVMPtr();

  SqPlus::SQClassDef<Entity>("Entity")
    .staticFuncVarArgs(&Entity::construct, "constructor", "*")
  ;
  SqPlus::SQClassDef<Point3>("Point3")
  ;


  SquirrelObject inst = SquirrelVM::CompileBuffer("\
    class A extends Entity {\n\
      function test(pos) {value=1; print(\"pos.x = \"+pos.x);}\n\
      value = 10;\n\
    };\n\
    function create() {return A();}\n\
  ");

  SquirrelVM::RunScript(inst);

  Entity *e = SqPlus::SquirrelFunction<Entity*>("create")();

  Point3 pt = {1,2,3};
  e->test(pt);

  SquirrelVM::Shutdown();

  return 0;
}

When executed it produces the following output:

construct()
p = {1.000000, 2.000000, 3.000000}

AN ERROR HAS OCCURED [the index 'value' does not exist]

CALLSTACK
*FUNCTION [test()] console buffer line [2]

LOCALS
[pos] INSTANCE
[this] TABLE

Note that error is in referencing member value and type of this is table.

That is because of bug in CreateConstructNativeClassInstance function.

inline BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className) {
  int oldtop = sq_gettop(v);
  sq_pushroottable(v);
  sq_pushstring(v,className,-1);
  if (SQ_FAILED(sq_rawget(v,-2))) { // Get the class (created with sq_newclass()).
    sq_settop(v,oldtop);
    return FALSE;
  } // if
  sq_remove(v,-3); // Remove the root table.
  sq_push(v,1);    // Push the 'this'.
  if (SQ_FAILED(sq_call(v,1,SQTrue))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called).
    sq_settop(v,oldtop);
    return FALSE;
  } // if
  sq_remove(v,-2); // Remove the class.
  //  int newtop = sq_gettop(v);
  return TRUE;
} // CreateConstructNativeClassInstance

Bug is in these lines:

sq_remove(v,-3); // Remove the root table. 
//^ -3 is index before root table pushed first at beginning of this function! 

sq_push(v,1); // Push the 'this'. 
//^ 1 is also invalid index because there was something on stack before

To fix this it is needed to replace them with

sq_remove(v,-2); // Remove the root table. 
sq_pushroottable(v); // Push the 'this'.
Not logged in. Log in

squirrel's community wiki

This is FlexWiki, an open source wiki engine.

Change Style

Recent Topics